Как настроить динамический список по табличной части документа с динамическим считыванием данных?

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

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

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

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

Выясним причину поведения платформы при различных попытках настройки:

  1. Ошибка «Основная таблица динамического списка задана неверно». В платформе 1С табличные части документов и справочников являются подчиненными объектами, не имеющими собственного уникального ссылочного идентификатора типа Ссылка. В качестве свойства ОсновнаяТаблица динамического списка можно указывать только объекты верхнего уровня: документы, справочники, планы видов характеристик, задачи, бизнес-процессы или регистры. Указать напрямую таблицу вида Документ.Заказ.Товары в качестве основной таблицы платформа не позволяет.
  2. Ошибка «Обнаружено дублирование ключевых значений в колонке». Если в качестве основной таблицы указать сам документ, а в произвольном запросе соединить его с табличной частью, в результат попадает несколько строк с одинаковым значением поля Ссылка (связь «один ко многим»). Механизм динамического считывания требует строгой уникальности ключа основной таблицы в каждой строке выборки. Обнаружив повторяющиеся ссылки документа, платформа прерывает работу с ошибкой.
  3. Отключение свойства «Основная таблица». Если очистить поле основной таблицы, список формируется, но флаг Динамическое считывание данных становится недоступным или отключается его ключевой функционал: данные больше не читаются порциями при прокрутке, а считываются целиком. Кроме того, список без основной таблицы перестает автоматически отслеживать изменения данных в базе, сделанные другими пользователями.

Вариант 1. Использование регистра сведений (рекомендуемый архитектурный паттерн)

Если требуется отображать строки документов с поддержкой полноценного динамического считывания (порционной подгрузки) и штатного автообновления списка, классическим решением в 1С является вынос строк в отдельный регистр сведений.

Разберем по шагам реализацию этого подхода:

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

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

Вариант 2. Использование объекта метаданных «Задача»

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

  1. При проведении документа создаются объекты метаданных Задача.ЗадачаИсполнителю.
  2. Рабочий стол мониторинга строится на базе стандартного динамического списка с основной таблицей Задача.ЗадачаИсполнителю.
  3. Это решение предоставляет готовую ролевую адресацию, контроль выполнения, штатное порционное считывание и автоматическую актуализацию интерфейса.

Вариант 3. Динамический список без основной таблицы с управляемым обновлением

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

Рассмотрим порядок настройки:

  1. В свойствах динамического списка очистим поле Основная таблица.
  2. Снимем флаг Динамическое считывание данных.
  3. В тексте произвольного запроса укажем прямую выборку из табличной части:

ВЫБРАТЬ
    ЗаказТовары.Ссылка КАК ДокументЗаказ,
    ЗаказТовары.НомерСтроки КАК НомерСтроки,
    ЗаказТовары.Номенклатура КАК Номенклатура,
    ЗаказТовары.Количество КАК Количество
ИЗ
    Документ.Заказ.Товары КАК ЗаказТовары
ГДЕ
    НЕ ЗаказТовары.Ссылка.ПометкаУдаления

Так как автоматическое обновление при изменении документов в таком списке работать не будет, добавим один из способов актуализации данных:

Способ А: Фоновый опрос через обработчик ожидания. На форме подключается клиентский таймер, периодически вызывающий обновление элемента формы. Разберем программный код:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Подключаем опрос с интервалом раз в 30 секунд
    ПодключитьОбработчикОжидания("ОбновитьСписокСтрок", 30, Ложь);
КонецПроцедуры

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

Способ Б: Обновление через Систему взаимодействия (Push-уведомления). Если в базе настроена Система взаимодействия, можно избежать лишней нагрузки от таймера. При записи заказа сервер отправляет оповещение через метод СистемаВзаимодействия.ОповеститьОСобытии(), а форма монитора перехватывает событие в обработчике ОбработкаОповещенияОСобытииВзаимодействия и вызывает метод Элементы.СписокЗаказов.Обновить() только в момент реального изменения данных.

← На главную