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

Разработка и Конфигурация · 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. 1
    Откройте свойства реквизита и уточните, какие типы входят в составной тип
  2. 2
    Добавьте в запрос проверку ТИПЗНАЧЕНИЯ(Поле) = ТИП(ЧИСЛО)
  3. 3
    Примените ВЫРАЗИТЬ к числу только внутри ветки КОГДА
  4. 4
    Задайте значение ИНАЧЕ для нечисловых записей
  5. 5
    Выполните запрос в консоли и проверьте результат на реальных данных

Сценарий 3: приведение даты, булево и других типов

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

Для булева значения, которое нужно превратить в 0 или 1 (например, для суммирования признаков), применяется конструкция ВЫБОР:

ВЫБОР

КОГДА Таб.ПометкаУдаления

ТОГДА 1

ИНАЧЕ 0

КОНЕЦ

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

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

Альтернативы ВЫРАЗИТЬ: когда проще обойтись без приведения

Не каждая задача требует приведения типов в запросе. Часто надёжнее выполнить преобразование во встроенном языке после выгрузки результата: выбрать поле как есть, обойти выборку и использовать функцию Число() с обработкой исключений через Попытка/Исключение. Это даёт полный контроль над нечисловыми значениями.

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

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

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

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

Быстро и выполняется на сервере СУБД, но работает только для совместимых типов и без обработки ошибок

Преобразование в коде после выборки

Полный контроль через Число() и Попытка/Исключение, но медленнее на больших объёмах

Отдельный числовой реквизит

Самое надёжное решение на перспективу, требует доработки конфигурации и заполнения данных

Вычисляемое поле СКД

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

Как проверить результат и не допустить повторения ошибки

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

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

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

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

Компиляция запроса
Норма

Запрос выполняется без сообщения о несовместимых типах

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

Ошибка осталась — тип поля всё ещё не приводится

Значения NULL в результате
Норма

NULL отсутствуют или их доля ожидаема

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

Массовые NULL — часть данных не преобразовалась

Итоговые суммы
Норма

Суммы совпадают с контрольными значениями из учёта

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

Расхождения — проверьте отброшенные записи

Типичные ошибки
01
Приведение ссылочного поля к числу вместо извлечения кода или реквизита — ошибка компиляции
02
Игнорирование строки неограниченной длины: попытка привести её напрямую вместо двухступенчатого приведения
03
Отсутствие проверки ТИПЗНАЧЕНИЯ для составного поля — ошибка на записях со ссылочными значениями
04
Проверка запроса только на тестовой базе с «чистыми» данными — на рабочей базе всплывают NULL и ошибки выполнения

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

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

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

Почему запрос с ВЫРАЗИТЬ работал, а после обновления конфигурации сломался?

Вероятно, изменился тип реквизита: например, строке сняли ограничение длины или в составной тип добавили новый вид ссылок. Сравните тип поля в текущей версии конфигурации с предыдущей и скорректируйте запрос.

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

В запросе надёжного способа нет. Вынесите преобразование во встроенный язык: обойдите выборку и используйте Число() внутри Попытка/Исключение, либо предварительно очистите данные обработкой и отфильтруйте нечисловые значения запросом с ПОДОБНО.

Чем ВЫРАЗИТЬ отличается от функции Число() во встроенном языке?

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

Ошибка возникает в отчёте на СКД, а запрос в консоли работает. В чём причина?

СКД может дополнительно обрабатывать выражения и вычисляемые поля, а также по-разному определять типы полей наборов данных. Проверьте вычисляемые поля и выражения ресурсов в схеме компоновки — часто проблема именно там, а не в тексте основного запроса.

Итог

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

Ошибка «Несовместимые типы ВЫРАЗИТЬ» означает недопустимое приведение: к числу можно приводить только числа и строки ограниченной длины. Составные поля фильтруйте через ТИПЗНАЧЕНИЯ, даты и булево преобразуйте специальными функциями и ВЫБОР, а «грязные» строки обрабатывайте во встроенном языке. После исправления проверяйте запрос на реальных данных и контролируйте долю NULL в результате.