При разработке расширений для типовых конфигураций, таких как 1С:Управление торговлей 11, ERP Управление предприятием или Комплексная автоматизация, программисты часто сталкиваются с необходимостью изменить логику проведения документов. Одна из самых распространенных задач — программное переключение режима проведения с оперативного на неоперативный. Это критично, когда документ должен быть проведен «будущей датой», так как платформа 1С по умолчанию запрещает оперативное проведение документов, дата которых превышает текущее время сервера, что требует корректного управления датами запрета изменений в разрезе пользователей — для решения подобных задач администрирования пригодится упрощенная настройка прав и ролей доступа пользователей.
В этой статье мы подробно разберем, почему стандартные попытки подменить режим проведения в расширении часто заканчиваются ошибкой «Дата оперативно проводимого документа больше текущей. Документ не может быть проведен оперативно!», и как правильно реализовать эту задачу, учитывая архитектуру типовых решений.
Рассмотрим ситуацию, с которой столкнулся автор темы. Он попытался изменить режим проведения в расширении модуля объекта, используя следующий код:
&Перед("ОбработкаПроведения")
Процедура Ан_ОбработкаПроведения(Отказ, РежимПроведения)
РежимПроведения = РежимПроведенияДокумента.Неоперативный;
КонецПроцедуры
Проанализируем, почему этот подход ошибочен. Проблема заключается в том, что платформа 1С выполняет проверку режима проведения и даты документа до начала транзакции проведения. Когда управление передается в процедуру ОбработкаПроведения, выбор между оперативным и неоперативным режимом уже сделан платформой. Если в форме было инициировано оперативное проведение, а дата документа — будущая, платформа «выбросит» исключение еще до того, как ваш код в модуле объекта начнет выполняться. Изменение переменной РежимПроведения внутри этой процедуры уже ни на что не влияет в контексте системной проверки даты.
В современных конфигурациях на базе Библиотеки стандартных подсистем (БСП) процесс записи и проведения документа из формы сильно кастомизирован. Мы можем увидеть это в стеке вызовов ошибки, выполнив анализ конфигураций и расширений на наличие ошибок:
Форма.Записать() вызывает внутренние механизмы платформы.ОбщегоНазначенияУТКлиент.ОбработатьЗаписьОбъектаВФорме, что является частью универсального механизма расширения конфигураций на основе 1С:БСП.В этих конфигурациях режим проведения определяется не просто нажатием кнопки, а сложной структурой ПараметрыЗаписи (или ПараметрыДляЗаписи). Если мы хотим изменить поведение системы, нам нужно вмешаться в процесс формирования этих параметров на стороне клиента, еще до того, как управление уйдет на сервер для выполнения метода Записать().
Самый правильный способ — модифицировать структуру параметров, которая передается в процедуру записи. В расширении формы документа нам необходимо найти обработчик, который отвечает за подготовку записи, используя механизм блокировки изменения объектов для управления формой. Рассмотрим пример расширения процедуры Подключаемый_ОбработатьЗаписьОбъекта:
&НаКлиенте
&Перед("Подключаемый_ОбработатьЗаписьОбъекта")
Процедура Ан_Подключаемый_ОбработатьЗаписьОбъекта(ПараметрыДляЗаписи)
// Устанавливаем режим проведения в структуре параметров
ПараметрыДляЗаписи.Вставить("РежимПроведения", РежимПроведенияДокумента.Неоперативный);
// В типовых УТ/ERP также важно проверить наличие флага оперативного проведения
Если ПараметрыДляЗаписи.Свойство("ИспользоватьОперативноеПроведение") Тогда
ПараметрыДляЗаписи.ИспользоватьОперативноеПроведение = Ложь;
КонецЕсли;
КонецПроцедуры
Здесь мы принудительно устанавливаем РежимПроведенияДокумента.Неоперативный. Важно помнить, что типовые конфигурации могут использовать свои свойства в структуре параметров, такие как ИспользоватьОперативноеПроведение. Если их не отключить, логика формы может переопределить ваш выбор непосредственно перед вызовом сервера.
Если по каким-то причинам клиентский перехват не подходит, мы можем использовать механизм ДополнительныеСвойства объекта. Рассмотрим ситуацию: платформа все равно пытается провести документ оперативно. Мы можем «обмануть» логику в процедуре ПередЗаписью модуля объекта (в расширении).
Разберем по шагам:
ПередЗаписью.Проведение.
&Перед("ПередЗаписью")
Процедура Ан_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
// Если дата документа больше текущей, принуждаем платформу к неоперативному режиму
Если ТекущийОбъект.Дата > ТекущаяДатаСеанса() Тогда
РежимПроведения = РежимПроведенияДокумента.Неоперативный;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важный нюанс: В некоторых версиях платформы 8.3 даже этот метод в ПередЗаписью модуля объекта может сработать слишком поздно, если инициатором была форма с жестко заданным режимом. Поэтому комбинация клиентского и серверного методов является наиболее надежной.
Проанализируем еще одну возможную причину неудачи. В метаданных каждого документа есть свойство «Оперативное проведение». Если оно установлено в значение Запретить, то документ всегда проводится неоперативно. Однако в типовых документах (например, «Приобретение товаров и услуг») оно обычно установлено в Разрешить.
Если программная подмена не срабатывает, проверьте следующие моменты:
Подводя итоги, отметим, что для успешного включения неоперативного проведения в расширении необходимо:
ОбработкаПроведения, так как это событие происходит после всех проверок платформы.ПараметрыДляЗаписи на клиенте.ОбщегоНазначения, которые могут переопределять параметры записи.ДополнительныеСвойства в ПередЗаписью на сервере для передачи флага о необходимости смены режима.Таким образом, комплексный подход к изменению параметров на стороне клиента и проверке условий на стороне сервера позволяет полностью контролировать процесс проведения документов в 1С, обходя стандартные ограничения платформы по дате оперативного проведения.