Перестанут ли работать запросы с оператором ОБЪЕДИНИТЬ в динамических списках 1С?

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

Среди разработчиков на платформе 1С:Предприятие периодически возникают слухи о кардинальных изменениях в работе механизмов платформы. Один из таких обсуждаемых вопросов — якобы планируемый фирмой «1С» отказ от поддержки оператора ОБЪЕДИНИТЬ (или ОБЪЕДИНИТЬ ВСЕ) в запросах динамических списков. Давайте проанализируем эту ситуацию, выясним реальное положение дел и разберем технические нюансы работы динамических списков.

Правда ли, что 1С отключит оператор ОБЪЕДИНИТЬ в динамических списках?

Сразу ответим на главный вопрос: **нет, это неправда**. Фирма «1С» не планирует и никогда не анонсировала отключение оператора ОБЪЕДИНИТЬ в запросах динамических списков. Вероятность такого шага стремится к нулю, поскольку это нарушило бы обратную совместимость со множеством существующих решений и типовых конфигураций.

Однако откуда же берутся подобные слухи? Чаще всего они возникают из-за неверного истолкования технических ограничений платформы, стандартов разработки фирм «1С» и поведения среды разработки (например, 1C:EDT или Конфигуратора). Рассмотрим подробнее, как именно устроен динамический список и почему использование объединений в нем требует особого внимания.

Как работает динамический список «изнутри»

Разберем механизм работы объекта ДинамическийСписок. В его основе лежит система компоновки данных (СКД). Главная задача динамического списка — обеспечивать быстрое, порционное (постраничное) считывание данных из базы по мере того, как пользователь прокручивает таблицу на форме.

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

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

Технические проблемы использования ОБЪЕДИНИТЬ в динамическом списке

Выясним, какие именно сложности возникают, когда мы пытаемся написать запрос с объединением нескольких таблиц в динамическом списке.

1. Дублирование ссылок и исключительные ситуации

Если у динамического списка указана ОсновнаяТаблица, а ваш запрос с оператором ОБЪЕДИНИТЬ в результате выборки возвращает две одинаковые ссылки (повторяющиеся ключи), платформа при построении и считывании страницы данных вызовет критическое исключение (ошибку дублирования ключей).

2. Ограничения среды разработки (1C:EDT)

В современных инструментах разработки, таких как 1C:EDT, встроен жесткий валидатор конфигурации. Если в корневом запросе динамического списка при установленной основной таблице используется конструктор объединения, среда разработки может выдавать предупреждение или ошибку валидации. Это связано с тем, что платформенный генератор запросов СКД не всегда может корректно наложить условия порционного считывания и RLS на корневое объединение.

3. Потеря производительности при сбросе основной таблицы

Если разработчик решает объединить данные из совершенно разных таблиц (например, справочника Контрагенты и справочника ФизическиеЛица), он не может указать одну ОсновнуюТаблицу. Без основной таблицы динамический список вынужден вычитывать данные большими объемами, что на объектах с сотнями тысяч записей приводит к существенным задержкам интерфейса.

Официальные стандарты разработки 1С и оператор ОБЪЕДИНИТЬ

Проанализируем рекомендации фирмы «1С», опубликованные на ресурсах ИТС (в частности, Стандарт разработки #std732). Фирма «1С» действительно **не рекомендует** создавать тяжелые запросы с объединениями непосредственно в динамических списках, и вот почему:

  1. Использование ОБЪЕДИНИТЬ вместо ОБЪЕДИНИТЬ ВСЕ: Обычный оператор ОБЪЕДИНИТЬ заставляет СУБД выполнять дополнительную и крайне затратную операцию поиска и удаления дублей (аналог DISTINCT). В динамических списках, где отклик интерфейса должен быть мгновенным, это недопустимо. Всегда следует использовать ОБЪЕДИНИТЬ ВСЕ.
  2. Сложные структуры запросов: Если данные собираются из множества разнородных таблиц, правильнее использовать вспомогательные регистры сведений, куда данные рассчитываются фоновыми заданиями заранее, либо применять простые левые соединения.

Как правильно использовать ОБЪЕДИНИТЬ в динамическом списке

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

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

Посмотрим на пример правильного построения запроса динамического списка:


ВЫБРАТЬ
    ВложенныйЗапрос.Ссылка КАК Ссылка,
    ВложенныйЗапрос.Дата КАК Дата,
    ВложенныйЗапрос.Номер КАК Номер,
    ВложенныйЗапрос.СуммаДокумента КАК СуммаДокумента
ИЗ
    (ВЫБРАТЬ
        ЗаказПокупателя.Ссылка КАК Ссылка,
        ЗаказПокупателя.Дата КАК Дата,
        ЗаказПокупателя.Номер КАК Номер,
        ЗаказПокупателя.СуммаДокумента КАК СуммаДокумента
    ИЗ
        Документ.ЗаказПокупателя КАК ЗаказПокупателя
    ГДЕ
        ЗаказПокупателя.Проведен = ИСТИНА

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
        СчетНаОплату.Ссылка КАК Ссылка,
        СчетНаОплату.Дата КАК Дата,
        СчетНаОплату.Номер КАК Номер,
        СчетНаОплату.СуммаДокумента КАК СуммаДокумента
    ИЗ
        Документ.СчетНаОплатуПокупателю КАК СчетНаОплату
    ГДЕ
        СчетНаОплату.Проведен = ИСТИНА) КАК ВложенныйЗапрос

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

Когда стоит переходить на Таблицу Значений (ТЗ)?

Если задача требует вывода сложных скомпонованных данных из множества источников, и при этом:

В этих случаях действительно целесообразно отказаться от ДинамическогоСписка и сформировать обычную ТаблицуЗначений на сервере с последующим выводом на форму. Но делать это нужно исходя из требований производительности и архитектуры, а не из-за несуществующих запретов платформы.

Итоги и выводы

Подведем итоги нашего анализа:

  1. Слухи о скором отключении оператора ОБЪЕДИНИТЬ в динамических списках — это миф. Разработчики 1С не отключают этот функционал.
  2. Ограничения на использование объединений связаны с особенностями работы механизма основной таблицы и требованиями к уникальности ключевых полей.
  3. При использовании объединений всегда следует выбирать ОБЪЕДИНИТЬ ВСЕ и при необходимости оборачивать объединение во вложенный запрос.
  4. Не нужно спешить переписывать все динамические списки на таблицы значений, если списки работают корректно и обеспечивают высокую скорость работы интерфейса.
← На главную