При разработке отчетов в системе компоновки данных (СКД) часто возникает задача объединения нескольких полей в одну строку. Типичный пример — формирование поля с паспортными данными, где необходимо собрать серию, номер, информацию о том, кем выдан документ, и дату его выдачи. Однако при простом сложении этих полей разработчики часто сталкиваются с ошибкой «Неверные параметры "+"». В этой статье мы подробно разберем, почему возникает эта ошибка и какими способами можно красиво и корректно вывести паспортные данные в одну ячейку.
Давайте проанализируем ситуацию. Основная причина ошибки заключается в строгой типизации данных. В СКД, как и в языке запросов, нельзя напрямую складывать значения разных типов. Если поля ФизЛицоДокументСерия и ФизЛицоДокументНомер обычно имеют строковый тип, то поле ФизЛицоДокументДатаВыдачи имеет тип Дата. Попытка прибавить дату к строке с помощью оператора + приводит к тому, что система не может определить, какое действие нужно выполнить, и выдает ошибку компоновки.
Кроме того, если одно из полей содержит значение NULL (например, у сотрудника не заполнена серия паспорта), результат всего сложения будет NULL, и в отчете отобразится пустая ячейка, даже если остальные данные заполнены.
Рассмотрим самый распространенный способ решения проблемы через вкладку «Вычисляемые поля» в схеме компоновки данных. Для того чтобы объединение заработало, нам необходимо привести дату к строковому виду и обезопасить выражение от пустых значений.
Шаг за шагом разберем правильное выражение:
ФОРМАТ(Дата, "ДФ = 'дд.ММ.гггг'"). Это превратит дату в строку нужного нам формата.ЕСТЬNULL(Поле, ""). Важно: во втором параметре нужно указывать именно пустую строку "", а не ЛОЖЬ или 0, чтобы не получить лишний текст в отчете.Итоговое выражение для вычисляемого поля будет выглядеть следующим образом:
ЕСТЬNULL(ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументСерия, "") + " " +
ЕСТЬNULL(ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументНомер, "") + ", выдан " +
ЕСТЬNULL(ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументКемВыдан, "") + " от " +
ФОРМАТ(ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументДатаВыдачи, "ДФ = 'дд.ММ.гггг'")
Важный нюанс: Если вы используете конфигурацию УПП 1.3 или ЗУП 2.5, убедитесь, что пути к полям соответствуют вашему набору данных. В примере выше используется обращение через точку, которое доступно, если в запросе выбрана соответствующая таблица или ссылка.
Проанализируем ситуацию, когда некоторые данные могут отсутствовать. Если мы просто склеиваем строки через запятую, а серия паспорта пустая, мы получим некрасивый результат: ", 123456, выдан..." (лишняя запятая в начале). Чтобы избежать этого, в СКД лучше использовать вкладку «Макеты».
Рассмотрим алгоритм настройки через макет поля:
[Серия] [Номер], выдан [КемВыдан] [ДатаВыдачи].Преимущество этого метода в том, что СКД сама управляет представлением параметров. Если параметр пустой, система может автоматически скрыть разделители, если настроить оформление ячейки соответствующим образом.
Если мы хотим остаться в рамках вычисляемых полей, но при этом сделать строку «умной» (чтобы запятые не появлялись там, где нет данных), мы можем использовать условные конструкции. Посмотрим на пример более сложного, но качественного выражения:
ВЫБОР КОГДА ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументСерия ЕСТЬ NULL ТОГДА "" ИНАЧЕ ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументСерия + " " КОНЕЦ +
ВЫБОР КОГДА ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументНомер ЕСТЬ NULL ТОГДА "" ИНАЧЕ ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументНомер КОНЕЦ +
", выдан " + ЕСТЬNULL(ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументКемВыдан, "") + " " +
ФОРМАТ(ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументДатаВыдачи, "ДФ = 'дд.ММ.гггг'")
Такой подход позволяет программно управлять каждым пробелом и знаком препинания в итоговой строке.
Выясним, как упростить задачу программиста, используя возможности типовых конфигураций (таких как УПП, ЗУП или ERP). В 1С часто существуют общие модули, в которых уже написаны функции для формирования представлений документов.
Например, если в общем модуле ОбщегоНазначения есть функция, возвращающая строку паспорта, мы можем вызвать ее прямо в выражении СКД:
ОбщегоНазначения.СформироватьПредставлениеДокумента(
ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументСерия,
ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументНомер,
ДанныеОФизЛице.ПаспортныеДанные.ФизЛицоДокументДатаВыдачи
)
Важно: Чтобы этот метод работал, у общего модуля в конфигураторе должны быть установлены флаги «Клиент», «Сервер» и «Внешнее соединение». Это самый правильный путь с точки зрения архитектуры, так как он обеспечивает единообразие данных во всех отчетах системы.
Проанализируем влияние таких преобразований на скорость работы отчета. Выполнение сложных манипуляций со строками в вычисляемых полях СКД на больших выборках (десятки тысяч строк) может замедлить формирование отчета. Если вы заметили падение производительности, рассмотрите возможность подготовки готовой строки непосредственно в тексте запроса.
Хотя в языке запросов нет функции ФОРМАТ, там можно использовать операторы ПОДСТРОКА для выделения дня, месяца и года из даты или использовать временные таблицы для предварительной сборки данных. Однако для большинства повседневных задач метод с ФОРМАТ() в вычисляемых полях является оптимальным балансом между скоростью разработки и результатом.
Таким образом, мы рассмотрели несколько способов вывода паспортных данных. Самым простым и быстрым является использование функции ФОРМАТ вместе с ЕСТЬNULL, а наиболее профессиональным — использование функций общих модулей или макетов СКД.