[Solved] Create a userfield if not excisting yet

Creating a macro - Writing a Script - Using the API

[Solved] Create a userfield if not excisting yet

Postby Stijn » Tue Feb 19, 2008 4:34 pm

Hello,

I am currently creating a LotusScript for Lotus Notes to automaticly generate documents.
LotusScript is based on VB. I am new to both LotusScript as VB so I might have made some mistakes.

I want to add values to userfields if they excist, if they don't then it should be created and this should be filled.
the problem is creating the new field, I found some java samples where a property value is needed to create the new field,
I thought this should be the way to do this.

Thanks in advance, Stijn.

Code: Select all   Expand viewCollapse view
'-----------------------------------------------------------------------------------
'--- FUNCTION:       AddDocumentField
'--- DESCRIPTION: Fills the field or adds the field if not available.
'--- Reflection: "com.sun.star.reflection.CoreReflection"
'-----------------------------------------------------------------------------------
Function AddDocumentField(strName As String, strValue As String, oFields, Reflection)
   On Error Goto ErrorHandler
      
onExit:         
   Dim field
   Set field = oFields.getByName("com.sun.star.text.FieldMaster.User."+strName)
   If Not field Is Nothing Then
      Call field.setPropertyValue("Content", strValue)
   End If
   Exit Function
ErrorHandler:
   Dim args(0)
   
   Set args(0) = createPropertyStruct("com.sun.star.text.FieldMaster.User", Reflection)
   args(0).Name = strName
   args(0).Value = strValue
   
   oFields.attachTextFieldMaster(args)
   
   Resume onExit
EndErrorHandler:
End Function
   
   
'---------------------------------------------------------------------------------------------------------------------
'--- FUNCTION:       createPropertyStruct
'--- DESCRIPTION: Create a property which can being added to the OOo / Symphony document.
'---------------------------------------------------------------------------------------------------------------------
Function createPropertyStruct(strTypeName As String, objCoreReflection As Variant) As Variant
   Dim classSize As Variant
   Print strTypeName
   Set classSize =  objCoreReflection.forName(strTypeName)       'This object is not been made and results in Nothing.
   Dim aStruct
   classSize.createObject aStruct       'because classSize is nothing an error shows.
   Set createPropertyStruct = aStruct
End Function
Last edited by Stijn on Wed Feb 20, 2008 6:14 pm, edited 1 time in total.
Stijn
 
Posts: 6
Joined: Tue Feb 19, 2008 4:13 pm

Re: Create a userfield if not excisting yet

Postby pitonyak » Wed Feb 20, 2008 5:27 am

Code: Select all   Expand viewCollapse view
vDoc = ThisComponent
sName = "Author Name"
If vDoc.getTextFieldMasters().hasByName("com.sun.star.text.FieldMaster.User." & sName) Then
  vField = vDoc.getTextFieldMasters().getByName("com.sun.star.text.FieldMaster.User." & sName)
  vField.Content = "Andrew Pitonyak"
  'vField.Value = 2.3  REM If you would rather this were a number!
Else
  vField = vDoc.createInstance("com.sun.star.text.FieldMaster.User")
  vField.Name = sName
  vField.Content = "Andrew Pitonyak"
  'vField.Value = 2.3  REM If you would rather this were a number!
End If


Notice that the document creates the user field (or at least it creates master field). I see that this routine does not bother to insert the field into the document. Take a look at this example:
Code: Select all   Expand viewCollapse view
'===========================================================================
' InsertDocumentVariable - routine used to insert a document variable into the document
' user's textfield list and into the ad text, at the current cursor
' position
' In  - strVarName: string with the name of the variable to be inserted
'       oTxtCursor: current cursor object with the position to place the doc var
' Out - none
'===========================================================================
Sub InsertDocumentVariable(strVarName As String, oTxtCursor As Object)

  oActiveDocument = thisComponent
  objField = thisComponent.createInstance("com.sun.star.text.TextField.User")
  sName = "com.sun.star.text.FieldMaster.User." + strVarName
  bFound = oActiveDocument.getTextFieldMasters.hasbyname(sName)  ' check if variable exists
  if bFound Then
    objFieldMaster =  oActiveDocument.getTextFieldMasters.getByName(sName)         
    objField.attachTextFieldMaster(objFieldMaster)
    ' Insert the Text Field
    oText = thisComponent.Text
    'oCursor = oText.createTextCursor()             
    'oCursor.gotoEnd(false)
    oText.insertTextContent(oTxtCursor, objField, false)
  End If
