Разработка и Конфигурация · 11 мин
1С: как выразить ресурс как число
Как в 1С выразить ресурс как число: функция ВЫРАЗИТЬ в запросе, СКД, преобразование строки в число, типичные ошибки и проверка результата.
В языке запросов 1С и в системе компоновки данных (СКД) ресурсы регистров нередко имеют составной или строковый тип, из-за чего с ними нельзя выполнять арифметические операции, сравнения и итоговые вычисления. Типичная ситуация: ресурс регистра сведений объявлен как «Строка» или как составной тип, а в отчёте его нужно суммировать или сравнивать как число.
Основной инструмент решения — функция ВЫРАЗИТЬ(<Значение> КАК ЧИСЛО(длина, точность)) в тексте запроса или в выражении вычисляемого поля СКД. Она выполняет приведение типа на уровне СУБД и позволяет дальше работать со значением как с числом: суммировать, округлять, сравнивать.
Важно понимать ограничение: ВЫРАЗИТЬ корректно приводит только те значения, которые физически могут быть интерпретированы как число. Если в строковом ресурсе хранятся произвольные тексты, часть значений превратится в NULL или ноль, и итоги будут занижены без каких-либо ошибок. Поэтому перед приведением стоит проверить, что реально лежит в данных.
Когда вообще нужно выражать ресурс как число
Потребность в приведении типа возникает в нескольких характерных сценариях. Первый — ресурс регистра сведений или накопления исторически создан строковым (например, «Цена» типа Строка(20)), а теперь по нему нужно строить аналитику с суммами и средними. Второй — реквизит имеет составной тип (Число + Строка), и запрос должен работать только с числовой частью. Третий — данные приходят из обмена или загрузки из Excel во временную таблицу строками, и перед соединением с регистром их нужно привести к числу.
Признак того, что без приведения не обойтись, простой: запрос или отчёт не считает итоги, сравнение вида Ресурс > 100 работает непредсказуемо (строки сравниваются лексикографически, и «9» окажется больше «100»), а СКД при попытке суммировать строковое поле выдаёт ошибку или пустой результат.
Откройте свойства ресурса регистра — если тип не Число, для арифметики потребуется ВЫРАЗИТЬ
Строки сравниваются по алфавиту: «9» > «100». Это признак того, что поле нужно привести к числу
СКД не суммирует строки — проверьте тип поля и добавьте приведение в выражение ресурса
Функция ВЫРАЗИТЬ в языке запросов
Синтаксис функции: ВЫРАЗИТЬ(<Выражение> КАК ЧИСЛО(Длина, Точность)). Длина — общее количество цифр (обычно 15), точность — количество знаков после запятой (обычно 2–3). Параметры должны покрывать реальный диапазон данных: если указать ЧИСЛО(5, 0), а в данных есть значения больше 99999, результат будет обрезан или приведёт к ошибке на уровне СУБД в зависимости от платформы.
Пример запроса, где строковый ресурс регистра сведений приводится к числу и суммируется:
ВЫБРАТЬ
Продажи.Номенклатура КАК Номенклатура,
СУММА(ВЫРАЗИТЬ(Продажи.СуммаСтрокой КАК ЧИСЛО(15, 2))) КАК Сумма
ИЗ
РегистрСведений.ДанныеПродаж КАК Продажи
СГРУППИРОВАТЬ ПО
Продажи.Номенклатура
Функция работает и в условиях: ГДЕ ВЫРАЗИТЬ(Ресурс КАК ЧИСЛО(15, 2)) > 1000. Однако фильтрация по выражению не использует индексы, поэтому на больших таблицах такой запрос будет медленным — лучше отбирать записи по другим полям, а приведение применять к уже сокращённому набору.
ВЫБРАТЬ ВЫРАЗИТЬ(Ресурс КАК ЧИСЛО(15, 2)) КАК СуммаЧислом ИЗ РегистрСведений.МоиДанныеКак выразить ресурс как число в СКД
В отчёте на СКД приведение можно выполнить на двух уровнях. Первый — непосредственно в тексте запроса набора данных: это предпочтительный вариант, так как приведение выполняется один раз на уровне СУБД, а дальше СКД работает с готовым числовым полем. Поле автоматически получит тип Число, и его можно назначить ресурсом отчёта с агрегатной функцией Сумма.
Второй уровень — вычисляемые поля и выражения ресурсов на закладках «Вычисляемые поля» и «Ресурсы». В выражении ресурса можно написать Сумма(Выразить(Поле, \"Число(15, 2)\")), используя синтаксис языка выражений СКД. Этот вариант удобен, когда запрос нельзя менять (например, он используется другими отчётами), но он медленнее и ограничен функциями языка выражений.
- 1Откройте схему компоновки данных и перейдите на закладку «Наборы данных»
- 2В тексте запроса оберните нужное поле в ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15, 2)) и задайте псевдоним
- 3На закладке «Ресурсы» проверьте, что поле попало в список ресурсов с агрегатной функцией Сумма
- 4Сформируйте отчёт и сверьте итог с контрольным значением из исходных данных
Приведение строки к числу в коде на встроенном языке
Если обработка идёт не в запросе, а в модуле, используется другой подход. Прямого аналога ВЫРАЗИТЬ в языке нет: строка преобразуется через Число(СтрокаЗначения), но эта функция выбрасывает исключение на любом нечисловом символе, включая неразрывные пробелы и непечатаемые символы, которые часто приходят из Excel и обменов.
Безопасный шаблон — очистка строки перед преобразованием и обработка ошибки:
СтрокаОчищенная = СтрЗаменить(СтрокаЗначения, Символ(160), "");
СтрокаОчищенная = СтрЗаменить(СтрокаОчищенная, " ", "");
СтрокаОчищенная = СтрЗаменить(СтрокаОчищенная, ",", ".");
Попытка
ЗначениеЧислом = Число(СтрокаОчищенная);
Исключение
ЗначениеЧислом = 0;
КонецПопытки;
Для массовых загрузок полезно логировать значения, которые не удалось преобразовать, а не молча заменять их нулём — иначе ошибки в источнике данных останутся незамеченными.
Типичные ошибки и ограничения
Самая распространённая ошибка — неверный выбор длины и точности. Если ресурс хранит суммы с копейками, а указано ЧИСЛО(15, 0), дробная часть будет отброшена, и итоги разойдутся с бухгалтерскими данными. Обратная ситуация — избыточная точность — безвредна для результата, но влияет на представление в отчёте.
Вторая ошибка — попытка привести составной тип, содержащий ссылки. ВЫРАЗИТЬ умеет приводить составное поле к конкретному типу, отсекая значения других типов (они станут NULL), но если в ресурсе хранятся, например, документы, приведение к числу не даст осмысленного результата. Третья ошибка — приведение в условии соединения таблиц: это разрушает использование индексов и на больших регистрах приводит к полному сканированию.
Альтернатива: исправить тип ресурса в конфигурации
Приведение в запросе — это обходное решение. Если ресурс систематически используется как число, правильнее изменить его тип в конфигураторе на Число с нужной разрядностью. После реструктуризации базы данные будут храниться в правильном типе, запросы упростятся, а индексы и сравнения начнут работать корректно.
Однако изменение типа — это модификация конфигурации со всеми последствиями: реструктуризация таблицы (на больших регистрах она занимает заметное время и требует монопольного доступа), необходимость обновления типовых конфигураций с учётом поддержки, возможная потеря значений, не приводимых к числу. Перед реструктуризацией обязательно сделайте резервную копию и контрольный запрос на нечисловые значения — они будут потеряны при конвертации.
Сравнение вариантов
Быстро внедрить, не требует изменения конфигурации. Ограничение: нечисловые значения теряются, приведение выполняется при каждом запросе
Подходит, когда запрос менять нельзя. Ограничение: медленнее, ограниченный набор функций языка выражений
Правильное долгосрочное решение с корректной работой индексов. Ограничение: реструктуризация, риск потери нечисловых данных, влияние на обновления типовой
Как проверить результат
После добавления приведения сверьте итоги с независимым источником. Для денежных сумм контрольным ориентиром служит бухгалтерский отчёт или сумма по исходным документам. Полезный приём — выполнить два запроса: один с СУММА(ВЫРАЗИТЬ(...)), другой — с КОЛИЧЕСТВО(*) и КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...), чтобы убедиться, что ни одна строка не выпала из-за NULL.
Также проверьте граничные случаи: максимальное значение в данных (не обрезает ли его выбранная длина числа), значения с дробной частью (сохранилась ли точность), пустые и нулевые значения (не превратились ли пустые строки в NULL там, где ожидался ноль — при необходимости оберните выражение в ЕСТЬNULL(..., 0)).
Как проверить результат
Сумма совпадает с источником до копейки
Расхождение — проверяйте точность приведения и NULL-значения
Число записей в группировке совпадает с исходным запросом
Строки «пропали» — в данных есть нечисловые значения, ставшие NULL
Копейки и знаки после запятой сохранены
Значения округлены до целых — увеличьте точность в ЧИСЛО(длина, точность)
Что важно запомнить
Ресурс выражается как число через ВЫРАЗИТЬ(Поле КАК ЧИСЛО(длина, точность)) — в запросе, СКД или выражении ресурса. Перед приведением проверьте данные на нечисловые значения, выбирайте достаточные длину и точность, не используйте приведение в соединениях, а при постоянной потребности рассмотрите изменение типа ресурса в конфигурации.
Частые вопросы
Можно ли выразить ресурс как число, если он имеет составной тип?
Да. ВЫРАЗИТЬ приводит составное поле к указанному типу: значения подходящего типа сохраняются, остальные становятся NULL. Если в составном типе хранятся и строки, и числа, строковые значения будут отброшены, поэтому предварительно проверьте, какие типы реально встречаются в данных.
Почему после ВЫРАЗИТЬ часть значений стала пустой?
Строки, которые нельзя интерпретировать как число (текст, пробелы, символы валют), при приведении в запросе дают NULL, а не ошибку. Чтобы не потерять такие записи в итогах, оберните выражение в ЕСТЬNULL(ВЫРАЗИТЬ(...), 0) и отдельно выведите список проблемных значений для исправления источника данных.
Какие длину и точность указывать в ЧИСЛО()?
Ориентируйтесь на реальный диапазон данных с запасом. Для денежных сумм обычно достаточно ЧИСЛО(15, 2), для количеств с дробными значениями — ЧИСЛО(15, 3). Длина должна покрывать максимальное значение, иначе результат будет обрезан или запрос завершится ошибкой.
Чем отличается ВЫРАЗИТЬ в запросе от Число() в коде?
ВЫРАЗИТЬ работает на уровне СУБД внутри запроса и для неприводимых значений возвращает NULL. Число() — функция встроенного языка для одиночных значений; на нечисловой строке она выбрасывает исключение, поэтому её нужно оборачивать в Попытка/Исключение и предварительно очищать строку от пробелов и разделителей.
Почему запрос с ВЫРАЗИТЬ в условии стал работать медленно?
Приведение типа в условии отбора или соединения отключает использование индексов — СУБД вынуждена вычислять выражение для каждой строки таблицы. Решение: отбирать записи по полям без преобразований, а ВЫРАЗИТЬ применять только в списке выбираемых полей или к уже сокращённой временной таблице.
Что лучше: ВЫРАЗИТЬ в каждом запросе или смена типа ресурса?
Если приведение требуется регулярно и в нескольких отчётах, правильнее изменить тип ресурса на Число в конфигураторе — это упростит запросы и включит нормальную работу индексов. ВЫРАЗИТЬ оставьте как временную меру или для разовых задач, помня о риске потери нечисловых значений при реструктуризации.