К статье
Практический материал

Разработка и Конфигурация · 12 мин

1С: как обратиться к динамическому списку программно

Как обратиться к динамическому списку в 1С из кода: доступ к настройкам, отбору, параметрам СКД, программная установка запроса и типичные ошибки разработчиков.

Динамический список — основной способ показа табличных данных в управляемых формах 1С. Списки справочников, документов, регистров сведений в типовых и самописных конфигурациях построены именно на нём. Когда нужно программно изменить отбор, подставить параметр, поменять запрос или перечитать данные, разработчику приходится обращаться к динамическому списку из кода встроенного языка.

Главная сложность в том, что динамический список — это не таблица значений и не результат запроса, а особый объект формы, который сам формирует SQL-запрос к базе на основе своих настроек. Прямой записи в него нет, а обращение идёт через реквизит формы, свойство «КомпоновщикНастроек» и коллекции отборов и параметров. Неправильное обращение приводит к ошибкам вида «Поле объекта не обнаружено» или к молчаливому игнорированию установленных настроек.

Материал разбирает практические приёмы: как получить объект динамического списка на форме, изменить текст запроса, установить отбор и параметры, обновить данные и избежать типичных ошибок. Примеры приведены для управляемых форм на встроенном языке 1С.

Где находится динамический список на форме

Когда в конфигураторе на форму добавляют таблицу с типом «ДинамическийСписок», в реквизитах формы появляется соответствующий реквизит — обычно его называют «Список». Именно через этот реквизит и идёт всё программное обращение. Элемент формы (таблица) лишь отображает данные реквизита, поэтому менять настройки нужно у реквизита, а не у элемента формы.

Обратиться к списку можно в любом серверном или клиентском контексте модуля формы:

&НаКлиенте

Процедура ПриОткрытии(Отказ)

Список.Отбор.Элементы.Очистить();

КонецПроцедуры

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

Как программно изменить текст запроса динамического списка

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

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Список.ПроизвольныйЗапрос = Истина;

Список.ТекстЗапроса =

"ВЫБРАТЬ

| Товары.Ссылка,

| Товары.Наименование,

| Остатки.КоличествоОстаток КАК Остаток

|ИЗ

| Справочник.Номенклатура КАК Товары

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

| ПО Товары.Ссылка = Остатки.Номенклатура";

КонецПроцедуры

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

Как установить отбор динамического списка из кода

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

Пример установки простого отбора:

&НаКлиенте

Процедура ПоказатьТолькоАктивные(Команда)

ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПометкаУдаления");

ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

ЭлементОтбора.ПравоеЗначение = Ложь;

ЭлементОтбора.Использование = Истина;

ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;

КонецПроцедуры

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

Порядок установки отбора
  1. 1
    Определите имя реквизита динамического списка в форме
  2. 2
    Найдите существующий элемент отбора по полю или очистите коллекцию
  3. 3
    Добавьте элемент отбора с нужным видом сравнения и значением
  4. 4
    Установите Использование = Истина и подходящий режим отображения
  5. 5
    Проверьте в форме, что список отфильтрован и отбор не сбрасывается

Работа с параметрами и настройками компоновщика

Если запрос списка содержит параметры (виртуальные таблицы регистров, отборы по периоду), их значения задаются через параметры компоновки данных. Обращение идёт через коллекцию Параметры настроек:

&НаКлиенте

Процедура УстановитьПериод(Команда)

Параметр = Список.Параметры.НайтиЗначениеПараметра(

Новый ПараметрКомпоновкиДанных("Период"));

Если Параметр <> Неопределено Тогда

Параметр.Использование = Истина;

Параметр.Значение = ТекущаяДатаСеанса();

КонецЕсли;

КонецПроцедуры

Частая ситуация: параметр в запросе есть, а НайтиЗначениеПараметра возвращает Неопределено. Причина — платформа не вывела параметр в настройки, потому что он не используется в доступных полях отбора. Решение — задать параметр через КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", Значение) или явно объявить параметр в настройках списка в конфигураторе.

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

Типичные ошибки
01
Обращение к элементу формы вместо реквизита: Элементы.Список не имеет свойства Отбор — настройки меняются у реквизита Список
02
Установка ТекстЗапроса без ПроизвольныйЗапрос = Истина — платформа игнорирует новый текст
03
Повторное добавление элемента отбора без поиска существующего — отборы дублируются и блокируют друг друга
04
Изменение настроек после вывода списка без обновления — пользователь видит старые данные

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

После программного изменения записей вне формы список может показывать устаревшие данные. Для обновления используется метод элемента формы:

Элементы.Список.Обновить();

Если нужно узнать, какая строка активна, и получить её данные, используют свойство ТекущаяСтрока таблицы формы. Для списка справочника или документов текущая строка — это ссылка на объект:

&НаКлиенте

