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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с динамическими списками — это одна из самых частых задач при разработке на платформе 1С:Предприятие 8.3. Однако начинающие разработчики часто сталкиваются с ситуацией, когда после программного добавления или удаления записей (например, в регистре сведений) список на форме «застывает» и не отображает изменения до тех пор, пока пользователь не нажмет кнопку «Обновить» вручную. В этой статье мы подробно разберем, как автоматизировать этот процесс, опираясь на лучшие практики разработки в 1С, а также коснемся смежных вопросов настройки интерфейса и добавления реквизитов и элементов на управляемые формы. Для автоматизации этих задач есть конструктор связей и состава динамических списков.

Метод 1. Использование встроенного метода Обновить()

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


&НаКлиенте
Процедура КомандаОбновитьСписок(Команда)
    // Выполняем действия с данными
    // ...
    // Принудительно обновляем отображение
    Элементы.Список.Обновить();
КонецПроцедуры

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

Метод 2. Механизм оповещений (ОповеститьОбИзменении)

Если данные меняются в одной форме (например, в форме записи регистра), а обновиться список должен в другой (в форме списка), нам на помощь приходит механизм оповещений платформы. Рассмотрим, как это работает. Метод ОповеститьОбИзменении() сообщает системе, что данные определенного типа или конкретный объект были изменены. Платформа 1С автоматически отслеживает такие оповещения и обновляет связанные динамические списки.

Для ссылочных типов (справочники, документы) мы обычно передаем ссылку на объект. Но что делать с регистрами сведений, где нет ссылок? Выясним причину, по которой обычный подход может не сработать. Для регистров следует передавать тип записей:


// В форме, где данные были изменены или созданы
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    ОповеститьОбИзменении(Тип("РегистрСведенийЗапись.ИмяВашегоРегистра"));
КонецПроцедуры

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

Метод 3. Использование ОписанияОповещения при открытии форм

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

  1. Создаем процедуру-обработчик на клиенте в основной форме.
  2. Инициализируем объект ОписаниеОповещения.
  3. Передаем его в метод ОткрытьФорму.

Пример реализации в основной форме:


&НаКлиенте
Процедура ДобавитьЗапись(Команда)
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияФормыЗаписи", ЭтотОбъект);
    ПараметрыФормы = Новый Структура("ЗначенияЗаполнения", Новый Структура("Склад", Объект.Ссылка));
    
    ОткрытьФорму("РегистрСведений.Склад.ФормаЗаписи", ПараметрыФормы, ЭтотОбъект, , , , Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияФормыЗаписи(Результат, ДополнительныеПараметры) Экспорт
    // Эта процедура выполнится автоматически после закрытия формы записи
    Элементы.Список.Обновить();
КонецПроцедуры

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

Важность свойства «Основная таблица»

Проанализируем ситуацию, почему иногда даже вызов Обновить() или оповещения не помогают. В свойствах динамического списка в конфигураторе есть критически важное поле — Основная таблица. Если оно не заполнено, динамический список «теряет связь» с реальными таблицами БД. В этом случае автоматическое обновление работать не будет. Всегда старайтесь указывать основную таблицу, чтобы задействовать механизмы оптимизации динамических списков.

Управление видимостью колонок динамического списка

Иногда требуется программно скрыть или показать колонки в зависимости от условий. Мы можем обращаться к коллекции элементов формы, используя стандартные функции или специальные модули для программного изменения форм. Здесь важно различать два свойства: Видимость и ПользовательскаяВидимость.

Если мы установим Видимость в значение Ложь, колонка исчезнет, но пользователь сможет вернуть ее через меню «Изменить форму» (если ему не запрещено редактирование, для которого часто используют редактор свойств форм в режиме предприятия). Если же мы хотим жестко управлять составом или порядком полей, можно применить алгоритм программного перемещения колонки динамического списка — есть готовая программная настройка видимости и состава полей. Проанализируем следующий пример управления видимостью:


&НаСервере
Процедура НастроитьВидимостьКолонок()
    // Скрываем колонку программно
    Элементы.СписокИмяКолонки.Видимость = Ложь;
    
    // Запрещаем пользователю включать её самостоятельно
    Элементы.СписокИмяКолонки.ПользовательскаяВидимость = Ложь;
КонецПроцедуры

Проблема нумерации строк: АВТОНОМЕРЗАПИСИ

Часто возникает вопрос: как вывести порядковый номер строки в динамическом списке? Многие пытаются использовать функцию АВТОНОМЕРЗАПИСИ() в языке запросов. Рассмотрим, почему это решение работает «криво».

Динамический список работает по принципу порционного считывания данных. Он не загружает всю таблицу сразу, а запрашивает только те 20-40 строк, которые видны на экране. Функция АВТОНОМЕРЗАПИСИ() в контексте SQL-запроса 1С вычисляет номер только для текущей выборки. При скроллинге или применении отборов номера могут «прыгать» — решается через настраиваемую панель фильтров и счетчик элементов.

Рекомендация: Если вам нужна строгая нумерация строк, динамический список — не лучший выбор. В таких случаях рекомендуем обратиться к использованию Таблицы Значений на форме. Если же динамический список необходим из-за больших объемов данных, рассмотрите возможность вывода идентификаторов, не привязанных к порядковому номеру в текущем окне просмотра.

«Лайфхак» для принудительного обновления через параметры

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


// В тексте запроса динамического списка:
ВЫБРАТЬ * ИЗ РегистрСведений.Склад ГДЕ (&ФлагОбновления = &ФлагОбновления ИЛИ ИСТИНА)

Теперь, когда нам нужно гарантированно обновить данные, мы просто меняем значение параметра ФлагОбновления (например, записываем туда текущее время):


&НаКлиенте
Процедура ПринудительныйСбросКэша()
    Элементы.Список.Период.ПараметрыДанных.УстановитьЗначениеПараметра("ФлагОбновления", ТекущаяДата());
КонецПроцедуры

Изменение значения параметра заставляет платформу полностью перестроить SQL-запрос, что гарантирует получение самых свежих данных из базы.

← На главную