Как программно изменить ставку НДС в справочнике Номенклатура в 1С:Бухгалтерия 3.0?

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

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

Анализ структуры хранения данных НДС

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

Проанализируем ключевые особенности этой структуры:

  1. Табличная часть вместо периодического регистра: В отличие от цен или ответственных лиц, история ставок НДС хранится непосредственно внутри объекта справочника.
  2. Реквизит Период: В табличной части есть поле Период типа Дата.
  3. Начальное значение: Если история никогда не заполнялась вручную, в системе всё равно подразумевается «начальное значение». При программном заполнении крайне важно создать запись с пустой датой ('00010101'), которая будет действовать для всех документов до момента первого явного изменения ставки.
  4. Синхронизация с основным реквизитом: Основной реквизит ВидСтавкиНДС в шапке справочника обычно синхронизируется с последней актуальной записью в истории при записи объекта.

Метод 1: Простое добавление записи в историю

Рассмотрим самый простой вариант, когда нам нужно просто добавить новую ставку на определенную дату для всей номенклатуры. Для этого нам потребуется получить объект справочника, добавить строку в табличную часть и записать его. Важным нюансом здесь является использование свойства ОбменДанными.Загрузка, так как типовые механизмы БП 3.0 могут блокировать прямое редактирование этой ТЧ без специальных условий.

Разберем пример кода для массового обновления:


&НаСервере
Процедура ДобавитьСтавкуНДСНаДату(НоваяСтавка, ДатаПерехода)
    
    Выборка = Справочники.Номенклатура.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        
        // Пропускаем группы, работаем только с элементами
        Если Выборка.ЭтоГруппа Тогда
            Продолжить;
        КонецЕсли;
        
        // Получаем объект для редактирования
        ОбъектНоменклатуры = Выборка.ПолучитьОбъект();
        
        // Включаем режим загрузки, чтобы обойти проверки платформы
        ОбъектНоменклатуры.ОбменДанными.Загрузка = Истина;
        
        // Добавляем новую строку в историю
        НоваяСтрока = ОбъектНоменклатуры.ИсторияВидаСтавкиНДС.Добавить();
        НоваяСтрока.Период = ДатаПерехода;
        НоваяСтрока.ВидСтавкиНДС = НоваяСтавка; // Например, Перечисления.ВидыСтавокНДС.Общая
        
        Попытка
            ОбъектНоменклатуры.Записать();
        Исключение
            Сообщить("Не удалось записать объект: " + ОбъектНоменклатуры.Ссылка + ". Ошибка: " + ОписаниеОшибки());
        КонецПопытки;
        
    КонецЦикла;
    
КонецПроцедуры

Метод 2: Профессиональный подход с проверкой дублей и начальным значением

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

Выясним причину, почему стоит проверять количество строк в ТЧ ИсторияВидаСтавкиНДС. Если табличная часть пуста, но в реквизите шапки ВидСтавкиНДС уже указано какое-то значение (например, «Без НДС» для периода УСН), то при добавлении новой строки (например, «20%» с 01.01.2024) старое значение может «потеряться» для документов прошлых периодов.

Рассмотрим по шагам правильный алгоритм обновления:

  1. Выполним запрос к справочнику Номенклатура, чтобы отобрать нужные элементы (например, только в конкретной папке).
  2. Для каждого элемента проверим, заполнена ли табличная часть ИсторияВидаСтавкиНДС.
  3. Если ТЧ пуста, создадим в ней «начальную» строку с пустой датой и текущим значением НДС.
  4. Выполним поиск существующей записи на целевую дату перехода. Если запись уже есть — обновим её, если нет — добавим новую.

&НаСервере
Процедура УстановитьСтавкуСИсториейНаСервере(ВыбранныйРодитель, ЦелеваяДата, ЦелеваяСтавка)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Номенклатура.Ссылка КАК Ссылка,
        |	Номенклатура.ВидСтавкиНДС КАК СтавкаИзШапки
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	НЕ Номенклатура.ЭтоГруппа
        |	И Номенклатура.Ссылка В ИЕРАРХИИ(&Родитель)";
    
    Запрос.УстановитьПараметр("Родитель", ВыбранныйРодитель);
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        
        НомОбъект = Выборка.Ссылка.ПолучитьОбъект();
        НомОбъект.ОбменДанными.Загрузка = Истина;
        
        ТЧ_История = НомОбъект.ИсторияВидаСтавкиНДС;
        
        // Шаг 1: Обработка начального значения (пустая дата)
        Если ТЧ_История.Количество() = 0 Тогда
            НачальнаяСтр = ТЧ_История.Добавить();
            НачальнаяСтр.Период = '00010101'; // Пустая дата для начального значения
            НачальнаяСтр.ВидСтавкиНДС = Выборка.СтавкаИзШапки;
        КонецЕсли;
        
        // Шаг 2: Поиск существующей записи на указанную дату
        ПараметрыПоиска = Новый Структура("Период", НачалоДня(ЦелеваяДата));
        НайденныеСтроки = ТЧ_История.НайтиСтроки(ПараметрыПоиска);
        
        Если НайденныеСтроки.Количество() > 0 Тогда
            // Если на эту дату уже есть запись, просто меняем ставку
            НайденныеСтроки[0].ВидСтавкиНДС = ЦелеваяСтавка;
        Иначе
            // Если записи нет, добавляем новую
            НоваяСтр = ТЧ_История.Добавить();
            НоваяСтр.Период = НачалоДня(ЦелеваяДата);
            НоваяСтр.ВидСтавкиНДС = ЦелеваяСтавка;
        КонецЕсли;
        
        // Сортировка по периоду для корректного отображения (необязательно, но полезно)
        ТЧ_История.Сортировать("Период Возр");
        
        Попытка
            НомОбъект.Записать();
        Исключение
            Сообщить("Ошибка записи " + Выборка.Ссылка + ": " + ОписаниеОшибки());
        КонецПопытки;
        
    КонецЦикла;
    
КонецПроцедуры

Важные технические моменты и рекомендации

Проанализируем ситуацию с производительностью. Если справочник Номенклатура содержит десятки тысяч позиций, выполнение ПолучитьОбъект() и Записать() в цикле может занять значительное время. В таких случаях рекомендуется:

Нюанс с перечислением: Ставка НДС в БП 3.0 — это значение перечисления ВидыСтавокНДС. Обратите внимание, что значения «Без НДС», «0%», «10%» и «20%» — это разные элементы перечисления. Например, ставка 20% в коде обычно соответствует значению Перечисления.ВидыСтавокНДС.Общая (в зависимости от релиза конфигурации наименование может варьироваться, лучше уточнить в Конфигураторе).

Выясним, что происходит после записи. После того как вы программно изменили историю ставок, новые документы будут подхватывать корректные значения. Однако старые (уже созданные, но еще не проведенные) документы могут сохранять старую ставку, так как она кэшируется в табличных частях самих документов. В некоторых случаях может потребоваться дополнительная обработка по обновлению ставок в документах за период перехода.

Использование свойства ОбменДанными.Загрузка = Истина является критически важным. Без него типовые подписки на события и обработчики ПередЗаписью могут пытаться перезаполнить табличную часть истории на основе логики конфигурации, что приведет к непредсказуемым результатам или ошибкам доступа.

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

← На главную