Как получить число из строки, даты, булева и составного поля в отчёте на СКД

· 10 мин

Содержание

В запросе набора данных СКД значение переводят в число конструкцией ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15, 2)). Она работает для чисел (меняет разрядность и округляет) и для полей составного типа (оставляет только числовые значения, остальные превращает в NULL). Строку так в число не превратить: язык запросов 1С это преобразование не поддерживает, и для строк нужен другой путь.

Дата и булево тоже не выражаются через ВЫРАЗИТЬ напрямую. Для них есть свои приёмы: ГОД(), РАЗНОСТЬДАТ(), ВЫБОР КОГДА … ТОГДА 1 ИНАЧЕ 0 КОНЕЦ. Ниже каждый случай с готовым кодом для запроса и для вычисляемого поля компоновки.

Какие средства преобразования в число есть в СКД

В отчёте на системе компоновки данных выражения живут в двух местах, и у каждого свой язык.

  • 🧾 Запрос набора данных. Язык запросов 1С: ВЫРАЗИТЬ, ВЫБОР, ЕСТЬNULL, ТИПЗНАЧЕНИЯ, функции дат. Выполняется на стороне СУБД, быстро.
  • 🧮 Вычисляемые поля и ресурсы. Язык выражений СКД: похож на язык запросов, но свой. В нём есть функция Выразить(Выражение, "Тип"), ЕстьNull(), ВЫБОР, агрегатные функции и вызов экспортных функций общих модулей.
  • 🎨 Оформление поля. Параметр Формат меняет только вид числа на экране. Тип значения он не меняет.

Сводная таблица — что чем решается:

Исходное значениеВ запросеВ вычисляемом поле СКД
Число другой разрядностиВЫРАЗИТЬ(Х КАК ЧИСЛО(15, 2))Выразить(Х, "Число(15, 2)")
Поле составного типаВЫРАЗИТЬ(Х КАК ЧИСЛО(15, 2))Выразить(Х, "Число")
БулевоВЫБОР КОГДА Х ТОГДА 1 ИНАЧЕ 0 КОНЕЦто же через Выбор
ДатаГОД(Х) * 10000 + МЕСЯЦ(Х) * 100 + ДЕНЬ(Х) или РАЗНОСТЬДАТфункции Год(), Месяц(), РазностьДат()
Строка с цифраминет штатного способафункция общего модуля
NULLЕСТЬNULL(Х, 0)ЕстьNull(Х, 0)

Если число можно получить в запросе — получайте его там. Вычисляемое поле считается по каждой строке уже после выборки, а запрос отдаёт готовый результат.

ВЫРАЗИТЬ КАК ЧИСЛО в запросе: синтаксис и разрядность

Общая запись:

ВЫРАЗИТЬ(<Выражение> КАК ЧИСЛО(<Длина>, <Точность>))
  • Длина — сколько цифр всего, вместе с дробной частью.
  • Точность — сколько из них после запятой.

ЧИСЛО(15, 2) вмещает 13 цифр целой части и 2 знака после запятой. Это привычная разрядность денежных реквизитов. Для количества в типовых конфигурациях чаще используют ЧИСЛО(15, 3).

Округление результата деления

Частая задача в отчётах — цена или процент, посчитанные делением. Результат деления в запросе приходит с длинным хвостом знаков. Ограничьте его:

ВЫБРАТЬ
	Продажи.Номенклатура,
	ВЫРАЗИТЬ(Продажи.Сумма / Продажи.Количество КАК ЧИСЛО(15, 2)) КАК СредняяЦена
ИЗ
	ВременнаяТаблицаПродаж КАК Продажи
ГДЕ
	Продажи.Количество <> 0

При уменьшении точности ВЫРАЗИТЬ округляет по арифметическим правилам: 10,456 превратится в 10,46, а 10,454 — в 10,45.

Целое число и отбрасывание дробной части

ВЫРАЗИТЬ(Х КАК ЧИСЛО(15, 0)) даёт округление до целого, а не отбрасывание. Из 7,6 получится 8. Если нужна именно целая часть положительного числа, вычтите 0,5 перед округлением:

