1

Тема: VBA -> WSH: обмен объектами между скриптами - детали

Так сложилось, что есть востребованный код на VBA(надстройка), которым реально пользуются. Не совсем на VBA: VBA создает объект ScriptControl, подгружает в него код на JScript и управляет его выполнением через пользовательское меню Excel.
Код работает сутками (конечно, можно поставить на паузу или прервать, но лень же) и этим затрудняет пользование Экселем - оставлена такая возможность. Такое пользование Экселем в процессе выполнения скрипта быстро прерывает его выполнение. При этом процесс Экселя за сутки пухнет до неприличия (поиск в листах и запись в них).
Хотелось бы по-возможности сократить конфликты скрипта и Экселя, чтобы они могли работать не критично мешая друг другу.
В качестве такой меры предполагается как-то вынести исполнение кода в объекте ScriptControl за пределы процесса Экселя. Хотелось бы сделать это попроще - взять готовый объект и передать его в другой процесс.
На роль другого процесса знаю только одного кандидата: nssm-скрипт-сервис.
Предпочтительной выглядит такая схема: из Экселя запускается nssm-скрипт-сервис, который далее работает полностью автономно и пишет данные в файлы xls без участия Экселя. Эксель можно закрыть, запущенный сервис продолжит работать. После этого Эксель можно снова запустить и управлять сервисом через пользовательское меню Экселя.

Просьба поделиться опытом: что в этой затее рабочее и что нет.
Конкретные вопросы:
1) Почему c GetObject не получается получить объект ScriptControl, созданный в VBA? Приходится получать его через var ScriptControlObject = Excel.run('Get_ScriptControlObject ').
2) В какой момент ScriptControlObject перейдет из процесса Экселя в процесс nssm-скрипт-сервиса? После удаления ссылок на него в Экселе? А если после удаления ссылок на него в Экселе снова передать ссылки на него из сервиса в Эксель - он снова сменит процесс? Или: из какого процесса запускается исполнение кода в ScriptControlObject, тот процесс этот код и обслуживает?

Заренее благодарен за любые соображения и комментарии.

2 (изменено: Xameleon, 2020-09-22 13:09:43)

Re: VBA -> WSH: обмен объектами между скриптами - детали

expertykt пишет:

1) Почему c GetObject не получается получить объект ScriptControl, созданный в VBA? Приходится получать его через var ScriptControlObject = Excel.run('Get_ScriptControlObject ').

Насколько мне известно, потому что GetObject может получать только объекты глобально зарегистрированные либо создавать их через моникеры.

expertykt пишет:

2) В какой момент ScriptControlObject перейдет из процесса Экселя в процесс nssm-скрипт-сервиса? После удаления ссылок на него в Экселе? А если после удаления ссылок на него в Экселе снова передать ссылки на него из сервиса в Эксель - он снова сменит процесс? Или: из какого процесса запускается исполнение кода в ScriptControlObject, тот процесс этот код и обслуживает?

Опять же, насколько мне известно, объекты не переходят от процесса к процессу. Они создаются в пределах исходного процесса и с ним живут до удаления всех ссылок. Поэтому если вы создали объект в пределах экселя и отдали ссылку на него в другой процесс, то не смотря на последующее удаление всех ссылок в экселе, объект продолжит своё существование в том же экселе. И только когда удалится ссылка в стороннем процессе, удалится и объект в экселе.

Если есть желание вытащить выполнение кода за пределы экселя, то тогда, как мне видится, Вам стоит создать JS / WSF скрипт, который будет создавать Excel.Application и из него же управлять внутренним функционалом экселя, а все вычисления выполнять внутри себя (скрипта). Но тут опять же нужны подробности задачи для принятия правильного решения. Возможно вообще можно обойтись без громоздкого и неповоротливого Excel-я.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

3

Re: VBA -> WSH: обмен объектами между скриптами - детали

Xameleon пишет:

GetObject может получать только объекты глобально зарегистрированные

В справке говорится о "серверах автоматизации". т.е. ScriptControl не OLE.

Xameleon пишет:

Опять же, насколько мне известно, объекты не переходят от процесса к процессу. Они создаются в пределах исходного процесса и с ним живут до удаления всех ссылок. Поэтому если вы создали объект в пределах экселя и отдали ссылку на него в другой процесс, то не смотря на последующее удаление всех ссылок в экселе, объект продолжит своё существование в том же экселе. И только когда удалится ссылка в стороннем процессе, удалится и объект в экселе.

И после закрытия Экселя объект будет удерживать его процесс от удаления?

4 (изменено: Xameleon, 2020-09-23 22:49:10)

Re: VBA -> WSH: обмен объектами между скриптами - детали

expertykt,
1) Сервер автоматизации это как раз в явном виде Word.Application / Excel.Application / InternetExplorer.Application и подобные им. При создании таких объектов через CreateObject("...") создаётся отдельный процесс, который и олицетворяет "сервер автоматизации". И как раз через GetObject("...") возвращается ссылка на созданный объект. ScriptControl таковым не является. Но в случае необходимости можно и ScriptControl передать через подобный механизм.

2)

И после закрытия Экселя объект будет удерживать его процесс от удаления?

Ни в коем случае. Закрытие процесса естественно приводит к уничтожению всех объектов внутри процесса.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

5

Re: VBA -> WSH: обмен объектами между скриптами - детали

expertykt пишет:

На роль другого процесса знаю только одного кандидата: nssm-скрипт-сервис.

А чем не устраивает wscript.exe? Может и ScriptControl будет не нужен.

Щт Уккщк Куыгьу Туче
’ҐЄгй п Є®¤®ў п бва Ёж : 1251