Обновлятор-1с. Учимся писать скрипты на OneScript
2021-11-17T11:08:39+00:00О чём вообще идёт речь?
Речь идёт о возможности написания скриптов на языке OneScript для автоматизации операций над группой баз вот на этой вкладке обновлятора:

Что такое OneScript?
Проект является независимой кросс-платформенной реализацией виртуальной машины, исполняющей скрипты на языке 1С:Предприятие.
Иными словами, это возможность писать программы на языке 1С без использования платформы 1С:Предприятие.
И это позволяет нам в конечном итоге брать уже готовые куски кода, написанные в конфигураторе и с минимальной адаптацией переносить их в программу на OneScript.
И пусть по словам разработчиков это не главная цель проекта, но я вижу интерес именно в том, чтобы из программы на OneScript подключаться к базе 1С через внешнее соединение и выполнять некоторый полезный код.
Вы спросите - а зачем это вообще надо? Почему бы не написать этот же код в обработке и запускать через 1с стандартным способом?
Но мы ведь говорим об автоматизации и тут есть фундаментальные проблемы:
- нет способа гарантированно запустить базу и выполнить в ней код некоторой внешней обработки (кто сталкивался с этим на практике знает, что слишком многое может пойти не так, начиная с того, что до выполнения обработки просто не дойдёт из-за какого-нибудь модального окна)
- нет простого способа генерировать такую обработку программно, а ведь это может нам понадобиться, если речь идёт о выполнении полезного кода над группой баз
- нет простого способа логировать выполнение этой обработки
Все эти проблемы решает OneScript.
Зачем писать и запускать эти скрипты именно в обновляторе?
Потому что обновлятор берёт на себя ряд непростых вещей, чтобы упростить написание таких скриптов в части взаимодействия с базами.
А именно.
Список баз для обработки
Прямо в обновляторе мы выбираем для какого количества баз нужно запустить написанный нами скрипт:

Передача параметров базы
При выполнении скрипта обновлятор сам передаёт в него необходимые параметры с информацией о текущей базе:

Все эти параметры мы можем использовать в своём скрипте, делая его универсальным для выполнения над любым количеством выбранных баз.
Примеры таких скриптов мы можем найти в списке шаблонов обновлятора:

Предварительная архивация базы
При необходимости обновлятор обеспечит создание резервной копии перед выполнением скрипта:

Эта резервная копия будет согласована с общей системой архивации, то есть её также можно подвергать "тюнингу" в дополнительных настройках обновлятора. Такая копия всегда будет иметь метку "перед опасной операцией".
Блокировка, разблокировка базы
При необходимости обновлятор выполнит полную блокировку базы перед выполнением вашего скрипта и разблокировку после:

И это одна из ключевых "фич" обновлятора - ведь, например, корректное выполнение блокировки серверной базы в общем случае является достаточно нетривиальной задачей.
Нужно "разрулить" текущие подключения пользователей, административные подключения, выполнение фоновых задач. И всё это через общение напрямую с кластером 1с.
Сохранение отчётов
Обновлятор сохраняет историю выполнения таких скриптов в менеджере отчётов.
Как в общем виде:

Так и в детальном:

Уведомление на почту
Если у вас настроены уведомления на почту (все или только при ошибках)...

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


Запуск скрипта по расписанию
Для добавления скрипта в запуск по расписанию следует сохранить сам скрипт:

Далее у нас есть 2 варианта:
Быстрый, но неудобный способ
При сохранении скрипта мы можем установить опцию "Настроить однократный запуск скрипта ...":

И далее уже отредактировать расписание этого задания непосредственно в планировщике Windows.
Чуть более медленный, но самый удобный способ
После того как вы сохранили скрипт (не добавляя его в планировщик Windows) вернитесь в главное окно Обновлятора на закладку "Настройки программы".
Далее нажмите кнопку "Расписание"...

И создайте задачу с типом операции "Запуск скрипта":

