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

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

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

Способ 1. Выгрузка результата в Таблицу Значений

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

Рассмотрим по шагам этот процесс:

  1. Выполняем запрос и получаем результат.
  2. Выгружаем результат в таблицу значений методом Выгрузить().
  3. Добавляем нужные колонки через коллекцию Колонки.
  4. Обходим таблицу в цикле для заполнения новых данных.

Проанализируем пример кода:


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

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

// Добавляем новое поле, которого не было в запросе
ТаблицаРезультат.Колонки.Добавить("ЦенаИзРегистра", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));

// Заполняем поле программно
Для Каждого СтрокаТЗ Из ТаблицаРезультат Цикл
    // Здесь может быть вызов функции или получение данных из другого источника
    СтрокаТЗ.ЦенаИзРегистра = ПолучитьЦенуНоменклатуры(СтрокаТЗ.Номенклатура);
КонецЦикла;

Важный нюанс: Данный метод потребляет значительный объем оперативной памяти, так как вся выборка данных передается из СУБД в память приложения. Если в результате запроса сотни тысяч строк, лучше использовать другие подходы.

Способ 2. Использование Схемы запроса (QuerySchema)

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

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


Схема = Новый СхемаЗапроса;
Схема.УстановитьТекст(ТекстЗапроса);

ОператорВыбора = Схема.ПакетЗапросов[0].Операторы[0];
// Добавляем новое поле в список выбора
НовоеПоле = ОператорВыбора.ВыбираемыеПоля.Добавить("Номенклатура.Артикул");
// Можно задать псевдоним
НовоеПоле.Псевдоним = "АртикулНоменклатуры";

// Получаем обратно измененный текст
ТекстЗапроса = Схема.ПолучитьТекст();

Этот метод считается более профессиональным и безопасным, так как исключает ошибки синтаксиса при динамическом формировании текста запроса.

Способ 3. Работа через Менеджер временных таблиц

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

Разберем ситуацию на примере:

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

Посмотрим на пример логики:


МВТ = Новый МенеджерВременныхТаблиц;
Запрос1 = Новый Запрос("ВЫБРАТЬ ... ПОМЕСТИТЬ ВТ_Данные ...");
Запрос1.МенеджерВременныхТаблиц = МВТ;
Запрос1.Выполнить();

// Нам нужно добавить поле "Остаток", не меняя первый запрос
Запрос2 = Новый Запрос;
Запрос2.МенеджерВременныхТаблиц = МВТ;
Запрос2.Текст = 
    "ВЫБРАТЬ
    |    ВТ.Номенклатура,
    |    ВТ.Количество,
    |    ЕСТЬNULL(ТоварыНаСкладахОстатки.ВНаличииОстаток, 0) КАК Остаток
    |ИЗ
    |    ВТ_Данные КАК ВТ
    |ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
    |ПО ВТ.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура";

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

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

Способ 4. Передача модифицированной таблицы обратно в запрос

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

Проанализируем шаги:

Важное ограничение: При использовании ТЗ в запросе обязательно нужно типизировать все колонки таблицы, иначе запрос выдаст ошибку.


// Предположим, у нас есть ТЗ с данными
Запрос.УстановитьПараметр("ВнешниеДанные", МояТаблицаЗначений);
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ВнешниеДанные.Номенклатура,
    |    ВнешниеДанные.СпецПоле
    |ПОМЕСТИТЬ ВТ_ИзмененныеДанные
    |ИЗ
    |    &ВнешниеДанные КАК ВнешниеДанные";

Рекомендации по выбору метода

Подведем итоги нашего анализа. Выбор метода зависит от объема данных и сложности логики:

  1. Выгрузка в ТЗ — идеально для небольших объемов (до нескольких тысяч строк) и сложной программной обработки каждой строки.
  2. Менеджер временных таблиц — лучший выбор для производительности, если дополнительные данные можно получить из базы данных.
  3. Схема запроса — незаменима при построении гибких динамических отчетов или конструкторов.
  4. Система компоновки данных (СКД) — если ваша конечная цель — отчет, используйте "Вычисляемые поля" в СКД. Это позволит добавить любые колонки без изменения основного текста запроса.

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

← На главную