Как преобразовать перечисление СтавкиНДС в число в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Комплексная автоматизация Бухгалтерский учет IT и автоматизация бизнеса
← На главную

В процессе разработки в среде 1С:Предприятие часто возникает задача получения числового значения ставки НДС (например, 20, 10 или 0) из соответствующего перечисления ПеречислениеСсылка.СтавкиНДС. Это необходимо для проведения математических расчетов в коде: вычисления суммы налога, заполнения печатных форм, интеграции со сторонними сервисами или выгрузки данных. Поскольку перечисление является ссылочным типом данных, напрямую использовать его в арифметических операциях невозможно.

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

Способ 1. Использование встроенных функций БСП (Рекомендуемый метод)

Если вы работаете в типовой конфигурации 1С (такой как «1С:Комплексная автоматизация», «1С:ERP Управление предприятием», «1С:Управление торговлей» или «1С:Бухгалтерия предприятия»), наиболее надежным решением будет использование стандартных механизмов БСП. Разработчики фирмы 1С уже предусмотрели готовые функции в общих модулях для безопасного извлечения числовых значений.

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

Пример программного кода для получения ставки НДС в виде числа:


// Определяем ссылку на перечисление
СтавкаСсылка = Перечисления.СтавкиНДС.НДС20;

// Вызываем типовую функцию БСП для получения числового значения
ЧисловаяСтавка = УчетНДСКлиентСервер.ПолучитьСтавкуНДС(СтавкаСсылка); 

// В результате переменная ЧисловаяСтавка примет значение 20

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

Способ 2. Архитектурный переход на Справочник.СтавкиНДС

В современных редакциях конфигураций 1С (ERP 2.5, КА 2.5, УТ 11.5) разработчики постепенно отказываются от жестко закодированных перечислений в пользу более гибкого справочника Справочник.СтавкиНДС. Это связано с частыми законодательными изменениями и необходимостью оперативного добавления новых ставок пользователями без изменения метаданных конфигурации.

Если в вашей системе ставка НДС является ссылкой на справочник, задача получения числа упрощается до прямого обращения к реквизиту элемента справочника. Давайте посмотрим на пример такого обращения:


Если ЗначениеЗаполнено(Объект.СтавкаНДС) Тогда
    // Обращаемся напрямую к числовому реквизиту "Ставка"
    ЧисловаяСтавка = Объект.СтавкаНДС.Ставка; 
КонецЕсли;

В конфигурации «1С:Бухгалтерия предприятия» (БП 3.0) используется гибридная схема. Там применяется перечисление Перечисление.ВидыСтавокНДС (значения: Общая, Пониженная, Нулевая и т.д.), а конкретный процент определяется динамически в зависимости от даты документа. Для получения числового коэффициента в БП 3.0 используется следующий двухэтапный метод:


// 1. Получаем ставку НДС на определенную дату документа
СтавкаНДСЗначение = УчетНДСКлиентСервер.СтавкаНДС(Объект.ВидСтавкиНДС, Объект.Дата);

// 2. Преобразуем полученное значение в числовой коэффициент (например, 0.20 или 0.10)
ЧисловойКоэффициент = УчетНДСКлиентСервер.ПолучитьСтавкуНДСЧислом(СтавкаНДСЗначение);

Способ 3. Преобразование ставки НДС в число внутри запроса

При работе со списками документов или отчетами бывает необходимо получить числовое значение ставки непосредственно в запросе к базе данных. Внутри SQL-запроса невозможно вызвать клиент-серверные функции общих модулей 1С. В таких случаях мы вынуждены использовать условные конструкции ВЫБОР КОГДА.

Проанализируем пример запроса, преобразующего перечисление в число:


ВЫБОР
    КОГДА ТаблицаДокумента.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20) ТОГДА 20
    КОГДА ТаблицаДокумента.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС20_120) ТОГДА 20
    КОГДА ТаблицаДокумента.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС18) ТОГДА 18
    КОГДА ТаблицаДокумента.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС18_118) ТОГДА 18
    КОГДА ТаблицаДокумента.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС10) ТОГДА 10
    КОГДА ТаблицаДокумента.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС10_110) ТОГДА 10
    ИНАЧЕ 0
КОНЕЦ КАК СтавкаЧислом

Важное примечание: данный способ требует ручной поддержки кода. Если в законодательство будут внесены изменения (как это было при переходе с 18% на 20%), вам потребуется обновить все подобные запросы в ваших доработках, добавив новые условия в конструкцию ВЫБОР.

Способ 4. Программный парсинг имени или синонима (Для нетиповых конфигураций)

Если вы ведете разработку в самописной или сильно измененной конфигурации, где нет БСП и справочников, а писать громоздкие конструкции Если...Тогда под каждую ставку не хочется, можно прибегнуть к текстовому анализу строкового представления перечисления.

Давайте разберем по шагам алгоритм, который извлекает все цифры из синонима или имени значения перечисления и преобразует их в число:


Функция ПолучитьСтавкуЧислом(СтавкаНДС) Экспорт
    
    // Преобразуем ссылку перечисления в строковое представление (например, "НДС 20%")
    СтрокаСтавки = Строка(СтавкаНДС); 
    
    // Создаем переменную для накопления найденных цифр
    ТолькоЦифры = "";
    
    // Перебираем каждый символ в строке
    Для Индекс = 1 По СтрДлина(СтрокаСтавки) Цикл
        Символ = Сред(СтрокаСтавки, Index, 1);
        // Если символ является цифрой, добавляем его в результирующую строку
        Если СтрНайти("0123456789", Символ) > 0 Тогда
            ТолькоЦифры = ТолькоЦифры + Символ;
        КонецЕсли;
    КонецЦикла;
    
    // Обрабатываем ситуацию для ставки "Без НДС" или пустых значений
    Если ПустаяСтрока(ТолькоЦифры) Тогда
        Возврат 0;
    КонецЕсли;
    
    // Дополнительная обработка для расчетных ставок типа "20/120" или "18/118"
    Если СтрНайти(СтрокаСтавки, "/") > 0 Тогда
        // Если в строке есть косая черта, берем только первые цифры до разделителя
        ЧастиСтроки = СтрРазделить(СтрокаСтавки, "/");
        // Повторно очищаем первую часть от нецифровых символов
        ОчищеннаяЧасть = "";
        Для Индекс = 1 По СтрДлина(ЧастиСтроки[0]) Цикл
            Символ = Сред(ЧастиСтроки[0], Индекс, 1);
            Если СтрНайти("0123456789", Символ) > 0 Тогда
                ОчищеннаяЧасть = ОчищеннаяЧасть + Символ;
            КонецЕсли;
        КонецЦикла;
        Возврат Число(ОчищеннаяЧасть);
    КонецЕсли;
    
    Возврат Число(ТолькоЦифры);
    
КонецФункции

Этот метод является универсальным, однако имеет ряд недостатков. Во-первых, он зависит от языка локализации интерфейса пользователя (синонимы перечисления на других языках могут не содержать привычных цифр). Во-вторых, строковые операции выполняются медленнее, чем прямое обращение к реквизитам или вызов оптимизированных функций БСП. Используйте этот способ только в крайних случаях, когда другие варианты недоступны.

← На главную