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