При разработке на управляемых формах 1С часто возникает задача: отобразить в динамическом списке данные, которые поступают из другой программы или обновляются регламентным заданием в другом сеансе. Стандартный механизм Динамический список отлично справляется с изменениями в основной таблице, но при использовании левых соединений или внешних записей обновление формы не происходит автоматически. Давайте разберем, почему это так и какие подходы помогут нам решить эту задачу.
Первое, что необходимо понять — это архитектурное разделение сеансов. В платформе 1С каждый сеанс пользователя является изолированным процессом. Когда мы записываем данные из другой программы или другого сеанса, серверный контекст формы, в которой открыт наш список, остается прежним. Сервер не может напрямую «толкнуть» клиентское приложение и заставить его перечитать данные, если форма не была уведомлена об изменениях.
Кроме того, платформа 1С отслеживает изменения только для основной таблицы Динамического списка. При использовании левых соединений (LEFT JOIN) с другими таблицами, платформа не «видит» правостороннюю таблицу как источник изменений, так как это требовало бы огромных вычислительных мощностей для постоянного мониторинга связей.
Самый простой и технически правильный с точки зрения платформы способ — настроить Автообновление самого динамического списка. Это позволяет форме периодически «спрашивать» сервер о новых данных.
Динамическим списком.Автообновление.Хотя этот метод создает дополнительную нагрузку при постоянном опросе, он является «стандартом» для 1С, обеспечивающим гарантированную актуальность данных без написания сложного кода синхронизации между сеансами.
Если вы хотите избежать лишнего трафика и обновлять список только тогда, когда данные действительно изменились, мы можем реализовать интеллектуальную проверку. Суть метода заключается в сравнении «версии» данных на сервере и клиенте.
Для реализации этого подхода выполним следующие шаги:
Параметр сеанса, в котором будет храниться идентификатор версии данных.Константу или регистр сведений, содержащий актуальный GUID или дату изменения.Обработчик ожидания.Разберем пример кода для такой проверки:
// На сервере (в модуле с повторным использованием)
Функция НужноОбновитьСписок() Экспорт
ТекущаяВерсия = ПараметрыСеанса.ВерсияДанных;
АктуальнаяВерсия = Константы.ДатаПоследнегоИзменения.Получить();
Возврат ТекущаяВерсия <> АктуальнаяВерсия;
КонецФункции
// На клиенте (в форме)
&НаКлиенте
Процедура ПриОткрытии()
ПодключитьОбработчикОжидания("ПроверитьНеобходимостьОбновления", 10);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьНеобходимостьОбновления()
Если СервернаяФункцияПроверки() Тогда
Элементы.Список.Обновить();
КонецЕсли;
КонецПроцедуры
Таким образом, мы передаем на клиент только логический результат (Да/Нет), что значительно снижает нагрузку по сравнению с полной перезагрузкой списка при каждом цикле.
Проанализировав ситуацию, можно сделать вывод, что попытки «дернуть» клиент с сервера (например, через механизмы ОповеститьОбИзменении) не принесут результата, так как они работают исключительно в рамках текущего сеанса. Если вы работаете с многопользовательской средой, где один пользователь вбивает данные, а второй смотрит список, ваш выбор — это либо автообновление, либо интеллектуальная проверка через серверные флаги.
Мы рекомендуем начать с простого Автообновления. Если же количество пользователей велико, а обновление списка происходит очень часто — используйте метод с Параметрами сеанса или кэшируемыми функциями, чтобы свести обмен данными к минимуму.