Как выполнить макрос в другом документе?

Автор eeigor, 16 февраля 2023, 10:57

0 Пользователи и 1 гость просматривают эту тему.

eeigor

Короткий вопрос. Как выполнить макрос в другом документе? Создаю документ на основе шаблона, в документе будут макросы из шаблона, надо выполнить один (по добавлению новых пустых строк в таблицу, в которые потом надо вставить данные).
Отсюда возникает второй вопрос, который я задам в новой теме:

https://forumooo.ru/index.php?topic=9670.msg65273;topicseen#msg65273
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

Предположим, в документе C:\Temp\Test.ods библиотека Standard модуль Module1 содержит макрос:
Sub MyMacro(ByVal arg)
  Msgbox arg
End Sub

Следующий макрос (может быть в другом документе или в My Macros...) откроет указанный документ и вызовет макрос MyMacro:

Option Explicit

Sub testInvoke()
 Dim oDoc, oScript, scriptUri As String
 oDoc = StarDesktop.LoadComponentFromUrl(ConvertToUrl("C:\Temp\Test.ods"),"_default",0,Array())  ' загружаем документ
 scriptUri = "vnd.sun.star.script:Standard.Module1.MyMacro?language=Basic&location=document"     ' ссылка: Библиотека.Модуль.Макрос
 oScript=oDoc.ScriptProvider.getScript(scriptUri)                                                ' получаем объект (сценарий)
 oScript.invoke(Array("Hello, forum"), Array(), Array())                                         ' вызываем макрос
End Sub
Владимир.

eeigor

#2
Владимир, макрос вызывается, но единственный аргумент не передаётся.

oScript.invoke(Array(9), Array(), Array())

Sub AddNew(Optional nRowCount&)

Я передаю параметр 9
В вызываемую процедуру параметр не передаётся: сразу на входе 0. В чём может быть причина? Первый массив – массив аргументов типа Variant, передаю число

Моя процедура добавляет пустые строки в таблицу – строго под принимаемые данные. Можно, конечно, добавлять по одной по умолчанию. Но я специально доработал процедуру, чтобы можно было добавлять много строк за раз.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

#3
Цитата: eeigor от 16 февраля 2023, 17:45Владимир, макрос вызывается, но единственный аргумент не передаётся.
В моем примере?

Обратите внимание на конструкцию ByVal в макросе MyMacro. Она "намекнет" методу invoke, что аргумент является входным (и вызывающую процедуру не надо уведомлять о его изменении).

Вот рекомендации, которым я следую, если предполагаю, что функция (процедура) может быть вызвана извне (через Invoke).

1. Все параметры должны иметь конструкцию ByVal.
2. Значение, возвращаемое функцией, должно быть явно инициализировано. В текущих версиях LO это не актуально (благодаря Михаилу), но у пользователя может быть и более старая версия...
3. В связи с правилом 1: если функция должна вернуть более одного значения, то возвращаем их в массиве.

Кстати: для Application.Run в Excel примерно такие же правила.
Владимир.

eeigor

А слона-то я и не заметил :)
Чуть позже отпишусь...
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

eeigor

#5
Владимир, Ваш код выполняется, значение параметра передается.
А мой не выполняется, несмотря на то, что я сделал опциональный параметр обязательным, передаваемым по значению  (ByVal nRowCount& вместо Optional nRowCount&).

Зато замена в Вашем макросе аргумента по значению на опциональный аргумент на работу не повлияла: работает.
Причина в чем-то другом... Как оказалось, аргумент должен иметь тип Variant:
Sub AddNew(Optional vRowCount)
В общем, методом тыка и подбора...
Sub MyMacro(ByVal arg)  здесь у Вас аргумент Variant.
Значит, если первый аргумент метода invoke массив []Variant, то передавать можно только этот тип данных.
Владимир, спасибо за помощь. Меня устраивает результат.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community