Как создать пустую временную таблицу с заданной структурой в запросе 1С?

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

При разработке на платформе 1С:Предприятие 8, особенно при работе со сложными запросами и обработке больших объемов данных, часто возникает необходимость создать временную таблицу (ВТ), которая имеет определенную структуру колонок, но при этом изначально не содержит ни одной строки. Такая, казалось бы, парадоксальная задача имеет вполне логичное обоснование и ряд практических применений, которые мы рассмотрим далее. Мы разберем различные методы создания такой таблицы с использованием языка запросов 1С.

Зачем нам нужна пустая временная таблица?

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

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

Как мы видим, потребность в пустой временной таблице – это не прихоть, а вполне обоснованный технический прием для решения ряда сложных задач программирования на 1С.

Метод 1: Использование оператора «ВЫБРАТЬ ПЕРВЫЕ 0»

Это один из наиболее простых, лаконичных и интуитивно понятных способов создания пустой временной таблицы с заданной структурой. Давайте рассмотрим его подробнее.

Принцип работы

Оператор ВЫБРАТЬ ПЕРВЫЕ 0 указывает системе запросов, что необходимо выбрать ноль записей. При этом система все равно анализирует поля, перечисленные в секции ВЫБРАТЬ, и определяет их типы данных, формируя таким образом структуру временной таблицы. В результате мы получаем таблицу, у которой есть все необходимые колонки с корректными типами, но нет ни одной строки.

Пример кода

Рассмотрим, как это выглядит на практике. Допустим, нам нужна пустая временная таблица с колонками "Номенклатура" (тип СправочникСсылка.Номенклатура), "Количество" (тип Число) и "Сумма" (тип Число).


ВЫБРАТЬ ПЕРВЫЕ 0
    Справочник.Номенклатура.ПустаяСсылка КАК Номенклатура,
    0 КАК Количество,
    0.00 КАК Сумма
ПОМЕСТИТЬ ВТ_ПустаяСтруктура
;

В этом примере:

  1. ВЫБРАТЬ ПЕРВЫЕ 0: указывает, что мы не хотим получать никаких строк.
  2. Справочник.Номенклатура.ПустаяСсылка КАК Номенклатура: мы используем пустую ссылку на элемент справочника Номенклатура. Это позволяет явно указать, что колонка Номенклатура должна иметь тип "СправочникСсылка.Номенклатура". При этом значение будет именно пустой ссылкой, которая не добавляется в таблицу из-за ПЕРВЫЕ 0.
  3. 0 КАК Количество: определяет колонку Количество с числовым типом.
  4. 0.00 КАК Сумма: определяет колонку Сумма с числовым типом, подразумевая точность два знака после запятой.
  5. ПОМЕСТИТЬ ВТ_ПустаяСтруктура: создает временную таблицу с именем ВТ_ПустаяСтруктура.

После выполнения этого запроса, временная таблица ВТ_ПустаяСтруктура будет существовать в контексте запроса, иметь три колонки ("Номенклатура", "Количество", "Сумма") с соответствующими типами, но не будет содержать ни одной записи.

Метод 2: Использование условия «ГДЕ ЛОЖЬ»

Этот метод по своему результату очень схож с предыдущим и также является весьма популярным для создания пустых временных таблиц.

Принцип работы

При использовании условия ГДЕ ЛОЖЬ (или любого другого заведомо ложного условия, например, ГДЕ 1 = 0), запрос выполняет все свои операции по определению полей и их типов, но на этапе выборки строк фильтрует их таким образом, что ни одна запись не проходит проверку. В итоге формируется временная таблица с корректно определенной структурой, но без данных.

Пример кода

Рассмотрим несколько вариантов использования условия ГДЕ ЛОЖЬ.

Вариант 1: Выборка из существующей таблицы с ложным условием

Предположим, нам нужна пустая временная таблица со всеми полями справочника Номенклатура. Мы можем сделать это так:


ВЫБРАТЬ
    Номенклатура.*
ПОМЕСТИТЬ ВТ_ПустаяНоменклатура
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    ЛОЖЬ
;

В этом случае система сначала определяет все колонки, которые будут выбраны из справочника Номенклатура (Номенклатура.*), а затем применяет условие ГДЕ ЛОЖЬ. Поскольку условие всегда ложно, ни один элемент справочника не будет выбран, и временная таблица ВТ_ПустаяНоменклатура будет создана пустой, но с полной структурой полей справочника Номенклатура.

Вариант 2: Использование менее очевидного, но также ложного условия

В некоторых случаях можно использовать условие, которое фактически равносильно ЛОЖЬ, но может быть более читаемым в контексте предметной области, если мы уверены в его ложности. Например, если мы знаем, что ссылок на пустые строки быть не должно, или определенный реквизит никогда не принимает определенное значение.


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Номенклатура
ПОМЕСТИТЬ ВТ_ПустаяСсылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
;

Этот запрос создаст пустую временную таблицу ВТ_ПустаяСсылка, если в справочнике Номенклатура нет элементов, у которых Ссылка равна пустой ссылке. Это может быть эффективным, если вы точно знаете, что такое условие всегда будет ложным для вашей базы данных. Однако, наиболее надежным является прямое использование ГДЕ ЛОЖЬ, так как оно не зависит от содержимого базы данных.