ВЫРАЗИТЬ(Остатки.Количество - 0.5 КАК ЧИСЛО(15, 0)) КАК ЦелыхУпаковок

Для 7,6 это 7,1 → 7, для 7,0 это 6,5 → 7 (половина округляется вверх), для 7,4 это 6,9 → 7. Для отрицательных чисел приём не годится: там нужна отдельная ветка ВЫБОР.

Длину задавайте с запасом. Если значение не помещается в указанную разрядность, запрос завершится ошибкой, причём на реальных данных, а не на тестовой базе с маленькими суммами.

Строка в число: почему ВЫРАЗИТЬ не помогает и что делать

Запись ВЫРАЗИТЬ(Комментарий КАК ЧИСЛО(10, 0)) для строкового поля не сработает. Язык запросов разрешает ВЫРАЗИТЬ для строк только в сторону строки другой длины: ВЫРАЗИТЬ(Комментарий КАК СТРОКА(100)). Это нужно, чтобы сравнивать и группировать строки неограниченной длины, но числа не даёт.

Рабочих путей три.

Путь 1. Функция общего модуля в вычисляемом поле

Самый надёжный вариант. Создайте общий модуль с флажком «Сервер», например ПреобразованиеТиповСервер, и добавьте экспортную функцию:

Функция СтрокуВЧисло(Знач Значение, ПоУмолчанию = 0) Экспорт
	
	Если ТипЗнч(Значение) = Тип("Число") Тогда
		Возврат Значение;
	КонецЕсли;
	
	Если ТипЗнч(Значение) <> Тип("Строка") Тогда
		Возврат ПоУмолчанию;
	КонецЕсли;
	
	Текст = СокрЛП(Значение);
	Текст = СтрЗаменить(Текст, " ", "");
	Текст = СтрЗаменить(Текст, Символы.НПП, "");
	Текст = СтрЗаменить(Текст, ",", ".");
	
	Если Текст = "" Тогда
		Возврат ПоУмолчанию;
	КонецЕсли;
	
	Попытка
		Возврат Число(Текст);
	Исключение
		Возврат ПоУмолчанию;
	КонецПопытки;
	
КонецФункции

Затем на закладке «Вычисляемые поля» схемы компоновки добавьте поле, например ЧислоИзКомментария, с выражением:

ПреобразованиеТиповСервер.СтрокуВЧисло(Комментарий, 0)

В колонке «Тип значения» поставьте Число. Тогда по полю будут доступны отбор «больше/меньше» и суммирование в ресурсах.

Что делает функция и зачем:

  1. Пропускает готовые числа без изменений — пригодится для полей составного типа.
  2. Убирает пробелы и неразрывные пробелы. Они приходят из Excel и из чисел, вставленных из документов: «1 250».
  3. Меняет запятую на точку, чтобы «12,5» и «12.5» разбирались одинаково.
  4. Ловит исключение. Одна строка «б/н» в выборке иначе обрушит весь отчёт.

Путь 2. Разбор по символам в запросе

Годится только для коротких кодов фиксированной длины, например двухзначного номера склада в строковом коде. Каждую позицию вырезают ПОДСТРОКА и переводят в цифру через ВЫБОР:

ВЫБОР ПОДСТРОКА(Склады.Код, 1, 1)
	КОГДА "1" ТОГДА 10 КОГДА "2" ТОГДА 20 КОГДА "3" ТОГДА 30
	КОГДА "4" ТОГДА 40 КОГДА "5" ТОГДА 50 КОГДА "6" ТОГДА 60
	КОГДА "7" ТОГДА 70 КОГДА "8" ТОГДА 80 КОГДА "9" ТОГДА 90
	ИНАЧЕ 0
КОНЕЦ

К этому выражению прибавляют такой же ВЫБОР по второму символу с весами 1–9. Для трёх и более символов запрос разрастается, и лучше вернуться к пути 1.

Путь 3. Хранить число числом

