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