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