UNO API or Basic for adding a Macro to a Sheet Event

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
Bal
Posts: 8
Joined: Wed Dec 25, 2019 6:25 pm

UNO API or Basic for adding a Macro to a Sheet Event

Post by Bal »

I have a sheet with a macro added to the Activate Document ("OnFocus") event. However, when the sheet is copied to a new sheet, the macro is not attached to the Activate Document. I would like to do this programmatically rather than make the user do it.

The Dispatcher uno:TableEvents will open the Assign Action dialog for the user to add the macro to the Activate Document event but I cannot find a set of arguments to pass to this API that will add the macro. Regardless of the arguments I've tried to pass, it seems to only open the dialog.

My questions are: 1) Is there a set of Name / Value arguments I can pass to uno:TableEvents that will do this or 2) Is there another API to use to do this and if so, what are the Name / Value arguments to do this.

Thanks for any help.
OpenOffice 4.1.7 on Windows 10
User avatar
Zizi64
Volunteer
Posts: 11362
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by Zizi64 »

Please upload your sample file and the macro code here.
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
Bal
Posts: 8
Joined: Wed Dec 25, 2019 6:25 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by Bal »

In the code below, sEvents uses the active sheet nSheet. getByName("OnFocus") returns the structure of the OnFocus event IF there is one. Otherwise, it returns an error. An error occurs if no macro is attached and is handled by ErrorHandler.

Inspection of the structure of sEvents when the macro IS present shows 2 elements whose Name & Value I supply as args1(1) and args1(2). All this does is open the Assign dialog as I mentioned before.

Code: Select all

On Error Goto ErrorHandler
sEvents = nSheet.Events.getByName("OnFocus")

ErrorHandler:
Reset
dim args1(2) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ElementNames" : args1(0).Value = "OnFocus"
args1(1).Name = "EventType" : args1(1).Value = "Script"
args1(2).Name = "Script" : args1(2).Value = "vnd.sun.star.script:Standard.Module1.Upload_Inventory?language=Basic&location=document"
dispatcher.executeDispatch(document, ".uno:TableEvents", "", 0, args1())
Exit Sub

Last edited by RoryOF on Thu Dec 26, 2019 9:52 pm, edited 1 time in total.
Reason: Added [code] tags [RoryOF. Moderator]
OpenOffice 4.1.7 on Windows 10
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by JeJe »

Why not use a template? Macros and event bindings in the template will be preserved in the newly created document.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Bal
Posts: 8
Joined: Wed Dec 25, 2019 6:25 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by Bal »

I've never worked with templates before but saving the sheet as a template doesn't seem to preserve the event binding. So a couple of questions come to mind. First, what needs to be done to save the sheet as a template that DOES preserve the event binding? Second, the workbook is available for download as a ZIP file. If I include a template in that file it would need to be available to the user without the need for a great deal of user interaction. Second, since this particular sheet has references to other objects in the workbook, it will contain errors when stored as a template and not easily resolved once placed in the workbook, so maybe not the happiest of solutions. And finally, I don't see a way to insert the template as a sheet in the current workbook so it would seem that for the user, it's a lot more work than a simple right-click for Move/Copy the sheet.
OpenOffice 4.1.7 on Windows 10
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by JeJe »

It worked for me... I created a simple spreadsheet template (attached - change the extension from .zip to .stc, .stc files not accepted here)... it has a macro that runs when a created document is activated, a simple message box. Saving and reopening the document I still got the message box.

Edit: so you might have a simple macro that creates a new document from the template then copies the sheet to it perhaps?
Edit2: alternatively you could have a macro that copies the document and deletes all the unwanted sheets?
Edit 3: see correction below
Last edited by JeJe on Fri Dec 27, 2019 4:28 pm, edited 1 time in total.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Bal
Posts: 8
Joined: Wed Dec 25, 2019 6:25 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by Bal »

As far as I can tell, there is no .ods or .ots file anywhere in this zip and a TON of folders, many of which are empty. The XML docs produce a General Error when I try to open then with Calc so I don't know what they contain. I suspect the reason it "works" for you is that the template & the macro to which it is bound are in the same structure. When I created my template with an event binding to a Basic subroutine under the workbook name in Standard / Module1, it did not become part of the template.
OpenOffice 4.1.7 on Windows 10
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by JeJe »

rename the file from Untitled 1.zip to Untitled 1.ots

I had to change the extension as the site doesn't let me upload a file with the stc extension but does allow .zip.


Edit: An OO file is a ton of folders zipped but given a different extension from .zip

Edit2: corrected for correct extension

Edit 3: see correction below
Last edited by JeJe on Fri Dec 27, 2019 4:34 pm, edited 3 times in total.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by JeJe »

Oops Sorry I should have said rename the extension .ots but it does let me postthat... don't know how I managed to create that botch up.
Attachments
Untitled 1.ots
(8.72 KiB) Downloaded 147 times
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
Lupp
Volunteer
Posts: 3553
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by Lupp »

Code: Select all

