BASIC: ByVal and arrays

In short: How to dereference an array?

Explication:

There was not a single strike when I searched the site for ‘ByVal’.

Regarding the distinction between the passing of parameters by reference or by value as a fundamental concept, I had expected otherwise.

LibreOffice BASIC supports the concept offering the keywords ByRef and ByVal as parameter specifiers. I also found a statement somewhere that ByRef Is the default. (External calls -from Calc e.g.- obviously create new dedicated variables to replace the parameters.)

Array variables, however, treat the reference (pointer to the access routine?) as the value itself. This results in the fact that any assignment to a content node of an array, whether made in the primary scope of the array variable or in the body of a routine that got the array passed as a parameter (whether ByRef or ByVal) inevitably afflicts that node independent of the path it is accessed on.

That’s just fine in many cases (where ByRef thinking is applicable). However, there are cases where a new instance of an array, initialized with identical contents, is needed. Even a recursive dereferencing might be needed sometimes concerning arrays containing arrays as elements in some positions.

(I know ways to do it by user code for arrays of a specific dimensionality, of course. But that’s limited and of poor efficiency.)

I do not understand, what do you want to ask. In addition, what “array” do you want to use? A Calc cell range? A Basic array? Something from com::sun::star ?

The question was generally about arrays in LibreOffice BASIC.
An array passed to a function called from a cell formula anyway is a “copy”, better a newly created variable containing the values precalculated in the evaluating process. (Always 2D!)
Assigning arrays to variables or passing them during one run of BASIC to a Routine (Sub or Function) as a parameter assigns/passes a reference.
You may better understand based on my own answer below. (I just intended to post it.)

Since I claimed to know a solution for a “specific dimensionality” in my question, I should prove this. See code below!
I would be happy to get your comments and criticisms on it. In specific I am interested in your experiences if you observe malfunctions. You may first run the test() Sub below and watch the variables in the BASIC IDE to check for my claims.
The now presented solution includes a short test. When I asked my question I had not yet had the idea with the ‘Redim-trick’. Originally there were nested For-loops with elementwise assignments. Now the code:

Function createArrayCopy2D(p2D)
If NOT IsArray(p2D)  Then Exit Function
If NOT (dimensionality(p2D)=2) Then Exit Function
dummy = p2D
l = Array(Lbound(dummy,1), Lbound(dummy,2)
u = Array(Ubound(dummy,1), Ubound(dummy,2)
Redim Preserve dummy(l(0) To u(0), l(1) To u(1))
createArrayCopy2D = dummy
End Function

Function dimensionality(pArray)
dim d As Long ' The code relies on the initialization with 0.
If NOT IsArray(pArray) Then Exit Function
On Local Error Goto doneExit
Do
    d = Ubound(pArray, d+1)*0 + d + 1 
Loop 
doneExit:
dimensionality = d
End Function 

The test actually showed for me consistency with the “theory” I presented in the comments.
(LibreOffice V 6.0.3 under Win 10)

Edit1:
I missed to emphasize that references to other arrays contained in elements of the processed variant array (if any) are not dereferenced.

Edit2:
The above provided code was proven to fail in a different test done by a contributor in a different forum.
I tryed to fix the problem. Please visit the other thread for details.

Edit3:
I replacd the long code containing many lines of remarks by a shortened and slightly reworked version. There also is an enhanced version now inserted below, capable of handlig arrays with up to 5 dimensions.
To find the remarks again and also adiscussion, please visit the above given link.

Function createArrayCopy(pA)
If NOT IsArray(pA)  Then Exit Function
dummy = pA
h     = ArrayDimensions(dummy)
n     = Ubound(h)
Select Case n
    Case > 5
        createArrayCopy = "Only up to 5 dimensions allowed!"
        Exit Function
    Case 1
        Redim Preserve dummy(h(1)(0) To h(1)(1))
    Case 2
        Redim Preserve dummy(h(1)(0) To h(1)(1), h(2)(0) To h(2)(1))
    Case 3
        Redim Preserve dummy(h(1)(0) To h(1)(1), h(2)(0) To h(2)(1), h(3)(0) To h(3)(1))
    Case 4
        Redim Preserve dummy(h(1)(0) To h(1)(1), h(2)(0) To h(2)(1), h(3)(0) To h(3)(1), h(4)(0) To h(4)(1))
    Case 5
        Redim Preserve dummy(h(1)(0) To h(1)(1), h(2)(0) To h(2)(1), h(3)(0) To h(3)(1), h(4)(0) To h(4)(1), h(4)(0) To h(4)(1))
    Case Else
        createArrayCopy = "Unknow error!"
        Exit Function
End Select
createArrayCopy = dummy
End Function

Function arrayDimensions(pArray)
If NOT IsArray(pArray) Then Exit Function
n = dimensionality(pArray)
Dim r(1 To n)
For j = 1 To n
    r(j)  = Array(Lbound(pArray, j) , Ubound(pArray, j) )
Next j
arrayDimensions = r
End Function