При обходе строк табличной части документа во внешних обработках 1С:Предприятие 7.7 разработчики часто сталкиваются с ошибкой «Поле агрегатного объекта не обнаружено». Такая ситуация обычно возникают в случаях, когда реквизит строки может хранить значения из разных справочников (например, «Номенклатура» и «Услуги»), у одного из которых нужный реквизит присутствует, а у другого — отсутствует.
Кроме того, распространенной ошибкой является попытка передать объект выборки документов вместо ссылки на конкретный документ через СписокЗначений или параметры процедуры. Разберем по шагам, как правильно решать обе эти задачи.
Проанализируем ситуацию, когда в табличной части документа реквизит (например, ТМЗ или Товар) имеет неопределенный тип или ссылку на составные справочники. Если попытаться напрямую обратиться к свойству объекта, которого нет у данного вида справочника (например, ТМЗ.ВидТовара), платформа выбросит критическую ошибку, если в текущей строке выбран элемент справочника «Услуги», у которого нет поля ВидТовара.
Чтобы избежать ошибки, необходимо придерживаться безопасной последовательности проверок:
ПустоеЗначение() или метода Выбран() = 1.ТипЗначенияСтр(), чтобы убедиться, что реквизит является справочником.Вид() определим конкретное имя справочника.Рассмотрим пример кода безопасного обращения к реквизиту элемента:
Если ПустоеЗначение(СтрокаТЧ.Товар) = 0 Тогда
Если ТипЗначенияСтр(СтрокаТЧ.Товар) = "Справочник" Тогда
Если СтрокаТЧ.Товар.Вид() = "Номенклатура" Тогда
ВидТВ = СтрокаТЧ.Товар.ВидТовара;
ИначеЕсли СтрокаТЧ.Товар.Вид() = "Услуги" Тогда
// Для услуг выполняем альтернативную логику
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если требуется проверить, существует ли сам реквизит в конфигурации (в шапке или табличной части документа), проанализируем структуру через объект Метаданные:
// Проверка реквизита табличной части документа
Если Метаданные.Документ(ВидДок).РеквизитТабличнойЧасти(ИмяРеквизита).Выбран() = 1 Тогда
// Реквизит существует в табличной части
КонецЕсли;
// Проверка реквизита справочника
Если Метаданные.Справочник(ИмяСправочника).Реквизит(ИмяРеквизита).Выбран() = 1 Тогда
// Реквизит существует у справочника
КонецЕсли;
Также для защиты от аварийного завершения обработки при работе с динамическими данными можно использовать конструкцию обработки ошибок:
Попытка
ЗначениеПоля = СтрокаТЧ.Товар.ВидТовара;
Исключение
ЗначениеПоля = Неопределено;
КонецПопытки;
Вторая частая проблема возникает при обходе подчиненных документов с помощью объекта СоздатьОбъект("Документ"). Разберем типичную ошибку: при добавлении переменной выборки в СписокЗначений передается не конкретная ссылка на найденный документ, а сам итератор выборки.
Выясним разницу:
подчДок): объект, созданный через СоздатьОбъект("Документ"). При каждом вызове ПолучитьДокумент() он позиционируется на новую строку, поэтому сохранение самого объекта в список приводит к передаче неверных данных.подчДок.ТекущийДокумент()): конкретная ссылка на позиционированный документ в базе данных, которую можно сохранять и передавать в структуры данных.Посмотрим на правильную реализацию обхода подчиненных документов и заполнения списка значений:
подчДок = СоздатьОбъект("Документ");
подчДок.ВыбратьПодчиненныеДокументы(,, ТекущийДокумент());
Параметры = СоздатьОбъект("СписокЗначений");
Пока подчДок.ПолучитьДокумент() = 1 Цикл
// Передаем точную ссылку на документ с помощью ТекущийДокумент()
Параметры.ДобавитьЗначение(подчДок.ТекущийДокумент(), "Контекст");
КонецЦикла;
Таким образом, использование метода Вид() гарантирует безопасное чтение реквизитов у элементов разных справочников, а метод ТекущийДокумент() позволяет корректно передавать ссылки из выборок 1С 7.7 в другие модули и обработки.