Как правильно передать строковый тип в объединении запросов 1С

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

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

Разберем проблему: почему просто «0» не подходит

В тексте вопроса автор столкнулся с ситуацией, когда в первом запросе объединения он указал 0 КАК НомерТТН, в то время как во втором запросе это же поле содержит реальные строковые данные. На первый взгляд это может показаться допустимым, но на практике это приводит к двум серьезным проблемам:

  1. Несовместимость типов: Система 1С:Предприятие при выполнении запроса определяет типы колонок результирующей выборки по первому запросу в объединении. Если в первом блоке стоит число 0, система решит, что вся колонка НомерТТН должна быть числовой.
  2. Ошибки поиска: Как отметил автор, «не ищет в списке». Это происходит потому, что механизмы поиска в динамических списках или таблицах значений ожидают строковый тип для текстовых полей. Когда в колонке вместо строки оказывается число, индекс поиска не срабатывает.

Решение 1: Использование строковых литералов (кавычки)

Проанализируем самый простой способ — использование пустой строки. Чтобы система поняла, что поле является строковым, вместо 0 нужно использовать кавычки. Однако здесь есть синтаксический нюанс, зависящий от того, где вы пишете запрос.

В Конструкторе запроса:

Если вы работаете в визуальном конструкторе на закладке «Объединения/Псевдонимы», в поле выражения достаточно поставить две двойные кавычки:

"" КАК НомерТТН

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

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


ТекстЗапроса = "ВЫБРАТЬ
               |    Данные.Ссылка КАК Ссылка,
               |    """" КАК НомерТТН
               |ИЗ
               |    Документ.РеализацияУслуг КАК Данные
               |ОБЪЕДИНИТЬ ВСЕ
               |ВЫБРАТЬ
               |    Данные.Ссылка,
               |    Данные.НомерТТН
               |ИЗ
               |    Документ.Заказ КАК Данные";

Решение 2: Использование оператора ВЫРАЗИТЬ (CAST)

Рассмотрим более профессиональный и надежный метод. Использование просто пустых кавычек """" может привести к тому, что система определит длину строки как 1 символ или как строку неограниченной длины, что негативно скажется на производительности и возможности сортировки. Чтобы четко заявить параметры поля, проанализируем использование оператора ВЫРАЗИТЬ.

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


| ВЫБРАТЬ
|    ДанныеДокумента.Ссылка КАК Ссылка,
|    ВЫРАЗИТЬ("""" КАК СТРОКА(100)) КАК НомерТТН
| ИЗ
|    Документ.РеализацияУслуг КАК ДанныеДокумента

Важные преимущества этого способа:

Проблема строк неограниченной длины

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

В этом случае необходимо обязательно ограничивать длину в обоих запросах:


| ВЫБРАТЬ
|    ВЫРАЗИТЬ("""" КАК СТРОКА(1000)) КАК ПолеТекст
| ...
| ОБЪЕДИНИТЬ ВСЕ
| ВЫБРАТЬ
|    ВЫРАЗИТЬ(Данные.Комментарий КАК СТРОКА(1000))

Порядок объединения и типизация

Нужно помнить критически важное правило: структура результата формируется по первой выборке. Посмотрим на примере:

  1. Если в первом ВЫБРАТЬ стоит 0 (Число), а во втором "Строка" — будет ошибка приведения типов или некорректные данные.
  2. Если в первом ВЫБРАТЬ стоит NULL, система попытается определить тип по следующим запросам, но это может привести к созданию «составного типа», что замедляет работу динамических списков.
  3. Если в первом ВЫБРАТЬ стоит пустая строка с ВЫРАЗИТЬ — это эталонный вариант.

Итоговый пример правильного кода

С учетом всех разобранных нюансов, правильный запрос для автора вопроса (с объединением РеализацииУслуг и Заказа) будет выглядеть следующим образом:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДанныеДокумента.Ссылка КАК Ссылка,
    |	ДанныеДокумента.Дата КАК Дата,
    |	ВЫРАЗИТЬ("""" КАК СТРОКА(50)) КАК НомерТТН
    |ИЗ
    |	Документ.РеализацияУслуг КАК ДанныеДокумента
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    |	ДанныеДокумента.Ссылка,
    |	ДанныеДокумента.Дата,
    |	ДанныеДокумента.НомерТТН
    |ИЗ
    |	Документ.Заказ КАК ДанныеДокумента";

Использование конструкции ВЫРАЗИТЬ("""" КАК СТРОКА(50)) гарантирует, что колонка НомерТТН всегда будет строкой, поиск по ней будет работать моментально, а данные из Документ.Заказ не потеряются и не изменят свой вид.

← На главную