Пять рабочих способов запустить свой код на стороне сервера 1С:Предприятия 8.3

· 9 мин

Содержание

Чтобы выполнить код на сервере 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С, лицензия расходуется так же.

Регламентные и фоновые задания: код на сервере по расписанию

Регламентное задание выполняет экспортную процедуру серверного общего модуля без участия пользователя. Создают его в Конфигураторе, в ветке Общие → Регламентные задания.

Настройка регламентного задания

  1. В конфигурации создайте общий модуль с флажком «Сервер» и экспортной процедурой.
  2. Добавьте регламентное задание, в поле «Имя метода» выберите эту процедуру.
  3. Включите флажки «Использование» и «Предопределенное», задайте расписание.
  4. Обновите конфигурацию базы данных.
  5. В консоли кластера откройте свойства информационной базы и проверьте, что не стоит флажок «Блокировка регламентных заданий включена».

Пример процедуры:

Процедура ОчиститьСтарыеЗаписи() Экспорт
	ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания();
	Удалено = 0;
	// ... здесь выборка и удаление, на каждую запись Удалено = Удалено + 1;
	ЗаписьЖурналаРегистрации("Очистка старых записей",
		УровеньЖурналаРегистрации.Информация, , , "Удалено записей: " + Формат(Удалено, "ЧН=0; ЧГ=0"));
КонецПроцедуры

Строка ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания() нужна только в конфигурациях на БСП: она проверяет, можно ли запускать задание. В самописной базе её не пишут.

Разовый фоновый запуск

Если код нужно выполнить один раз, но долго и без зависания интерфейса, запускайте фоновое задание:

&НаСервереБезКонтекста
Функция ЗапуститьПересчет(Период)
	Параметры = Новый Массив;
	Параметры.Добавить(Период);
	Задание = ФоновыеЗадания.Выполнить("СервисныеОперации.ПересчитатьИтоги", Параметры, , "Пересчёт итогов");
	Возврат Задание.УникальныйИдентификатор;
КонецФункции

Метод в строке указывается как ИмяМодуля.ИмяПроцедуры, процедура должна быть экспортной и лежать в серверном модуле.

В файловой базе регламентные задания выполняет один из открытых клиентских сеансов. Нет открытых сеансов — задание не сработает. Для ночных операций в файловом варианте это ненадёжно, лучше запускать клиент по расписанию Windows с параметром /C и обработкой, которая отрабатывает при старте.

Консоль кода: выполнить произвольный фрагмент без программирования формы

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

&НаСервере
Процедура ВыполнитьКодНаСервере(ТекстКода)
	УстановитьБезопасныйРежим(Ложь);
	Выполнить(ТекстКода);
КонецПроцедуры

Оператор Выполнить() компилирует и исполняет строку прямо в серверном контексте. Переменные из окружения процедуры внутри строки доступны.

Как работать с консолью безопасно:

  1. Сначала прогоните код на копии базы, а не на рабочей.
  2. Пишите изменения в транзакции и проверяйте результат через Сообщить() до записи.
  3. Сохраняйте удачные фрагменты как сниппеты: это и шаблон на будущее, и след того, что меняли в базе.
  4. Свойство объекта ОбменДанными.Загрузка = Истина ускоряет массовую запись, но отключает проверки и большую часть обработчиков при записи. Ставьте его, только если понимаете, что именно будет пропущено.

Код, который записывает или удаляет объекты, сначала запускайте на копии базы и только после проверки — в рабочей.

Перед запуском кода в рабочей базе
Выполнено: 0 / 5

Права, безопасный режим и защита от чужого кода на сервере

Возможность выполнить код на сервере — это полный доступ к данным и к файловой системе сервера от имени службы 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С

Можно ли выполнить код на сервере без Конфигуратора и прав на изменение конфигурации?
Да. Достаточно внешней обработки или консоли кода и права на открытие внешних обработок. Конфигурацию при этом менять не нужно.
Почему в серверной процедуре недоступны `Предупреждение()` и открытие форм?
Интерфейсные методы работают только на клиенте. На сервере выводите результат через Сообщить() или возвращайте значение в клиентскую процедуру.
Расходует ли лицензию фоновое задание?
Нет, фоновые и регламентные задания клиентскую лицензию не занимают. COM-соединение и HTTP-сервис занимают.
Как проверить в самом коде, что он выполняется на сервере?
Используйте инструкции препроцессора #Если Сервер Тогда … #КонецЕсли. В модуле формы ориентир проще — директива над процедурой.
Можно ли выполнить код на сервере из файловой базы?
Да, директивы и фоновые задания работают. Но «сервер» здесь — процесс клиента, открывшего базу, поэтому нагрузка ложится на этот компьютер.