При разработке сложных отчетов или динамических списков программисты 1С часто сталкиваются с необходимостью объединения результатов нескольких запросов с помощью оператора ОБЪЕДИНИТЬ или ОБЪЕДИНИТЬ ВСЕ. Одной из неочевидных проблем в этой ситуации является типизация колонок. Если в одном запросе поле заполнено данными, а в другом оно должно быть пустым, важно правильно «подсказать» системе тип этого поля. Рассмотрим подробнее, почему возникают ошибки и как их избежать.
В тексте вопроса автор столкнулся с ситуацией, когда в первом запросе объединения он указал 0 КАК НомерТТН, в то время как во втором запросе это же поле содержит реальные строковые данные. На первый взгляд это может показаться допустимым, но на практике это приводит к двум серьезным проблемам:
0, система решит, что вся колонка НомерТТН должна быть числовой.Проанализируем самый простой способ — использование пустой строки. Чтобы система поняла, что поле является строковым, вместо 0 нужно использовать кавычки. Однако здесь есть синтаксический нюанс, зависящий от того, где вы пишете запрос.
В Конструкторе запроса:
Если вы работаете в визуальном конструкторе на закладке «Объединения/Псевдонимы», в поле выражения достаточно поставить две двойные кавычки:
"" КАК НомерТТН
В тексте программного модуля:
Поскольку сам текст запроса в коде 1С уже обрамляется кавычками, строковый литерал внутри него должен удваиваться. Для передачи пустой строки необходимо использовать четыре кавычки подряд. Выясним, как это выглядит в коде:
ТекстЗапроса = "ВЫБРАТЬ
| Данные.Ссылка КАК Ссылка,
| """" КАК НомерТТН
|ИЗ
| Документ.РеализацияУслуг КАК Данные
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ
| Данные.Ссылка,
| Данные.НомерТТН
|ИЗ
| Документ.Заказ КАК Данные";
Рассмотрим более профессиональный и надежный метод. Использование просто пустых кавычек """" может привести к тому, что система определит длину строки как 1 символ или как строку неограниченной длины, что негативно скажется на производительности и возможности сортировки. Чтобы четко заявить параметры поля, проанализируем использование оператора ВЫРАЗИТЬ.
Этот метод позволяет явно указать длину строки, которая будет зарезервирована в базе данных для этой колонки. Рекомендуется указывать длину, соответствующую максимальной длине поля во втором запросе.
| ВЫБРАТЬ
| ДанныеДокумента.Ссылка КАК Ссылка,
| ВЫРАЗИТЬ("""" КАК СТРОКА(100)) КАК НомерТТН
| ИЗ
| Документ.РеализацияУслуг КАК ДанныеДокумента
Важные преимущества этого способа:
Посмотрим на ситуацию, когда поле НомерТТН во втором запросе имеет тип «Строка (неограниченная длина)». В 1С нельзя напрямую объединять такие поля. Если вы попытаетесь сделать ОБЪЕДИНИТЬ для полей неограниченной длины, система выдаст ошибку.
В этом случае необходимо обязательно ограничивать длину в обоих запросах:
| ВЫБРАТЬ
| ВЫРАЗИТЬ("""" КАК СТРОКА(1000)) КАК ПолеТекст
| ...
| ОБЪЕДИНИТЬ ВСЕ
| ВЫБРАТЬ
| ВЫРАЗИТЬ(Данные.Комментарий КАК СТРОКА(1000))
Нужно помнить критически важное правило: структура результата формируется по первой выборке. Посмотрим на примере:
ВЫБРАТЬ стоит 0 (Число), а во втором "Строка" — будет ошибка приведения типов или некорректные данные.ВЫБРАТЬ стоит NULL, система попытается определить тип по следующим запросам, но это может привести к созданию «составного типа», что замедляет работу динамических списков.ВЫБРАТЬ стоит пустая строка с ВЫРАЗИТЬ — это эталонный вариант.С учетом всех разобранных нюансов, правильный запрос для автора вопроса (с объединением РеализацииУслуг и Заказа) будет выглядеть следующим образом:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДанныеДокумента.Ссылка КАК Ссылка,
| ДанныеДокумента.Дата КАК Дата,
| ВЫРАЗИТЬ("""" КАК СТРОКА(50)) КАК НомерТТН
|ИЗ
| Документ.РеализацияУслуг КАК ДанныеДокумента
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДанныеДокумента.Ссылка,
| ДанныеДокумента.Дата,
| ДанныеДокумента.НомерТТН
|ИЗ
| Документ.Заказ КАК ДанныеДокумента";
Использование конструкции ВЫРАЗИТЬ("""" КАК СТРОКА(50)) гарантирует, что колонка НомерТТН всегда будет строкой, поиск по ней будет работать моментально, а данные из Документ.Заказ не потеряются и не изменят свой вид.