[Solved] Create a userfield if not excisting yet

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
Stijn
Posts: 6
Joined: Tue Feb 19, 2008 4:13 pm

[Solved] Create a userfield if not excisting yet

Post by Stijn »

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

'-----------------------------------------------------------------------------------
'--- 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.
pitonyak
Volunteer
Posts: 186
Joined: Sun Oct 07, 2007 9:13 pm
Location: Columbus, Ohio, USA

Re: Create a userfield if not excisting yet

Post by pitonyak »

Code: Select all

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

'===========================================================================
' 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
Stijn
Posts: 6
Joined: Tue Feb 19, 2008 4:13 pm

Re: Create a userfield if not excisting yet

Post by Stijn »

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

'-----------------------------------------------------------------------------------
'--- 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
pitonyak
Volunteer
Posts: 186
Joined: Sun Oct 07, 2007 9:13 pm
Location: Columbus, Ohio, USA

Re: Create a userfield if not excisting yet

Post by pitonyak »

I just tested the following macro

Code: Select all

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

'-----------------------------------------------------------------------------------
'--- 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
Stijn
Posts: 6
Joined: Tue Feb 19, 2008 4:13 pm

Re: Create a userfield if not excisting yet

Post by Stijn »

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

'---------------------------------------------------------------------------------------------------------
'--- 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
Post Reply