1

I've been asked to do something at work, and being that I'm running Ubuntu and not Windows, I have Libre Office (LO Writer is the equivalent of Word). - The task is to automate some contracts, where the document stays 90% the same except for a few variables that change from doc to doc.

First of all - Basic is a nightmare, and generally this whole Macro writing process is also pretty awful.

Now to the "code" - I keep getting some error about BASIC error: Argument is not optional and all I'm trying to do is pass two arrays to another function:

Function test ( ByVal changeFrom() As String ,ByVal changeTo() As String  )
Dim I As Long
Dim Doc As Object
Dim Replace As Object

Doc = ThisComponent

Replace = Doc.createReplaceDescriptor
For I = 0 To 2
  Replace.SearchString = changeFrom(I) //Error is here
  Replace.ReplaceString = changeTo(I)
  Doc.replaceAll(Replace)
Next I
End Function


REM  *****  BASIC  *****
Sub main
Dim changeFrom(3) As String
Dim changeTo(3) As String


changeFrom() = Array("<word2>", "<word3>", "<word1>")
changeTo() = Array("value1", "value2", "value3")
test( changeFrom , changeTo)
End Sub

Generally -

does anyone know a better way for me to do this OTHER than "Basic" which is really driving me crazy.. I understand it can be done with Python, but I kind of wish there was an even easier way, problem is the word document has tables and things which need to be defined, so I can't just copy/paste the template in to a java class and modify it..

Thanks!

5
  • Is it possibly because you defined an array of four items, but only gave it three values?Libre Office Basic Arrays Commented May 15, 2014 at 13:21
  • I don't see what's wrong, but the Libre Office Basic Guide(download) covers this on page 83. Commented May 15, 2014 at 13:32
  • yeah I've downloaded the guide - thanks - however this doesn't help me with my error.. Commented May 15, 2014 at 13:41
  • Don't you need the Call keyword before test( changeFrom , changeTo) like in VBA? Commented May 15, 2014 at 14:07
  • Not according to the guidebook - Can anyone recommend a less tedious way/language of doing this? Sounds so simple but I'm not able to make it happen Commented May 15, 2014 at 14:44

2 Answers 2

2

the Basic function ARRAY() returns a VARIANT that contains an array. So if you use the function ARRAY, you have to dial with Variants:

Function test ( ByVal changeFrom As Variant ,ByVal changeTo As Variant  )
Dim I As Long
Dim Doc As Object
Dim Replace As Object

Doc = ThisComponent

Replace = Doc.createReplaceDescriptor
For I = lbound(changefrom) To ubound(changefrom)
  Replace.SearchString = changeFrom(I) 'Error is here
  Replace.ReplaceString = changeTo(I)
  Doc.replaceAll(Replace)
Next I
End Function


REM  *****  BASIC  *****
Sub main
Dim changeFrom As variant
Dim changeTo As variant

changeFrom = Array("<word2>", "<word3>", "<word1>")
changeTo = Array("value1", "value2", "value3")
test( changeFrom , changeTo)
End Sub

Or if you don't use the function ARRAY, you can use String() arrays:

Function test1 ( ByVal changeFrom() As String ,ByVal changeTo() As String  )
Dim I As Long
Dim Doc As Object
Dim Replace As Object

Doc = ThisComponent

Replace = Doc.createReplaceDescriptor
For I = lbound(changefrom) To ubound(changefrom)
  Replace.SearchString = changeFrom(I)
  Replace.ReplaceString = changeTo(I)
  Doc.replaceAll(Replace)
Next I
End Function


REM  *****  BASIC  *****
Sub main1
Dim changeFrom(2) As String
Dim changeTo(2) As String

changeFrom(0) = "<word2>"
changeFrom(1) = "<word3>"
changeFrom(2) = "<word1>"

changeTo(0) = "value1"
changeTo(1) = "value2"
changeTo(2) = "value3"

test1( changeFrom , changeTo)
End Sub

Greetings

Axel

Sign up to request clarification or add additional context in comments.

1 Comment

Axel's solution should function fine if you change the call to use test1 rather than test in main1.
1

I think that an array is ALWAYS passed as a reference, even if you state that the parameter is by value. I would need to verify that this is still true, but call it 90% certain.

The provided answer properly uses LBound and UBound to use only the limits as set for the passed array. This is likely the largest part of your problem. Now, that said, you can simply the macro and do something like this:

Function test1 (Doc, changeFrom, changeTo)
Dim I As Long
Dim Replace As Object

' A paranoid person would verify the parameters. Things like:
' Are the parameters NOT IsEmpty and Not IsNull
' Is the Doc object really a text document
' Are the other parameters really arrays

Replace = Doc.createReplaceDescriptor
For I = lbound(changefrom) To ubound(changefrom)
  Replace.SearchString = changeFrom(I)
  Replace.ReplaceString = changeTo(I)
  Doc.replaceAll(Replace)
Next I
End Function


REM  *****  BASIC  *****
Sub main1
  test1(ThisComponent, Array("<word2>", "<word3>", "<word1>"), Array("value1", "value2", "value3"))
End Sub

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.