End Sub


Notice that the field is attached to a master and then inserted into the document. Does this OOo Basic example help any?
Andrew Pitonyak
http://www.pitonyak.org/oo.php
LO and AOO on Fedora
pitonyak
Volunteer
 
Posts: 186
Joined: Sun Oct 07, 2007 9:13 pm
Location: Columbus, Ohio, USA

Re: Create a userfield if not excisting yet

Postby Stijn » Wed Feb 20, 2008 11:20 am

Thanks alot for your response Pitonyak.

I have edited my code now, but I get an error when I create the new field.
Error: Instance member NAME does not exist

Any Idea what makes this error Occure and how to solve it?

Thanks,
Stijn.

Edit: The fields don't have to be visible btw, the values are needed for an IBM Lotus Symphony plugin.

Code: Select all   Expand viewCollapse view
'-----------------------------------------------------------------------------------
'--- FUNCTION:       AddDocumentField
'--- DESCRIPTION: Fills the field or adds the field if not available.
'-----------------------------------------------------------------------------------
Function AddDocumentField(strName As String, strValue As String, oDoc, Reflection)
   Dim oFieldMaster
   Dim oField
   
   'get the textfield master which contains all the textfields
   Set oFieldMaster  = oDoc.getTextFieldMasters()
   
   If oFieldMaster.hasByName("com.sun.star.text.FieldMaster.User."+strName) Then
      Set oField = oFieldMaster.getByName("com.sun.star.text.FieldMaster.User."+strName)
      Call oField.setPropertyValue("Content", strValue)
   Else
      Messagebox "Create new field:" & strName & "->" & strValue
      Set oField = oDoc.createInstance("com.sun.star.text.TextField.User")
      'Call oField.setPropertyValue("Name", strName)
      'Call oField.setPropertyValue("Content", strValue)
      oField.Name = strName           'This field can not be found for some reason, did the createInstance failed?
      oField.Content = strValue
      Call oField.attachTextFieldMaster(oFieldMaster)
      
      If(oFieldMaster.hasbyname( "com.sun.star.text.FieldMaster.User." + strName)) Then  ' check if variable exists
         Messagebox "Field added"
      Else
         Messagebox "Failed to add field"
      End If
   End If
End Function
Stijn
 
Posts: 6
Joined: Tue Feb 19, 2008 4:13 pm

Re: Create a userfield if not excisting yet

Postby pitonyak » Wed Feb 20, 2008 4:52 pm

I just tested the following macro

Code: Select all   Expand viewCollapse view
Sub InsertDocumentVariable()
  Dim strVarName$
  Dim oTxtCursor
  Dim objFieldMaster
  Dim objField
  Dim sName$
  Dim bFound As Boolean
  Dim oText

  strVarName = "AuthorName"
  oTxtCursor = ThisComponent.CurrentController.getViewCursor()

  sName = "com.sun.star.text.FieldMaster.User." + strVarName
  bFound = thisComponent.getTextFieldMasters.hasbyname(sName)  ' check if variable exists
 
  If NOT bFound Then
    objFieldMaster = thisComponent.createInstance("com.sun.star.text.FieldMaster.User")
    objFieldMaster.Name = strVarName
    objFieldMaster.Content = "Andrew Pitonyak"
  Else
    objFieldMaster =  thisComponent.getTextFieldMasters.getByName(sName)
  End If
 
  objField = thisComponent.createInstance("com.sun.star.text.TextField.User")
  objField.attachTextFieldMaster(objFieldMaster)
  oText = oTxtCursor.Text
  oText.insertTextContent(oTxtCursor, objField, false)
End Sub


Notice that the name that I set for the master is "AuthorName". Initially, I tried to set it to com.sun.star.text.FieldMaster.User.AuthorName, but this caused an error. This gives me a few thoughts.

Oops, now I take a closer look at your code... I see the problem clearly...

You have a text field master that contains the text to display. Each text field master may have zero to many attached user fields. All user fields display the value in their text field master. You must create the text field master if it does not exist. You name the text field master and set the value in the text field master.

