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