Sub copyOnFocusEventFromSheetToSheet(pSourceIndex, pTargetIndex)
REM The sheet indices are zero-based here!
doc         = ThisComponent
sheetSource = doc.Sheets(pSourceIndex)
sheetTarget = doc.Sheets(pTargetIndex)
sheetTarget.Events.replaceByName("OnFocus", sheetSource.Events.getByName("OnFocus"))
End Sub
Adapted based on https://ask.libreoffice.org/en/question ... y-a-macro/. Many thanks to Pierre-Yves Samyn who unfortunately seems to no longer contribute to the forums. Hope he is well.

Also:
Since the word "sheet" (short for "spreadsheet") is indispensable for use with its actual meaning of "one single spreadsheet contained in a spreadsheet document" we must not use it with a different meaning like "spreadsheet document".

Unfortunately we often find the misuse, and tend to understand questions in a wrong way. In this case I was caught as also "JeJe" may have been. Everybody learn from this to try to be even clearer about his intentions as he anyway is.

In this case the scandalous replacement of what's correctly named "OnFocus" in the API to "Activate Document" for the UI concerning SHEET events was specifically misleading. The current question seemed to be about "document events" therefore, instead of about "sheet events".
I will never understand this idiotic kind of renaming hard coded in the software which is to find in many places. However, it may be too hard a task for the developers to fix the issue. It would be extremely meritorious on the other hand, imo.
"One thing - one name!" must be the guiding principle in the realm of programming/software.
Last edited by Lupp on Fri Dec 27, 2019 5:02 pm, edited 1 time in total.
On Windows 10: LibreOffice 24.2 (new numbering) and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
User avatar
RoryOF
Moderator
Posts: 34618
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by RoryOF »

Lupp wrote: Many thanks to Pierre-Yves Samyn who unfortunately seems to no longer contribute to the forums. Hope he is well.
He was active on another list a few minutes ago.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
Bal
Posts: 8
Joined: Wed Dec 25, 2019 6:25 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by Bal »

I appreciate the code snippet and it would work just fine if the user does not delete or rename the sheet SheetSource which they often do. Even if they do not, it can appear anywhere in the workbook so it has no "constant" pSourceIndex I'm afraid. These are among the reasons I was looking to recreate it in some manner. Perhaps there is a way to create the structure of the getByName("OnFocus") so it could be used with the replaceByName call? That would work I think.

I'm apologize for any confusion over the use of the word sheet in my original post. I meant a single sheet & thought this was clear in context. Names should be consistent and unambiguous but as you point out, often are not. The Assign dialog for a sheet specifies Activate Document which is the "OnFocus" event for that sheet but for a workbook the Tools > Customize > Events dialog also specifies Activate Document which is the "OnFocus" event for the workbook itself. The workbook "OnFocus" event does not seem to fire as you change between sheets in the workbook.
OpenOffice 4.1.7 on Windows 10
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by JeJe »

There is this thread if you haven't seen it, "How to copy Sheet with Event macro via vba code" :

viewtopic.php?f=20&t=74454
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
Lupp
Volunteer
Posts: 3553
Joined: Sat May 31, 2014 7:05 pm
Location: München, Germany

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by Lupp »

Unfortunately I am not a sorcerer, and I cannot write code for spreadsheet documents working as expected under any circumstances, even if someone changed the structure of the document or - in the extreme case - the code itself.
I am afraid nobody could do such a job.

On the other hand I lack information I would need to mimick a sorcerer in this specific case.

If you tell me that all the sheets of the document over all its lifetime shall have the same specific macro associated with their events OnFocus, I can tell you how to ensure that. If you tell me something else sufficiently unambiguous I may also find a solution ...
I will not try to change the source code of "our" software, and I will not find a hidden event thrown OnCopySheet which - if existing - would allow to intercept it for the purpose under discussion. I think there is none.

(My code anyway does not identify the source sheet by its name, but by its index.)

And: The source of the confusion wasn't you, but bad practise adopted by others, and misleading me and JeJe.
Concerning the naming we seem to agree. Arbitrarily changing the name of a specific thing is bad. Doing it in a gravely misleading way ("Activate Document" for a SHEET event) is worse. That's the developers' fault, however.
On Windows 10: LibreOffice 24.2 (new numbering) and older versions, PortableOpenOffice 4.1.7 and older, StarOffice 5.2
---
Lupp from München
Bal
Posts: 8
Joined: Wed Dec 25, 2019 6:25 pm

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by Bal »

Thanks to you all for your help. I have decided that since there is 1 hidden sheet in the workbook the user must maintain in the book for other parts to work successfully, including the type of sheet where the OnFocus event comes into play, I've decided to bind the OnFocus macro I need there & copy it from there as Lupp suggests. The post JeJe refers to has code that would work as well. If the user deletes the sheet, that's on them as much as changing the code would be. Under either of those conditions the "sorcery" of the programming is undone and so be it. One cannot be expected to protect people from themselves if they do what they've been instructed not to do.
OpenOffice 4.1.7 on Windows 10
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: UNO API or Basic for adding a Macro to a Sheet Event

Post by Villeroy »

Contrary to "sheet protection" which protects the locked contents of a sheet, the similarly misleading term "document protection" protects the collection of sheets. With "document protection" you can not move, delete, (un-)hide, rename nor add sheets. You would have to write a simple macro to allow adding sheets.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Post Reply