Using ScriptForge breaks failure-free loading of a document after a restart of LibreOffice

That’s the macro getting called as a UDF from a fresh spreadsheet (ODF).

Function examplefun(your_array as variant) As Variant
    GlobalScope.BasicLibraries.loadLibrary("ScriptForge")
    dim my_array() as variant
    
    for each item in your_array()
        my_array = SF_Array.Append(my_array, item)
    next item

    examplefun = my_array
End Function

The Basic IDE pops up here but with no possibility to interact (it’s in the ScriptForge library):

Public Function Item(Optional ByVal Key As Variant) As Variant
'''	Return the value of the item related to Key
'''	Args:
'''		Key: the key value (string)
'''	Returns:
'''		Empty if not found, otherwise the found value
'''	Example:
'''		myDict.Item("ThisKey")
'''	NB: defined as a function to not disrupt the Basic IDE debugger

	Item = _PropertyGet("Item", Key)

End Function	'	ScriptForge.SF_Dictionary.Item

After the first failure, everything works and recalc does its job in the spreadsheet until LibreOffice is closed. Closing the spreadsheet alone does not trigger the issue.

EDIT:

image
examplefun.ods (11.2 KB)

The workaround is below.
The OnOpen macro is assigned to the document open event.

Global Err_init as Long 

Function examplefun(your_array)
    On Error Goto ErrLabel 
    GlobalScope.BasicLibraries.loadLibrary("ScriptForge")
    dim my_array()
    
    for each item in your_array()
        my_array = SF_Array.Append(my_array, item)
    next item

    examplefun = my_array
    Err_init = 2
    Exit Function
ErrLabel:
    Err_init = 1      
End Function

Sub OnOpen(oEvent)
    If  Err_init = 1 Then ThisComponent.calculateAll
End Sub

examplefun.ods (11.0 KB)

@mikekaganski Something I can do or is this somewhere part of a bug report already?

It also breaks on Collabora.

@sokol92 Thanks for that work-around!

It seems like the “item” is problematic in your code. It is a local variable in a non-explicit module; but there is some bug, that causes it to spill and find the “Item” method in ScriptForge…

@sokol92 Is that OnOpen implicitly assigned by name or do I need to connect it somewhere in the GUI?

Is it because of the name or because there is no DIM declaration for it?

Dim item is enough; rename to item1 is also enough. The name “item” is not special; the problem is just a name clash, and some problem here, that needs investigating and fixing.

1 Like

@mikekaganski OK. I would have expected an error. But after the initial hiccup, the function just runs perfectly without DIM. Thanks for checking, though.

In my opinion, we should always use

Option Explicit

and explicitly declare all variables used.

In our case, using item without explicitly defining it in Excel would have resulted in a compilation error.

In LO Basic, the namespace is structured differently. If any loaded library contains a Global variable named Item or a function (procedure) named Item, it will be used. So, we need to be careful.

1 Like

In the end …

This is likely a ScriptForge bug (@JPLED could you please confirm?). The problem is using Public keyword with a name like Item. As explained in help, names defined using that decoration are valid in all modules. I don’t know how we can change that - so the name clash is inevitable (I don’t even try to guess how many macros out there could ever use the name Item without Option Explicit); after initial resolution/evaluation, the code in the @srkunze’s function re-defines it, which I don’t know how would affect ScriptForge, but in this specific case, the failure is because at the load time, class modules aren’t yet initialized in this loading phase, and the Item implementation (and _PropertyGet) is in such a module.

Maybe we need some restriction for class modules about the unqualified names (used without module name)? Definitely the case. Not a bug in SF; rather, in our implementation of class modules.

It looks interesting to learn how VBA resolves this Public problem.

A bug report is needed.

1 Like

Mike, I didn’t quite understand the question.
VBA Class Module TestClass.

Option Explicit
Public PublicProp
Private PrivateProp

Standard Module:

Sub Test()
  Dim MyClass, v
  Set MyClass = New TestCLass
  v = MyClass.PublicProp   ' no error
  v = MyClass.PrivateProp  ' error
End Sub

No question already - that was some kind of living thought process :slight_smile: in the end, it turned out a plain bug. Thanks!

1 Like

Filed tdf#168750.

1 Like

@mikekaganski @sokol92 thanks for taking care.

That was my very first Basic macro, so I appreciate your help. Also nice to see this led to some improvements in the core :relaxed:

See you around.