Укажите ваш сохраненный скрипт по ссылке "выбрать скрипт для запуска...".
Облачный мониторинг
При сохранении скрипта нам также доступна опция для облачного мониторинга его работы - совершенно потрясающая возможность на мой взгляд. Вот здесь подробнее об облачном мониторинге.
Многопоточное выполнение скриптов
О том как запускать скрипт параллельно для нескольких баз подробно рассказывается здесь.
Что ещё полезно изучить перед написанием скриптов?
Ну, конечно же, сам язык 1С. Куда же без него... 
Прежде всего есть вот этот справочник языка 1С с примерами: ссылка.
Также стоит пробежаться по отличиям OneScript от стандартного языка 1С. Их немного (ссылка).
Ну, и наконец, у OneScript есть также свой синтакс-помощник.
Изучать сторонние библиотеки на OneScript (которые также можно подключать в обновлятор) на первом этапе я не советую. Вы сможете вернуться к ним, когда освоитесь с простейшими скриптами в достаточной мере.
Ну, поехали!
Хватит говорить про скрипты - давайте их писать
Изучаем структуру простейшего скрипта
Для этого выберем из шаблонов пункт "1. Привет, база".
В редактор вставится шаблон простейшего скрипта:
Сам скрипт (раскрыть)
#use "updater1c"
// ****************************************************************************
// Переменные модуля
// ****************************************************************************
Перем errors; // Признак того, что при выполнении скрипта были ошибки.
Перем updater; // Обновлятор, через который мы получаем информацию о базе,
// а также вызываем различные функции обновлятора.
Перем connector; // Коннектор для подключения к базе.
Перем v8; // Само подключение к базе через коннектор.
// ****************************************************************************
// Ваш код для выполнения обновлятором
// ****************************************************************************
Процедура Главная()
Сообщить("Привет, " + updater.BaseName);
КонецПроцедуры
// ****************************************************************************
// Служебные процедуры
// ****************************************************************************
Процедура ПриНачалеРаботы()
errors = Ложь;
updater = Новый Updater1C;
// Если в скрипте не планируется использовать
// подключение к базе - просто закомментируйте
// две нижние строки.
connector = Новый COMОбъект("V" + updater.PlatformRelease + ".COMConnector");
v8 = updater.BaseConnect(connector);
КонецПроцедуры
Процедура ПриОкончанииРаботы()
Если v8 <> Неопределено Тогда
Попытка
ОсвободитьОбъект(v8);
v8 = Неопределено;
Исключение
КонецПопытки;
КонецЕсли;
Если connector <> Неопределено Тогда
Попытка
ОсвободитьОбъект(connector);
connector = Неопределено;
Исключение
КонецПопытки;
КонецЕсли;
Если updater <> Неопределено Тогда
Попытка
ОсвободитьОбъект(updater);
updater = Неопределено;
Исключение
КонецПопытки;
КонецЕсли;
ВыполнитьСборкуМусора();
Если errors Тогда
ЗавершитьРаботу(1);
КонецЕсли;
КонецПроцедуры
// ****************************************************************************
// Инициализация и запуск скрипта
// ****************************************************************************
ПриНачалеРаботы();
Попытка
Главная();
Исключение
errors = Истина;
Сообщить(ОписаниеОшибки());
КонецПопытки;
ПриОкончанииРаботы(); |
Результат выполнения скрипта
Не пугайтсь
Всё, что окружает процедуру "Главная" - служебный код обновлятора, его мы всегда будем вставлять из этого шаблона.
А наш собственный код мы всегда будем начинать писать в процедуре "Главная".
Но прежде всего обратите внимание на строку...
... в начале скрипта.
Этим самым мы подключаем в скрипт библиотеку обновлятора, которая генерируется "на лету" перед выполнением самого скрипта.
Эта библиотека позволяет нам создавать объект типа Updater1C:
updater = Новый Updater1C; |
А затем использовать его в скрипте для связи с обновлятором.
Объект updater ключевой в нашем скрипте - именно от него мы узнаём всю необходимую информацию о текущей базе (ведь скрипт может быть запущен сразу для группы баз).
И именно его свойства и методы вставляются в скрипт вот из этих пунктов меню:


