При работе с данными в 1С часто возникает задача, когда необходимо представить информацию об одном объекте, имеющуюся в разных полях таблицы, в виде списка характеристик и их значений. Например, если у нас есть справочник "Компьютеры" с полями "Модель", "ЧастотаПроцессора", "ОбъемПамяти" и так далее, и мы хотим вывести эти данные в двух столбцах: "Характеристика" и "Значение". Давайте разберем, как мы можем решить эту задачу с помощью языка запросов 1С.
Наша цель — получить информацию о компьютере с максимальным кодом из справочника "Компьютеры" и представить ее в виде таблицы с двумя колонками: "Характеристика" (например, "Модель", "ЧастотаПроцессора") и "Значение" (фактическое значение этих характеристик для выбранного компьютера).
В языке запросов 1С отсутствует прямой оператор
UNPIVOT
ОБЪЕДИНИТЬ ВСЕ
ОБЪЕДИНИТЬ ВСЕ
Рассмотрим каждый шаг подробнее.
Прежде всего, нам необходимо найти ссылку на тот компьютер, у которого код является максимальным. Это можно сделать с помощью подзапроса, который определит максимальное значение кода, а затем основной запрос выберет соответствующий ему элемент.
Начнем с того, что найдем максимальный код в справочнике
Компьютеры
МАКСИМУМ
ВЫБРАТЬ МАКСИМУМ(Код) ИЗ Справочник.Компьютеры
Далее, мы используем этот результат для получения ссылки на нужный компьютер:
ВЫБРАТЬ
Ссылка
ИЗ
Справочник.Компьютеры
ГДЕ
Код В
(ВЫБРАТЬ
МАКСИМУМ(Код)
ИЗ
Справочник.Компьютеры)
Таким образом, мы получили ссылку на объект, характеристики которого нам предстоит вывести.
Чтобы упростить последующую работу с данными, мы можем поместить все нужные характеристики найденного компьютера во временную таблицу. Использование временных таблиц — это очень мощный и рекомендуемый инструмент в 1С для разбиения сложных запросов на более простые и управляемые части. Они улучшают читаемость кода и позволяют повторно использовать результаты промежуточных вычислений.
Мы выбираем все необходимые поля и помещаем их в новую временную таблицу. В нашем случае это будут Модель, ЧастотаПроцессора, ОбъемПамяти, РазмерДиска, Цена, СкоростьПривода.
ВЫБРАТЬ
Модель,
ЧастотаПроцессора,
ОбъемПамяти,
РазмерДиска,
Цена,
СкоростьПривода
ПОМЕСТИТЬ ВТ1
ИЗ
Справочник.Компьютеры
ГДЕ
Код В
(ВЫБРАТЬ
МАКСИМУМ(Код)
ИЗ
Справочник.Компьютеры)
Как альтернативный вариант, мы можем выполнить эти действия в два отдельных этапа с использованием двух временных таблиц, что делает запрос еще более структурированным и наглядным:
ВЫБРАТЬ
МАКСИМУМ(Компьютеры.Код) КАК Код
ПОМЕСТИТЬ втМаксКодКомпьютера
ИЗ
Справочник.Компьютеры КАК Компьютеры
;
ВЫБРАТЬ
Компьютеры.Модель КАК Модель,
Компьютеры.ЧастотаПроцессора КАК ЧастотаПроцессора,
Компьютеры.ОбъемПамяти КАК ОбъемПамяти,
Компьютеры.РазмерДиска КАК РазмерДиска,
Компьютеры.Цена КАК Цена,
Компьютеры.СкоростьПривода КАК СкоростьПривода
ПОМЕСТИТЬ втКомпьютерСМаксКодом
ИЗ
Справочник.Компьютеры КАК Компьютеры
ВНУТРЕННЕЕ СОЕДИНЕНИЕ втМаксКодКомпьютера КАК втМаксКодКомпьютера
ПО (втМаксКодКомпьютера.Код = Компьютеры.Код)
;
Оба варианта рабочие, и выбор зависит от предпочтений в структурировании запроса.
Теперь, когда у нас есть временная таблица с характеристиками одного компьютера, нам нужно "развернуть" их. Это означает, что каждая колонка (например, "Модель", "ЧастотаПроцессора") должна стать строкой в новом столбце "Характеристика", а ее значение должно попасть в столбец "Значение". Мы достигнем этого с помощью оператора
ОБЪЕДИНИТЬ ВСЕ
Для каждого поля, которое мы хотим вывести как характеристику, мы формируем отдельный блок
ВЫБРАТЬ
"Модель"
Характеристика
втКомпьютерСМаксКодом.Модель
Значение
Все эти блоки
ВЫБРАТЬ
ОБЪЕДИНИТЬ ВСЕ
ВСЕ
Вот как будет выглядеть финальный запрос, использующий временную таблицу
втКомпьютерСМаксКодом
ВЫБРАТЬ
"Модель" КАК Характеристика,
втКомпьютерСМаксКодом.Модель КАК Значение
ИЗ
втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Частота процессора",
втКомпьютерСМаксКодом.ЧастотаПроцессора
ИЗ
втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Объем памяти",
втКомпьютерСМаксКодом.ОбъемПамяти
ИЗ
втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Размер диска",
втКомпьютерСМаксКодом.РазмерДиска
ИЗ
втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Цена",
втКомпьютерСМаксКодом.Цена
ИЗ
втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Скорость привода",
втКомпьютерСМаксКодом.СкоростьПривода
ИЗ
втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом
В результате выполнения этого запроса мы получим таблицу с двумя столбцами: "Характеристика" и "Значение", где каждая строка будет представлять одну из характеристик нашего компьютера.
Предложенное решение с
ОБЪЕДИНИТЬ ВСЕ
"Модель"
"Частота процессора"
Для повышения гибкости мы можем использовать динамическое формирование текста запроса. В 1С существует возможность программно получить доступ к метаданным конфигурации, чтобы узнать список реквизитов справочника и их типы. Это делается с помощью объекта
Метаданные
Например, чтобы получить список реквизитов справочника "Компьютеры", мы можем использовать следующий код в модуле 1С:
СписокРеквизитов = Метаданные.Справочники.Компьютеры.Реквизиты;
Для Каждого Реквизит Из СписокРеквизитов Цикл
Сообщить("Имя реквизита: " + Реквизит.Имя + ", Синоним: " + Реквизит.Синоним);
КонецЦикла;
Полученные имена и синонимы реквизитов можно затем использовать для построения строки запроса, динамически добавляя их в предложения
ВЫБРАТЬ
ОБЪЕДИНИТЬ ВСЕ
Хотя метод с
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Тем не менее, в условиях отсутствия прямого оператора
UNPIVOT
В некоторых случаях, для еще более сложных сценариев или при необходимости работы с иерархическими данными, можно рассмотреть подходы с использованием JSON. Этот метод обычно подразумевает более сложные программные манипуляции с данными после их получения из запроса (например, получение одной строки с агрегированным JSON-объектом, а затем его программный разбор) или формирование специализированных запросов, которые возвращают данные уже в формате JSON. Прямого универсального инструмента для такого преобразования исключительно средствами языка запросов 1С, сравнимого с
FOR JSON
В дополнение к рассмотренному решению, хотим обратить ваше внимание на несколько общих рекомендаций, которые могут быть полезны при написании любых запросов в 1С:
Как уже упоминалось, временные таблицы (
ПОМЕСТИТЬ ВТ
Функция
ВЫРАЗИТЬ
ВЫРАЗИТЬ(ПолеСоставногоТипа КАК СПРАВОЧНИК.Номенклатура)
ВЫРАЗИТЬ(СтроковоеПолеНеограниченнойДлины КАК СТРОКА(100))
В языке запросов 1С очень удобно использовать "разыменование через точку" для доступа к свойствам связанных объектов. Например, вместо того чтобы делать
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
Номенклатура.Поставщик.Наименование
Консоль запросов 1С — это незаменимый инструмент для любого разработчика. Она позволяет не только выполнять весь запрос целиком, но и отлаживать его по частям: выполнять отдельные подзапросы, заполнять и просматривать временные таблицы. Консоль также предлагает функции для визуального выравнивания ширины колонок, отображения вложенных результатов и анализа плана выполнения запроса, что очень удобно для поиска узких мест и оптимизации.
Мы рассмотрели эффективный и распространенный способ вывода характеристик элемента справочника 1С в двухколоночном формате "Характеристика - Значение" с помощью языка запросов, используя временные таблицы и оператор
ОБЪЕДИНИТЬ ВСЕ