Как проверить наличие определенного реквизита во всех документах в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В процессе разработки отчетов или обработок в системе 1С:Предприятие 7.7 программисты часто сталкиваются с необходимостью обращения к реквизитам документов, которые могут присутствовать не во всех видах документов конфигурации. Прямое обращение к отсутствующему реквизиту (например, Док.Основание) неизбежно приводит к фатальной ошибке выполнения: "Поле агрегатного объекта не обнаружено". Чтобы сделать код универсальным и избежать аварийного завершения работы программы, необходимо реализовать проверку наличия реквизита перед обращением к нему. Разберем детально, как это сделать программно.

Метод 1: Использование объекта Метаданные

Самый надежный и правильный способ в 1С 7.7 — это обращение к коллекции Метаданные. Этот объект позволяет получить полную информацию о структуре конфигурации в режиме реального времени. Если нам известен вид документа (строковый идентификатор), мы можем проверить, выбран ли конкретный реквизит в его структуре.

Рассмотрим пример кода для проверки конкретного документа:


ВидДока = Док.Вид(); // Получаем вид текущего документа
ИмяРеквизита = "Основание";

Если Метаданные.Документ(ВидДока).РеквизитШапки(ИмяРеквизита).Выбран() = 1 Тогда
    // Реквизит существует, можем безопасно обращаться
    ЗначениеОснования = Док.ПолучитьАтрибут(ИмяРеквизита);
    Сообщить("У документа есть реквизит: " + ЗначениеОснования);
Иначе
    Сообщить("У документа " + ВидДока + " нет реквизита " + ИмяРеквизита);
КонецЕсли;

В данном примере функция Выбран() возвращает 1, если реквизит с указанным идентификатором физически существует в метаданных данного вида документа, и 0 в противном случае. Обратите внимание на использование ПолучитьАтрибут() — это позволяет обращаться к полю динамически по имени.

Метод 2: Перебор всех видов документов в конфигурации

Если задача стоит шире — найти все виды документов, в которых присутствует определенный реквизит (например, для построения реестра), нам необходимо организовать цикл по всей коллекции документов в метаданных. Проанализируем следующий алгоритм:


Для К = 1 По Метаданные.Документ() Цикл
    ИдентификаторДока = Метаданные.Документ(К).Идентификатор;
    
    // Проверяем наличие реквизита "Основание" в шапке
    Если Метаданные.Документ(ИдентификаторДока).РеквизитШапки("Основание").Выбран() = 1 Тогда
        Сообщить("Документ " + ИдентификаторДока + " содержит реквизит 'Основание'");
        
        // Здесь можно создать объект и выбрать документы этого вида
        ТекДок = СоздатьОбъект("Документ." + ИдентификаторДока);
        // ... дальнейшая логика выборки ...
    КонецЕсли;
КонецЦикла;

Этот подход позволяет еще на этапе подготовки отчета определить список "валидных" видов документов, чтобы не тратить ресурсы на проверку каждого конкретного экземпляра документа в общем цикле выборки.

Метод 3: Использование типовых функций глобального модуля

В большинстве типовых конфигураций 1С 7.7 (Бухгалтерия, Торговля и Склад, Комплексная) уже реализованы вспомогательные функции, которые упрощают эту задачу. Одной из самых популярных является функция глЕстьРеквизитШапки. Выясним, как она работает и почему её использование предпочтительно.

Типовой вызов выглядит так:


Если глЕстьРеквизитШапки("Основание", Док.Вид()) = 1 Тогда
    ПечДокОснование = Док.Основание;
Иначе
    ПечДокОснование = "";
КонецЕсли;

Преимущество этого метода заключается в краткости кода и его читаемости. Если вы работаете в типовой конфигурации, обязательно проверьте наличие этой функции в Глобальном модуле. Если же вы разрабатываете конфигурацию с нуля, крайне рекомендуется перенести эту функцию к себе. Она обычно выглядит так:


Функция глЕстьРеквизитШапки(ИмяРеквизита, ВидДокумента) Экспорт
    Возврат Метаданные.Документ(ВидДокумента).РеквизитШапки(ИмяРеквизита).Выбран();
КонецФункции

Важные нюансы и оптимизация

При реализации проверок реквизитов следует учитывать несколько критических моментов:

  1. Общие реквизиты: В 1С 7.7, помимо реквизитов конкретного документа, существуют "Общие реквизиты документов" (например, Автор или Фирма). Проверка Метаданные.Документ(...).РеквизитШапки(...) для них может не сработать. Для таких случаев нужно проверять Метаданные.ОбщийРеквизитДокумента("Имя").Выбран().
  2. Регистр имен: Идентификаторы в метаданных нечувствительны к регистру, однако рекомендуется соблюдать точность написания для предотвращения путаницы.
  3. Производительность: Если в вашем отчете обрабатываются десятки тысяч документов, постоянное обращение к Метаданные внутри цикла может замедлить работу. Рекомендуем перед началом цикла создать СписокЗначений или Таблицу Значений, куда поместить все виды документов, имеющие нужный реквизит, и в цикле проверять вид документа по этому списку.
  4. Метод Шаблон(): Существует "хакерский" способ проверки через функцию Шаблон(). Если написать Значение = Шаблон("[Док.Основание]");, система не выдаст ошибку, если реквизита нет, а просто вернет пустую строку. Однако этот метод считается "плохим тоном" и менее надежен, чем работа с метаданными.

Проанализировав все способы, можно сделать вывод: для разовых проверок идеально подходит Метаданные, для типовых конфигураций — глЕстьРеквизитШапки, а для массовой обработки документов — предварительное кэширование списка видов документов. Используя эти подходы, вы сделаете свои отчеты устойчивыми к изменениям в структуре базы данных.

← На главную