При разработке сложных отчетов или обработок на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью «развернуть» вертикальную таблицу в горизонтальную (транспонирование). Типичный пример — получение контактной информации (адрес, телефон, email) в одну строку для каждого контрагента или физического лица. Однако попытка использовать агрегатную функцию МАКСИМУМ в сочетании с конструкцией ВЫБОР КОГДА часто приводит к ошибке: «Неверные параметры МАКСИМУМ». Разберем подробно, почему это происходит и как правильно решить эту задачу.
Давайте проанализируем ситуацию. Основная причина ошибки кроется в типах данных, которыми оперирует система управления базами данных (СУБД). В конфигурациях 1С (особенно в подсистеме контактной информации) поле Представление часто имеет тип «Строка неограниченной длины». На уровне базы данных такие поля хранятся как объекты NTEXT, BLOB или NVARCHAR(MAX).
Важный технический нюанс: СУБД (будь то Microsoft SQL Server или PostgreSQL) не умеет выполнять операции группировки (GROUP BY) или агрегации (MAX, MIN) над полями неограниченной длины. Когда платформа 1С пытается транслировать ваш запрос в SQL-код, она обнаруживает это ограничение и выдает ошибку еще на этапе проверки запроса.
Самый быстрый способ заставить запрос работать — это явно ограничить длину строки. Рассмотрим, как это сделать правильно. Если мы приведем строку неограниченной длины к строке фиксированной длины, платформа позволит СУБД вычислить максимум.
Разберем пример кода, который решает проблему:
ВЫБРАТЬ
Анкета.Ссылка.ФизЛицо КАК ФизЛицо,
МАКСИМУМ(ВЫРАЗИТЬ(ВЫБОР
КОГДА Анкета.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АбитуриентАдресПроживания)
ТОГДА Анкета.Представление
ИНАЧЕ ""
КОНЕЦ КАК СТРОКА(500))) КАК АдресПроживания,
МАКСИМУМ(ВЫРАЗИТЬ(ВЫБОР
КОГДА Анкета.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АбитуриентТелефон)
ТОГДА Анкета.Представление
ИНАЧЕ ""
КОНЕЦ КАК СТРОКА(100))) КАК Телефон
ИЗ
Документ.АнкетаАбитуриента.КонтактнаяИнформация КАК Анкета
СГРУППИРОВАТЬ ПО
Анкета.Ссылка.ФизЛицо
Что мы здесь сделали:
ВЫБОР в функцию ВЫРАЗИТЬ(... КАК СТРОКА(N)).МАКСИМУМ получает на вход строку фиксированной длины, и запрос успешно выполняется.Проанализируем еще одну тонкость. В языке запросов 1С существует системное поле Представление (виртуальное поле ссылки). С ним нельзя совершать никакие действия в запросе: его нельзя помещать в ГДЕ, СГРУППИРОВАТЬ ПО или использовать в агрегатных функциях. Оно предназначено только для вывода в результат запроса.
Однако в случае с контактной информацией (как в конфигурации 1С:Колледж или в БСП), Представление — это реальный реквизит табличной части или регистра. Несмотря на то что это физическое поле, ограничение на неограниченную длину все равно сохраняется. Поэтому использование ВЫРАЗИТЬ остается обязательным.
Хотя первый метод рабочий, его часто называют «почерком восьмиклассника» из-за громоздкости и потенциальных проблем с производительностью на очень больших объемах данных. Разберем более профессиональный подход — последовательное соединение таблиц.
Посмотрим на пример архитектурно правильного запроса:
ВЫБРАТЬ
ФизЛица.Ссылка КАК ФизЛицо,
КИ_Адрес.Представление КАК АдресПроживания,
КИ_Телефон.Представление КАК Телефон
ИЗ
Справочник.ФизическиеЛица КАК ФизЛица
ЛЕВОЕ СОЕДИНЕНИЕ Документ.АнкетаАбитуриента.КонтактнаяИнформация КАК КИ_Адрес
ПО ФизЛица.Ссылка = КИ_Адрес.Ссылка.ФизЛицо
И КИ_Адрес.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АбитуриентАдресПроживания)
ЛЕВОЕ СОЕДИНЕНИЕ Документ.АнкетаАбитуриента.КонтактнаяИнформация КАК КИ_Телефон
ПО ФизЛица.Ссылка = КИ_Телефон.Ссылка.ФизЛицо
И КИ_Телефон.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АбитуриентТелефон)
Преимущества этого метода:
ВЫРАЗИТЬ, а значит, адрес любой длины (даже более 1000 символов) попадет в отчет целиком.Если вы все же решили использовать метод с МАКСИМУМ, помните о правилах группировки. Любое поле, которое вы выбираете в списке ВЫБРАТЬ и к которому не применяется агрегатная функция (СУММА, МАКСИМУМ, КОЛИЧЕСТВО), обязательно должно быть перечислено в секции СГРУППИРОВАТЬ ПО.
Рассмотрим типичную ошибку:
ВЫБРАТЬ
Анкета.Ссылка.ФизЛицо КАК ФизЛицо,
Анкета.Вид КАК Вид, // ОШИБКА: Это поле не в группировке и без функции
МАКСИМУМ(ВЫРАЗИТЬ(Анкета.Представление КАК СТРОКА(100)))
...
Выясним причину: СУБД не знает, какое именно значение поля Вид показать, если для одного ФизЛица их несколько, а функции для выбора конкретного значения не указано.
Когда мы используем ВЫРАЗИТЬ(... КАК СТРОКА(N)), важно правильно выбрать N:
СТРОКА(20) или СТРОКА(50).СТРОКА(500), так как адреса с указанием муниципальных округов, строений и литер могут быть весьма длинными.СТРОКА(100).Мы проанализировали ситуацию и выяснили, что проблема с функцией МАКСИМУМ в запросах 1С почти всегда связана с типом данных «Строка неограниченной длины». Для решения можно либо использовать ВЫРАЗИТЬ, превращая данные в фиксированную строку, либо перестроить логику запроса на левые соединения. Второй вариант предпочтительнее для стабильной работы системы и сохранения целостности длинных данных.