Как вывести характеристики элемента справочника 1С в двухколоночном формате 'Характеристика - Значение' с использованием языка запросов?

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

При работе с данными в 1С часто возникает задача, когда необходимо представить информацию об одном объекте, имеющуюся в разных полях таблицы, в виде списка характеристик и их значений. Например, если у нас есть справочник "Компьютеры" с полями "Модель", "ЧастотаПроцессора", "ОбъемПамяти" и так далее, и мы хотим вывести эти данные в двух столбцах: "Характеристика" и "Значение". Давайте разберем, как мы можем решить эту задачу с помощью языка запросов 1С.

Наша цель — получить информацию о компьютере с максимальным кодом из справочника "Компьютеры" и представить ее в виде таблицы с двумя колонками: "Характеристика" (например, "Модель", "ЧастотаПроцессора") и "Значение" (фактическое значение этих характеристик для выбранного компьютера).

Основные подходы к решению задачи

В языке запросов 1С отсутствует прямой оператор


UNPIVOT
, который позволяет "разворачивать" столбцы в строки, как это есть в некоторых других SQL-системах. Однако, мы можем достичь желаемого результата, комбинируя временные таблицы и оператор

ОБЪЕДИНИТЬ ВСЕ
.

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

Рассмотрим каждый шаг подробнее.

Шаг 1: Идентификация объекта с максимальным кодом

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

Начнем с того, что найдем максимальный код в справочнике


Компьютеры
. Для этого мы используем функцию

МАКСИМУМ
в подзапросе:


ВЫБРАТЬ МАКСИМУМ(Код) ИЗ Справочник.Компьютеры

Далее, мы используем этот результат для получения ссылки на нужный компьютер:


ВЫБРАТЬ
    Ссылка
ИЗ
    Справочник.Компьютеры
ГДЕ
    Код В
        (ВЫБРАТЬ
            МАКСИМУМ(Код)
        ИЗ
            Справочник.Компьютеры)

Таким образом, мы получили ссылку на объект, характеристики которого нам предстоит вывести.

Шаг 2: Извлечение и сохранение характеристик целевого объекта во временную таблицу

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

Мы выбираем все необходимые поля и помещаем их в новую временную таблицу. В нашем случае это будут Модель, ЧастотаПроцессора, ОбъемПамяти, РазмерДиска, Цена, СкоростьПривода.


ВЫБРАТЬ
    Модель,
    ЧастотаПроцессора,
    ОбъемПамяти,
    РазмерДиска,
    Цена,
    СкоростьПривода
ПОМЕСТИТЬ ВТ1
ИЗ
    Справочник.Компьютеры
ГДЕ
    Код В
        (ВЫБРАТЬ
            МАКСИМУМ(Код)
        ИЗ
            Справочник.Компьютеры)

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

  1. Получаем максимальный код и помещаем его во временную таблицу:
    
    ВЫБРАТЬ
        МАКСИМУМ(Компьютеры.Код) КАК Код
    ПОМЕСТИТЬ втМаксКодКомпьютера
    ИЗ
        Справочник.Компьютеры КАК Компьютеры
    ;
    
  2. Используем полученный код для выбора нужного компьютера и его характеристик:
    
    ВЫБРАТЬ
        Компьютеры.Модель КАК Модель,
        Компьютеры.ЧастотаПроцессора КАК ЧастотаПроцессора,
        Компьютеры.ОбъемПамяти КАК ОбъемПамяти,
        Компьютеры.РазмерДиска КАК РазмерДиска,
        Компьютеры.Цена КАК Цена,
        Компьютеры.СкоростьПривода КАК СкоростьПривода
    ПОМЕСТИТЬ втКомпьютерСМаксКодом
    ИЗ
        Справочник.Компьютеры КАК Компьютеры
            ВНУТРЕННЕЕ СОЕДИНЕНИЕ втМаксКодКомпьютера КАК втМаксКодКомпьютера
            ПО (втМаксКодКомпьютера.Код = Компьютеры.Код)
    ;
    

Оба варианта рабочие, и выбор зависит от предпочтений в структурировании запроса.

Шаг 3: Преобразование столбцов в строки с помощью ОБЪЕДИНИТЬ ВСЕ

Теперь, когда у нас есть временная таблица с характеристиками одного компьютера, нам нужно "развернуть" их. Это означает, что каждая колонка (например, "Модель", "ЧастотаПроцессора") должна стать строкой в новом столбце "Характеристика", а ее значение должно попасть в столбец "Значение". Мы достигнем этого с помощью оператора


ОБЪЕДИНИТЬ ВСЕ
.

Для каждого поля, которое мы хотим вывести как характеристику, мы формируем отдельный блок


ВЫБРАТЬ
, где:

  1. Первый столбец будет строковым литералом, содержащим название характеристики (например,
    
    "Модель"
    
    ). Мы даем ему псевдоним
    
    Характеристика
    
    .
  2. Второй столбец будет ссылаться на соответствующее поле из нашей временной таблицы (например,
    
    втКомпьютерСМаксКодом.Модель
    
    ). Мы даем ему псевдоним
    
    Значение
    
    .

