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