Если строка с числом нужна в отчётах постоянно, правильнее завести реквизит типа Число и заполнять его при записи объекта. Отчёт тогда берёт готовое значение, и никаких преобразований не нужно.

Для сортировки строковых кодов «по числу» иногда хватает выравнивания: коды «2» и «10» сортируются правильно, если хранить их как «002» и «010».

Дата и булево как число в отчёте компоновки

Булево → 1 или 0

Типичный случай — посчитать, сколько документов в выборке проведено или помечено на удаление. Флаг переводится в число через ВЫБОР:

ВЫБОР
	КОГДА Документ.Проведен
		ТОГДА 1
	ИНАЧЕ 0
КОНЕЦ КАК ПризнакПроведен

Дальше на закладке «Ресурсы» ставите для ПризнакПроведен функцию Сумма — и в каждой группировке видно число проведённых документов. Среднее по этому полю даёт долю проведённых: 0,85 значит 85%.

Дата → число

Здесь важно понять, что именно нужно получить.

ЗадачаВыражение в запросеПример результата
Номер годаГОД(Дата)2026
Номер месяцаМЕСЯЦ(Дата)10
Ключ вида ГГГГММДДГОД(Дата) * 10000 + МЕСЯЦ(Дата) * 100 + ДЕНЬ(Дата)20261007
Возраст долга в дняхРАЗНОСТЬДАТ(Дата, &ДатаОтчета, ДЕНЬ)45
Секунды от начала эпохи 1СРАЗНОСТЬДАТ(ДАТАВРЕМЯ(1, 1, 1), Дата, СЕКУНДА)большое целое

Проверим ключ ГГГГММДД на 7 октября 2026: 2026 × 10000 = 20 260 000, плюс 10 × 100 = 1000, плюс 7. Итого 20 261 007. Такое число удобно сравнивать и сортировать, а глазами оно читается как дата.

РАЗНОСТЬДАТ — основной инструмент для отчётов по просрочке. Параметр &ДатаОтчета в СКД заполняется из настроек, и пользователь сам выбирает дату расчёта.

Если &ДатаОтчета не заполнен, он равен пустой дате, и разность получится отрицательной на тысячи лет. Задайте параметру значение по умолчанию или условие ГДЕ на заполненность.

Составные типы, NULL и точность в ресурсах

Поле составного типа

Классический пример — значение дополнительного реквизита или субконто. В одном поле лежат и числа, и строки, и ссылки. Чтобы суммировать только числовые значения:

ВЫБОР
	КОГДА ТИПЗНАЧЕНИЯ(ДопРеквизиты.Значение) = ТИП(ЧИСЛО)
		ТОГДА ВЫРАЗИТЬ(ДопРеквизиты.Значение КАК ЧИСЛО(15, 2))
	ИНАЧЕ 0
КОНЕЦ КАК ЧисловоеЗначение

Проверка ТИПЗНАЧЕНИЯ здесь для ясности: ВЫРАЗИТЬ и сам вернёт NULL для нечисловых значений. Но с явной веткой ИНАЧЕ 0 в ресурсе не появится пустых ячеек.

В вычисляемом поле СКД аналог — Выразить(ДопЗначение, "Число").

NULL после соединения

Левое соединение даёт NULL там, где справа нет записей. Любая арифметика с NULL даёт NULL: Сумма + NULL — это NULL, а не сумма. Поэтому:

ЕСТЬNULL(Оплаты.Сумма, 0) КАК Оплачено,
Реализации.Сумма - ЕСТЬNULL(Оплаты.Сумма, 0) КАК Долг

Точность в ресурсах

Ресурс вида Сумма(Сумма) / Сумма(Количество) считается в языке выражений СКД после группировки. Разрядность там не задаётся типом поля, поэтому:

  • 🔢 ограничьте знаки через Выразить(…, "Число(15, 2)") в самом выражении ресурса;
  • 🎨 или задайте в параметре оформления Формат строку ЧДЦ=2 — значение останется точным, а покажется с двумя знаками.

Разница существенна при последующих расчётах: округлённое через Выразить значение уходит дальше округлённым, оформленное через формат — нет.

