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

Программист 1С v8.3 (Обычные формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

Почему данные на форме не обновляются автоматически

Проанализируем архитектуру работы внешних обработок заполнения. Стандартный механизм заполнения передает в обработку ссылку на объект документа (ДокументОбъект), а не саму экранную форму. При изменении строк табличной части программно меняются данные в оперативной памяти объекта, но элементы интерфейса, не привязанные напрямую к реквизитам объекта (например, вычисляемые итоги, надписи или переменные формы), не получают уведомления об изменениях.

Рассмотрим типичный пример: в документе «Акт сверки взаиморасчетов» поля начального и конечного сальдо, а также расхождения отображаются через элементы управления формы и рассчитываются отдельным кодом:


ОстатокНаКонец = ОстатокНаНачало + ПоДаннымОрганизации.Итог("Дебет") - ПоДаннымОрганизации.Итог("Кредит");
ЭлементыФормы.ОстатокНаНачалоКонтрагент.Значение = - ОстатокНаНачало;
ЭлементыФормы.ОстатокНаКонец.Значение = ОстатокНаКонец;

ОстатокНаКонецКонтрагент = - ОстатокНаНачало + ПоДаннымКонтрагента.Итог("Дебет") - ПоДаннымКонтрагента.Итог("Кредит");
ЭлементыФормы.ОстатокНаКонецКонтрагент.Значение = ОстатокНаКонецКонтрагент;

Если Расхождение <> ОстатокНаКонец + ОстатокНаКонецКонтрагент Тогда
    Расхождение = ОстатокНаКонец + ОстатокНаКонецКонтрагент;
КонецЕсли; 
ЭлементыФормы.Расхождение.Значение = Расхождение;
ЭлементыФормы.РасхождениеКонтрагент.Значение = Расхождение * (-1);

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

Способ 1. Использование механизма оповещений формы (обычные формы)

В обычном приложении наиболее универсальным и безопасным способом взаимодействия обработки с открытой формой является механизм глобальных оповещений. Этот подход не требует прямого обращения к элементам формы через объектную модель и корректно работает даже с новыми, еще не сохраненными документами.

  1. В коде внешней обработки после завершения заполнения табличных частей вызываем процедуру Оповестить:
    
    // В обработке заполнения ТЧ
    Оповестить("ОбновитьОстаткиАктаСверки");
    
  2. В модуле формы документа находим предопределенную процедуру ОбработкаОповещения и связываем ее с вызовом внутренней процедуры пересчета:
    
    Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
        Если ИмяСобытия = "ОбновитьОстаткиАктаСверки" Тогда
            ПересчитатьОстатки();
        КонецЕсли;
    КонецПроцедуры
    

Способ 2. Экспортная процедура формы и вызов через контекст

Если конфигурация находится на поддержке с возможностью изменения, мы можем объявить процедуру пересчета итогов с ключевым словом Экспорт:


Процедура ПересчитатьОстатки() Экспорт
    // Код пересчета итогов и заполнения ЭлементыФормы
КонецПроцедуры

После этого форма может вызвать данный метод самостоятельно сразу после возврата управления из внешней обработки в обработчике нажатия кнопки заполнения (например, в процедуре ЗаполнитьТабличнуюЧастьПоВнешнейОбработке):


// В коде формы документа после вызова внешней обработки
ЭтотОбъект.ПересчитатьОстатки();
ЭлементыФормы.ОбновитьОтображениеДанных();

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

Способ 3. Автоматическое обновление отображения данных

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

ДокументОбъект.Модифицированность = Истина;

Если документ открыт, изменение флага модифицированности сигнализирует форме о необходимости перерисовать зависимые элементы интерфейса.

Способ 4. Реализация для управляемых форм (БСП)

В конфигурациях на управляемых формах с внедренной Библиотекой стандартных подсистем (БСП) внешние обработки заполнения регистрируются через механизм дополнительных отчетов и обработок. Для доступа к контексту формы используем тип команды ВызовКлиентскогоМетода:

  1. При регистрации команды обработки указываем параметр Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода().
  2. В модуле клиентской команды обработка получает структуру ПараметрыВыполнения, где в свойстве ПараметрыВыполнения.ЭтаФорма передается прямая ссылка на открытую форму.
  3. Через эту ссылку можно вызывать экспортные методы клиентского модуля формы или серверные модули пересчета:
    
    &НаКлиенте
    Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполнения) Экспорт
        ФормаДокумента = ПараметрыВыполнения.ЭтаФорма;
        
        // Заполняем данные через серверную функцию
        ЗаполнитьТабличнуюЧастьНаСервере(ФормаДокумента.Объект);
        
        // Вызываем пересчет или обновление на форме
        ФормаДокумента.ОбновитьОтображениеДанных();
    КонецПроцедуры
    

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

← На главную