К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С: как выразить ресурс как число

Как в 1С выразить ресурс как число: функция ВЫРАЗИТЬ в запросе, СКД, преобразование строки в число, типичные ошибки и проверка результата.

В языке запросов 1С и в системе компоновки данных (СКД) ресурсы регистров нередко имеют составной или строковый тип, из-за чего с ними нельзя выполнять арифметические операции, сравнения и итоговые вычисления. Типичная ситуация: ресурс регистра сведений объявлен как «Строка» или как составной тип, а в отчёте его нужно суммировать или сравнивать как число.

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

Важно понимать ограничение: ВЫРАЗИТЬ корректно приводит только те значения, которые физически могут быть интерпретированы как число. Если в строковом ресурсе хранятся произвольные тексты, часть значений превратится в NULL или ноль, и итоги будут занижены без каких-либо ошибок. Поэтому перед приведением стоит проверить, что реально лежит в данных.

Когда вообще нужно выражать ресурс как число

Потребность в приведении типа возникает в нескольких характерных сценариях. Первый — ресурс регистра сведений или накопления исторически создан строковым (например, «Цена» типа Строка(20)), а теперь по нему нужно строить аналитику с суммами и средними. Второй — реквизит имеет составной тип (Число + Строка), и запрос должен работать только с числовой частью. Третий — данные приходят из обмена или загрузки из Excel во временную таблицу строками, и перед соединением с регистром их нужно привести к числу.

Признак того, что без приведения не обойтись, простой: запрос или отчёт не считает итоги, сравнение вида Ресурс > 100 работает непредсказуемо (строки сравниваются лексикографически, и «9» окажется больше «100»), а СКД при попытке суммировать строковое поле выдаёт ошибку или пустой результат.

Тип ресурса в конфигуратореСтрока или составной тип

Откройте свойства ресурса регистра — если тип не Число, для арифметики потребуется ВЫРАЗИТЬ

Сравнение в запросеРаботает «странно»

Строки сравниваются по алфавиту: «9» > «100». Это признак того, что поле нужно привести к числу

Итоги в отчётеПустые или нулевые

СКД не суммирует строки — проверьте тип поля и добавьте приведение в выражение ресурса

Функция ВЫРАЗИТЬ в языке запросов

Синтаксис функции: ВЫРАЗИТЬ(<Выражение> КАК ЧИСЛО(Длина, Точность)). Длина — общее количество цифр (обычно 15), точность — количество знаков после запятой (обычно 2–3). Параметры должны покрывать реальный диапазон данных: если указать ЧИСЛО(5, 0), а в данных есть значения больше 99999, результат будет обрезан или приведёт к ошибке на уровне СУБД в зависимости от платформы.

Пример запроса, где строковый ресурс регистра сведений приводится к числу и суммируется:

ВЫБРАТЬ

Продажи.Номенклатура КАК Номенклатура,

СУММА(ВЫРАЗИТЬ(Продажи.СуммаСтрокой КАК ЧИСЛО(15, 2))) КАК Сумма

ИЗ

РегистрСведений.ДанныеПродаж КАК Продажи

СГРУППИРОВАТЬ ПО

Продажи.Номенклатура

Функция работает и в условиях: ГДЕ ВЫРАЗИТЬ(Ресурс КАК ЧИСЛО(15, 2)) > 1000. Однако фильтрация по выражению не использует индексы, поэтому на больших таблицах такой запрос будет медленным — лучше отбирать записи по другим полям, а приведение применять к уже сокращённому набору.

bsl
ВЫБРАТЬ ВЫРАЗИТЬ(Ресурс КАК ЧИСЛО(15, 2)) КАК СуммаЧислом ИЗ РегистрСведений.МоиДанные

Как выразить ресурс как число в СКД

В отчёте на СКД приведение можно выполнить на двух уровнях. Первый — непосредственно в тексте запроса набора данных: это предпочтительный вариант, так как приведение выполняется один раз на уровне СУБД, а дальше СКД работает с готовым числовым полем. Поле автоматически получит тип Число, и его можно назначить ресурсом отчёта с агрегатной функцией Сумма.

