I have an Excel macro that I am trying to port to LibreOffice Calc. The Excel macro has the line: iRow = Application.Caller.Row, but when this is run in IDE, I get the error: Object variable not set.
What can I do within the IDE to return the row, and column, from which the macro is being called?
A Calc macro in StarBasic, Python, JavaScript, BeanShell can easily refer to the cell it was called from. But an Excel macro (somehow interpreted by LibreOffice) may fail because it was written for a completely different application.
doc = ThisComponent
selection = doc.CurrentSelection
If selection.ImplementationName = "ScCellObj" Then
MsgBox selection.CellAddress.Row
MsgBox selection.CellAddress.Column
End If
CurrentSelection is not “the cell it was called from”. When you press Ctrl+F9, your file may recalculate thousands of cells with the UDF, but only one (or even none) of them may be selected.
The Application.Caller property relates to custom functions (or user-defined functions, UDF) that are written e.g. in Basic, and used as spreadsheet functions. These spreadsheet functions have nothing to do with selection.
E.g., you may have this Basic code:
Function Foo(n)
Foo = n * n * n
End Function
and in a spreadsheet, you put this into A1: =Foo(5)
This calls the Basic code when calculating the cell A1; and OP wants to find a way to know in Foo that is is called from A1. But it is unrelated to what is selected on the sheet at the moment: you may go to another sheet on the same spreadsheet, and select B2, and press Ctrl+Shift+F9 to hard-recalc everything - and your current selection will be Sheet2.B2, but the Basic code Foo will still be run in cell Sheet1.A1.
Option VBASupport 1
Function UDF(Arg1, Arg2, Optional Caller)
If Not IsMissing(Caller) Then
sCallerName = Caller.CellRange.AbsoluteName
Print sCallerName
With Caller
Print "Column = " & .Column, "Row = " & .Row '1-based indexing
End With
End If
End Function
Works, but the danger is, of course, that if the address passed ever gets desynchronized with the address the formula is in, then you have a mess, and one that might be pretty hard to sort out. This is why I think that if you are going to pass a parameter, anyway, it might be safer to pass ROW() and COLUMN() themselves, or just whichever you actually need.
The address is relative. Move the cell to another location and the reference will change.
And such things, I suppose, are required for selected cells, there shouldn’t be many of them.
I’m sure you are right. I’m OCD about encoding the same value twice in any way, implicitly or explicitly, probably because I’m so good at finding a way to break things five minutes after I thought about not breaking them that way.
Thanks for the feedback. The CurrentSelection did not seem to work and the Caller seemed to reference to parameter passed in. The notion of passing the row and column worked. Please keep in mind that when it comes to LibreOffice, I am a total newbie!
Now, if there were only some way, perhaps something like a #ifdef, so that I could have one version of the code that worked under both Excel and LibreOffice…