Как отредактировать запрос динамического списка в расширении 1С без ручного заимствования всех объектов?

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

Разработка в расширениях конфигурации 1С — мощный инструмент, однако он накладывает ряд ограничений, с которыми часто сталкиваются разработчики. Типичная проблема: при попытке отредактировать или переписать запрос динамического списка в расширении, платформа выдает ошибку и отказывается сохранять конфигурацию. Она требует, чтобы все таблицы, реквизиты и справочники, участвующие в запросе, были физически заимствованы в расширение.

Если запрос сложный и объемный, ручное заимствование десятков объектов превращается в рутину. Более того, это захламляет структуру расширения, усложняет последующие обновления основной конфигурации и размывает контроль над сделанными изменениями. В этой статье мы подробно разберем, как решить эту проблему красивыми техническими способами.

Причина проблемы: почему платформа требует заимствования?

Прежде чем перейти к решениям, выясним причину такого поведения системы. Платформа 1С выполняет статическую проверку метаданных. Когда вы открываете конструктор запроса или пытаетесь сохранить текст запроса в свойствах динамического списка внутри расширения, конфигуратор пытается сопоставить имена таблиц (например, Справочник.Номенклатура или РегистрНакопления.Продажи) с объектами, которые объявлены в самом расширении. Если этих объектов в расширении нет, проверка целостности метаданных завершается ошибкой. Система «не видит» эти таблицы в контексте расширения, даже если они существуют в основной конфигурации.

Давайте проанализируем четыре практических метода, которые позволяют обойти это неудобство.

Способ 1. Автоматическое заимствование зависимостей через свойства списка

Это самый простой интерактивный способ, который позволяет быстро подготовить динамический список к редактированию прямо в конфигураторе, не добавляя каждый связанный объект вручную.

Разберем этот процесс по шагам:

  1. Добавьте форму, содержащую нужный динамический список, в ваше расширение.
  2. Откройте форму в редакторе расширения.
  3. Перейдите на вкладку Реквизиты формы.
  4. Найдите реквизит, который является динамическим списком (он имеет тип ДинамическийСписок).
  5. Нажмите на него правой кнопкой мыши и выберите команду Добавить в расширение.

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

Способ 2. Программное переопределение текста запроса

Многие опытные разработчики сознательно отказываются от визуального редактирования свойств динамического списка в расширении, предпочитая управлять запросом программно. Это позволяет сохранить структуру расширения абсолютно чистой — вам не придется заимствовать метаданные таблиц.

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


&НаСервере
&Вместо("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Вызываем оригинальный обработчик, чтобы форма инициализировалась стандартно
    ПродолжитьВызов(Отказ, СтандартнаяОбработка);
    
    // Директивно меняем текст запроса динамического списка
    НовыйТекстЗапроса = 
        "ВЫБРАТЬ
        |   ТаблицаДокумента.Ссылка КАК Ссылка,
        |   ТаблицаДокумента.Номер КАК Номер,
        |   ТаблицаДокумента.Дата КАК Дата,
        |   ТаблицаДокумента.Контрагент КАК Контрагент,
        |   ЕСТЬNULL(ДополнительныеСведения.Значение, """") КАК ДопСвойство
        |ИЗ
        |   Документ.РеализацияТоваровУслуг КАК ТаблицаДокумента
        |   ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
        |       ПО ТаблицаДокумента.Ссылка = ДополнительныеСведения.Объект";
        
    Список.ТекстЗапроса = НовыйТекстЗапроса;

КонецПроцедуры

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

Способ 3. Использование объекта «СхемаЗапроса» для ювелирной модификации

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

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

Рассмотрим пример реализации. Обратите внимание на важнейшую деталь: динамические списки используют конструкции Системы компоновки данных (фигурные скобки вида {ГДЕ...}). Чтобы СхемаЗапроса не испортила эти конструкции, необходимо обязательно активировать специальное свойство.

Проанализируем программный код:


&НаСервере
&Вместо("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ПродолжитьВызов(Отказ, СтандартнаяОбработка);
    
    // Инициализируем схему запроса
    Схема = Новый СхемаЗапроса;
    
    // КРИТИЧЕСКИ ВАЖНО: включаем режим компоновки данных, 
    // чтобы сохранить фигурные скобки и параметры СКД в запросе списков!
    Схема.РежимКомпоновкиДанных = Истина;
    
    Попытка
        Схема.УстановитьТекстЗапроса(Список.ТекстЗапроса);
        
        // Получаем первый пакет запроса
        ПакетЗапроса = Схема.ПакетЗапросов[0];
        
        // Добавляем новую таблицу для левого соединения
        ИндексТаблицы = ПакетЗапроса.Источники.Добавить("РегистрСведений.ДополнительныеСведения", "ДопСведения");
        ИсточникДопСведения = ПакетЗапроса.Источники[ИндексТаблицы];
        
        // Описываем условие связи (соединения)
        НоваяСвязь = ПакетЗапроса.СвязиИсточников.Добавить();
        НоваяСвязь.ЛевыйИсточник = ПакетЗапроса.Источники[0]; // Основная таблица списка
        НоваяСвязь.ПравыйИсточник = ИсточникДопСведения;
        НоваяСвязь.ТипСоединения = ТипСоединенияСхемыЗапроса.Левое;
        
        // Задаем само условие соединения
        НоваяСвязь.Условие.УстановитьТекст("ОсновнойИсточник.Ссылка = ДопСведения.Объект");
        
        // Добавляем нужное поле в выборку запроса
        ПолеВыбора = ПакетЗапроса.Колонки.Добавить("ДопСведения.Значение");
        ПолеВыбора.Псевдоним = "ДополнительноеСвойство";
        
        // Применяем измененный текст обратно в динамический список
        Список.ТекстЗапроса = Схема.ПолучитьТекстЗапроса();
    Исключение
        ЗаписьЖурналаРегистрации("Расширение.ДинамическийСписок", 
            УровеньЖурналаРегистрации.Ошибка, , , 
            ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    КонецПопытки;
КонецПроцедуры

Способ 4. Современные возможности платформы (для версии 8.3.23 и выше)

Если вы работаете на современных версиях платформы (начиная с 8.3.23), вам больше не нужно использовать сложные программные обходы или вручную заимствовать метаданные. Фирма «1С» добавила штатный механизм облегченного конструирования запросов в расширениях.

Выясним, как это работает:

Развенчиваем мифы: влияет ли обилие заимствованных объектов на производительность?

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

Как обстоят дела на самом деле: Само по себе пассивное заимствование объектов (когда вы просто добавили справочник или документ в расширение, но не изменяли его структуру, не добавляли новые реквизиты базы данных и не переопределяли его модули) никак не влияет на производительность работы базы данных и скорость выполнения запросов.

Однако избыточное заимствование несет в себе другие реальные технические риски:

  1. Проблемы при обновлениях: Если в очередном обновлении типовой конфигурации от фирмы «1С» изменится тип реквизита или какое-то важное свойство заимствованного вами объекта, возникнет конфликт свойств. Расширение просто откажется подключаться к базе данных, пока вы вручную не устраните конфликт.
  2. Увеличение времени разработки: Чем тяжелее файл расширения, тем дольше происходит процесс обновления конфигурации базы данных (F7) в конфигураторе, что существенно замедляет ежедневную работу программиста.

Именно поэтому использование программных методов модификации (таких как СхемаЗапроса) считается признаком высокого качества кода и профессионализма разработчика 1С.

← На главную