Как использовать функцию МАКСИМУМ для строковых полей в запросах 1С и избежать ошибки параметров

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

При разработке сложных отчетов или обработок на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью «развернуть» вертикальную таблицу в горизонтальную (транспонирование). Типичный пример — получение контактной информации (адрес, телефон, email) в одну строку для каждого контрагента или физического лица. Однако попытка использовать агрегатную функцию МАКСИМУМ в сочетании с конструкцией ВЫБОР КОГДА часто приводит к ошибке: «Неверные параметры МАКСИМУМ». Разберем подробно, почему это происходит и как правильно решить эту задачу.

Почему возникает ошибка при использовании МАКСИМУМ

Давайте проанализируем ситуацию. Основная причина ошибки кроется в типах данных, которыми оперирует система управления базами данных (СУБД). В конфигурациях 1С (особенно в подсистеме контактной информации) поле Представление часто имеет тип «Строка неограниченной длины». На уровне базы данных такие поля хранятся как объекты NTEXT, BLOB или NVARCHAR(MAX).

Важный технический нюанс: СУБД (будь то Microsoft SQL Server или PostgreSQL) не умеет выполнять операции группировки (GROUP BY) или агрегации (MAX, MIN) над полями неограниченной длины. Когда платформа 1С пытается транслировать ваш запрос в SQL-код, она обнаруживает это ограничение и выдает ошибку еще на этапе проверки запроса.

Решение №1: Использование функции ВЫРАЗИТЬ

Самый быстрый способ заставить запрос работать — это явно ограничить длину строки. Рассмотрим, как это сделать правильно. Если мы приведем строку неограниченной длины к строке фиксированной длины, платформа позволит СУБД вычислить максимум.

Разберем пример кода, который решает проблему:


ВЫБРАТЬ
    Анкета.Ссылка.ФизЛицо КАК ФизЛицо,
    МАКСИМУМ(ВЫРАЗИТЬ(ВЫБОР
                КОГДА Анкета.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АбитуриентАдресПроживания)
                    ТОГДА Анкета.Представление
                ИНАЧЕ ""
            КОНЕЦ КАК СТРОКА(500))) КАК АдресПроживания,
    МАКСИМУМ(ВЫРАЗИТЬ(ВЫБОР
                КОГДА Анкета.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АбитуриентТелефон)
                    ТОГДА Анкета.Представление
                ИНАЧЕ ""
            КОНЕЦ КАК СТРОКА(100))) КАК Телефон
ИЗ
    Документ.АнкетаАбитуриента.КонтактнаяИнформация КАК Анкета
СГРУППИРОВАТЬ ПО
    Анкета.Ссылка.ФизЛицо

Что мы здесь сделали:

  1. Мы обернули конструкцию ВЫБОР в функцию ВЫРАЗИТЬ(... КАК СТРОКА(N)).
  2. Для адреса мы выбрали длину 500 символов, а для телефона — 100. Этого достаточно для большинства задач.
  3. Теперь функция МАКСИМУМ получает на вход строку фиксированной длины, и запрос успешно выполняется.

Нюансы работы с полем Представление

Проанализируем еще одну тонкость. В языке запросов 1С существует системное поле Представление (виртуальное поле ссылки). С ним нельзя совершать никакие действия в запросе: его нельзя помещать в ГДЕ, СГРУППИРОВАТЬ ПО или использовать в агрегатных функциях. Оно предназначено только для вывода в результат запроса.

Однако в случае с контактной информацией (как в конфигурации 1С:Колледж или в БСП), Представление — это реальный реквизит табличной части или регистра. Несмотря на то что это физическое поле, ограничение на неограниченную длину все равно сохраняется. Поэтому использование ВЫРАЗИТЬ остается обязательным.

Решение №2: Метод левых соединений (Pivot без агрегации)

Хотя первый метод рабочий, его часто называют «почерком восьмиклассника» из-за громоздкости и потенциальных проблем с производительностью на очень больших объемах данных. Разберем более профессиональный подход — последовательное соединение таблиц.

Посмотрим на пример архитектурно правильного запроса:


ВЫБРАТЬ
    ФизЛица.Ссылка КАК ФизЛицо,
    КИ_Адрес.Представление КАК АдресПроживания,
    КИ_Телефон.Представление КАК Телефон
ИЗ
    Справочник.ФизическиеЛица КАК ФизЛица
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.АнкетаАбитуриента.КонтактнаяИнформация КАК КИ_Адрес
        ПО ФизЛица.Ссылка = КИ_Адрес.Ссылка.ФизЛицо
            И КИ_Адрес.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АбитуриентАдресПроживания)
            
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.АнкетаАбитуриента.КонтактнаяИнформация КАК КИ_Телефон
        ПО ФизЛица.Ссылка = КИ_Телефон.Ссылка.ФизЛицо
            И КИ_Телефон.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АбитуриентТелефон)

Преимущества этого метода:

Ошибки при группировке

Если вы все же решили использовать метод с МАКСИМУМ, помните о правилах группировки. Любое поле, которое вы выбираете в списке ВЫБРАТЬ и к которому не применяется агрегатная функция (СУММА, МАКСИМУМ, КОЛИЧЕСТВО), обязательно должно быть перечислено в секции СГРУППИРОВАТЬ ПО.

Рассмотрим типичную ошибку:


ВЫБРАТЬ
    Анкета.Ссылка.ФизЛицо КАК ФизЛицо,
    Анкета.Вид КАК Вид, // ОШИБКА: Это поле не в группировке и без функции
    МАКСИМУМ(ВЫРАЗИТЬ(Анкета.Представление КАК СТРОКА(100)))
...

Выясним причину: СУБД не знает, какое именно значение поля Вид показать, если для одного ФизЛица их несколько, а функции для выбора конкретного значения не указано.

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

Когда мы используем ВЫРАЗИТЬ(... КАК СТРОКА(N)), важно правильно выбрать N:

Итоги

Мы проанализировали ситуацию и выяснили, что проблема с функцией МАКСИМУМ в запросах 1С почти всегда связана с типом данных «Строка неограниченной длины». Для решения можно либо использовать ВЫРАЗИТЬ, превращая данные в фиксированную строку, либо перестроить логику запроса на левые соединения. Второй вариант предпочтительнее для стабильной работы системы и сохранения целостности длинных данных.

← На главную