Как в запросе 1С соединить текст и числовое значение (параметр)

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

В процессе разработки на платформе 1С программисты часто сталкиваются с необходимостью сформировать красивое текстовое сообщение непосредственно в тексте запроса, объединив статичный текст и значение числового параметра или поля. Типичный пример: "Осталось 5 дней", где число 5 — это динамический параметр. Однако при попытке написать в запросе "Текст " + &Число система выдает ошибку "Неверные параметры '+'". Разберем подробно, почему это происходит и какими способами можно решить эту задачу.

Почему возникает ошибка при конкатенации в запросе?

Язык запросов 1С является строго типизированным. Оператор + (сложение) в нем перегружен: он может либо складывать числа, либо соединять строки (конкатенация). Однако платформа не умеет выполнять неявное приведение типов. Если один операнд — строка, а второй — число, запрос не знает, что с ними делать, и аварийно завершается.

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

Рассмотрим несколько эффективных подходов к решению этой проблемы.

Решение 1: Передача двух параметров

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

Разберем этот метод на примере кода:


КоличествоДней = 42;

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ВЫБОР
    |        КОГДА РАЗНОСТЬДАТ(Итог.ДатаПоследнегоОтела, &КонецПериода, ДЕНЬ) < &МинимальноеЧисло
    |            ТОГДА &ТекстСообщения
    |        ИНАЧЕ """"
    |    КОНЕЦ КАК Сообщение";

Запрос.УстановитьПараметр("МинимальноеЧисло", КоличествоДней);
Запрос.УстановитьПараметр("ТекстСообщения", "Не прошло " + Строка(КоличествоДней) + " дня с момента отела");
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);

В данном случае мы выполняем преобразование типа Число в Строка средствами встроенного языка 1С (функция Строка()), что полностью снимает нагрузку с движка СУБД и исключает ошибки типизации в запросе.

Решение 2: Постобработка результата запроса

Часто текст сообщения зависит от данных, полученных из базы (например, от значения поля в конкретной строке). В этом случае сформировать текст заранее невозможно. Проанализируем ситуацию: запрос должен вернуть "сырые" данные, а мы оформим их при обходе выборки.

Посмотрим на пример реализации:


// В запросе выбираем только число
// ... ВЫБОР КОГДА ... ТОГДА РАЗНОСТЬДАТ(...) ИНАЧЕ 0 КОНЕЦ КАК ДнейПрошло ...

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Если Выборка.ДнейПрошло < 42 Тогда
        ТекстДляВывода = "Внимание: прошло всего " + Выборка.ДнейПрошло + " дн.";
        // Выводим ТекстДляВывода в область макета или ячейку формы
    КонецЕсли;
КонецЦикла;

Этот метод считается наиболее правильным с точки зрения архитектуры, так как он разделяет бизнес-логику (получение данных) и логику представления (формирование текстов для пользователя).

Решение 3: Использование возможностей СКД (Системы компоновки данных)

Если вы разрабатываете отчет на базе СКД, вам не нужно идти на ухищрения в самом запросе. Механизмы компоновки гораздо гибче в плане работы с типами данных. Выясним, как это настроить:

  1. Перейдите на закладку "Вычисляемые поля".
  2. Добавьте новое поле (например, СообщениеОбОтеле).
  3. В колонке "Выражение" напишите: "Не прошло " + Строка(Параметры.МинимальноеКоличествоДней) + " дня".

В языке выражений СКД функция Строка() работает корректно, и вы можете свободно выполнять конкатенацию. Также в СКД можно использовать поле "Выражение представления" на закладке "Наборы данных". Если там написать "Дней: " + Формат(ИмяПоля, "ЧДЦ=0"), то в отчет будет выводиться текст, хотя само поле в памяти останется числом, доступным для суммирования.

Решение 4: Использование шаблонов в макетах

При формировании печатных форм (через ТабличныйДокумент) удобнее всего использовать механизм шаблонов. Это избавит вас от написания лишнего кода преобразования.

Выполним следующие шаги:

  1. В ячейке макета установите свойство "Заполнение" в значение "Шаблон".
  2. В тексте ячейки напишите: Не прошло [Дней] дня с момента отела.
  3. В коде при заполнении области просто передайте число: Область.Параметры.Дней = 42;.

Платформа автоматически сконвертирует число в строку и подставит его в квадратные скобки внутри фразы.

Важное замечание о склонении числительных

Проанализируем тонкий момент: когда мы пишем статичный текст "дня", мы привязываемся к конкретному числу. Если ваш параметр изменится на 5, фраза "5 дня" будет звучать некорректно (правильно — "5 дней").

Для решения этой задачи в 1С рекомендуется использовать функцию ПредставлениеЧисла() или форматные строки, но лучше всего — формировать такие сообщения в коде, используя простую функцию склонения в зависимости от остатка от деления числа на 10 и 100. Это еще один аргумент в пользу того, чтобы не заниматься конкатенацией внутри запроса.

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

← На главную