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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Разберем основную ошибку новичков

При попытке обратиться к табличной части многие пытаются получить доступ через метаданные или менеджер справочника. Например, пишут код вида: Справочники.Контрагенты.УсловияПоСтраховым.Найти(...). Это вызывает ошибку "Поле объекта не обнаружено". Выясним причину: обращаться нужно не к классу справочника вообще, а к конкретной ссылке на элемент (конкретному контрагенту). Для этого у вас уже должна быть получена ссылка на элемент, которую мы и будем использовать в коде.

Способ 1: Прямое обращение по индексу строки

Если мы точно знаем номер нужной строки (или нам нужна строго определенная строка, например, первая), мы можем обратиться к ней по индексу. Рассмотрим подробнее два варианта синтаксиса:

  1. С использованием метода Получить().
  2. С использованием квадратных скобок (индексы начинаются с нуля).

// Вариант 1
Ставка = Контрагент.УсловияПоСтраховым.Получить(0).Ставка;

// Вариант 2
Ставка = Контрагент.УсловияПоСтраховым[2].Ставка;

Способ 2: Перебор строк табличной части в цикле

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


Для Каждого СтрокаТабличнойЧасти Из Контрагент.УсловияПоСтраховым Цикл
    // Выполняем действия с реквизитом текущей строки
    ТекущаяСтавка = СтрокаТабличнойЧасти.Ставка;
КонецЦикла;

Способ 3: Поиск по одному условию с помощью метода Найти

Если стоит задача получить строку в соответствии с конкретным значением (например, найти ставку для заданной страховой компании), применим метод Найти(). Он возвращает первую найденную строку или Неопределено.


СтрокаТаблицы = Контрагент.УсловияПоСтраховым.Найти(ИскомаяСтраховаяКомпания, "СтраховаяКомпания");

Если СтрокаТаблицы <> Неопределено Тогда
    СуммаСтавки = СтрокаТаблицы.Ставка;
КонецЕсли;

Способ 4: Поиск по нескольким условиям (метод НайтиСтроки)

Усложним задачу. Проанализируем ситуацию, когда необходимо задать условие не только по страховой компании, но и по виду страхования (например, КАСКО или ОСАГО). Метод Найти() здесь не подойдет, так как ищет только по одной колонке. Воспользуемся методом НайтиСтроки(), передав ему объект Структура с отборами.


Отбор = Новый Структура;
Отбор.Вставить("СтраховаяКомпания", ИскомаяСтраховаяКомпания);
Отбор.Вставить("ВидСтрахования", ИскомыйВидСтрахования);

СтрокиТаблицы = Контрагент.УсловияПоСтраховым.НайтиСтроки(Отбор);

Если СтрокиТаблицы.Количество() > 0 Тогда
    // Обращаемся к первой найденной строке из массива
    Ставка = СтрокиТаблицы[0].Ставка;
КонецЕсли;

Способ 5: Использование запроса (Оптимальный вариант)

Рассмотрим вопрос производительности. При обращении к табличной части через точку от ссылки (как в примерах выше), платформа неявно загружает с сервера баз данных весь объект целиком вместе со всеми строками. Это неоптимально. Правильным и быстрым решением для чтения данных будет использование запроса к табличной части.


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   УсловияСтр.Ставка КАК Ставка
    |ИЗ
    |   Справочник.Контрагенты.УсловияПоСтраховым КАК УсловияСтр
    |ГДЕ
    |   УсловияСтр.Ссылка = &Контрагент
    |   И УсловияСтр.СтраховаяКомпания = &СтраховаяКомпания
    |   И УсловияСтр.ВидСтрахования = &ВидСтрахования";

Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("СтраховаяКомпания", ИскомаяСтраховаяКомпания);
Запрос.УстановитьПараметр("ВидСтрахования", ИскомыйВидСтрахования);

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

Если Не РезультатЗапроса.Пустой() Тогда
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    ВыборкаДетальныеЗаписи.Следующий();
    Ставка = ВыборкаДетальныеЗаписи.Ставка;
КонецЕсли;

Важные нюансы и архитектурные особенности

При программной работе с табличными частями справочников, обратим внимание на следующие критически важные аспекты:

  1. Чтение против Изменения: Обращаясь через ссылку (когда тип переменной СправочникСсылка), вы можете только прочитать данные. Если вам нужно изменить ставку или добавить новую строку, необходимо получить объект для редактирования. Для этого вызовем метод ПолучитьОбъект() у ссылки, произведем изменения в его табличной части и вызовем метод Записать().
  2. Контекст выполнения (Клиент / Сервер): В конфигурациях на управляемых формах выполнение запросов или чтение объектов через ссылку на клиенте недоступно. Любое обращение к базе данных выносите в серверные процедуры с директивами &НаСервере или &НаСервереБезКонтекста. На клиенте методы поиска сработают, только если вы ищете по данным, которые уже находятся в данных самой формы.
  3. Выгрузка в Таблицу Значений: Для сложных манипуляций (группировка, свертка дублей, сортировка) вы можете выгрузить табличную часть в независимую структуру. Для этого используем метод Выгрузить(). В результате мы получаем полноценную таблицу значений, которую можно обрабатывать любым удобным способом в памяти сервера.
← На главную