Wolfgang,
I verified that there is a bug related to how Basic handles arrays of Structures.
I tested against LibreOffice 7.2.2.2 on Fedora Linux as well as Windows 7.1.2.2 and 7.2.4.1 so I filed a bug report:
https://bugs.documentfoundation.org/show_bug.cgi?id=146082
Note that a Structure copies by value, not be reference.
A work around until the bug is fixed, is to not use a notation such as:
Dim p(1 To 2) As PersonType
Dim p(1 To 2) As New com.sun.star.awt.Point
Instead, define the array as an Object or Variant and then initialize each entry
p(1) = CreateUnoStruct( "com.sun.star.awt.Point" )
p(2) = CreateUnoStruct( "com.sun.star.awt.Point" )
Use CreateObject("PersonType") for user defined types.
Developers,
Any suggestions as to where I might find the code where an array is “initialized” or where to look for handling to suggest what might cause the really strange behavior? I have not looked at LibreOffice code or built it for a while now.
Clearly there are differences in how an UNO struct and a user defined structure is created and stored since an array value might show as different depending on whether or not we copy it after access it. And how different solutions vary depending on the type after passed as an argument.
For those who are interested but too lazy to look up the bug referenced above:
This bug was originally noted with a user defined type so I wrote a test using a built-in UNO Struct com.sun.star.awt.Point
Test using User type “PersonType”
Type PersonType
FirstName As String
LastName As String
End Type
Sub PrintPersons(s, x)
Print "Expect (" & s & ") found (" & x.FirstName & " " & x.LastName & ")"
End Sub
Sub PrintPoint(s, x)
Print "Expect " & s & " Found (" & x.X & ", " & x.Y & ")"
End Sub
This is the original disturbing code. Attempting to copy an element from the array causes problems. The same when trying to assign back into to the array.
Sub otherExampleCreateNewType
REM Producing very strange errors.
REM Inspect the two array elements and h at the same time
REM down to the inside variables while executing lines 19 through 21 stepwise.
Dim Person(1 To 2) As PersonType
Person(1).FirstName = "Andrew"
Person(1).LastName = "Pitonyak"
Person(2).FirstName = "Funny"
Person(2).LastName = "Lupp"
PrintPersons("Andrew", Person(1)) ' Andrew (correct)
PrintPersons("Funny", Person(2)) ' Funny (correct)
Dim h As PersonType
h = Person(1)
Person(1) = Person(2)
Person(2) = h
PrintPersons("Funny", Person(1)) ' Andrew (wrong)
PrintPersons("Andrew", Person(2)) ' Funny (wrong)
REM Now look at the prints, and frown.
Dim h1 As PersonType, h2 As PersonType
h1 = Person(1)
h2 = Person(2)
PrintPersons("Funny", h1) ' Funny (correct)
PrintPersons("Andrew", h2) ' Funny (wrong)
End Sub
Next I run this using a built-in UNO type and have exactly the same incorrect behaviors
Sub otherExampleCreateAWTPoint
Dim p(1 To 2) As New com.sun.star.awt.Point
p(1).X = 1
p(1).Y = 2
p(2).X = 3
p(2).Y = 4
PrintPoint("(1, 2)", p(1)) ' Correct
PrintPoint("(3, 4)", p(2)) ' Correct
Dim h As New com.sun.star.awt.Point
h = p(1)
p(1) = p(2)
p(2) = h
PrintPoint("(3, 4)", p(1)) ' wrong
PrintPoint("(1, 2)", p(2)) ' wrong
REM Now look at the prints, and frown.
Dim h1 As New com.sun.star.awt.Point, h2 As New com.sun.star.awt.Point
h1 = p(1)
h2 = p(2)
PrintPoint("(3, 4)", h1) ' Correct
PrintPoint("(1, 2)", h2) ' Wrong
End Sub
I then changed how the array is declared as shown below and this fixed the problematic
Dim p(1 To 2) As Object
p(1) = CreateUnoStruct( "com.sun.star.awt.Point" )
p(2) = CreateUnoStruct( "com.sun.star.awt.Point" )
Doing the same for the PersonType also causes it to work as expected:
Dim Person(1 To 2) As Object
Person(1) = CreateObject("PersonType")
Person(2) = CreateObject("PersonType")
It gets worse. If I modify the subroutine to always make a copy of the object and then use the object that is passed to the subroutine, then suddenly the first program works for points, but the same fix does not work when done for PersonType.
Sub PrintPoint(s, y)
Dim x
x = y
Print "Expect " & s & " Found (" & x.X & ", " & x.Y & ")"
End Sub
Clearly something is wrong / inconsistent.