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