Как получить число из строки, даты, булева и составного поля в отчёте на СКД
Содержание
В запросе набора данных СКД значение переводят в число конструкцией ВЫРАЗИТЬ(Поле КАК ЧИСЛО(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)
В колонке «Тип значения» поставьте Число. Тогда по полю будут доступны отбор «больше/меньше» и суммирование в ресурсах.
Что делает функция и зачем:
- Пропускает готовые числа без изменений — пригодится для полей составного типа.
- Убирает пробелы и неразрывные пробелы. Они приходят из Excel и из чисел, вставленных из документов: «1 250».
- Меняет запятую на точку, чтобы «12,5» и «12.5» разбирались одинаково.
- Ловит исключение. Одна строка «б/н» в выборке иначе обрушит весь отчёт.
Путь 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. Значение останется числом, изменится только вид.