Разработка в расширениях конфигурации 1С — мощный инструмент, однако он накладывает ряд ограничений, с которыми часто сталкиваются разработчики. Типичная проблема: при попытке отредактировать или переписать запрос динамического списка в расширении, платформа выдает ошибку и отказывается сохранять конфигурацию. Она требует, чтобы все таблицы, реквизиты и справочники, участвующие в запросе, были физически заимствованы в расширение.
Если запрос сложный и объемный, ручное заимствование десятков объектов превращается в рутину. Более того, это захламляет структуру расширения, усложняет последующие обновления основной конфигурации и размывает контроль над сделанными изменениями. В этой статье мы подробно разберем, как решить эту проблему красивыми техническими способами.
Прежде чем перейти к решениям, выясним причину такого поведения системы. Платформа 1С выполняет статическую проверку метаданных. Когда вы открываете конструктор запроса или пытаетесь сохранить текст запроса в свойствах динамического списка внутри расширения, конфигуратор пытается сопоставить имена таблиц (например, Справочник.Номенклатура или РегистрНакопления.Продажи) с объектами, которые объявлены в самом расширении. Если этих объектов в расширении нет, проверка целостности метаданных завершается ошибкой. Система «не видит» эти таблицы в контексте расширения, даже если они существуют в основной конфигурации.
Давайте проанализируем четыре практических метода, которые позволяют обойти это неудобство.
Это самый простой интерактивный способ, который позволяет быстро подготовить динамический список к редактированию прямо в конфигураторе, не добавляя каждый связанный объект вручную.
Разберем этот процесс по шагам:
ДинамическийСписок).При выполнении этого действия платформа 1С самостоятельно проанализирует текущий текст запроса динамического списка. Она автоматически заимствует в расширение все связанные таблицы, справочники, документы и их реквизиты, которые фигурируют в запросе. После этого вы сможете открыть конструктор запроса, внести любые изменения и успешно сохранить форму.
Многие опытные разработчики сознательно отказываются от визуального редактирования свойств динамического списка в расширении, предпочитая управлять запросом программно. Это позволяет сохранить структуру расширения абсолютно чистой — вам не придется заимствовать метаданные таблиц.
Для реализации этого подхода мы перехватываем событие формы ПриСозданииНаСервере. Посмотрим на пример кода, который решает эту задачу:
&НаСервере
&Вместо("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Вызываем оригинальный обработчик, чтобы форма инициализировалась стандартно
ПродолжитьВызов(Отказ, СтандартнаяОбработка);
// Директивно меняем текст запроса динамического списка
НовыйТекстЗапроса =
"ВЫБРАТЬ
| ТаблицаДокумента.Ссылка КАК Ссылка,
| ТаблицаДокумента.Номер КАК Номер,
| ТаблицаДокумента.Дата КАК Дата,
| ТаблицаДокумента.Контрагент КАК Контрагент,
| ЕСТЬNULL(ДополнительныеСведения.Значение, """") КАК ДопСвойство
|ИЗ
| Документ.РеализацияТоваровУслуг КАК ТаблицаДокумента
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
| ПО ТаблицаДокумента.Ссылка = ДополнительныеСведения.Объект";
Список.ТекстЗапроса = НовыйТекстЗапроса;
КонецПроцедуры
Важное правило стандартов разработки (БСП): Любое изменение текста запроса или состава полей динамического списка должно происходить в самом начале инициализации формы, строго до того, как система начнет обращаться к пользовательским настройкам (отборам, группировкам и условной компоновке). В противном случае платформа выполнит инициализацию списка дважды, что приведет к замедлению открытия формы пользователем.
Предыдущий способ имеет один недостаток: если в типовом решении разработчики фирмы «1С» обновят исходный запрос динамического списка (например, добавят новые важные поля), ваш жестко прописанный в коде текст полностью затрет эти изменения. Чтобы избежать этой проблемы, рекомендуется использовать объект СхемаЗапроса.
Этот подход позволяет программно «разобрать» исходный запрос списка, добавить к нему новое левое соединение или поле, и собрать его обратно. При этом заимствовать таблицы конфигурации в расширение по-прежнему не нужно.
Рассмотрим пример реализации. Обратите внимание на важнейшую деталь: динамические списки используют конструкции Системы компоновки данных (фигурные скобки вида {ГДЕ...}). Чтобы СхемаЗапроса не испортила эти конструкции, необходимо обязательно активировать специальное свойство.
Проанализируем программный код:
&НаСервере
&Вместо("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПродолжитьВызов(Отказ, СтандартнаяОбработка);
// Инициализируем схему запроса
Схема = Новый СхемаЗапроса;
// КРИТИЧЕСКИ ВАЖНО: включаем режим компоновки данных,
// чтобы сохранить фигурные скобки и параметры СКД в запросе списков!
Схема.РежимКомпоновкиДанных = Истина;
Попытка
Схема.УстановитьТекстЗапроса(Список.ТекстЗапроса);
// Получаем первый пакет запроса
ПакетЗапроса = Схема.ПакетЗапросов[0];
// Добавляем новую таблицу для левого соединения
ИндексТаблицы = ПакетЗапроса.Источники.Добавить("РегистрСведений.ДополнительныеСведения", "ДопСведения");
ИсточникДопСведения = ПакетЗапроса.Источники[ИндексТаблицы];
// Описываем условие связи (соединения)
НоваяСвязь = ПакетЗапроса.СвязиИсточников.Добавить();
НоваяСвязь.ЛевыйИсточник = ПакетЗапроса.Источники[0]; // Основная таблица списка
НоваяСвязь.ПравыйИсточник = ИсточникДопСведения;
НоваяСвязь.ТипСоединения = ТипСоединенияСхемыЗапроса.Левое;
// Задаем само условие соединения
НоваяСвязь.Условие.УстановитьТекст("ОсновнойИсточник.Ссылка = ДопСведения.Объект");
// Добавляем нужное поле в выборку запроса
ПолеВыбора = ПакетЗапроса.Колонки.Добавить("ДопСведения.Значение");
ПолеВыбора.Псевдоним = "ДополнительноеСвойство";
// Применяем измененный текст обратно в динамический список
Список.ТекстЗапроса = Схема.ПолучитьТекстЗапроса();
Исключение
ЗаписьЖурналаРегистрации("Расширение.ДинамическийСписок",
УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Если вы работаете на современных версиях платформы (начиная с 8.3.23), вам больше не нужно использовать сложные программные обходы или вручную заимствовать метаданные. Фирма «1С» добавила штатный механизм облегченного конструирования запросов в расширениях.
Выясним, как это работает:
Среди разработчиков 1С существует популярный миф, что если заимствовать в расширение большое количество объектов метаданных «про запас», то это снизит скорость работы пользователей в режиме «1С:Предприятие». Проанализируем эту ситуацию детально.
Как обстоят дела на самом деле: Само по себе пассивное заимствование объектов (когда вы просто добавили справочник или документ в расширение, но не изменяли его структуру, не добавляли новые реквизиты базы данных и не переопределяли его модули) никак не влияет на производительность работы базы данных и скорость выполнения запросов.
Однако избыточное заимствование несет в себе другие реальные технические риски:
Именно поэтому использование программных методов модификации (таких как СхемаЗапроса) считается признаком высокого качества кода и профессионализма разработчика 1С.