При разработке внешних обработок для современных конфигураций на базе 1С:ERP или «1С:Комплексная автоматизация 2.0» программисты часто сталкиваются с задачей программного заполнения документов. Одной из типичных проблем является доступ к «подвалу» формы, где отображаются итоговые суммы, налоги и залоги. В этой статье мы разберем, как правильно взаимодействовать с данными формы, почему не всегда нужно искать прямой доступ к её реквизитам и как обеспечить корректный расчет всех показателей документа.
Для начала проанализируем ситуацию: почему при попытке найти реквизит, который мы видим на экране (например, СуммаЗаказаноСЗалоговойТарой), его не оказывается в списке реквизитов объекта? В управляемом приложении 1С существует четкое разделение между данными объекта (которые записываются в базу данных) и реквизитами формы (которые нужны только для визуализации).
Многие поля в «подвале» документов ERP-систем являются чисто оформительскими. Они рассчитываются «на лету» при открытии формы или при изменении состава табличной части. Рассмотрим, как это работает на примере: если вы программно заполняете таблицу Товары, система должна автоматически пересчитать итоги. Если вы пытаетесь записать значение напрямую в реквизит формы из модуля внешней обработки, это значение исчезнет, как только форма решит выполнить свой штатный алгоритм пересчета.
Рассмотрим наиболее верный подход: вместо того чтобы пытаться «достучаться» до элементов управления на форме, мы должны сосредоточиться на заполнении данных самого документа. Выясним причину, по которой итоги могут не отображаться. Как правило, это происходит из-за того, что не заполнены ключевые поля, на основании которых срабатывают формулы пересчета.
Посмотрим на пример формулы, которая используется в типовых решениях для расчета итогов в заказе клиента:
Форма.СуммаЗаказаноСЗалоговойТарой = ?(Форма.Объект.ТребуетсяЗалогЗаТару,
КоллекцияТовары.Итог("СуммаСНДС") - КоллекцияТовары.Итог("СуммаСНДСОтменено"),
КоллекцияТовары.Итог("СуммаСНДСБезВозвратнойТары") - КоллекцияТовары.Итог("СуммаСНДСОтмененоБезВозвратнойТары"));
Из этого кода становится ясно: чтобы в подвале формы отобразилось корректное значение, ваша внешняя обработка должна выполнить следующие действия:
Товары.ТребуетсяЗалогЗаТару.Когда пользователь откроет документ, форма самостоятельно выполнит процедуру ПриСозданииНаСервере или ПриЧтенииНаСервере, вызовет расчетные механизмы и заполнит визуальные реквизиты «подвала» на основании ваших данных.
Проанализируем ситуацию, когда нам нужно выполнить расчет не вручную, а используя логику, заложенную разработчиками фирмы «1С». В современных конфигурациях бизнес-логика часто выносится в модули менеджера или специализированные серверные модули. Это позволяет избежать дублирования кода.
Вместо написания собственных формул, рекомендуется вызывать серверные методы пересчета. Например, для «Заказа клиента» это могут быть методы, находящиеся в модуле ЗаказКлиентаСервер или ОбработкаТабличнойЧастиТоварыСервер. Рассмотрим примерный алгоритм действий в модуле внешней обработки:
// Предположим, ОбъектДокумент - это созданный или прочитанный объект документа
// Заполняем товары
НоваяСтрока = ОбъектДокумент.Товары.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("00001");
НоваяСтрока.Количество = 10;
// Вызываем типовой механизм пересчета цен и сумм
СтруктураПересчета = Новый Структура("ПересчитатьСумму, ПересчитатьНДС", Истина, Истина);
ОбработкаТабличнойЧастиТоварыСервер.ПересчитатьСтрокуТЧ(НоваяСтрока, СтруктураПересчета);
// Вызываем общий пересчет итогов объекта
ЗаказКлиентаСервер.РассчитатьИтоговыеПоказатели(ОбъектДокумент);
ОбъектДокумент.Записать();
Такой подход гарантирует, что все скрытые реквизиты, влияющие на отображение данных в форме, будут заполнены корректно и в соответствии с методологией типового решения.
Разберем случай, когда внешняя обработка запущена интерактивно через механизм «Дополнительные отчеты и обработки» (БСП) и нам все же требуется изменить что-то непосредственно в открытой форме. Если обработка подключена с типом «Заполнение объекта», то в процедуру модуля обработки ВыполнитьКоманду передается параметр ПараметрыВыполнения.
В этом параметре содержится свойство ЭтаФорма, которое является прямой ссылкой на форму документа, из которой была вызвана обработка. Посмотрим, как можно обратиться к реквизиту формы напрямую:
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполнения) Экспорт
// Получаем форму документа
ТекущаяФорма = ПараметрыВыполнения.ЭтаФорма;
// Обращаемся к реквизиту формы напрямую
// Важно: реквизит должен быть доступен на клиенте
Попытка
ТекущаяФорма.СуммаЗаказаноСЗалоговойТарой = 1500;
// Если нужно изменить данные самого объекта через форму
ТекущаяФорма.Объект.Комментарий = "Заполнено внешней обработкой";
Исключение
Сообщить("Не удалось изменить реквизиты формы напрямую.");
КонецПопытки;
КонецПроцедуры
Важный момент: Прямое изменение реквизитов формы — это «хрупкий» путь. При обновлении конфигурации названия реквизитов формы могут измениться (в отличие от реквизитов объекта, которые меняются реже), и ваша обработка перестанет работать. Используйте этот метод только тогда, когда данные не сохраняются в объекте, а нужны лишь для временного отображения пользователю.
Подводя итог нашему анализу, выделим основные правила работы с внешними обработками при заполнении документов:
Объект.Товары, Объект.Цена и т.д. Если данные в объекте верны, форма сама отобразит правильные итоги в подвале.ПутьКДанным. Если там указано не Объект.ИмяРеквизита, а просто ИмяРеквизита, значит это программно вычисляемое поле.ОповеститьОбИзменении(ОбъектДокумент.Ссылка).Следуя этим принципам, вы создадите надежный инструмент, который будет корректно работать даже после обновлений системы, обеспечивая целостность данных в вашей базе 1С.