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