Готовые выражения для отчётов

Процент выполнения плана без деления на ноль

Ресурс в СКД:

Выбор
	Когда Сумма(План) = 0 Тогда 0
	Иначе Выразить(Сумма(Факт) * 100 / Сумма(План), "Число(15, 1)")
Конец

При плане 240 000 и факте 198 000 получится 198 000 × 100 / 240 000 = 82,5. Без проверки на ноль группа с пустым планом остановит формирование отчёта ошибкой деления.

Наценка в процентах в запросе

ВЫБОР
	КОГДА Продажи.Себестоимость = 0
		ТОГДА 0
	ИНАЧЕ ВЫРАЗИТЬ((Продажи.Выручка - Продажи.Себестоимость) * 100 / Продажи.Себестоимость КАК ЧИСЛО(15, 2))
КОНЕЦ КАК НаценкаПроцент

Проверка: выручка 15 600, себестоимость 12 000. (15 600 − 12 000) × 100 / 12 000 = 360 000 / 12 000 = 30,00.

Счётчик строк для ресурса

Чтобы посчитать строки с условием, удобнее суммировать единицы, чем пользоваться Количество(Различные …):

ВЫБОР КОГДА Остатки.КоличествоОстаток < 0 ТОГДА 1 ИНАЧЕ 0 КОНЕЦ КАК ОтрицательныйОстаток

Ресурс Сумма(ОтрицательныйОстаток) покажет, сколько позиций ушло в минус на каждом складе.

Ошибки при преобразовании и как их узнать

Диагностика: выберите симптом

Скорость отчёта: где преобразование тормозит

Преобразования сами по себе дешёвые. Проблемы начинаются, когда они стоят не в том месте.

  • 🐢 ВЫРАЗИТЬ в условиях ГДЕ и ПО. Выражение над полем мешает СУБД использовать индекс. Отбирайте по исходному полю, а преобразуйте в списке выборки.
  • ⚡ ВЫРАЗИТЬ для ссылок составного типа ускоряет запрос. Обращение Регистр.Субконто1.Наименование без уточнения типа соединяет таблицы всех возможных типов. ВЫРАЗИТЬ(Регистр.Субконто1 КАК Справочник.Контрагенты).Наименование оставляет одно соединение.
  • 🐌 Функции общих модулей в вычисляемых полях. Вызываются по каждой строке. На 200 строках это незаметно, на 500 000 — минуты. Если таких полей много, перенесите расчёт в запрос или храните число в реквизите.
  • 📉 Деление в запросе до группировки. Средняя цена, посчитанная по каждой строке и потом усреднённая, неверна по смыслу и считается дольше. Делите итоги: Сумма(Сумма) / Сумма(Количество) в ресурсе.

Сравнить варианты удобно в консоли запросов: выполните запрос с преобразованием в ГДЕ и без него на одном периоде и посмотрите время.

Частые вопросы

Можно ли в СКД задать полю тип Число, не меняя запрос?
В колонке «Тип значения» на закладке набора данных или вычисляемого поля можно указать тип. Это влияет на отборы и выбор значения в настройках, но не превращает строки в числа.
Почему после ВЫРАЗИТЬ сумма в итогах отличается на копейки от суммы строк?
Каждая строка округлена отдельно, а итог считается по округлённым значениям. Округляйте итог, а не строки, если нужна точная сумма.
Как вывести число без разделителя тысяч?
В параметре оформления поля Формат укажите ЧГ=0. Значение останется числом, изменится только вид.
Работает ли ВЫРАЗИТЬ КАК ЧИСЛО одинаково в файловой и клиент-серверной базе?
Синтаксис один и тот же, запрос переводится на язык конкретной СУБД платформой. Различия возможны на граничных случаях переполнения, поэтому разрядность задавайте с запасом.
Можно ли получить число из представления ссылки?
Нет смысла: представление — строка, и для неё действуют те же ограничения. Берите нужный реквизит ссылки напрямую, например числовой реквизит справочника.