При формировании регламентного документа «Записи книги покупок» в конфигурациях на платформе 1С:Предприятие 7.7 пользователи иногда сталкиваются с аварийным завершением работы модуля. Текст ошибки выглядит следующим образом: {Документ.ЗаписиКнигиПокупок.Форма.Модуль(720)}: Поле агрегатного объекта не обнаружено (ДатаНомерСчетаФактуры). Разберем подробно, почему возникает эта ошибка, как найти проблемный документ в информационной базе и как правильно доработать программный код для предотвращения подобных сбоев в будущем.
Проанализируем механизм работы типового алгоритма книги покупок. При заполнении табличной части выполняется бухгалтерский запрос по счету 19 («НДС по приобретенным ценностям»). Субконто данного счета имеет составной тип («Счета-фактуры» / «Документы поступления»).
В типовом коде программы обращение к реквизитам документа-основания происходит напрямую через точку:
Если СокрЛП(Запрос.ДокументПоставки.ДатаНомерСчетаФактуры) <> "" Тогда
ТЗ.СчетФактура = Запрос.ДокументПоставки;
Иначе
// Поиск подчиненного счета-фактуры
КонецЕсли;
Ошибка времени выполнения возникает в следующих ситуациях:
ДатаНомерСчетаФактуры (например, ручная Операция, Бухгалтерская справка, Авансовый отчет, Ввод остатков или нетиповой самописный документ).Если конфигурация типовая и вносить изменения в код нежелательно, найдем некорректную проводку штатными средствами отчетов:
Если документов за период много и визуально найти ошибку сложно, воспользуемся отладочной конструкцией в коде модуля формы документа ЗаписиКнигиПокупок. Заменим прямое обращение к реквизиту на безопасный блок с выводом информации в окно сообщений.
Посмотрим на пример отладочного кода:
Попытка
ДатаНомерСчетаФактуры = Запрос.ДокументПоставки.ДатаНомерСчетаФактуры;
Исключение
Сообщить("Обнаружен документ без реквизита ДатаНомерСчетаФактуры!");
Сообщить("Вид документа: " + Запрос.ДокументПоставки.Вид());
Сообщить("Документ: " + Строка(Запрос.ДокументПоставки));
КонецПопытки;
Запустим формирование книги покупок заново. В служебное окно будет выведен конкретный вид и номер документа, на котором спотыкается алгоритм, после чего мы сможем быстро открыть его в журнале и скорректировать проводку.
Для полного исключения падения программы при наличии нестандартных документов выполним корректную проверку наличия реквизита через метаданные конфигурации перед обращением к нему.
Разберем готовый фрагмент безопасного кода для модуля формирования записей книги покупок:
Если ПустоеЗначение(Запрос.ДокументПоставки) = 0 Тогда
ЕстьРеквизит = 0;
ВидДок = Запрос.ДокументПоставки.Вид();
// Проверяем наличие реквизита в структуре метаданных документа
Если Метаданные.Документ(ВидДок).РеквизитШапки("ДатаНомерСчетаФактуры").Выбран() = 1 Тогда
ЕстьРеквизит = 1;
КонецЕсли;
Если ЕстьРеквизит = 1 Тогда
Если СокрЛП(Запрос.ДокументПоставки.ДатаНомерСчетаФактуры) <> "" Тогда
ТЗ.СчетФактура = Запрос.ДокументПоставки;
Иначе
Док.ВыбратьПодчиненныеДокументы(Запрос.ДокументПоставки.ДатаДок, ДатаКон, Запрос.ДокументПоставки);
Пока Док.ПолучитьДокумент() = 1 Цикл
Если Док.Вид() = "СчетФактураПолученный" Тогда
ТЗ.СчетФактура = Док.ТекущийДокумент();
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе
// Обработка документов, не имеющих реквизита (Операция, Авансовый отчет и др.)
Док.ВыбратьПодчиненныеДокументы(Запрос.ДокументПоставки.ДатаДок, ДатаКон, Запрос.ДокументПоставки);
Пока Док.ПолучитьДокумент() = 1 Цикл
Если Док.Вид() = "СчетФактураПолученный" Тогда
ТЗ.СчетФактура = Док.ТекущийДокумент();
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Также в платформе 1С 7.7 можно применить альтернативный компактный прием с использованием встроенной функции Шаблон(). Конструкция Шаблон("[Запрос.ДокументПоставки.ДатаНомерСчетаФактуры]") при отсутствии реквизита в объекте не вызывает критическую ошибку, а возвращает пустую строку, что позволяет коду продолжить выполнение без сбоев.