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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с типовыми конфигурациями «1С:Предприятие 8.3», построенными на базе Библиотеки стандартных подсистем (БСП), разработчики часто сталкиваются с необходимостью автоматизации рутинных задач без снятия конфигурации с поддержки. Одной из таких задач является ежедневный сдвиг даты запрета изменения данных. Поскольку добавить новое регламентное задание напрямую в типовую конфигурацию нельзя, логичным выходом кажется использование механизма дополнительных отчетов и обработок. Однако здесь программистов подстерегают ошибки, связанные с особенностями программного интерфейса БСП.

В данной статье мы подробно разберем, почему возникает ошибка при выполнении внешней обработки, как правильно составить модуль объекта для интеграции с БСП и какие существуют альтернативные способы решения задачи через расширения.

Разбор основной причины ошибки: параметры процедуры ВыполнитьКоманду

Рассмотрим ситуацию: вы создали внешнюю обработку, добавили её в справочник «Дополнительные отчеты и обработки», но при попытке выполнения (вручную или по расписанию) система выдает ошибку. Чаще всего проблема кроется в несоответствии сигнатуры экспортной процедуры ВыполнитьКоманду ожиданиям системы.

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


// ПРАВИЛЬНО: процедура с двумя параметрами
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполнения) Экспорт
    
    Если ИдентификаторКоманды = "СдвинутьДатуЗапрета" Тогда
        СдвинутьДатуЗапретаНаОдинДень();
    КонецЕсли;
    
КонецПроцедуры

Если вы укажете только ИдентификаторКоманды, платформа при попытке передать структуру ПараметрыВыполнения вызовет исключение, так как количество фактических параметров не совпадет с количеством формальных. Это именно та причина, по которой у автора темы в сообщении №5 «все заработало» после правки параметров.

Шаблон функции СведенияОВнешнейОбработке

Для того чтобы система «увидела» вашу обработку и позволила запускать её по расписанию, необходимо правильно заполнить регистрационные данные. Рассмотрим структуру функции СведенияОВнешнейОбработке, которая должна располагаться в модуле объекта. Мы будем использовать универсальный шаблон, подходящий для большинства современных конфигураций (УТ 11, КА 2, ERP 2, БП 3.0, ЗУП 3.1).


Функция СведенияОВнешнейОбработке() Экспорт
    
    РегистрационныеДанные = Новый Структура;
    РегистрационныеДанные.Вставить("Вид", "ДополнительнаяОбработка");
    РегистрационныеДанные.Вставить("Наименование", "Автоматический сдвиг даты запрета");
    РегистрационныеДанные.Вставить("Версия", "1.1");
    РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь); // Важно для записи в БД
    РегистрационныеДанные.Вставить("Информация", "Обработка для ежедневного обновления даты запрета изменений.");
    
    ТаблицаКоманд = ПолучитьТаблицуКоманд();
    
    // Тип использования: ВызовСерверногоМетода - позволяет запускать код в фоновом задании
    ДобавитьКоманду(ТаблицаКоманд, 
                   "Сдвинуть дату запрета на 1 день", 
                   "СдвинутьДатуЗапрета", 
                   "ВызовСерверногоМетода", 
                   Истина);
    
    РегистрационныеДанные.Вставить("Команды", ТаблицаКоманд);
    
    Возврат РегистрационныеДанные;
    
КонецФункции

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

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование = "ОткрытиеФормы", ПоказыватьОповещение = Ложь, Модификатор = "")
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор;
    НоваяКоманда.Использование = Использование;
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры

Обратите особое внимание на параметр БезопасныйРежим. Если вы установите его в значение Истина, обработка будет ограничена в правах и не сможет выполнять запись в регистры сведений или использовать привилегированные модули. Для задачи изменения даты запрета этот флаг должен быть Ложь.

Алгоритм изменения даты запрета: правильный подход

В сообщениях форума (№17 и №18) завязалась дискуссия о том, как правильно записывать данные в регистр. Автор предлагал делать это в цикле через набор записей. Однако в типовых конфигурациях 1С прямой доступ к регистрам ДатыЗапретаИзменения крайне не рекомендуется. Выясним почему.

Проблема прямой записи заключается в кэшировании. Система хранит актуальные даты запрета в параметрах сеанса для повышения производительности. Если вы просто запишете новую строку в регистр, пользователи (и серверные фоновые процессы) могут не «увидеть» изменений до тех пор, пока их сеанс не будет перезапущен или кэш не очистится.

