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

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

Как выгрузить колонку таблицы значений в список значений в 1С 8

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

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

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

Ниже разобраны оба способа с готовым кодом, варианты для управляемых и обычных форм, способы получить только уникальные значения и типичные ошибки, которые приводят к пустому списку или дублям.

Чем таблица значений отличается от списка значений

Таблица значений (объект ТаблицаЗначений) — двумерная структура: колонки описываются в коллекции Колонки, данные хранятся в строках. Каждая колонка имеет имя и тип. Обращение к значению идёт через строку: СтрокаТЗ.Номенклатура.

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

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

Способ 1: через ВыгрузитьКолонку и ЗагрузитьЗначения

Самый короткий вариант — получить массив значений колонки и загрузить его в список одним методом. Подходит, когда не нужны представления, пометки и дополнительная обработка элементов.

// ТЗ — заполненная таблица значений

МассивЗначений = ТЗ.ВыгрузитьКолонку("Номенклатура");

Список = Новый СписокЗначений;

Список.ЗагрузитьЗначения(МассивЗначений);

Метод ЗагрузитьЗначения() очищает список и заполняет его элементами массива, сохраняя порядок. Представления при этом устанавливаются автоматически — как строковое представление значения, пометки сброшены.

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

bsl
Массив = ТЗ.ВыгрузитьКолонку("Ссылка");
Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(Массив);

Способ 2: перебор строк в цикле

Цикл даёт полный контроль над каждым добавляемым элементом: можно задать представление, пометку, пропустить пустые значения или отфильтровать дубли на лету.

Список = Новый СписокЗначений;

Для Каждого СтрокаТЗ Из ТЗ Цикл

Если ЗначениеЗаполнено(СтрокаТЗ.Номенклатура) Тогда

Список.Добавить(СтрокаТЗ.Номенклатура, Строка(СтрокаТЗ.Номенклатура), Истина);

КонецЕсли;

КонецЦикла;

Метод Добавить() принимает параметры: значение, представление, пометка, картинка. В примере выше каждый элемент добавляется с пометкой и явным представлением — это удобно для последующего показа списка пользователю через ОтметитьЭлементы() или ВыбратьЭлемент().

Цикл также единственный вариант, когда в список нужно перенести не одну колонку, а комбинацию: например, значение из колонки «Ссылка», а представление собрать из колонок «Код» и «Наименование».

Порядок действий для цикла
  1. 1
    Создайте пустой список: Список = Новый СписокЗначений
  2. 2
    Организуйте цикл Для Каждого СтрокаТЗ Из ТЗ Цикл
  3. 3
    Внутри цикла проверьте заполненность значения колонки
  4. 4
    Добавьте элемент: Список.Добавить(Значение, Представление, Пометка)
  5. 5
    После цикла проверьте Список.Количество() — оно должно соответствовать числу обработанных строк

Как получить только уникальные значения колонки

Если в колонке встречаются повторы, оба способа выше перенесут их в список как есть — дубли включительно. Для уникальности есть два рабочих приёма.

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

ТЗКопия = ТЗ.Скопировать();

ТЗКопия.Свернуть("Номенклатура");

Список = Новый СписокЗначений;

Список.ЗагрузитьЗначения(ТЗКопия.ВыгрузитьКолонку("Номенклатура"));

Второй приём — проверка через НайтиПоЗначению() внутри цикла. Метод возвращает Неопределено, если элемента с таким значением в списке ещё нет:

Для Каждого СтрокаТЗ Из ТЗ Цикл

Если Список.НайтиПоЗначению(СтрокаТЗ.Номенклатура) = Неопределено Тогда

Список.Добавить(СтрокаТЗ.Номенклатура);

КонецЕсли;

КонецЦикла;

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

Сравнение способов получения уникальных значений

Свернуть + ВыгрузитьКолонку

Быстро на больших таблицах, короткий код. Требует копии таблицы, теряются остальные колонки в копии.

НайтиПоЗначению в цикле

Не трогает исходную таблицу, позволяет задать представления. Медленнее при большом числе строк из-за поиска на каждой итерации.

Запрос с РАЗЛИЧНЫЕ

Если таблица получается запросом — проще сразу выбрать различные значения в запросе и обойти результат.

Использование списка в параметре запроса и отборе

Частая цель выгрузки колонки — передать значения в запрос для условия В (&Список) или в отбор динамического списка. Здесь есть нюанс: запрос принимает и массив, и список значений, поэтому промежуточный массив из ВыгрузитьКолонку() можно передать напрямую, без создания списка.

Запрос = Новый Запрос;

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

"ВЫБРАТЬ

