Многие разработчики и пользователи 1С сталкиваются с необходимостью автоматизировать выполнение рутинных операций, которые реализованы во внешних обработках. Стандартные регламентные задания в 1С позволяют запускать методы общих модулей конфигурации по расписанию, но прямое подключение внешней обработки к регламентному заданию невозможно. Существуют расширения для упрощения этой задачи, но давайте разберем, как мы можем обойти это ограничение самостоятельно, используя минимальные изменения в конфигурации и адаптируя саму внешнюю обработку.
Суть проблемы: мы хотим, чтобы внешняя обработка запускалась, например, раз в час, выполняя определенные действия (проверку данных, формирование отчетов и т.п.).
Основная идея заключается в том, чтобы создать в конфигурации специальный общий модуль, который будет содержать экспортную функцию. Именно эту функцию мы и будем назначать регламентному заданию. Внутри этой функции будет осуществляться программное создание и выполнение нашей внешней обработки. Таким образом, конфигурация претерпит лишь минимальные изменения (добавление одного общего модуля), а сама внешняя обработка останется внешней, но будет адаптирована для программного запуска.
Давайте рассмотрим каждый шаг подробнее.
Начнем с того, что нам понадобится общий модуль в нашей информационной базе. Если у вас уже есть общий модуль для серверных операций, можно использовать его, добавив в него новую функцию. Если нет, создадим новый.
Шаг 1.1: Создание общего модуля.
Откроем конфигуратор, в дереве объектов конфигурации найдем ветку "Общие" -> "Общие модули". Добавим новый общий модуль, например, МойОбщийМодульСервер.
Шаг 1.2: Настройка свойств модуля.
Для корректной работы регламентных заданий и доступа к файловой системе сервера, необходимо установить следующие свойства для созданного общего модуля:
Шаг 1.3: Написание экспортной функции.
Внутри нашего общего модуля МойОбщийМодульСервер нам потребуется экспортная функция, которая будет отвечать за загрузку и запуск внешней обработки. Назовем ее, например, ВыполнитьВнешнююОбработкуПоПути.
Посмотрим на пример кода для такой функции (для быстрой генерации подобных конструкций удобно использовать консоль кода с ИИ-помощником):
// Модуль: МойОбщийМодульСервер
&НаСервере
Функция ВыполнитьВнешнююОбработкуПоПути(ПутьКФайлуОбработки, ПараметрыЗапуска = Неопределено) Экспорт
// Прежде всего, необходимо убедиться, что файл внешней обработки существует и доступен
// для сервера 1С:Предприятия по указанному пути.
Если НЕ ФайлСуществует(ПутьКФайлуОбработки) Тогда
ЗаписатьЖурналРегистрации(
"Ошибка запуска внешней обработки: файл не найден по пути '" + ПутьКФайлуОбработки + "'",
УровеньЖурналаРегистрации.Ошибка
);
Возврат Ложь;
КонецЕсли;
Попытка
// Создаем объект внешней обработки, используя ее путь к файлу.
// Функция ВнешниеОбработки.Создать() загружает и инициализирует внешнюю обработку.
// Важно: в этот момент вызываются методы ПриСозданииНаСервере, ПриСозданииНаКлиенте
// и ПриОткрытии (если у обработки есть форма и она открывается).
ОбработкаОбъект = ВнешниеОбработки.Создать(ПутьКФайлуОбработки);
// Теперь нам нужно вызвать основной функционал внешней обработки.
// Идеально, если обработка имеет заранее определенную экспортную функцию
// в своем модуле объекта, которая инкапсулирует всю логику.
// Например, МояОсновнаяФункцияДляЗапускаПоРасписанию.
// Проверяем наличие нашей специфической функции.
// Мы будем искать экспортный метод с именем "МояОсновнаяФункцияДляЗапускаПоРасписанию"
// в модуле объекта внешней обработки.
Если ТипЗнч(ОбработкаОбъект.МояОсновнаяФункцияДляЗапускаПоРасписанию) = Тип("Метод") Тогда
// Если функция найдена, вызываем ее, передавая параметры.
// ПараметрыЗапуска могут быть структурой, массивом или любым другим значением,
// которое ожидает наша функция в обработке.
ОбработкаОбъект.МояОсновнаяФункцияДляЗапускаПоРасписанию(ПараметрыЗапуска);
Возврат Истина;
Иначе
// Если специфический метод не найден, можно попробовать стандартные варианты,
// если обработка предполагает их. Например, метод "Выполнить" или "ОсновноеДействие".
// Однако, рекомендуется придерживаться строгого именования для ясности.
ЗаписатьЖурналРегистрации(
"Ошибка запуска внешней обработки: не найден экспортный метод 'МояОсновнаяФункцияДляЗапускаПоРасписанию' в обработке по пути '" + ПутьКФайлуОбработки + "'",
УровеньЖурналаРегистрации.Ошибка
);
Возврат Ложь;
КонецЕсли;
Исключение
// В случае любой ошибки во время создания или выполнения обработки,
// записываем подробную информацию в журнал регистрации.
ЗаписатьЖурналРегистрации(
"Ошибка при выполнении внешней обработки по пути '" + ПутьКФайлуОбработки + "': " + ОписаниеОшибки(),
УровеньЖурналаРегистрации.Ошибка
);
Возврат Ложь;
КонецПопытки;
КонецФункции
Пояснения к коду:
&НаСервере: эта директива указывает, что функция должна выполняться на сервере. Это критично для регламентных заданий.Экспорт: делает функцию доступной для вызова извне, в том числе из регламентных заданий.ФайлСуществует(ПутьКФайлуОбработки): это важная проверка. Путь к файлу должен быть абсолютным и доступным с сервера 1С:Предприятия. Если 1С работает в клиент-серверном варианте, то путь должен быть доступен для пользователя, под которым запущен серверный процесс 1С.ВнешниеОбработки.Создать(ПутьКФайлуОбработки): эта функция создает экземпляр объекта внешней обработки. Фактически, она загружает код обработки в память сервера.ОбработкаОбъект.МояОсновнаяФункцияДляЗапускаПоРасписанию(ПараметрыЗапуска): это вызов той самой экспортной функции, которую мы ожидаем увидеть в нашей внешней обработке. Если логика обработки требует каких-то входных данных (например, дата начала периода, идентификатор пользователя), их можно передать через параметр ПараметрыЗапуска.ЗаписатьЖурналРегистрации(...): мы активно используем запись в журнал регистрации для отслеживания ошибок. Это позволяет оперативно выявлять проблемы с доступом к файлу, ошибки в коде обработки или неправильно переданные параметры.Как мы выяснили в предыдущем шаге, наша внешняя обработка должна иметь экспортную функцию в своем модуле объекта, которую мы будем вызывать из общего модуля конфигурации. Изначально многие внешние обработки имеют логику, привязанную к кнопкам на форме. Наша задача – вынести эту логику в отдельную экспортную функцию.
Шаг 2.1: Перенос логики в экспортную функцию.
Откроем нашу внешнюю обработку в конфигураторе. Найдем ее модуль объекта (обычно это "Модуль объекта"). В этом модуле создадим новую экспортную функцию, например, МояОсновнаяФункцияДляЗапускаПоРасписанию. Весь код, который должен выполняться автоматически, перенесем из обработчика кнопки или других процедур формы в эту функцию.
Для более сложных задач, требующих гибкости, может пригодиться шаблон дополнительной обработки с удобной системой хранения настроек. Посмотрим на пример кода для модуля объекта нашей внешней обработки:
// Модуль объекта внешней обработки (.epf файл)
// Эта функция будет вызываться регламентным заданием через общий модуль конфигурации.
Функция МояОсновнаяФункцияДляЗапускаПоРасписанию(Параметры = Неопределено) Экспорт
// Здесь размещаем весь основной код, который раньше был привязан к кнопке на форме
// или должен выполняться автоматически.
// Если требуется доступ к данным ИБ, помните, что эта функция будет выполняться
// на сервере, в фоновом режиме.
Попытка
// Пример: Получаем текущую дату
ТекущаяДатаСервера = ТекущаяДата();
ЗаписатьЖурналРегистрации(
"Внешняя обработка запущена по расписанию. Текущая дата: " + ТекущаяДатаСервера,
УровеньЖурналаРегистрации.Информация
);
// Если переданы параметры, можно их использовать
Если ТипЗнч(Параметры) = Тип("Структура") Тогда
Если Параметры.Свойство("ИмяПараметра") Тогда
ЗначениеПараметра = Параметры.ИмяПараметра;
ЗаписатьЖурналРегистрации(
"Получен параметр 'ИмяПараметра': " + ЗначениеПараметра,
УровеньЖурналаРегистрации.Информация
);
КонецЕсли;
КонецЕсли;
// Здесь может быть вызов запросов к базе данных:
// Запрос = Новый Запрос;
// Запрос.Текст = "ВЫБРАТЬ ... ИЗ ...";
// Результат = Запрос.Выполнить().Выгрузить();
// Или создание документов:
// НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
// НовыйДокумент.Дата = ТекущаяДата();
// НовыйДокумент.Записать();
// ... Ваш основной функционал обработки ...
Возврат Истина; // Возвращаем Истина в случае успешного выполнения
Исключение
// Если что-то пошло не так внутри самой обработки,
// также записываем ошибку в журнал регистрации.
ЗаписатьЖурналРегистрации(
"Ошибка выполнения логики во внешней обработке: " + ОписаниеОшибки(),
УровеньЖурналаРегистрации.Ошибка
);
Возврат Ложь; // Возвращаем Ложь в случае ошибки
КонецПопытки;
КонецФункции
Важные моменты:
&НаСервере не нужна для методов модуля объекта внешней обработки, которые вызываются из серверного общего модуля. Когда мы создаем объект ВнешниеОбработки.Создать(), вся его логика уже выполняется на сервере.ЭлементыФормы.МояКнопка.Доступность = Ложь;), должен быть исключен или модифицирован.МояОсновнаяФункцияДляЗапускаПоРасписанию должна быть написана с учетом серверного выполнения. Вы можете выполнять запросы к базе данных, создавать и изменять объекты, работать с файлами на сервере и т.д.Истина или Ложь, чтобы вызывающий код (наш общий модуль) мог понять, успешно ли завершилась обработка.Шаг 2.2: Сохранение внешней обработки.
После внесения изменений во внешнюю обработку, обязательно сохраните ее в файле .epf. Убедитесь, что файл сохранен в месте, доступном для сервера 1С:Предприятия. Идеально, если это какая-то общая сетевая папка или папка на диске самого сервера.
После того как мы подготовили общий модуль в конфигурации и адаптировали внешнюю обработку, пришло время настроить само регламентное задание, которое будет запускать нашу логику по расписанию.
Шаг 3.1: Открытие списка регламентных заданий.
В режиме 1С:Предприятие перейдем в раздел "Администрирование" (обычно доступен из рабочего стола или главного меню). В этом разделе найдем пункт "Обслуживание" (или "Настройки"), а затем "Регламентные и фоновые задания" (названия могут немного отличаться в разных конфигурациях, но суть остается та же).
Шаг 3.2: Создание нового регламентного задания.
В открывшемся списке регламентных заданий нажмем кнопку "Создать" или "Добавить".
Шаг 3.3: Заполнение параметров задания.
ИмяОбщегоМодуля.ИмяЭкспортнойФункции. В нашем случае это будет МойОбщийМодульСервер.ВыполнитьВнешнююОбработкуПоПути.Шаг 3.4: Настройка расписания.
Нажмите кнопку "Расписание" и настройте периодичность выполнения. В нашем случае, если нам нужно запускать обработку раз в час, мы можем настроить так:
Шаг 3.5: Установка параметров (необязательно).
В некоторых конфигурациях может быть поле "Параметры". Если оно есть, вы можете передать дополнительные параметры в функцию ВыполнитьВнешнююОбработкуПоПути. Обычно это строка JSON или XML, которую затем разбирает ваша функция. В нашем случае, путь к файлу обработки мы передаем как первый параметр метода. Дополнительные параметры, если они необходимы для вашей внешней обработки (например, период, отбор), можно передать вторым параметром функции ПараметрыЗапуска.
Например, если вашей обработке нужен период и какой-то флаг, то в поле "Параметры" регламентного задания вы могли бы указать строку, которую затем разбирает функция:
// Пример строки для передачи в поле "Параметры" регламентного задания,
// если конфигурация позволяет передавать строку, которая затем будет
// преобразована в структуру функцией ВыполнитьВнешнююОбработкуПоПути.
// Это не прямое поле для второго параметра, а скорее пример, как можно
// передать дополнительные данные, которые нужно будет разобрать в коде.
// Например, в вашей функции ВыполнитьВнешнююОбработкуПоПути
// можно добавить логику разбора такой строки:
// ПараметрыЗапуска = Новый Структура("ДатаНачала, ФлагОтбора", '20230101', Истина);
// Или если параметры передаются вторым параметром в виде Структуры,
// то вам нужно программно заполнить эту структуру при создании РЗ,
// или РЗ должно уметь парсить некую строку в Структуру.
Для простоты, если вам нужно передать только путь к файлу внешней обработки, вы просто указываете его как часть вызова функции или как первый аргумент, если интерфейс настройки регламентных заданий это позволяет. В приведенном примере кода, ПутьКФайлуОбработки и ПараметрыЗапуска являются аргументами метода, и их значения должны быть либо жестко заданы в коде общего модуля, либо динамически определяться (например, путь к файлу может храниться в константе).
Важно: в большинстве типовых конфигураций поле "Параметры" в форме регламентного задания предназначено для передачи строкового значения, которое будет передано как *единый* параметр в метод. Если вам нужно передать несколько параметров, ваша функция ВыполнитьВнешнююОбработкуПоПути должна быть модифицирована для разбора этой строки (например, в JSON или XML) в структуру или массив.
Более простой способ для передачи параметров: в самом общем модуле МойОбщийМодульСервер мы можем сделать жесткий путь к файлу обработки или считывать его из константы. Например:
// Модифицированная функция в МойОбщийМодульСервер, если путь фиксированный или из константы
&НаСервере
Функция ЗапуститьМоюВнешнююОбработкуПоРасписанию() Экспорт
// Путь к файлу обработки можно хранить в константе или просто указать здесь
ПутьКФайлуОбработки = Константы.ПутьКФайлуМоейОбработки.Получить(); // Или "C:\НашиОбработки\MyExternalProc.epf";
// Если нужны дополнительные параметры для самой обработки, формируем их
ПараметрыДляОбработки = Новый Структура();
ПараметрыДляОбработки.Вставить("ДатаОтчета", ТекущаяДата());
ПараметрыДляОбработки.Вставить("ТолькоАктивные", Истина);
Возврат ВыполнитьВнешнююОбработкуПоПути(ПутьКФайлуОбработки, ПараметрыДляОбработки);
КонецФункции
Тогда в регламентном задании вы просто указываете метод МойОбщийМодульСервер.ЗапуститьМоюВнешнююОбработкуПоРасписанию, и никаких дополнительных параметров в форме регламентного задания не требуется.
Попытка...Исключение и ЗаписатьЖурналРегистрации() для надежной обработки ошибок. Это поможет вам отслеживать проблемы и оперативно их решать. Подробные сообщения в журнале регистрации с описанием ошибок значительно упрощают отладку..epf на сервере при каждом изменении.Используя этот подход, мы получаем гибкий и относительно простой механизм для автоматического выполнения внешних обработок по расписанию в 1С 8.3 Управляемых формах, минимизируя при этом изменения в основной конфигурации.