Метод 3: Комбинированный подход с явным указанием типов и «ГДЕ ЛОЖЬ»

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

Принцип работы

Мы используем оператор ЗНАЧЕНИЕ(...) для явного указания типа колонки, а затем применяем ГДЕ ЛОЖЬ, чтобы гарантировать отсутствие строк. Этот подход позволяет нам точно контролировать структуру и типы данных будущей временной таблицы.

Пример кода

Представим, что нам нужна временная таблица с колонкой Номенклатура, которая может быть как обычной номенклатурой, так и номенклатурной группой, и мы хотим, чтобы ее тип был Составной (СправочникСсылка.Номенклатура, СправочникСсылка.НоменклатурныеГруппы).


ВЫБРАТЬ
    ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) КАК Номенклатура
ПОМЕСТИТЬ ВТ_СмешанныйТип
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
    ЗНАЧЕНИЕ(Справочник.НоменклатурныеГруппы.ПустаяСсылка)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_СмешанныйТип.Номенклатура
ИЗ
    ВТ_СмешанныйТип КАК ВТ_СмешанныйТип
ГДЕ
    ЛОЖЬ
;

Давайте разберем этот пример по шагам:

  1. Первая часть запроса с ОБЪЕДИНИТЬ ВСЕ создает временную таблицу ВТ_СмешанныйТип. За счет объединения пустых ссылок разных типов, колонка Номенклатура получает составной тип (например, "СправочникСсылка.Номенклатура, СправочникСсылка.НоменклатурныеГруппы"). При этом каждая из этих подвыборок сама по себе даст по одной строке с пустой ссылкой.
  2. Вторая часть запроса ВЫБРАТЬ ВТ_СмешанныйТип.Номенклатура ИЗ ВТ_СмешанныйТип ГДЕ ЛОЖЬ берет эту таблицу, которая уже имеет нужный составной тип колонки, и применяет к ней условие ГДЕ ЛОЖЬ.

В итоге, мы получаем пустую временную таблицу, в которой колонка Номенклатура имеет требуемый составной тип данных, но при этом таблица не содержит ни одной записи.

Метод 4: Передача пустой ТаблицыЗначений как параметра запроса

Хотя этот метод не является исключительно "запросным" в том смысле, что часть работы выполняется на стороне кода 1С, он является очень гибким и часто используется для инициализации временных таблиц с точно заданной структурой.

Принцип работы

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

Пример кода (с использованием кода 1С)


// Шаг 1: Создаем пустую ТаблицуЗначений в коде 1С
Перем ПустаяТЗ;
ПустаяТЗ = Новый ТаблицаЗначений;

// Добавляем колонки с явным указанием их имен и типов
ПустаяТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ПустаяТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
ПустаяТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));

// Шаг 2: Создаем запрос и передаем ТаблицуЗначений как параметр
Запрос = Новый Запрос;
Запрос.Текст = "
    |ВЫБРАТЬ
    |    ПараметрТЗ.Номенклатура КАК Номенклатура,
    |    ПараметрТЗ.Количество КАК Количество,
    |    ПараметрТЗ.Сумма КАК Сумма
    |ПОМЕСТИТЬ ВТ_ИзПараметра
    |ИЗ
    |    &ПараметрТЗ КАК ПараметрТЗ
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВТ_ИзПараметра.Номенклатура,
    |    ВТ_ИзПараметра.Количество,
    |    ВТ_ИзПараметра.Сумма
    |ИЗ
    |    ВТ_ИзПараметра КАК ВТ_ИзПараметра
    |";

Запрос.УстановитьПараметр("ПараметрТЗ", ПустаяТЗ);

РезультатЗапроса = Запрос.Выполнить();

// Теперь во временной таблице ВТ_ИзПараметра будет нужная структура, но без строк.

В этом примере:

  1. Мы явно определяем структуру ТаблицыЗначений ПустаяТЗ, добавляя колонки с конкретными типами и квалификаторами.
  2. Затем мы передаем эту ПустаяТЗ в запрос как параметр &ПараметрТЗ.
  3. Запрос выбирает данные из этого параметра и помещает их во временную таблицу ВТ_ИзПараметра. Поскольку ПустаяТЗ не содержит строк, ВТ_ИзПараметра также будет пустой, но с точно заданной структурой.

Этот метод особенно полезен, когда структура временной таблицы зависит от сложной логики в коде 1С, и ее проще определить программно, чем пытаться смоделировать исключительно средствами запроса.

Заключение

Мы рассмотрели несколько эффективных способов создания пустой временной таблицы с заданной структурой в запросах 1С. Каждый из методов – ВЫБРАТЬ ПЕРВЫЕ 0, ГДЕ ЛОЖЬ, комбинированный подход с явным указанием типов, а также передача пустой ТаблицыЗначений как параметра – имеет свои преимущества и может быть применен в зависимости от конкретной задачи и предпочтений разработчика.

Важно понимать, что создание пустой временной таблицы – это не избыточное действие, а мощный и полезный технический прием. Он позволяет нам гибко управлять структурой данных внутри запроса, упрощает разработку и отладку сложных алгоритмов, а также обеспечивает надежность и предсказуемость поведения системы при работе с динамически формируемыми или итерационно собираемыми данными. Выбирайте тот метод, который наилучшим образом соответствует вашей задаче и делает код более читаемым и поддерживаемым.

← На главную