Далее обратите внимание вот на эти строки:
connector = Новый COMОбъект("V" + updater.PlatformRelease + ".COMConnector");
v8 = updater.BaseConnect(connector); |
Здесь мы подключаемся к базе через COM, чтобы затем выполнять в ней некоторый полезный код (об этом ниже) через переменную v8, которая и является внешним подключением к базе.
Если нашему скрипту не требуется внешнее подключение к базе (это довольно затратная по времени процедура), то просто комментируем данные строки.
Во всём остальном скрипт полностью в нашем распоряжении. Мы можем подключать свои библиотеки, писать свои процедуры и функции.
В следующих примерах я буду писать только код процедуры "Главная", а вы зная всю структуру скрипта вставляйте его уже в правильное место.
Выводим пользователей базы
А давайте поставим перед собой более интересную задачу - вывести на экран всех пользователей базы.
В платформе 1С за это отвечает переменная глобального контекста ПользователиИнформационнойБазы.
Попробуем написать в процедуре "Главная" такой код:
СписокПользователей = ПользователиИнформационнойБазы.ПолучитьПользователей(); |
Но запустив его мы получим следующую ошибку:

Всё правильно, переменная ПользователиИнформационнойБазы - это часть глобального контекста базы, но не нашего скрипта.
И как же нам добраться до контекста базы? А очень просто - через внешнее подключение, которое мы обсуждали выше.
После такого подключение сам контекст доступен нам через переменную уже нашего скрипта v8.
Перепишем наш код следующим образом:
СписокПользователей = v8.ПользователиИнформационнойБазы.ПолучитьПользователей(); |
Запустив его, мы увидим что всё ок.
Ну а дальше пишем код точно также, как если бы мы писали его в конфигураторе:
Сообщить("Выводим всех пользователей базы:");
Для Индекс = 0 По СписокПользователей.Количество() - 1 Цикл
Сообщить(СписокПользователей.Получить(Индекс).Имя);
КонецЦикла; |
Запускаем на выполнение и видим:

Пишем запрос к базе
Как известно почти любую информацию из базы можно и нужно получать запросами.
Давайте напишем простейший запрос, который читает из базы поля Наименование и ИНН всех элементов справочника Контрагенты.
Прежде всего попробуем создать объект типа Запрос.
В конфигураторе мы написали бы, например:
Но если запустить такой скрипт через OneScript, то получим ошибку:

И он прав ведь типа Запрос в OneScript просто не существует.
Поэтому создавать этот объект будем на стороне платформы 1С через всё то же внешнее подключение к базе:
Запрос = v8.NewObject("Запрос"); |
Запомните этот приём, ведь при помощи него мы можем создавать и другие объекты и других типов на стороне платформы 1с, когда нам это потребуется.
Ну а дальше для нас не будет ничего необычного:
Запрос.Текст = "Выбрать Наименование, ИНН ИЗ Справочник.Контрагенты ГДЕ ЭтоГруппа = Ложь";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование + " (" + Выборка.ИНН + ")");
КонецЦикла; |
Результат выполнения скрипта будет таким:

И давайте я сразу покажу как разбивать текст запроса на несколько строк:
Запрос.Текст = "
| Выбрать Наименование, ИНН
| ИЗ Справочник.Контрагенты
| ГДЕ ЭтоГруппа = Ложь"; |
Замечание про COM-объекты
Обязательно ознакомьтесь со статьей об использовании COM-объектов в OneScript, вот она: helpme1s.ru/ispolzovanie-com-obektov-v-onescript
Как мне придумывать свои скрипты?
Для вдохновления вначале советую разобрать и понять скрипты из шаблонов обновлятора. Это уже многое вам даст.
А если же вам нужна идея для написания скрипта, который будет полезен сотням других пользоватей, то я прошу вас - напишите об этом мне любым удобным для вас способом (ссылка). Идей у меня огромное количество, но времени и возможностей не хватает.
Я написал классный скрипт и хочу поделиться
Для этого я завёл специальный проект на github, где собираю полезные скрипты от пользователей обновлятора, чтобы как можно большее количество людей смогло использовать их в своей работе.
Хотите прислать мне свой скрипт? Прошу вас сюда (ссылка).

).
расскажите (кнопки поделиться ниже) о нём своим друзьям и коллегам. Сделайте это один раз и вы внесете существенный вклад в развитие сайта. На сайте
, но чем больше людей им пользуются, тем больше сил у меня для его поддержки.