Как программно изменить ставку НДС в печатной форме в зависимости от группы номенклатуры

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

При формировании документов на отгрузку часто возникают ситуации, когда стандартные механизмы программы не позволяют вывести специфические требования законодательства. Одной из таких задач является вывод особой надписи в графе НДС при реализации металлолома. Согласно статье 161 НК РФ, в таких случаях в печатных формах (например, ТОРГ-12) вместо ставки НДС должна выводиться фраза "НДС исчисляется налоговым агентом".

В этой статье мы разберем, как правильно реализовать отбор по группе номенклатуры, как работать с таблицами значений в контексте печати и как оптимизировать код, чтобы он работал надежно.

Анализ исходной проблемы

Рассмотрим ситуацию, с которой столкнулся автор темы. Проблема заключалась в том, что при попытке программно определить принадлежность товара к группе «Металлолом» возникали ошибки обращения к данным. Основная сложность была связана с тем, что переменная СведенияТОРГ12 является объектом типа ТаблицаЗначений, а обращение к ней происходило некорректно. Кроме того, логика проверки иерархии требовала уточнения.

Разберем по шагам, как решить эту задачу правильно.

Шаг 1. Получение ссылки на группу номенклатуры

Для начала нам нужно определить, с какой группой (папкой) мы будем сравнивать товары в документе. Автор использовал поиск по коду:

Металлолом = Справочники.Номенклатура.НайтиПоКоду("00009724");

Важное замечание: Использование метода НайтиПоКоду в программном коде считается не самой лучшей практикой. Если в базе данных изменятся коды или произойдет перенумерация, поиск перестанет работать. Рассмотрим более надежные варианты:

Шаг 2. Корректное обращение к таблице значений

Проанализируем структуру данных. В процедурах печати данные часто передаются в виде таблицы значений. Чтобы получить данные из первой строки таблицы СведенияТОРГ12, необходимо обращаться к ней по индексу и имени колонки.

Выясним причину ошибки автора: он пытался обращаться к данным через СФ.Товары, хотя ссылка на документ или данные строк уже находились в структуре СведенияТОРГ12. Правильный способ обращения к колонке выглядит так:


// Сначала проверяем, есть ли вообще строки в таблице
Если СведенияТОРГ12.Количество() > 0 Тогда
    // Получаем первую строку таблицы
    СтрокаДанных = СведенияТОРГ12[0];
    
    // Обращаемся к колонке "Номенклатура" (убедитесь, что колонка с таким именем существует)
    ТекущаяНоменклатура = СтрокаДанных.Номенклатура;
КонецЕсли;

Шаг 3. Проверка вхождения в группу (Иерархия)

Для проверки того, входит ли конкретный товар в папку «Металлолом» (включая все вложенные подпапки), в 1С предусмотрен встроенный метод ВИерархии. Это гораздо эффективнее, чем пытаться перебирать все товары вручную.

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


Если НоменклатураСсылка.ВИерархии(Металлолом) Тогда
    // Товар принадлежит группе металлолома
    Метал = Истина;
Иначе
    // Обычный товар
    Метал = Ложь;
КонецЕсли;

Метод ПринадлежитЭлементу, который использовал автор, также существует, но ВИерархии является более универсальным стандартом для платформы 8.3.

Шаг 4. Реализация логики вывода в печатную форму

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

Проанализируем правильный алгоритм заполнения параметров строки макета:


// Предположим, мы находимся внутри цикла "Для Каждого СтрокаДокумента Из ..."
// Получаем ссылку на группу (лучше вынести за пределы цикла)
ГруппаМеталлолом = Справочники.Номенклатура.НайтиПоКоду("00009724");

Для Каждого СтрокаДокумента Из ТабличнаяЧастьТовары Цикл
    
    // Создаем область для вывода строки
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    
    // Проверяем принадлежность текущего товара к металлолому
    Если СтрокаДокумента.Номенклатура.ВИерархии(ГруппаМеталлолом) Тогда
        // Заполняем параметр для спец. НДС
        ОбластьСтрока.Параметры.СтавкаНДС = "НДС исчисляется налоговым агентом";
        // Если в макете есть отдельный параметр СтавкаНДС1
        // ОбластьСтрока.Параметры.СтавкаНДС1 = "НДС исчисляется налоговым агентом";
    Иначе
        // Обычное заполнение из данных документа
        ОбластьСтрока.Параметры.СтавкаНДС = СтрокаДокумента.СтавкаНДС;
    КонецЕсли;
    
    // Выводим область в табличный документ
    ТабДок.Вывести(ОбластьСтрока);
    
КонецЦикла;

Работа с отладчиком

Если код всё равно не работает, нужно научиться пользоваться отладчиком. Посмотрим, на что обратить внимание:

  1. Тип значения: Поставьте точку останова на переменной СведенияТОРГ12. В окне "Табло" напишите ТипЗнч(СведенияТОРГ12). Если это ТаблицаЗначений, вы увидите список колонок и строк.
  2. Имена колонок: Убедитесь, что вы обращаетесь к колонке именно так, как она называется в конфигураторе. Например, Номенклатура или Товар. Регистр букв важен.
  3. Значение группы: Проверьте, что Металлолом = Справочники.Номенклатура.НайтиПоКоду(...) не возвращает Неопределено или пустую ссылку. Если группа не найдена, условие ВИерархии всегда будет ложным.

Рекомендации по учету металлолома в типовых решениях

Если вы работаете в современных конфигурациях (например, 1С:Бухгалтерия 3.0 или 1С:Управление торговлей 11), разберем встроенные возможности. В этих программах уже реализован механизм учета НДС при продаже лома и отходов металлов.

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

Таким образом, мы выяснили, что для решения задачи необходимо правильно определить контекст данных (таблица значений или ссылка), использовать встроенный метод проверки иерархии ВИерархии и корректно заполнять параметры области макета в цикле перебора строк. Это обеспечит гибкость печати и соответствие требованиям законодательства.

← На главную