Второй уровень — вычисляемые поля и выражения ресурсов на закладках «Вычисляемые поля» и «Ресурсы». В выражении ресурса можно написать Сумма(Выразить(Поле, \"Число(15, 2)\")), используя синтаксис языка выражений СКД. Этот вариант удобен, когда запрос нельзя менять (например, он используется другими отчётами), но он медленнее и ограничен функциями языка выражений.

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

Приведение строки к числу в коде на встроенном языке

Если обработка идёт не в запросе, а в модуле, используется другой подход. Прямого аналога ВЫРАЗИТЬ в языке нет: строка преобразуется через Число(СтрокаЗначения), но эта функция выбрасывает исключение на любом нечисловом символе, включая неразрывные пробелы и непечатаемые символы, которые часто приходят из Excel и обменов.

Безопасный шаблон — очистка строки перед преобразованием и обработка ошибки:

СтрокаОчищенная = СтрЗаменить(СтрокаЗначения, Символ(160), "");

СтрокаОчищенная = СтрЗаменить(СтрокаОчищенная, " ", "");

СтрокаОчищенная = СтрЗаменить(СтрокаОчищенная, ",", ".");

Попытка

ЗначениеЧислом = Число(СтрокаОчищенная);

Исключение

ЗначениеЧислом = 0;

КонецПопытки;

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

Типичные ошибки и ограничения

Самая распространённая ошибка — неверный выбор длины и точности. Если ресурс хранит суммы с копейками, а указано ЧИСЛО(15, 0), дробная часть будет отброшена, и итоги разойдутся с бухгалтерскими данными. Обратная ситуация — избыточная точность — безвредна для результата, но влияет на представление в отчёте.

Вторая ошибка — попытка привести составной тип, содержащий ссылки. ВЫРАЗИТЬ умеет приводить составное поле к конкретному типу, отсекая значения других типов (они станут NULL), но если в ресурсе хранятся, например, документы, приведение к числу не даст осмысленного результата. Третья ошибка — приведение в условии соединения таблиц: это разрушает использование индексов и на больших регистрах приводит к полному сканированию.

Типичные ошибки
01
Указана точность 0 для денежных сумм — копейки теряются, итоги расходятся с учётными данными
02
ВЫРАЗИТЬ использовано в условии соединения таблиц — запрос перестаёт использовать индексы и резко замедляется
03
Нечисловые значения в ресурсе молча превращаются в NULL — итоги занижены, ошибка не видна
04
Число() в коде применено к строке с неразрывным пробелом из Excel — исключение и остановка обработки

Альтернатива: исправить тип ресурса в конфигурации

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

Однако изменение типа — это модификация конфигурации со всеми последствиями: реструктуризация таблицы (на больших регистрах она занимает заметное время и требует монопольного доступа), необходимость обновления типовых конфигураций с учётом поддержки, возможная потеря значений, не приводимых к числу. Перед реструктуризацией обязательно сделайте резервную копию и контрольный запрос на нечисловые значения — они будут потеряны при конвертации.

Сравнение вариантов

ВЫРАЗИТЬ в запросе

Быстро внедрить, не требует изменения конфигурации. Ограничение: нечисловые значения теряются, приведение выполняется при каждом запросе

Выражение ресурса в СКД

Подходит, когда запрос менять нельзя. Ограничение: медленнее, ограниченный набор функций языка выражений

Изменение типа ресурса в конфигураторе

Правильное долгосрочное решение с корректной работой индексов. Ограничение: реструктуризация, риск потери нечисловых данных, влияние на обновления типовой

Как проверить результат

После добавления приведения сверьте итоги с независимым источником. Для денежных сумм контрольным ориентиром служит бухгалтерский отчёт или сумма по исходным документам. Полезный приём — выполнить два запроса: один с СУММА(ВЫРАЗИТЬ(...)), другой — с КОЛИЧЕСТВО(*) и КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...), чтобы убедиться, что ни одна строка не выпала из-за NULL.

Также проверьте граничные случаи: максимальное значение в данных (не обрезает ли его выбранная длина числа), значения с дробной частью (сохранилась ли точность), пустые и нулевые значения (не превратились ли пустые строки в NULL там, где ожидался ноль — при необходимости оберните выражение в ЕСТЬNULL(..., 0)).

Контрольные точки

Как проверить результат

Итог отчёта против контрольной суммы
Норма

Сумма совпадает с источником до копейки

Тревожный признак

Расхождение — проверяйте точность приведения и NULL-значения

Количество строк до и после приведения
Норма

Число записей в группировке совпадает с исходным запросом

Тревожный признак

Строки «пропали» — в данных есть нечисловые значения, ставшие NULL

Дробная часть значений
Норма

Копейки и знаки после запятой сохранены

Тревожный признак

Значения округлены до целых — увеличьте точность в ЧИСЛО(длина, точность)

Итог

Что важно запомнить

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

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

Можно ли выразить ресурс как число, если он имеет составной тип?

Да. ВЫРАЗИТЬ приводит составное поле к указанному типу: значения подходящего типа сохраняются, остальные становятся NULL. Если в составном типе хранятся и строки, и числа, строковые значения будут отброшены, поэтому предварительно проверьте, какие типы реально встречаются в данных.

Почему после ВЫРАЗИТЬ часть значений стала пустой?

Строки, которые нельзя интерпретировать как число (текст, пробелы, символы валют), при приведении в запросе дают NULL, а не ошибку. Чтобы не потерять такие записи в итогах, оберните выражение в ЕСТЬNULL(ВЫРАЗИТЬ(...), 0) и отдельно выведите список проблемных значений для исправления источника данных.

Какие длину и точность указывать в ЧИСЛО()?

Ориентируйтесь на реальный диапазон данных с запасом. Для денежных сумм обычно достаточно ЧИСЛО(15, 2), для количеств с дробными значениями — ЧИСЛО(15, 3). Длина должна покрывать максимальное значение, иначе результат будет обрезан или запрос завершится ошибкой.

Чем отличается ВЫРАЗИТЬ в запросе от Число() в коде?

ВЫРАЗИТЬ работает на уровне СУБД внутри запроса и для неприводимых значений возвращает NULL. Число() — функция встроенного языка для одиночных значений; на нечисловой строке она выбрасывает исключение, поэтому её нужно оборачивать в Попытка/Исключение и предварительно очищать строку от пробелов и разделителей.

Почему запрос с ВЫРАЗИТЬ в условии стал работать медленно?

Приведение типа в условии отбора или соединения отключает использование индексов — СУБД вынуждена вычислять выражение для каждой строки таблицы. Решение: отбирать записи по полям без преобразований, а ВЫРАЗИТЬ применять только в списке выбираемых полей или к уже сокращённой временной таблице.

Что лучше: ВЫРАЗИТЬ в каждом запросе или смена типа ресурса?

Если приведение требуется регулярно и в нескольких отчётах, правильнее изменить тип ресурса на Число в конфигураторе — это упростит запросы и включит нормальную работу индексов. ВЫРАЗИТЬ оставьте как временную меру или для разовых задач, помня о риске потери нечисловых значений при реструктуризации.