При разработке отчетов или динамических списков программисты часто сталкиваются с необходимостью сформировать красивое текстовое представление документа или записи непосредственно в запросе. Типичная задача: объединить статичный текст, номер документа и его дату. Однако простая попытка использовать оператор + часто приводит к ошибке «Неверные параметры "+"». Разберем детально, почему это происходит и какими способами можно решить эту задачу в современных реалиях платформы «1С:Предприятие».
Прежде всего, давайте проанализируем ситуацию, описанную в теме. Автор пытается выполнить следующую операцию:
ВЫБОР
КОГДА КОЛИЧЕСТВО(ВложенныйЗапрос.СчетФактура) >= 1
ТОГДА ВложенныйЗапрос.СчетФактура
ИНАЧЕ "Счет-фактура (УПД) №" + ПриобретениеТоваровУслуг.НомерВходящегоДокумента + " от " + ПриобретениеТоваровУслуг.ДатаВходящегоДокумента
КОНЕЦ
Проблема здесь заключается в том, что язык запросов 1С — это строго типизированный механизм, который транслирует команды в SQL-запрос. В классическом языке запросов 1С оператор + предназначен исключительно для работы с числами (сложение) или строками (конкатенация). Но он не умеет автоматически приводить дату или ссылку к строке.
Когда вы пытаетесь прибавить к строке " от " поле с типом Дата, система выдает ошибку, так как не знает, в каком формате эту дату нужно превратить в текст. Аналогичная проблема возникнет, если попытаться прибавить число или ссылку на объект (документ или справочник).
Если вы работаете на платформе версии 8.3.20 и выше, нам доступно штатное решение. Разработчики добавили в язык запросов функцию СТРОКА(), которая позволяет преобразовывать примитивные типы данных прямо в теле запроса.
Рассмотрим, как изменится наш код с использованием этой функции:
"Счет-фактура (УПД) №" + ПриобретениеТоваровУслуг.НомерВходящегоДокумента + " от " + СТРОКА(ПриобретениеТоваровУслуг.ДатаВходящегоДокумента)
Важные нюансы использования функции СТРОКА():
Число, Дата, Булево.Наименование или использовать другие методы.Если ваша задача — вывести данные в отчет, то лучше всего перенести логику формирования строки из запроса в Вычисляемые поля СКД. Это наиболее гибкий и «правильный» метод с точки зрения архитектуры 1С.
Разберем по шагам, как это сделать:
НомерВходящегоДокумента и ДатаВходящегоДокумента как отдельные поля.ПредставлениеДокумента."Счет-фактура (УПД) №" + НомерВходящегоДокумента + " от " + Формат(ДатаВходящегоДокумента, "ДФ=dd.MM.yyyy").В чем преимущество этого метода? СКД при обработке выражений использует не язык запросов, а язык выражений СКД, который гораздо ближе к объектному языку 1С. Здесь нам доступна функция Формат(), которая позволяет задать любой вид даты без сложных манипуляций в запросе.
Если запрос выполняется программно в коде модуля, мы можем применить метод постобработки. Выясним, почему это иногда эффективнее: SQL-сервер гораздо быстрее справляется с выборкой чистых данных, чем с операциями манипуляции строками.
Проанализируем пример кода:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Номер, Дата ИЗ Документ.ПриобретениеТоваровУслуг";
Результат = Запрос.Выполнить().Выгрузить();
Для Каждого СтрокаТЗ Из Результат Цикл
СтрокаТЗ.Представление = СтрШаблон("Счет-фактура №%1 от %2", СтрокаТЗ.Номер, Формат(СтрокаТЗ.Дата, "ДЛФ=D"));
КонецЦикла;
Здесь мы используем функцию СтрШаблон(), которая делает код читаемым и избавляет от нагромождения плюсов. Этот метод идеален, если данных не миллионы строк, так как цикл обхода коллекции в памяти 1С-сервера работает очень быстро.
Бывают ситуации, когда мы ограничены старой версией платформы (ниже 8.3.20) и не можем использовать СКД (например, в динамическом списке). В этом случае программисты используют сложную конструкцию из функций ДЕНЬ(), МЕСЯЦ() и ГОД() в сочетании с ВЫБОР.
Посмотрим на пример формирования дня даты в строковом виде:
ВЫБОР
КОГДА ДЕНЬ(ДатаДок) = 1 ТОГДА "01"
КОГДА ДЕНЬ(ДатаДок) = 2 ТОГДА "02"
...
ИНАЧЕ СТРОКА(ДЕНЬ(ДатаДок)) // Если версия позволяет хотя бы это
КОНЕЦ + "." + ...
Внимание: Мы крайне не рекомендуем использовать этот метод, так как текст запроса раздувается до огромных размеров, его становится невозможно поддерживать, а производительность значительно падает. Если вы столкнулись с такой необходимостью — это верный признак того, что логику нужно выносить в СКД или программный код.
Проанализируем еще один важный технический момент. При сложении строк в запросе (конкатенации) существует ограничение: результат не может превышать 1024 символа.
Если вы попытаетесь сложить несколько длинных полей (например, комментарии к документу или длинные наименования номенклатуры), и итоговая строка окажется длиннее, данные будут обрезаны. В некоторых случаях это может привести к непредсказуемому поведению отчета. Всегда контролируйте длину складываемых полей с помощью функции ПОДСТРОКА(), если есть риск превышения лимита.
Для решения проблемы с конкатенацией в запросе придерживайтесь следующего алгоритма:
СТРОКА().Формат().Представление() ссылки — помните, что его нельзя складывать с другими строками внутри запроса через +, так как оно формируется уже на стороне клиента.