Как организовать взаимодействие между расширениями 1С и использовать реквизиты одного расширения в другом?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При активном использовании механизма расширений в 1С:Предприятие 8.3 часто возникает задача: как обеспечить работу одного расширения с данными, которые были созданы или изменены в другом расширении. Например, в первом расширении мы добавили новый реквизит в справочник Номенклатура, а во втором расширении нам нужно вывести этот реквизит в отчет или использовать его в логике проведения документа. В данной статье мы подробно разберем, как реализовать такое взаимодействие, какие инструменты предоставляет платформа и как избежать типичных ошибок, которые могут привести к нестабильной работе базы данных.

Метод 1. Настройка явных зависимостей через свойства расширений

Начиная с современных версий платформы (8.3.15 и выше), разработчикам стал доступен штатный механизм управления связями между расширениями. Разберем по шагам, как настроить конфигуратор так, чтобы одно расширение «видело» объекты другого.

Во-первых, проанализируем свойство Используемые расширения (Required Extensions). Если мы разрабатываем «Расширение_Б», которое должно использовать реквизит из «Расширение_А», нам необходимо открыть свойства «Расширение_Б» и добавить «Расширение_А» в список используемых. Это дает конфигуратору понимание структуры метаданных на этапе разработки. Без этой настройки вы не сможете выбрать добавленный в другом расширении объект в качестве типа данных или обратиться к нему напрямую в коде — система выдаст ошибку компиляции.

Во-вторых, крайне важно проконтролировать Порядок применения расширений. В окне «Управление расширениями» расширения применяются строго сверху вниз. Рассмотрим ситуацию: если «Расширение_Б» стоит в списке выше, чем «Расширение_А», то в момент его инициализации целевого реквизита еще не существует в структуре базы. Поэтому всегда следите, чтобы «донор» метаданных (то расширение, которое создает объект) располагалось в списке выше, чем «потребитель».

Метод 2. Программная проверка наличия реквизита или объекта

Иногда создание жесткой зависимости между расширениями нежелательно. Например, если вы хотите, чтобы «Расширение_Б» могло работать как с установленным «Расширение_А», так и без него (просто отключая часть функционала). В этом случае мы не можем обращаться к новым реквизитам напрямую. Нам необходимо использовать программные проверки.

Рассмотрим пример функции, которая позволяет определить, существует ли реквизит у объекта метаданных. Это поможет избежать падения системы с ошибкой «Поле объекта не обнаружено».


Функция ЕстьРеквизитОбъекта(ИмяРеквизита, Объект) Экспорт
    МетаданныеОбъекта = Объект.Метаданные();
    Если МетаданныеОбъекта.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
        Возврат Ложь;
    Иначе
        Возврат Истина;
    КонецЕсли;
КонецФункции

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


// Пример использования в коде
Если ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(Объект, "НовыйРеквизитИзРасширения") Тогда
    // Выполняем логику, зная, что реквизит существует
    Значение = Объект.НовыйРеквизитИзРасширения;
КонецЕсли;

Проанализируем альтернативный способ проверки, который работает быстрее в некоторых сценариях, не обращаясь напрямую к метаданным, а используя попытку заполнения свойств. Разберем код такой функции:


Функция ЕстьРеквизитИлиСвойствоОбъекта(Объект, ИмяРеквизита)
    КлючУникальности = Новый УникальныйИдентификатор;
    СтруктураРеквизита = Новый Структура(ИмяРеквизита, КлючУникальности);
    ЗаполнитьЗначенияСвойств(СтруктураРеквизита, Объект);
    Возврат СтруктураРеквизита[ИмяРеквизита] <> КлючУникальности;
КонецФункции

Здесь мы создаем структуру с уникальным значением-маркером. Если после ЗаполнитьЗначенияСвойств значение в структуре изменилось — значит, реквизит у объекта существует.

Метод 3. Использование динамического выполнения кода

В ситуациях, когда нам нужно вызвать процедуру или функцию, добавленную в другом расширении, и при этом избежать ошибок компиляции при отсутствии этого расширения, мы можем прибегнуть к операторам Выполнить() или Вычислить(). Рассмотрим, как это выглядит на практике:


// Вместо прямого вызова: Расширение1_МойМодуль.ВыполнитьДействие();
// Используем безопасный вызов:
ИмяМодуля = "Расширение1_МойМодуль";
Если Метаданные.ОбщиеМодули.Найти(ИмяМодуля) <> Неопределено Тогда
    Выполнить(ИмяМодуля + ".ВыполнитьДействие()");
КонецЕсли;

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

Важные нюансы и архитектурные риски

Разберем несколько критически важных моментов, которые часто упускают разработчики при проектировании взаимодействия расширений:

  1. Проблема типизации данных. Если в «Расширение_Б» вы создали реквизит и указали ему тип — справочник, созданный в «Расширение_А», то при удалении или отключении «Расширение_А» вы получите «битые ссылки». Платформа не всегда блокирует удаление расширения-родителя, что может привести к появлению записей вида <Объект не найден> в базе данных.
  2. Работа с запросами. Конструктор запроса в «Расширение_Б» увидит поля из «Расширение_А» только в том случае, если настроены зависимости (Метод 1). Если же вы пишете текст запроса вручную, он успешно выполнится в режиме 1С:Предприятие, так как база данных оперирует уже объединенной схемой метаданных.
  3. Автономность как идеал. Согласно стандартам разработки 1С, расширения должны быть максимально независимы. Если вы чувствуете, что связь между расширениями становится слишком тесной (одно вызывает методы другого, использует его типы и реквизиты), возможно, стоит объединить эти расширения в одно. Разделение на множество мелких, но сильно связанных между собой расширений — это прямой путь к трудностям при обновлении конфигурации.

Подводя итог, можно сказать: взаимодействие между расширениями в 1С технически полностью реализовано. Для стабильных, долгосрочных проектов лучше всего использовать штатный механизм Используемые расширения. Для гибких или опциональных доработок идеально подойдут программные проверки через Метаданные или функции БСП. Главное — всегда помнить о порядке применения расширений в списке и стараться не создавать «спагетти-код» из взаимных вызовов между разными модулями.

← На главную