Разработка и Конфигурация · 12 мин
Как получить данные из динамического списка в 1С
Как программно получить данные из динамического списка 1С: обход через СКД, запрос по основной таблице, выборка текущей строки, ограничения и типичные ошибки разработчиков.
Динамический список в 1С — это не таблица значений, которую можно просто перебрать в цикле. Это объект, который сам строит и выполняет запрос к базе данных, показывая пользователю только видимую часть результата. Поэтому попытка обратиться к нему как к обычной коллекции через Для Каждого заканчивается ошибкой или пустым результатом.
Задача «получить данные из динамического списка» на практике распадается на три разных сценария: взять текущую выделенную строку, получить все данные с учётом установленных отборов или выгрузить результат списка в таблицу значений для дальнейшей обработки. У каждого сценария свой правильный способ решения, и смешивать их нельзя.
Ниже разобраны рабочие приёмы для управляемых форм: чтение текущей строки, программное выполнение запроса динамического списка через СКД, обход результата и типичные ошибки, из-за которых данные не получаются или получаются не те.
Как устроен динамический список и почему его нельзя перебрать
Динамический список на форме — это реквизит типа «ДинамическийСписок», у которого есть текст запроса, параметры, отборы и настройки СКД. Когда пользователь листает список, платформа выполняет запрос порциями и отдаёт форме только нужные строки. Полного результата в памяти клиента или сервера в виде коллекции не существует.
Из этого следуют два важных ограничения. Во-первых, у реквизита списка нет методов вроде Количество() или индексированного доступа к строкам. Во-вторых, даже если визуально в списке тысяча строк, программно «дотянуться» можно только к тем данным, которые платформа отдала форме, — в первую очередь к текущей и выделенным строкам.
Поэтому универсальное правило звучит так: если нужны все данные списка — нужно выполнить его запрос заново программно, а не искать способ «вытащить» строки из реквизита формы. Это не дублирование работы: запрос выполняется на сервере и при корректных отборах работает быстро.
Как прочитать текущую и выделенные строки списка
Самая частая задача — узнать, какую строку выбрал пользователь, например при нажатии своей кнопки в командной панели списка. Для этого используется элемент формы (таблица), связанный с динамическим списком, а не сам реквизит списка.
&НаКлиенте
Процедура ПоказатьТекущуюСтроку(Команда)
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
ПоказатьПредупреждение(, "Строка не выбрана");
Возврат;
КонецЕсли;
Сообщить("Ссылка: " + ТекущиеДанные.Ссылка);
КонецПроцедуры
Если у таблицы включён множественный выбор, используется свойство ВыделенныеСтроки — это массив ключей (ссылок или ключей записей регистра сведений), а не сами данные строк. По каждому ключу при необходимости получают объект или выполняют запрос.
&НаКлиенте
Процедура ОбработатьВыделенные(Команда)
Для Каждого КлючСтроки Из Элементы.Список.ВыделенныеСтроки Цикл
// Для списка документов ключ — это ссылка на документ
Сообщить(Строка(КлючСтроки));
КонецЦикла;
КонецПроцедуры
Как получить все данные списка программным выполнением СКД
Когда нужен полный результат — например, для обработки всех отобранных пользователем строк или выгрузки в файл — правильный путь: взять схему компоновки данных динамического списка и выполнить её программно на сервере. Так вы получите данные с учётом отборов, которые пользователь установил в настройках списка.
&НаСервере
Функция ПолучитьДанныеСписка()
Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(Схема, Настройки, , ,
Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет);
Результат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Возврат Результат;
КонецФункции
Методы ПолучитьИсполняемуюСхемуКомпоновкиДанных и ПолучитьИсполняемыеНастройкиКомпоновкиДанных возвращают именно ту схему и те настройки, которые реально применяются к списку сейчас, — с учётом пользовательских отборов, отборов из кода и параметров. Это ключевое отличие от чтения настроек из свойств реквизита, где пользовательских настроек может не быть.
- 1Убедитесь, что обработка выполняется на сервере: директива &НаСервере или вызов серверной процедуры
- 2Получите исполняемую схему и настройки через методы элемента формы Список
- 3Сформируйте макет компоновки с генератором для коллекции значений
- 4Выведите результат процессором вывода в таблицу значений
- 5Проверьте количество строк и наличие нужных колонок в результате
Альтернатива: отдельный запрос с теми же отборами
Если пользовательские настройки списка не важны, а нужны просто данные по известным условиям, часто проще и надёжнее выполнить обычный запрос. Текст запроса можно взять из свойства ТекстЗапроса динамического списка (если он задан вручную) или написать свой по основной таблице.
&НаСервере
Функция ПолучитьДанныеЗапросом()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Сравнение вариантов
Подходит, когда нужны данные с учётом отборов пользователя. Ограничение: код сложнее, требуется серверный контекст
Подходит для фиксированных условий и фоновых обработок. Ограничение: пользовательские настройки списка не учитываются
Подходит для действий над выбранными строками. Ограничение: доступны только выделенное и выведенные в список поля
Минус этого подхода очевиден: отборы, которые пользователь настроил в списке интерактивно, в ваш запрос не попадут. Если требуется их учесть, отборы придётся считывать из настроек компоновщика и транслировать в параметры или условия запроса — обычно это сложнее, чем выполнить СКД целиком.
Как учесть отборы и параметры динамического списка
Отборы динамического списка живут в нескольких местах, и их легко перепутать. Фиксированный отбор задаётся в конфигураторе или через Список.КомпоновщикНастроек.ФиксированныеНастройки. Пользовательские отборы — в ПользовательскиеНастройки. Параметры запроса устанавливаются через Список.Параметры.УстановитьЗначениеПараметра().
Программно добавить отбор к списку можно так:
&НаСервере
Процедура УстановитьОтборПоОрганизации(Организация)
ЭлементОтбора = Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(
Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Организация;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
Если вы получаете данные через программное выполнение СКД (как в разделе выше), все эти отборы уже попадут в исполняемые настройки автоматически. Если же строите отдельный запрос — каждый нужный отбор придётся переносить вручную, и это частый источник расхождений между тем, что видит пользователь, и тем, что обработал код.
Проверка результата и типичные ошибки
После получения данных обязательно проверьте, что результат соответствует ожиданиям: количество строк совпадает с тем, что видно в списке (с учётом отборов), нужные колонки присутствуют, а ссылки не пустые. Расхождение почти всегда означает, что учтены не все отборы или использована не та схема.
Как проверить результат
Совпадает с количеством строк в списке при тех же отборах
Строк больше — не учтены отборы; меньше — лишние условия
Все нужные поля присутствуют в таблице значений
Поля нет — оно не добавлено в выборку запроса списка
Ссылки заполнены и разыменовываются
Пустые ссылки или значения Неопределено — ошибка в соединениях запроса
Отдельная группа ошибок связана с контекстом выполнения. Методы получения исполняемой схемы и настройки доступны только на сервере, а ТекущиеДанные и ВыделенныеСтроки — на клиенте. Если нужно по кнопке на клиенте обработать много данных, правильная схема такая: на клиенте читаются ключи выделенных строк или просто вызывается серверная процедура, а вся тяжёлая работа с запросом выполняется на сервере.
Ограничения и частные случаи
У динамических списков есть особенности, которые влияют на получение данных. Если отключён флаг «Произвольный запрос» и список построен на основной таблице, ключом строки является ссылка (или ключ записи регистра сведений). При произвольном запросе с группировками или соединениями ключ строки может быть составным или отсутствовать вовсе — тогда ТекущиеДанные.Ссылка может не существовать, и ориентироваться нужно на поля запроса.
Ещё один частный случай — динамический список с включённым динамическим считыванием данных и иерархией. Программное выполнение СКД вернёт плоский или сгруппированный результат в зависимости от настроек, что не всегда совпадает с тем, как данные выглядят в дереве на форме. Для обработки иерархии надёжнее строить отдельный запрос с итогами.
Что важно запомнить
Динамический список не перебирается как коллекция. Выделенные строки читаются через элемент формы, полный результат — программным выполнением СКД с исполняемыми настройками или отдельным запросом. Всегда контролируйте объём выгружаемых данных и проверяйте совпадение результата с тем, что видит пользователь.
Частые вопросы
Можно ли узнать количество строк в динамическом списке без их получения?
Штатного свойства «количество строк» у динамического списка нет. Практичный вариант — выполнить запрос с теми же отборами, выбрав только Количество(Различные Ссылка), либо выполнить СКД программно и посчитать строки результата. Первый способ дешевле по ресурсам.
Почему ТекущиеДанные возвращает Неопределено?
Чаще всего список пуст, пользователь снял выделение или код выполняется не в том контексте (свойство доступно только на клиенте у элемента формы-таблицы). Всегда проверяйте значение на Неопределено перед обращением к полям.
Как получить данные списка в фоновом задании?
Элементы формы в фоновом задании недоступны, поэтому схему и настройки нужно подготовить на сервере в контексте формы, сериализовать (например, через ЗначениеВСтрокуВнутр или в хранилище настроек) и передать в фоновое задание, где уже выполнить компоновку и обработку.
Чем отличается основная таблица от произвольного запроса в динамическом списке?
При основной таблице платформа сама строит запрос и обеспечивает стандартные возможности: ключ строки — ссылка, работают интерактивные действия (создание, пометка удаления). При произвольном запросе вы контролируете текст выборки, но часть стандартных механизмов и однозначный ключ строки могут быть недоступны.
Как выгрузить данные списка в Excel или табличный документ?
Получите данные программным выполнением СКД в таблицу значений, затем выведите их в табличный документ через построитель отчёта или вручную построчно. Готовый табличный документ сохраняется в файл методом Записать с нужным типом файла.
Почему программный результат не совпадает с тем, что видно в списке?
Почти всегда причина в настройках: использованы фиксированные настройки вместо исполняемых, не переданы значения параметров запроса или не учтён пользовательский отбор. Используйте ПолучитьИсполняемуюСхемуКомпоновкиДанных и ПолучитьИсполняемыеНастройкиКомпоновкиДанных — они отражают фактическое состояние списка.