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