Часто в процессе разработки обработок или модификации конфигураций возникает задача извлечь данные из табличной части конкретного элемента справочника. Проанализируем типичную ситуацию, когда нам нужно программно получить значение из строки табличной части (например, ставку для определенной страховой компании), и разберем по шагам все возможные варианты решения данной задачи.
При попытке обратиться к табличной части многие пытаются получить доступ через метаданные или менеджер справочника. Например, пишут код вида: Справочники.Контрагенты.УсловияПоСтраховым.Найти(...). Это вызывает ошибку "Поле объекта не обнаружено". Выясним причину: обращаться нужно не к классу справочника вообще, а к конкретной ссылке на элемент (конкретному контрагенту). Для этого у вас уже должна быть получена ссылка на элемент, которую мы и будем использовать в коде.
Если мы точно знаем номер нужной строки (или нам нужна строго определенная строка, например, первая), мы можем обратиться к ней по индексу. Рассмотрим подробнее два варианта синтаксиса:
Получить().
// Вариант 1
Ставка = Контрагент.УсловияПоСтраховым.Получить(0).Ставка;
// Вариант 2
Ставка = Контрагент.УсловияПоСтраховым[2].Ставка;
Посмотрим на пример, когда нам нужно обойти все строки табличной части по очереди. Это полезно, если требуется проанализировать каждую запись или произвести вычисления с накоплением.
Для Каждого СтрокаТабличнойЧасти Из Контрагент.УсловияПоСтраховым Цикл
// Выполняем действия с реквизитом текущей строки
ТекущаяСтавка = СтрокаТабличнойЧасти.Ставка;
КонецЦикла;
Если стоит задача получить строку в соответствии с конкретным значением (например, найти ставку для заданной страховой компании), применим метод Найти(). Он возвращает первую найденную строку или Неопределено.
СтрокаТаблицы = Контрагент.УсловияПоСтраховым.Найти(ИскомаяСтраховаяКомпания, "СтраховаяКомпания");
Если СтрокаТаблицы <> Неопределено Тогда
СуммаСтавки = СтрокаТаблицы.Ставка;
КонецЕсли;
Усложним задачу. Проанализируем ситуацию, когда необходимо задать условие не только по страховой компании, но и по виду страхования (например, КАСКО или ОСАГО). Метод Найти() здесь не подойдет, так как ищет только по одной колонке. Воспользуемся методом НайтиСтроки(), передав ему объект Структура с отборами.
Отбор = Новый Структура;
Отбор.Вставить("СтраховаяКомпания", ИскомаяСтраховаяКомпания);
Отбор.Вставить("ВидСтрахования", ИскомыйВидСтрахования);
СтрокиТаблицы = Контрагент.УсловияПоСтраховым.НайтиСтроки(Отбор);
Если СтрокиТаблицы.Количество() > 0 Тогда
// Обращаемся к первой найденной строке из массива
Ставка = СтрокиТаблицы[0].Ставка;
КонецЕсли;
Рассмотрим вопрос производительности. При обращении к табличной части через точку от ссылки (как в примерах выше), платформа неявно загружает с сервера баз данных весь объект целиком вместе со всеми строками. Это неоптимально. Правильным и быстрым решением для чтения данных будет использование запроса к табличной части.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| УсловияСтр.Ставка КАК Ставка
|ИЗ
| Справочник.Контрагенты.УсловияПоСтраховым КАК УсловияСтр
|ГДЕ
| УсловияСтр.Ссылка = &Контрагент
| И УсловияСтр.СтраховаяКомпания = &СтраховаяКомпания
| И УсловияСтр.ВидСтрахования = &ВидСтрахования";
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("СтраховаяКомпания", ИскомаяСтраховаяКомпания);
Запрос.УстановитьПараметр("ВидСтрахования", ИскомыйВидСтрахования);
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
ВыборкаДетальныеЗаписи.Следующий();
Ставка = ВыборкаДетальныеЗаписи.Ставка;
КонецЕсли;
При программной работе с табличными частями справочников, обратим внимание на следующие критически важные аспекты:
СправочникСсылка), вы можете только прочитать данные. Если вам нужно изменить ставку или добавить новую строку, необходимо получить объект для редактирования. Для этого вызовем метод ПолучитьОбъект() у ссылки, произведем изменения в его табличной части и вызовем метод Записать().&НаСервере или &НаСервереБезКонтекста. На клиенте методы поиска сработают, только если вы ищете по данным, которые уже находятся в данных самой формы.Выгрузить(). В результате мы получаем полноценную таблицу значений, которую можно обрабатывать любым удобным способом в памяти сервера.