При работе с типовыми конфигурациями «1С:Предприятие 8.3», построенными на базе Библиотеки стандартных подсистем (БСП), разработчики часто сталкиваются с необходимостью автоматизации рутинных задач без снятия конфигурации с поддержки. Одной из таких задач является ежедневный сдвиг даты запрета изменения данных. Поскольку добавить новое регламентное задание напрямую в типовую конфигурацию нельзя, логичным выходом кажется использование механизма дополнительных отчетов и обработок. Однако здесь программистов подстерегают ошибки, связанные с особенностями программного интерфейса БСП.
В данной статье мы подробно разберем, почему возникает ошибка при выполнении внешней обработки, как правильно составить модуль объекта для интеграции с БСП и какие существуют альтернативные способы решения задачи через расширения.
Рассмотрим ситуацию: вы создали внешнюю обработку, добавили её в справочник «Дополнительные отчеты и обработки», но при попытке выполнения (вручную или по расписанию) система выдает ошибку. Чаще всего проблема кроется в несоответствии сигнатуры экспортной процедуры ВыполнитьКоманду ожиданиям системы.
В старых версиях БСП процедура могла принимать один параметр — идентификатор команды. Однако в современных версиях (начиная с 2.3 и выше) стандарт требует наличия двух параметров, даже если второй параметр не используется в вашем коде. Проанализируем правильное объявление процедуры в модуле объекта:
// ПРАВИЛЬНО: процедура с двумя параметрами
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполнения) Экспорт
Если ИдентификаторКоманды = "СдвинутьДатуЗапрета" Тогда
СдвинутьДатуЗапретаНаОдинДень();
КонецЕсли;
КонецПроцедуры
Если вы укажете только ИдентификаторКоманды, платформа при попытке передать структуру ПараметрыВыполнения вызовет исключение, так как количество фактических параметров не совпадет с количеством формальных. Это именно та причина, по которой у автора темы в сообщении №5 «все заработало» после правки параметров.
Для того чтобы система «увидела» вашу обработку и позволила запускать её по расписанию, необходимо правильно заполнить регистрационные данные. Рассмотрим структуру функции СведенияОВнешнейОбработке, которая должна располагаться в модуле объекта. Мы будем использовать универсальный шаблон, подходящий для большинства современных конфигураций (УТ 11, КА 2, ERP 2, БП 3.0, ЗУП 3.1).
Функция СведенияОВнешнейОбработке() Экспорт
РегистрационныеДанные = Новый Структура;
РегистрационныеДанные.Вставить("Вид", "ДополнительнаяОбработка");
РегистрационныеДанные.Вставить("Наименование", "Автоматический сдвиг даты запрета");
РегистрационныеДанные.Вставить("Версия", "1.1");
РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь); // Важно для записи в БД
РегистрационныеДанные.Вставить("Информация", "Обработка для ежедневного обновления даты запрета изменений.");
ТаблицаКоманд = ПолучитьТаблицуКоманд();
// Тип использования: ВызовСерверногоМетода - позволяет запускать код в фоновом задании
ДобавитьКоманду(ТаблицаКоманд,
"Сдвинуть дату запрета на 1 день",
"СдвинутьДатуЗапрета",
"ВызовСерверногоМетода",
Истина);
РегистрационныеДанные.Вставить("Команды", ТаблицаКоманд);
Возврат РегистрационныеДанные;
КонецФункции
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ОткрытиеФормы", ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Обратите особое внимание на параметр БезопасныйРежим. Если вы установите его в значение Истина, обработка будет ограничена в правах и не сможет выполнять запись в регистры сведений или использовать привилегированные модули. Для задачи изменения даты запрета этот флаг должен быть Ложь.
В сообщениях форума (№17 и №18) завязалась дискуссия о том, как правильно записывать данные в регистр. Автор предлагал делать это в цикле через набор записей. Однако в типовых конфигурациях 1С прямой доступ к регистрам ДатыЗапретаИзменения крайне не рекомендуется. Выясним почему.
Проблема прямой записи заключается в кэшировании. Система хранит актуальные даты запрета в параметрах сеанса для повышения производительности. Если вы просто запишете новую строку в регистр, пользователи (и серверные фоновые процессы) могут не «увидеть» изменений до тех пор, пока их сеанс не будет перезапущен или кэш не очистится.
Правильный способ — использование программного интерфейса общего модуля ДатыЗапретаИзменения. Рассмотрим пример реализации основной логики:
Процедура СдвинутьДатуЗапретаНаОдинДень()
// Получаем текущую дату и вычисляем новую (вчерашний день)
НоваяДатаЗапрета = НачалоДня(ТекущаяДата()) - 24 * 60 * 60;
// Используем штатный механизм БСП.
// Это гарантирует очистку кэша и корректность прав.
// Если нужно установить для всех пользователей (Объект = Неопределено)
Попытка
ДатыЗапретаИзменения.УстановитьДатуЗапрета(НоваяДатаЗапрета);
ЗаписьЖурналаРегистрации("ВнешняяОбработка.СдвигДатыЗапрета",
УровеньЖурналаРегистрации.Информация, , ,
"Дата запрета успешно изменена на " + НоваяДатаЗапрета);
Исключение
ЗаписьЖурналаРегистрации("ВнешняяОбработка.СдвигДатыЗапрета",
УровеньЖурналаРегистрации.Ошибка, , ,
ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
В сообщении №11 предлагается альтернатива — использование расширения. Давайте проанализируем этот вариант. Если внешняя обработка — это «надстройка», то расширение — это часть системы.
Преимущества расширения:
РегламентноеЗадание прямо в расширение. Оно будет отображаться в стандартной консоли регламентных заданий и его проще администрировать..epf на диске и не удалил ли его кто-то случайно.Для реализации этого метода нам нужно:
Расш_РаботаСДатамиЗапрета) с установленным флагом «Сервер».РегламентноеЗадание, указав в качестве метода процедуру из этого модуля.
// В общем модуле расширения
Процедура ВыполнитьСдвигДатыЗапрета() Экспорт
// Аналогичный код с вызовом ДатыЗапретаИзменения.УстановитьДатуЗапрета
КонецПроцедуры
Если вы решили остановиться на варианте с внешней обработкой, разберем по шагам, как заставить её работать автоматически в типовой конфигурации:
Подводя итог нашему разбору, выделим ключевые моменты, которые гарантируют успех:
Во-первых, всегда проверяйте количество параметров у экспортных процедур, вызываемых БСП. Использование ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполнения) — это стандарт де-факто.
Во-вторых, не изобретайте велосипед при работе с данными, для которых в типовой конфигурации уже написан программный интерфейс (API). Использование модуля ДатыЗапретаИзменения вместо прямой записи в регистр сведений сэкономит вам время на отладку проблем с кэшированием.
В-третьих, при выборе между внешней обработкой и расширением руководствуйтесь требованиями к поддержке. Если конфигурация полностью типовая и находится на замке, внешняя обработка — самый безопасный вариант. Если же база уже имеет расширения, добавление нового регламентного задания через расширение будет более профессиональным и надежным решением.
Надеемся, данный разбор помог вам разобраться в тонкостях взаимодействия с БСП и успешно автоматизировать контроль периодов редактирования данных в вашей системе.