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