Все эти блоки


ВЫБРАТЬ
мы объединяем с помощью

ОБЪЕДИНИТЬ ВСЕ
. Оператор

ВСЕ
важен, так как он гарантирует, что все строки будут включены, даже если они окажутся дублирующимися (хотя в нашем случае дубликатов быть не должно, потому что это разные характеристики).

Вот как будет выглядеть финальный запрос, использующий временную таблицу


втКомпьютерСМаксКодом
из предыдущего шага:


ВЫБРАТЬ
    "Модель" КАК Характеристика,
    втКомпьютерСМаксКодом.Модель КАК Значение
ИЗ
    втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Частота процессора",
    втКомпьютерСМаксКодом.ЧастотаПроцессора
ИЗ
    втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Объем памяти",
    втКомпьютерСМаксКодом.ОбъемПамяти
ИЗ
    втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Размер диска",
    втКомпьютерСМаксКодом.РазмерДиска
ИЗ
    втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Цена",
    втКомпьютерСМаксКодом.Цена
ИЗ
    втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Скорость привода",
    втКомпьютерСМаксКодом.СкоростьПривода
ИЗ
    втКомпьютерСМаксКодом КАК втКомпьютерСМаксКодом

В результате выполнения этого запроса мы получим таблицу с двумя столбцами: "Характеристика" и "Значение", где каждая строка будет представлять одну из характеристик нашего компьютера.

Альтернативные подходы и важные нюансы

Динамическое формирование запроса для гибкости

Предложенное решение с


ОБЪЕДИНИТЬ ВСЕ
является эффективным и прямым, но оно имеет один недостаток: наименования характеристик (

"Модель"
,

"Частота процессора"
и т.д.) жестко "зашиты" в тексте запроса. Если структура справочника изменится (например, добавятся новые реквизиты или переименуются существующие), придется вручную менять текст запроса.

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


Метаданные
.

Например, чтобы получить список реквизитов справочника "Компьютеры", мы можем использовать следующий код в модуле 1С:


СписокРеквизитов = Метаданные.Справочники.Компьютеры.Реквизиты;
Для Каждого Реквизит Из СписокРеквизитов Цикл
    Сообщить("Имя реквизита: " + Реквизит.Имя + ", Синоним: " + Реквизит.Синоним);
КонецЦикла;

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


ВЫБРАТЬ
и

ОБЪЕДИНИТЬ ВСЕ
. Такой подход значительно повышает гибкость решения, так как запрос будет адаптироваться к изменениям в структуре данных без необходимости ручного изменения кода.

Ограничения подхода с ОБЪЕДИНИТЬ ВСЕ

Хотя метод с


ОБЪЕДИНИТЬ ВСЕ
является рабочим, он имеет свои минусы:

Тем не менее, в условиях отсутствия прямого оператора


UNPIVOT
в языке запросов 1С, этот способ остается одним из наиболее распространенных и понятных решений для транспонирования данных.

Другие методы: JSON

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


FOR JSON
в SQL Server, не существует, поэтому большая часть работы выполняется на стороне программного кода.

Общие рекомендации по работе с запросами в 1С

В дополнение к рассмотренному решению, хотим обратить ваше внимание на несколько общих рекомендаций, которые могут быть полезны при написании любых запросов в 1С:

Эффективное использование временных таблиц

Как уже упоминалось, временные таблицы (


ПОМЕСТИТЬ ВТ
) являются ключевым инструментом для структурирования сложных запросов. Они позволяют нам:

Приведение типов с помощью ВЫРАЗИТЬ

Функция


ВЫРАЗИТЬ
позволяет явно приводить типы данных в запросе. Это критически важно при работе с полями составного типа (когда поле может хранить значения разных типов) или при сравнении строковых полей неограниченной длины. Неявное приведение типов может привести к ошибкам в запросе, некорректным результатам или неоптимальной работе. Например,

ВЫРАЗИТЬ(ПолеСоставногоТипа КАК СПРАВОЧНИК.Номенклатура)
или

ВЫРАЗИТЬ(СтроковоеПолеНеограниченнойДлины КАК СТРОКА(100))
.

Разыменование ссылочных полей

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


ВНУТРЕННЕЕ СОЕДИНЕНИЕ
со справочником "Номенклатура" для получения наименования поставщика, мы можем просто написать

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

Отладка запросов в Консоли запросов

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

Заключение

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


ОБЪЕДИНИТЬ ВСЕ
. Несмотря на некоторую многословность, этот подход является надежным и понятным. Мы также обсудили важность динамического формирования запросов для повышения гибкости и рассмотрели общие рекомендации по работе с запросами в 1С, которые помогут вам писать более производительный, читаемый и поддерживаемый код.

← На главную