К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как получить значение табличной части в 1С

Как получить значение табличной части в 1С: обращение к реквизитам строки, перебор в цикле, выгрузка в таблицу значений, типичные ошибки и примеры кода.

Табличная часть — это коллекция строк внутри документа или справочника, и работа с ней начинается с понимания, где именно выполняется код: в модуле объекта, в модуле формы или во внешней обработке. От этого зависит синтаксис обращения к строкам и реквизитам. Ошибка «Поле объекта не обнаружено» почти всегда означает, что код обращается не к тому контексту.

В типовых конфигурациях табличные части документов называются «Товары», «Услуги», «Начисления» и т.п. Каждая строка — это объект со своим набором реквизитов: номенклатура, количество, цена, сумма. Получить значение можно напрямую по индексу строки, перебором в цикле, через выгрузку в таблицу значений или запросом.

Ниже разобраны основные способы с примерами кода на встроенном языке 1С, различия между толстым и тонким клиентом, а также типичные ошибки, из-за которых значение не читается или возвращается пустым.

Обращение к строке табличной части по индексу

Самый простой способ — взять конкретную строку по индексу. Нумерация начинается с нуля, поэтому первая строка имеет индекс 0. Если табличная часть пустая, обращение по индексу вызовет ошибку, поэтому перед чтением стоит проверить количество строк.

// Модуль объекта документа

Если Товары.Количество() > 0 Тогда

ПерваяСтрока = Товары[0];

СуммаПервойСтроки = ПерваяСтрока.Сумма;

// или короче:

СуммаПервойСтроки = Товары[0].Сумма;

КонецЕсли;

Последнюю строку удобно получать через Товары[Товары.Количество() - 1]. Этот приём часто используют после программного добавления строки методом Добавить(), когда нужно сразу заполнить или прочитать её реквизиты.

Перебор строк в цикле

Когда нужно обработать все строки, используют цикл Для Каждого. Это основной приём для расчёта итогов, проверки заполнения и поиска нужной строки по условию.

Для Каждого СтрокаТоваров Из Товары Цикл

Если СтрокаТоваров.Номенклатура = ИскомаяНоменклатура Тогда

НайденноеКоличество = СтрокаТоваров.Количество;

Прервать;

КонецЕсли;

КонецЦикла;

Если нужен индекс текущей строки, применяют классический цикл со счётчиком или метод Индекс() у коллекции. Для поиска по нескольким условиям эффективнее метод НайтиСтроки() — он возвращает массив подходящих строк без ручного перебора.

Отбор = Новый Структура("Номенклатура", ИскомаяНоменклатура);

НайденныеСтроки = Товары.НайтиСтроки(Отбор);

Если НайденныеСтроки.Количество() > 0 Тогда

Сумма = НайденныеСтроки[0].Сумма;

КонецЕсли;

Порядок действий при переборе
  1. 1
    Убедитесь, что обращаетесь к табличной части по её точному имени из конфигуратора
  2. 2
    Проверьте количество строк перед обращением по индексу
  3. 3
    Используйте НайтиСтроки с отбором вместо ручного цикла, если нужна конкретная строка
  4. 4
    Проверьте результат в отладчике: раскройте строку и посмотрите значения реквизитов

Различия синтаксиса в модуле объекта и в модуле формы

В модуле объекта (документа или справочника) табличная часть доступна напрямую по имени: Товары. В модуле формы управляемого приложения данные объекта лежат в реквизите формы, обычно это Объект, поэтому обращение выглядит как Объект.Товары.

Текущая строка на форме

Чтобы получить значение строки, которую пользователь выделил в таблице на форме, используют свойство ТекущиеДанные элемента формы. Это работает только в клиентском контексте.

&НаКлиенте

Процедура ТоварыПриАктивизацииСтроки(Элемент)

ТекущиеДанные = Элементы.Товары.ТекущиеДанные;

Если ТекущиеДанные <> Неопределено Тогда

ТекущаяСумма = ТекущиеДанные.Сумма;

КонецЕсли;

КонецПроцедуры

Проверка на Неопределено обязательна: если таблица пуста или фокус снят, ТекущиеДанные вернёт именно это значение, и обращение к реквизиту вызовет ошибку.

Типичные ошибки
01
Обращение к Товары напрямую в модуле формы вместо Объект.Товары — ошибка «Переменная не определена»
02
Чтение ТекущиеДанные без проверки на Неопределено — падение кода на пустой таблице
03
Обращение к несуществующему имени табличной части — проверяйте имя в конфигураторе, а не по подсистеме
04
Попытка вызвать серверные методы объекта в клиентской процедуре формы

Получение значений через выгрузку в таблицу значений

Метод Выгрузить() превращает табличную часть в таблицу значений, с которой удобно работать дальше: сортировать, сворачивать, искать, передавать между процедурами. Можно выгрузить все колонки или только нужные, указав их имена строкой.

