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