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