ТЗ = Товары.Выгрузить(, "Номенклатура, Количество, Сумма");

ТЗ.Свернуть("Номенклатура", "Количество, Сумма");

Для Каждого СтрокаТЗ Из ТЗ Цикл

Сообщить(СтрокаТЗ.Номенклатура);

КонецЦикла;

Выгрузка особенно полезна, когда нужно сгруппировать данные (метод Свернуть) или передать строки в другую процедуру, не таща за собой весь объект документа. Обратная операция — Загрузить(ТЗ) — полностью заменяет содержимое табличной части.

Получение значений запросом

Если документ уже записан в базу, значения табличной части можно получить запросом к виртуальной таблице вида Документ.РеализацияТоваровУслуг.Товары. Это оптимальный путь для отчётов и обработок, где не нужно открывать каждый объект.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Номенклатура,

| Товары.Количество,

| Товары.Сумма

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);

Результат = Запрос.Выполнить().Выгрузить();

Запрос читает только сохранённые данные: если документ открыт и изменён, но не записан, запрос вернёт старое состояние. Для незаписанных данных работайте с объектом в памяти, а не запросом.

Сравнение способов

Обращение по индексу

Быстро для одной строки; опасно при пустой табличной части

Цикл Для Каждого

Универсально для обработки всех строк; медленнее при больших объёмах

НайтиСтроки

Удобен для поиска по отбору; возвращает массив, а не одну строку

Выгрузить в ТЗ

Лучший вариант для группировок и передачи данных; тратит память на копию

Запрос

Подходит для записанных документов и отчётов; не видит незаписанные изменения

Проверка результата и контрольные точки

После получения значения убедитесь, что оно корректно: тип данных соответствует ожиданию, строка не пустая, ссылочные реквизиты не содержат пустых ссылок. Для отладки используйте точку останова и просмотр переменных или функцию ЗначениеЗаполнено().

Контрольные точки

Как проверить результат

Количество строк
Норма

Товары.Количество() больше нуля перед обращением по индексу

Тревожный признак

Ошибка «Индекс находится за границами массива»

Значение реквизита
Норма

Переменная содержит ожидаемое значение нужного типа

Тревожный признак

Неопределено или пустая ссылка при заполненной строке

ТекущиеДанные на форме
Норма

Объект с реквизитами выделенной строки

Тревожный признак

Неопределено при пустой таблице или снятом фокусе

Данные запроса
Норма

Возвращаются актуальные записанные данные документа

Тревожный признак

Пустой результат — проверьте параметр Ссылка и факт записи документа

Если значение «не читается», первым делом сверьте имя табличной части и реквизита с конфигуратором — имена чувствительны к точному написанию, а в типовых конфигурациях одна и та же сущность может называться по-разному в разных документах.

Итог

Что важно запомнить

Для одной строки используйте обращение по индексу с проверкой количества, для всех строк — цикл, для поиска — НайтиСтроки, для группировки — Выгрузить, для записанных документов — запрос. В модуле формы обращайтесь через Объект, а выделенную строку читайте через ТекущиеДанные с проверкой на Неопределено.

Часто задаваемые вопросы

Как получить значение табличной части документа из внешней обработки?

Получите объект через ссылку: ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект(), после чего табличная часть доступна как ДокОбъект.Товары. Если изменять данные не нужно, быстрее и безопаснее использовать запрос к табличной части документа — он не блокирует объект и не требует записи.

Почему при обращении к табличной части возникает ошибка «Поле объекта не обнаружено»?

Чаще всего имя табличной части указано неверно или код выполняется не в том контексте — например, в модуле формы написано Товары вместо Объект.Товары. Откройте конфигуратор, найдите документ и сверьте точное имя табличной части на вкладке «Данные».

Как получить итог по колонке табличной части?

Используйте метод Итог("Сумма") — он возвращает сумму по указанной колонке без цикла. Для нескольких итогов или группировок выгрузите табличную часть в таблицу значений и примените метод Свернуть.

Можно ли получить значение табличной части на клиенте без вызова сервера?

Да, данные табличной части на управляемой форме доступны на клиенте через Объект.ИмяТабличнойЧасти и Элементы.ИмяТаблицы.ТекущиеДанные. Серверный вызов нужен только для операций, требующих доступа к базе данных, например для запросов.

Как обратиться к табличной части справочника, например к составу набора?

Точно так же, как у документа: у объекта справочника табличная часть доступна по имени — СпрОбъект.СоставНабора. Через ссылку напрямую обратиться нельзя, нужно сначала получить объект методом ПолучитьОбъект() либо использовать запрос к табличной части справочника.

Что возвращает НайтиСтроки, если подходящих строк нет?

Метод возвращает пустой массив, а не Неопределено. Поэтому проверяйте результат через НайденныеСтроки.Количество() > 0 перед обращением к элементу массива — иначе получите ошибку выхода за границы массива.