Процедура ОткрытьТекущий(Команда)

ТекСсылка = Элементы.Список.ТекущаяСтрока;

Если ТекСсылка <> Неопределено Тогда

ПоказатьЗначение(, ТекСсылка);

КонецЕсли;

КонецПроцедуры

Данные текущей строки (значения всех колонок, а не только ссылку) даёт свойство Элементы.Список.ТекущиеДанные. Учтите: получить весь набор данных списка в виде таблицы значений напрямую нельзя — динамический список не материализуется целиком. Если нужна полная выгрузка, выполните отдельный запрос с теми же отборами или используйте схему компоновки данных с тем же текстом запроса.

Контрольные точки

Как проверить результат

Отбор применён
Норма

Список показывает только нужные строки, в панели настроек отбор виден (или скрыт намеренно)

Тревожный признак

Строки не изменились или пропали все записи — проверьте вид сравнения и значение

Произвольный запрос работает
Норма

Колонки из запроса отображаются, открытие элемента по двойному клику работает

Тревожный признак

Ошибка «Поле не найдено» или не открывается объект — проверьте поле Ссылка в выборке

Параметр установлен
Норма

Виртуальная таблица считается с нужным значением, данные соответствуют периоду

Тревожный признак

Параметр равен Неопределено — используйте УстановитьЗначениеПараметра через ПараметрыДанных

Обращение к динамическому списку вне формы и альтернативы

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

Типовой приём для выгрузки данных списка: создать схему компоновки с тем же текстом запроса, скопировать настройки из Список.КомпоновщикНастроек.Настройки в компоновщик схемы и вывести результат через ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений. Так сохраняются все отборы, которые пользователь установил интерактивно.

Способы получить данные списка

ТекущиеДанные таблицы формы

Подходит для чтения выделенной строки; не даёт доступ к остальным строкам

Запрос с тем же текстом

Подходит для серверной обработки всех данных; отборы пользователя нужно переносить вручную

СКД с копией настроек компоновщика

Сохраняет интерактивные отборы и параметры; требует больше кода и понимания механизмов компоновки

Выбор зависит от задачи: для обработки выделенной строки достаточно ТекущиеДанные, для пакетной обработки — запрос, для отчётов по пользовательским отборам — СКД. Не пытайтесь перебирать динамический список построчно через элементы формы: это не поддерживается платформой и приведёт к неработоспособному коду.

Часто задаваемые вопросы

Почему возникает ошибка «Поле объекта не обнаружено (Отбор)»?

Чаще всего код обращается к элементу формы (Элементы.Список.Отбор) вместо реквизита формы. У элемента-таблицы нет свойства «Отбор» — оно есть у реквизита типа «ДинамическийСписок». Проверьте имя реквизита в панели реквизитов формы и обращайтесь к нему напрямую.

Как снять все отборы динамического списка?

Вызовите Список.Отбор.Элементы.Очистить(). Учтите, что это удалит и отборы, установленные пользователем вручную. Если нужно убрать только программный отбор, найдите его элемент по левому значению поля и установите Использование = Ложь или удалите конкретный элемент.

Можно ли обратиться к динамическому списку другой формы?

Напрямую — нет, каждая форма изолирована. Передайте нужные значения через параметры при открытии формы (ОткрытьФорму с параметрами) либо через оповещения: Оповестить() в одной форме и обработчик ОбработкаОповещения в другой, где уже меняются настройки списка.

Почему после изменения ТекстЗапроса список пустой?

Проверьте три вещи: установлено ли ПроизвольныйЗапрос = Истина до присвоения текста, нет ли в запросе ошибок (проверьте его в консоли запросов), не остались ли в настройках отборы по полям, которых в новом запросе нет. Отбор по несуществующему полю делает выборку пустой или вызывает ошибку.

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

Переберите коллекцию Список.КомпоновщикНастроек.Настройки.Отбор.Элементы в цикле. У каждого элемента доступны ЛевоеЗначение (поле), ВидСравнения, ПравоеЗначение и Использование. Учитывайте, что элементы могут быть вложены в группы отборов — тогда нужен рекурсивный обход.

Работает ли обращение к динамическому списку в обычных формах?

В обычных формах используются другие объекты — табличные поля с типом источника данных «Список справочника» или «Список документа». Там отбор устанавливается через ЭлементыФормы.Список.Отбор с похожим синтаксисом, но объектная модель отличается. Примеры из этой статьи предназначены для управляемых форм.

Итог

Что важно запомнить

Обращение к динамическому списку идёт через реквизит формы, а не через элемент-таблицу. Отбор — через Список.Отбор, параметры — через Параметры или ПараметрыДанных компоновщика, текст запроса — через ТекстЗапроса с обязательным признаком ПроизвольныйЗапрос. Данные всего списка получают отдельным запросом или через СКД, а не перебором строк.