Правильный способ — использование программного интерфейса общего модуля ДатыЗапретаИзменения. Рассмотрим пример реализации основной логики:


Процедура СдвинутьДатуЗапретаНаОдинДень()
    
    // Получаем текущую дату и вычисляем новую (вчерашний день)
    НоваяДатаЗапрета = НачалоДня(ТекущаяДата()) - 24 * 60 * 60;
    
    // Используем штатный механизм БСП. 
    // Это гарантирует очистку кэша и корректность прав.
    // Если нужно установить для всех пользователей (Объект = Неопределено)
    Попытка
        ДатыЗапретаИзменения.УстановитьДатуЗапрета(НоваяДатаЗапрета);
        ЗаписьЖурналаРегистрации("ВнешняяОбработка.СдвигДатыЗапрета", 
            УровеньЖурналаРегистрации.Информация, , , 
            "Дата запрета успешно изменена на " + НоваяДатаЗапрета);
    Исключение
        ЗаписьЖурналаРегистрации("ВнешняяОбработка.СдвигДатыЗапрета", 
            УровеньЖурналаРегистрации.Ошибка, , , 
            ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Метод через расширение конфигурации: когда это лучше?

В сообщении №11 предлагается альтернатива — использование расширения. Давайте проанализируем этот вариант. Если внешняя обработка — это «надстройка», то расширение — это часть системы.

Преимущества расширения:

  1. Регламентные задания: Вы можете добавить полноценный объект РегламентноеЗадание прямо в расширение. Оно будет отображаться в стандартной консоли регламентных заданий и его проще администрировать.
  2. Стабильность: Расширение не зависит от того, лежит ли файл .epf на диске и не удалил ли его кто-то случайно.
  3. Контроль версий: Код расширения хранится в базе данных и загружается вместе с конфигурацией.

Для реализации этого метода нам нужно:

  1. Создать новое расширение (с назначением «Адаптация»).
  2. Добавить в него новый общий модуль (например, Расш_РаботаСДатамиЗапрета) с установленным флагом «Сервер».
  3. Добавить объект РегламентноеЗадание, указав в качестве метода процедуру из этого модуля.
  4. Настроить расписание (например, каждый день в 00:01).

// В общем модуле расширения
Процедура ВыполнитьСдвигДатыЗапрета() Экспорт
    // Аналогичный код с вызовом ДатыЗапретаИзменения.УстановитьДатуЗапрета
КонецПроцедуры

Настройка расписания для внешней обработки

Если вы решили остановиться на варианте с внешней обработкой, разберем по шагам, как заставить её работать автоматически в типовой конфигурации:

  1. Перейдите в раздел Администрирование — Печатные формы, отчеты и обработки.
  2. Убедитесь, что флаг «Дополнительные отчеты и обработки» включен.
  3. Нажмите гиперссылку «Дополнительные отчеты и обработки».
  4. Нажмите «Добавить из файла» и выберите вашу обработку.
  5. После загрузки в таблице «Команды» найдите созданную вами команду.
  6. В колонке «Расписание» (она появляется только для команд с типом «Вызов серверного метода») нажмите «Не определено» и настройте нужное время запуска.
  7. Важно: Укажите пользователя, от имени которого будет запускаться задание. У этого пользователя должны быть полные права или права на изменение дат запрета (сообщение №10).

Итоги и рекомендации

Подводя итог нашему разбору, выделим ключевые моменты, которые гарантируют успех:

Во-первых, всегда проверяйте количество параметров у экспортных процедур, вызываемых БСП. Использование ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполнения) — это стандарт де-факто.

Во-вторых, не изобретайте велосипед при работе с данными, для которых в типовой конфигурации уже написан программный интерфейс (API). Использование модуля ДатыЗапретаИзменения вместо прямой записи в регистр сведений сэкономит вам время на отладку проблем с кэшированием.

В-третьих, при выборе между внешней обработкой и расширением руководствуйтесь требованиями к поддержке. Если конфигурация полностью типовая и находится на замке, внешняя обработка — самый безопасный вариант. Если же база уже имеет расширения, добавление нового регламентного задания через расширение будет более профессиональным и надежным решением.

Надеемся, данный разбор помог вам разобраться в тонкостях взаимодействия с БСП и успешно автоматизировать контроль периодов редактирования данных в вашей системе.

← На главную