Как перевести из строки в число: Перечисления.СтавкиНДС

Программист 1С v8.3 (Обычные формы) Управленческий учет
← На главную

В практике разработки на платформе 1С:Предприятие часто возникает ситуация, когда при выводе документа на печать или выполнении расчетов программа выдает ошибку: «Преобразование значения к типу Число не может быть выполнено». Чаще всего это происходит при попытке произвести математические действия со ставкой НДС. Проблема заключается в том, что в поле СтавкаНДС хранится не число 20 или 10, а ссылка на объект перечисления. Для системы Перечисления.СтавкиНДС.НДС_20 — это сложный программный объект, а не цифра, поэтому его нельзя просто поделить на 100.

В данной статье мы подробно разберем, как правильно преобразовать значение перечисления в число, рассмотрим различные подходы — от простых условий до универсальных функций и использования современных библиотек.

Причина возникновения ошибки

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


СтавкаНДС = Номенклатура.СтавкаНДС; // Здесь переменная получает тип "ПеречислениеСсылка.СтавкиНДС"
СуммаБезНДС = Сумма - Сумма * (СтавкаНДС / 100); // Ошибка: деление ссылки на 100

Платформа не может интерпретировать имя значения перечисления (например, «НДС_20») как числовое значение автоматически. Наша задача — «объяснить» программе, какое число соответствует каждому элементу перечисления.

Решение 1: Простое сопоставление через условие

Это самый быстрый способ, если вам нужно решить задачу «здесь и сейчас» внутри конкретной процедуры печати. Мы создаем вспомогательную переменную и присваиваем ей числовое значение в зависимости от выбранного пункта перечисления.

Рассмотрим пример реализации:


СтавкаЧислом = 0;
Если СтавкаНДС = Перечисления.СтавкиНДС.НДС_20 Тогда
    СтавкаЧислом = 20;
ИначеЕсли СтавкаНДС = Перечисления.СтавкиНДС.НДС_10 Тогда
    СтавкаЧислом = 10;
ИначеЕсли СтавкаНДС = Перечисления.СтавкиНДС.НДС_0 Тогда
    СтавкаЧислом = 0;
КонецЕсли;

// Теперь используем переменную СтавкаЧислом в расчетах
СуммаНДС = Сумма * (СтавкаЧислом / 100);

Этот метод надежен, но требует ручного обновления кода, если в законодательстве появятся новые ставки НДС.

Решение 2: Универсальная функция-преобразователь

Если в вашей конфигурации расчеты НДС встречаются в разных документах (счетах, накладных, актах), правильнее будет вынести логику преобразования в отдельную функцию. Это позволит избежать дублирования кода и упростит его поддержку.

Посмотрим на пример такой функции, которую можно разместить в общем модуле:


Функция ПолучитьЧисловоеЗначениеСтавки(СсылкаНаСтавку) Экспорт
    Если ТипЗнч(СсылкаНаСтавку) = Тип("Число") Тогда
        Возврат СсылкаНаСтавку;
    КонецЕсли;

    Если СсылкаНаСтавку = Перечисления.СтавкиНДС.НДС_20 Тогда
        Возврат 20;
    ИначеЕсли СсылкаНаСтавку = Перечисления.СтавкиНДС.НДС_18 Тогда
        Возврат 18;
    ИначеЕсли СсылкаНаСтавку = Перечисления.СтавкиНДС.НДС_10 Тогда
        Возврат 10;
    ИначеЕсли СсылкаНаСтавку = Перечисления.СтавкиНДС.БезНДС 
        ИЛИ СсылкаНаСтавку = Перечисления.СтавкиНДС.НДС_0 Тогда
        Возврат 0;
    КонецЕсли;
    
    Возврат 0;
КонецФункции

При использовании такой функции основной код расчета станет чище и понятнее:


СтавкаНДС = Номенклатура.СтавкаНДС;
ЧислоСтавки = ПолучитьЧисловоеЗначениеСтавки(СтавкаНДС);
СуммаБезНДС = Сумма / ((100 + ЧислоСтавки) / 100);

Решение 3: Использование объекта «Соответствие»

Для повышения производительности, особенно если расчет происходит в цикле по тысячам строк номенклатуры, профессиональные разработчики используют объект Соответствие. Это позволяет избежать многократных проверок Если...ИначеЕсли.

Разберем, как это работает по шагам:

  1. Создаем объект Соответствие, где ключом выступает ссылка перечисления, а значением — число.
  2. Заполняем его один раз перед началом цикла.
  3. Внутри цикла просто получаем значение по ключу.

// 1. Инициализация
КартаСтавок = Новый Соответствие;
КартаСтавок.Вставить(Перечисления.СтавкиНДС.НДС_20, 20);
КартаСтавок.Вставить(Перечисления.СтавкиНДС.НДС_10, 10);
КартаСтавок.Вставить(Перечисления.СтавкиНДС.НДС_0, 0);

// 2. Использование в цикле
Для Каждого СтрокаТовара Из Товары Цикл
    ТекСтавка = КартаСтавок[СтрокаТовара.СтавкаНДС];
    ЧислоСтавки = ?(ТекСтавка = Неопределено, 0, ТекСтавка);
    // Дальнейший расчет...
КонецЦикла;

Решение 4: Использование механизмов БСП

Если ваша конфигурация построена на базе БСП (Библиотеки стандартных подсистем), что характерно для всех современных типовых решений (УТ 11, БП 3.0, ERP), то в ней уже есть готовые инструменты. Не нужно изобретать велосипед — достаточно вызвать общую функцию.

Проанализируем использование модуля УчетНДСКлиентСервер:

Метод УчетНДСКлиентСервер.ПолучитьСтавкуНДСЧислом(СтавкаНДС) вернет вам готовое число. А если вам нужен коэффициент для умножения, воспользуйтесь функцией УчетНДСКлиентСервер.ПолучитьКоэффициентСтавкиНДС(СтавкаНДС), которая для ставки 20% сразу вернет значение 0.2.


// Пример для современных конфигураций
СтавкаНДС = СтрокаТовара.СтавкаНДС;
Коэффициент = УчетНДСКлиентСервер.ПолучитьКоэффициентСтавкиНДС(СтавкаНДС);
СуммаНДС = Сумма * Коэффициент;

Важные нюансы расчетов

При работе со ставками НДС важно помнить о расчетных ставках (например, 20/120 или 18/118). Они используются, когда НДС уже включен в сумму и его нужно «выделить».

Если вы просто разделите 20 на 100, вы получите налог «сверху». Для расчетных ставок логика должна быть иной. В типовых конфигурациях для этого проверяется свойство перечисления или используется специальный флаг. Если вы пишете расчет самостоятельно, обязательно уточните, должна ли ваша функция поддерживать такие значения.

Также не забывайте про значение «Без НДС». Математически оно эквивалентно нулю, но в печатных формах часто требуется выводить именно текст «Без НДС» вместо цифры 0. Для этого в параметрах макета лучше использовать условие:


ОбластьМакета.Параметры.СтавкаНДС = ?(ЧислоСтавки = 0, "Без НДС", СокрЛП(ЧислоСтавки) + "%");

Резюме: Чтобы избавиться от ошибки преобразования, всегда разделяйте ссылку на объект и его числовое представление. Для небольших правок используйте условия Если, для серьезной разработки — общие функции или механизмы БСП.

← На главную