Пять рабочих способов запустить свой код на стороне сервера 1С:Предприятия 8.3
Содержание
Чтобы выполнить код на сервере 1С, его нужно поместить в серверный контекст: процедура формы с директивой &НаСервере, серверный общий модуль, внешняя обработка, вызванная с сервера, внешнее соединение через V83.COMConnector или фоновое и регламентное задание. Во всех случаях код исполняет рабочий процесс кластера rphost, а не компьютер пользователя.
Выбор способа зависит от задачи. Разово поправить данные удобнее из внешней обработки или консоли кода. Запустить расчёт из другой программы — через COM-соединение. Выполнять что-то каждую ночь — регламентным заданием. Ниже каждый способ с примером кода, правами и типичными ошибками.
Всё описанное относится к платформе 8.3 в клиент-серверном варианте. В файловой базе «сервером» считается процесс, который открыл базу, поэтому директивы работают так же, но кластера, rphost и его логов там нет.
Где на самом деле исполняется код и как это задаётся
Модуль формы и общие модули компилируются по директивам. От них зависит, на чьей стороне выполнится процедура.
| Директива / свойство | Где выполняется | Доступ к данным формы |
|---|---|---|
&НаКлиенте | на компьютере пользователя | есть |
&НаСервере | на сервере, с передачей формы | есть, форма передаётся на сервер и обратно |
&НаСервереБезКонтекста | на сервере | нет, только параметры |
| Общий модуль с флажком «Сервер» | на сервере | — |
| Флажок «Вызов сервера» у общего модуля | на сервере, можно вызывать с клиента | — |
Минимальный пример из модуля формы:
&НаКлиенте
Процедура Выполнить(Команда)
КоличествоДокументов = ПосчитатьНаСервере(НачалоМесяца(ТекущаяДата()));
Сообщить("Документов с начала месяца: " + Формат(КоличествоДокументов, "ЧН=0; ЧГ=0"));
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПосчитатьНаСервере(ДатаНачала)
Запрос = Новый Запрос(
"ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Количество
|ИЗ Документ.РеализацияТоваровУслуг КАК Д
|ГДЕ Д.Дата >= &ДатаНачала");
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Выборка = Запрос.Выполнить().Выбрать();
Возврат ?(Выборка.Следующий(), Выборка.Количество, 0);
КонецФункции
Предпочитайте &НаСервереБезКонтекста, если данные формы не нужны. Каждый вызов &НаСервере гоняет форму по сети целиком, и на тонком клиенте через интернет
это заметно.
Каждый вызов сервера с клиента — отдельный сетевой запрос. Вызов в цикле по 5 000 строк превращается в 5 000 обращений. Собирайте данные в массив и передавайте одним вызовом.
Внешняя обработка: разовый запуск своего кода на сервере
Внешняя обработка — главный способ выполнить код без изменения конфигурации. Файл .epf открывается у пользователя, а сама обработка создаётся и работает на сервере.
Как подключить обработку на сервере
Файл лежит на компьютере пользователя, серверу его нужно передать через временное хранилище:
&НаКлиенте
Процедура ЗагрузитьИВыполнить(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
НачатьПомещениеФайла(Оповещение, , , Истина, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмя, ДополнительныеПараметры) Экспорт
Если Результат Тогда
ВыполнитьОбработкуНаСервере(Адрес);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ВыполнитьОбработкуНаСервере(Адрес)
ИмяОбработки = ВнешниеОбработки.Подключить(Адрес, , Ложь);
Обработка = ВнешниеОбработки.Создать(ИмяОбработки);
Обработка.ВыполнитьНаСервере();
КонецПроцедуры
Здесь ВыполнитьНаСервере() — экспортная процедура модуля объекта самой обработки. В модуле объекта нет директив компиляции: он всегда работает там, где создан объект, то есть на сервере.
Третий параметр Подключить — безопасный режим. По умолчанию он равен Истина, и тогда обработке запрещены запись файлов, COM-объекты, внешние компоненты и привилегированный режим. Для служебной обработки, которая правит данные, его ставят в Ложь, но только при доверии к файлу.
Что умеют типовые конфигурации
В конфигурациях на БСП (БП 3.0, ЗУП 3.1, УТ 11) обработку не обязательно открывать через Файл → Открыть. Её регистрируют в справочнике дополнительных обработок: в БП путь Администрирование → Печатные формы, отчеты и обработки → Дополнительные отчеты и обработки. Зарегистрированная обработка вида «Дополнительная обработка» может работать по расписанию прямо на сервере, без открытой формы.
COM-соединение: выполнить код на сервере из внешней программы
COM-соединение (внешнее соединение) нужно, когда код запускает другая программа: скрипт, другая база 1С, сервис интеграции. Это работает только под Windows: на машине, откуда идёт подключение, должна быть зарегистрирована библиотека comcntr.dll той же версии, что и сервер.
Регистрация из командной строки администратора:
regsvr32 "C:\Program Files\1cv8\8.3.24.1548\bin\comcntr.dll"
Номер в пути подставьте свой: он совпадает с версией установленной платформы. Разрядность библиотеки должна совпадать с разрядностью программы, которая её вызывает.
Подключение из другой базы 1С:
Коннектор = Новый COMОбъект("V83.COMConnector");
СтрокаПодключения = "Srvr=""srv-1c"";Ref=""buh"";Usr=""Обмен"";Pwd=""пароль""";
База = Коннектор.Connect(СтрокаПодключения);
Результат = База.ОбменСВнешнимиСистемами.ПолучитьОстаток("00-00001");
Сообщить(Результат);
Что учесть:
- 🔹 вызывать можно только экспортные методы общих модулей, у которых стоит флажок «Внешнее соединение»;
- 🔹 пользователь из
Usrдолжен существовать в базе и иметь право «Внешнее соединение»; - 🔹 каждое подключение занимает сеанс и лицензию, поэтому открывайте его один раз на пакет операций, а не на каждый вызов;
- 🔹 в строке для файловой базы вместо
SrvrиRefуказываютFile="D:\Base\Buh".
Когда COM неудобен (Linux, удалённая площадка, другая платформа), тот же код публикуют как HTTP-сервис. Вызов идёт по HTTP, сеанс открывается на сервере 1С, лицензия расходуется так же.
Регламентные и фоновые задания: код на сервере по расписанию
Регламентное задание выполняет экспортную процедуру серверного общего модуля без участия пользователя. Создают его в Конфигураторе, в ветке Общие → Регламентные задания.
Настройка регламентного задания
- В конфигурации создайте общий модуль с флажком «Сервер» и экспортной процедурой.
- Добавьте регламентное задание, в поле «Имя метода» выберите эту процедуру.
- Включите флажки «Использование» и «Предопределенное», задайте расписание.
- Обновите конфигурацию базы данных.
- В консоли кластера откройте свойства информационной базы и проверьте, что не стоит флажок «Блокировка регламентных заданий включена».
Пример процедуры:
Процедура ОчиститьСтарыеЗаписи() Экспорт
ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания();
Удалено = 0;
// ... здесь выборка и удаление, на каждую запись Удалено = Удалено + 1;
ЗаписьЖурналаРегистрации("Очистка старых записей",
УровеньЖурналаРегистрации.Информация, , , "Удалено записей: " + Формат(Удалено, "ЧН=0; ЧГ=0"));
КонецПроцедуры
Строка ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания() нужна только в конфигурациях на БСП: она проверяет, можно ли запускать задание. В самописной базе её не пишут.
Разовый фоновый запуск
Если код нужно выполнить один раз, но долго и без зависания интерфейса, запускайте фоновое задание:
&НаСервереБезКонтекста
Функция ЗапуститьПересчет(Период)
Параметры = Новый Массив;
Параметры.Добавить(Период);
Задание = ФоновыеЗадания.Выполнить("СервисныеОперации.ПересчитатьИтоги", Параметры, , "Пересчёт итогов");
Возврат Задание.УникальныйИдентификатор;
КонецФункции
Метод в строке указывается как ИмяМодуля.ИмяПроцедуры, процедура должна быть экспортной и лежать в серверном модуле.
В файловой базе регламентные задания выполняет один из открытых клиентских сеансов. Нет открытых сеансов — задание не сработает. Для ночных операций в файловом варианте это ненадёжно, лучше запускать клиент по расписанию Windows с параметром /C и обработкой, которая отрабатывает при старте.
Консоль кода: выполнить произвольный фрагмент без программирования формы
Консоль кода — внешняя обработка с полем для текста на встроенном языке и кнопкой запуска. Таких обработок много, у большинства есть переключатель «Выполнять на клиенте / на сервере». Под капотом серверный режим устроен просто:
&НаСервере
Процедура ВыполнитьКодНаСервере(ТекстКода)
УстановитьБезопасныйРежим(Ложь);
Выполнить(ТекстКода);
КонецПроцедуры
Оператор Выполнить() компилирует и исполняет строку прямо в серверном контексте. Переменные из окружения процедуры внутри строки доступны.
Как работать с консолью безопасно:
- Сначала прогоните код на копии базы, а не на рабочей.
- Пишите изменения в транзакции и проверяйте результат через
Сообщить()до записи. - Сохраняйте удачные фрагменты как сниппеты: это и шаблон на будущее, и след того, что меняли в базе.
- Свойство объекта
ОбменДанными.Загрузка = Истинаускоряет массовую запись, но отключает проверки и большую часть обработчиков при записи. Ставьте его, только если понимаете, что именно будет пропущено.
Код, который записывает или удаляет объекты, сначала запускайте на копии базы и только после проверки — в рабочей.
Права, безопасный режим и защита от чужого кода на сервере
Возможность выполнить код на сервере — это полный доступ к данным и к файловой системе сервера от имени службы 1С. Поэтому права разграничивают в нескольких местах.
| Уровень | Что ограничивает | Где настраивается |
|---|---|---|
| Права роли | открытие внешних обработок, внешнее соединение, администрирование | Конфигуратор, роли пользователя |
| Защита от опасных действий | предупреждение при открытии внешних файлов | свойства пользователя в Конфигураторе |
| Безопасный режим | файлы, COM, внешние компоненты, привилегии в коде | параметр Подключить, УстановитьБезопасныйРежим() |
| Профили безопасности | что разрешено коду на уровне кластера | консоль администрирования кластера |
Практические правила:
- 🔒 права «Интерактивное открытие внешних обработок» и «Интерактивное открытие внешних отчетов» оставляйте только администраторам;
- 🔒 для COM и HTTP-интеграций заводите отдельного пользователя с узкой ролью, а не подключайтесь под администратором;
- 🔒
УстановитьПривилегированныйРежим(Истина)включайте только на нужный кусок кода и выключайте сразу после; - 🔒 службу агента сервера запускайте под отдельной учётной записью с правами только на свои каталоги, а не под системной.
Профиль безопасности в кластере особенно полезен в облаке и у франчайзи: даже администратор базы не сможет выполнить код, который пишет в каталоги сервера вне разрешённого списка.
Отладка и логи, когда серверный код не работает
Серверный код падает тише клиентского: пользователь видит общее сообщение, а подробности остаются в журналах.
Отладка на сервере
Чтобы точки останова срабатывали в серверных процедурах клиент-серверной базы, агент сервера должен работать в режиме отладки. Для этого в параметры запуска службы ragent добавляют ключ -debug и перезапускают службу.
Перезапуск службы агента обрывает сеансы всех пользователей всех баз этого сервера. Делайте это вне рабочего времени или на тестовом сервере.
После этого в Конфигураторе откройте Отладка → Подключение и включите автоматическое подключение к серверным процессам. Для фоновых и регламентных заданий отладку подключают так же: выберите в списке нужный тип предмета отладки.
Журнал регистрации и технологический журнал
- 📘 Журнал регистрации — ошибки и записи из
ЗаписьЖурналаРегистрации(). В БП 3.0 открывается изАдминистрирование → Обслуживание. Фильтруйте по событию и пользователю. - 📗 Технологический журнал — исключения рабочих процессов, долгие вызовы, блокировки. Включается файлом
logcfg.xmlв каталогеconfплатформы на сервере.
Минимальная настройка для поиска исключений:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="D:\techlog" history="24">
<event>
<eq property="name" value="EXCP"/>
</event>
<property name="all"/>
</log>
</config>
Параметр history задаёт, сколько часов хранить файлы. Не оставляйте журнал с широким набором событий надолго: на нагруженном сервере он занимает гигабайты за часы.
Частые вопросы о выполнении кода на сервере 1С
Можно ли выполнить код на сервере без Конфигуратора и прав на изменение конфигурации?
Почему в серверной процедуре недоступны `Предупреждение()` и открытие форм?
Сообщить() или возвращайте значение в клиентскую процедуру.Расходует ли лицензию фоновое задание?
Как проверить в самом коде, что он выполняется на сервере?
#Если Сервер Тогда … #КонецЕсли. В модуле формы ориентир проще — директива над процедурой.