When you desire to insert a user field, you create the user field, attach it to the master, and insert the field into the document. You do NOT name the user field.

You are NOT creating a master field. You then create a user field and try to set its name. I will add some comments to your code:

Code: Select all   Expand viewCollapse view
'-----------------------------------------------------------------------------------
'--- FUNCTION:       AddDocumentField
'--- DESCRIPTION: Fills the field or adds the field if not available.
'-----------------------------------------------------------------------------------
Function AddDocumentField(strName As String, strValue As String, oDoc, Reflection)
   Dim oFieldMasters   'All of the document master fields
   Dim oFieldMaster     'Specific document master field
   Dim oField
   
   'get the textfield master which contains all the textfields
   Set oFieldMasters  = oDoc.getTextFieldMasters()
   
   If oFieldMaster.hasByName("com.sun.star.text.FieldMaster.User."+strName) Then
      Set oFieldMaster = oFieldMaster.getByName("com.sun.star.text.FieldMaster.User."+strName)
  Else
      Set oFieldMaster = oDoc.createInstance("com.sun.star.text.FieldMaster.User")
      Call oFieldMaster.setPropertyValue("Name", strName)
  EndIf
  // I moved this out of the loop
  Call oFieldMaster.setPropertyValue("Content", strValue)

  // Now, create your field to insert
  // DO not set name or content, the value will come from the
  // master field.
  Set oField = oDoc.createInstance("com.sun.star.text.TextField.User")
  Call oField.attachTextFieldMaster(oFieldMaster)

  // You MUST insert this text field into the document if you want to display the text...
     
      If(oFieldMasters.hasbyname( "com.sun.star.text.FieldMaster.User." + strName)) Then  ' check if variable exists
         Messagebox "Field added"
      Else
         Messagebox "Failed to add field"
      End If
   End If
End Function


I did not test this code in any way....
Andrew Pitonyak
http://www.pitonyak.org/oo.php
LO and AOO on Fedora
pitonyak
Volunteer
 
Posts: 186
Joined: Sun Oct 07, 2007 9:13 pm
Location: Columbus, Ohio, USA

Re: Create a userfield if not excisting yet

Postby Stijn » Wed Feb 20, 2008 6:13 pm

Thanks alot! Problem solved thanks to you!
There still was a little error in the code, but as you said, you didn't test the code, so that understandable :)
If anyone else wants to use this code, note that the fields are NOT being shown on the document.
They can be added to the document manually using the UserField system (Ctrl+F2 or Insert -> Fields -> Other).
Or you can extend this code ofc. to make it visible.

Code: Select all   Expand viewCollapse view
'---------------------------------------------------------------------------------------------------------
'--- FUNCTION:       AddDocumentField
'--- DESCRIPTION: Fills the field or adds the field if not available.
'---------------------------------------------------------------------------------------------------------
Function AddDocumentField(strName As String, strValue As String, oDoc, Reflection)
   Dim oFieldMasters   'All of the document master fields
   Dim oFieldMaster     'Specific document master field
   Dim oField
   
   'get the textfield master which contains all the textfields
   Set oFieldMasters  = oDoc.getTextFieldMasters()
   
   'If the field excists in the document, use it, else create a new field.
   If oFieldMasters.hasByName("com.sun.star.text.FieldMaster.User."+strName) Then
      Set oFieldMaster = oFieldMasters.getByName("com.sun.star.text.FieldMaster.User."+strName)
   Else
      Set oFieldMaster = oDoc.createInstance("com.sun.star.text.FieldMaster.User")
      Call oFieldMaster.setPropertyValue("Name", strName)
   End If
   
   'Set the value of the field
   Call oFieldMaster.setPropertyValue("Content", strValue)
   
   ' Create your field to insert
   ' Do not set name or content, the value will come from the
   ' master field.
   Set oField = oDoc.createInstance("com.sun.star.text.TextField.User")
   Call oField.attachTextFieldMaster(oFieldMaster)
End Function
Stijn
 
Posts: 6
Joined: Tue Feb 19, 2008 4:13 pm


Return to Macros and UNO API

Who is online

Users browsing this forum: Peterd51 and 9 guests