При разработке механизмов заполнения документов, умном пересчете цен или расчете сумм в табличных частях программисты часто сталкиваются с ошибкой «Преобразование значения к типу Число не может быть выполнено» (быстро найти причину поможет инструмент пошаговой отладки кода в режиме предприятия). Эта проблема возникает, когда мы пытаемся совершить арифметическую операцию (сложение или деление) с реквизитом СтавкаНДС. Давайте разберем, почему это происходит и какими способами можно получить реальное число (например, 20 или 10) из объекта метаданных.
Проанализируем ситуацию: в большинстве типовых и самописных конфигураций реквизит СтавкаНДС не является числом. Это либо ПеречислениеСсылка.СтавкиНДС, либо СправочникСсылка.СтавкиНДС. Для системы 1С значение «НДС 20%» — это сложный объект (ссылка), а не цифра 20. Поэтому выражение вида 100 + Стр.СтавкаНДС приводит к аварийному завершению программы. Также ошибки в расчетах часто возникают из-за путаницы в методе расчета (сверху или внутри), чего можно избежать, если правильно настроить флажок "Цена включает НДС" по умолчанию. Наша задача — «извлечь» число из этой ссылки.
Если в вашей конфигурации ставки НДС хранятся в виде перечисления, самый простой и надежный способ — написать вспомогательную функцию, которая сопоставит значение перечисления с числом. Рассмотрим пример такой функции:
Функция ПолучитьСтавкуНДСЧислом(СтавкаНДС) Экспорт
Если СтавкаНДС = Перечисления.СтавкиНДС.НДС20 Тогда
Возврат 20;
ИначеЕсли СтавкаНДС = Перечисления.СтавкиНДС.НДС10 Тогда
Возврат 10;
ИначеЕсли СтавкаНДС = Перечисления.СтавкиНДС.НДС18 Тогда
Возврат 18;
ИначеЕсли СтавкаНДС = Перечисления.СтавкиНДС.НДС5 Тогда
Возврат 5;
Иначе
// Сюда попадают значения "Без НДС" или "0%"
Возврат 0;
КонецЕсли;
КонецФункции
Теперь мы можем безопасно использовать эту функцию в расчетах. Перепишем фрагмент кода, который вызывал ошибку у автора вопроса:
Для каждого Стр из Объект.Запасы Цикл
ЧислоСтавки = ПолучитьСтавкуНДСЧислом(Стр.СтавкаНДС);
// Расчет НДС "в том числе"
Стр.СуммаНДС = Стр.Сумма - (Стр.Сумма / (100 + ЧислоСтавки) * 100);
Стр.СуммаБезНДС = Стр.Сумма - Стр.СуммаНДС;
КонецЦикла;
В некоторых конфигурациях, например в «1С:Управление нашей фирмой» (УНФ), ставки НДС хранятся в справочнике. Это удобнее, так как в самом справочнике уже есть числовой реквизит Ставка. Это особенно полезно, если вы выполняете анализ наценки на закупочные цены и вам нужно точно оперировать цифрами — для этого подойдёт автоматическая корректировка НДС в себестоимости. Проанализируем, как в этом случае получить значение:
Ставка).Стр.СтавкаНДС.Ставка.Пример кода для работы со справочником:
Если ЗначениеЗаполнено(Стр.СтавкаНДС) Тогда
ЧислоСтавки = Стр.СтавкаНДС.Ставка; // Получаем число напрямую из справочника
Стр.СуммаНДС = СуммаПродажи * (ЧислоСтавки / 100); // Расчет НДС "сверху"
Иначе
Стр.СуммаНДС = 0;
КонецЕсли;
Профессиональный подход в разработке на платформе 1С 8.3 предполагает использование готовых функций из Библиотеки Стандартных Подсистем (БСП). Чтобы не изобретать велосипед, рекомендуется изучить справочник по методам БСП. В конфигурациях «Управление торговлей» или «ERP» уже есть общие модули, которые умеют корректно обрабатывать ставки НДС. Рассмотрим наиболее популярные методы:
Для УТ 11, ERP 2.x, КА 2.x используем функцию:
ЦенообразованиеКлиентСервер.ПолучитьСтавкуНДСЧислом(СтавкаНДС)
Для Бухгалтерии предприятия 3.0 используем функцию:
УчетНДСКлиентСервер.ПолучитьСтавкуНДСЗначение(СтавкаНДС)
Использование готовых функций рекомендуется по нескольким причинам:
КлиентСервер, что позволяет вызывать их как в серверном коде, так и в модуле формы.Разберем ситуацию, на которую указывали опытные коллеги в обсуждении. При расчете важно учитывать разницу между ставкой «0%» и значением «Без НДС».
С точки зрения математики (расчета суммы) — в обоих случаях НДС будет равен нулю. Однако с точки зрения законодательства и заполнения печатных форм (счет-фактура, УПД) — это разные сущности. Если ваша функция возвращает 0 для обоих случаев, убедитесь, что это не нарушит логику формирования отчетности.
Также важно всегда использовать Отладчик. Если вы видите ошибку преобразования, остановитесь на строке расчета и проверьте тип переменной Стр.СтавкаНДС. Для более глубокой проверки кода рекомендуется выполнять анализ конфигурации на наличие ошибок, чтобы заранее выявить некорректные вызовы — в этом помогут инструменты разработчика для тестирования и отладки кода. Если тип ПеречислениеСсылка — используйте Способ 1. Если СправочникСсылка — Способ 2.
ЦенообразованиеКлиентСервер. Если его нет — создайте свою функцию в модуле объекта или общем модуле.Попытка...Исключение при записи документа, но не внутри цикла расчета, чтобы видеть, на какой именно строке данных происходит сбой.