| РеализацияТовары.Номенклатура,

| СУММА(РеализацияТовары.Количество) КАК Количество

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары

|ГДЕ

| РеализацияТовары.Номенклатура В (&СписокНоменклатуры)

|СГРУППИРОВАТЬ ПО

| РеализацияТовары.Номенклатура";

Запрос.УстановитьПараметр("СписокНоменклатуры", ТЗ.ВыгрузитьКолонку("Номенклатура"));

Результат = Запрос.Выполнить().Выгрузить();

Если же список нужен для отбора СКД или динамического списка на форме, там тип параметра часто ожидается именно как СписокЗначений — тогда загрузка массива в список обязательна. Проверьте тип параметра в настройках отбора, иначе получите ошибку несоответствия типов или пустой результат.

Особенности для управляемых форм и клиент-серверного режима

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

&НаСервере

Процедура ЗаполнитьСписокНаСервере()

ТЗ = РеквизитФормыВЗначение("ТаблицаТоваров");

Список = Новый СписокЗначений;

Список.ЗагрузитьЗначения(ТЗ.ВыгрузитьКолонку("Номенклатура"));

// далее — передача списка в реквизит формы или параметр

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

На тонком клиенте объект СписокЗначений доступен, а вот ТаблицаЗначений — нет: она существует только на сервере. Поэтому вся работа с выгрузкой колонки выполняется в серверных процедурах, а на клиент возвращается уже готовый список или массив.

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

Проверка результата и типичные ошибки

После заполнения списка проверьте его содержимое до передачи дальше. Минимальная диагностика — количество элементов и тип значений первого элемента:

Если Список.Количество() = 0 Тогда

Сообщить("Список пуст: проверьте имя колонки и заполненность ТЗ");

Иначе

Сообщить("Элементов: " + Список.Количество()

+ ", тип первого: " + ТипЗнч(Список[0].Значение));

КонецЕсли;

Если список оказался пустым, чаще всего причина в опечатке в имени колонки — ВыгрузитьКолонку() с несуществующим именем выбрасывает исключение, но если колонка существует и пуста, массив будет нулевой длины без всякой ошибки. Проверяйте также, что таблица вообще заполнена к моменту выгрузки.

Типичные ошибки
01
Опечатка в имени колонки — исключение «Колонка не найдена» при вызове ВыгрузитьКолонку
02
Вызов ВыгрузитьКолонку у реквизита формы вместо преобразованной таблицы — метод отсутствует у ДанныеФормыКоллекция
03
Ожидание уникальности без Свернуть() — в списке появляются дубли, что искажает отборы и счётчики
04
Использование ЗагрузитьЗначения для заполненного списка — прежние элементы безвозвратно удаляются
05
Сворачивание исходной таблицы вместо копии — теряются строки и остальные колонки
Контрольные точки

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

Количество элементов списка
Норма

Равно числу строк ТЗ (или числу уникальных значений после сворачивания)

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

Ноль или меньше ожидаемого — проверьте имя колонки и заполненность таблицы

Тип значений элементов
Норма

Совпадает с типом колонки (ссылка, строка, число)

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

Неопределено или строковое представление вместо ссылки — выгружена не та колонка

Отсутствие дублей
Норма

НайтиПоЗначению находит каждый элемент один раз

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

Повторы значений — не выполнено сворачивание или проверка в цикле

FAQ

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

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

Как сохранить порядок строк таблицы в списке?

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

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

Напрямую никак: ТаблицаЗначений недоступна на тонком клиенте. Выполните выгрузку в серверной процедуре и верните на клиент готовый СписокЗначений или массив. Если данные на форме — сначала преобразуйте реквизит через РеквизитФормыВЗначение на сервере.

Что делать, если в колонке есть пустые значения?

Отфильтруйте их в цикле проверкой ЗначениеЗаполнено() перед добавлением. Альтернатива — выгрузить колонку в массив, затем при копировании таблицы применить отбор строк перед выгрузкой: ТЗ.Скопировать(Новый Структура("Номенклатура", ...)) не подходит для неравенств, поэтому цикл с проверкой остаётся самым гибким вариантом.

Можно ли использовать массив вместо списка значений в запросе?

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

Как добавить в список значения из двух колонок таблицы?

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

Итог

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

Выгрузка колонки в список значений делается в два шага: ВыгрузитьКолонку() даёт массив, ЗагрузитьЗначения() переносит его в список. Для представлений, пометок и фильтрации используйте цикл с Добавить(). Уникальность обеспечивайте через Свернуть() копии таблицы. На управляемых формах сначала преобразуйте реквизит в таблицу значений на сервере.