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