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