Как исправить ошибку «Переменная не определена» при вызове общего модуля и настроить расчет НДС в табличной части

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

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

Причина 1: Неправильная настройка свойств общего модуля

Рассмотрим ситуацию, когда вы создали общий модуль с именем СуммаДляНДС, написали там функцию, но при попытке вызвать ее из модуля формы документа система «не видит» этот модуль. Проанализируем настройки, которые определяют видимость программного кода:

  1. Флаг «Клиент (управляемое приложение)»: Если вы вызываете процедуру из клиентского метода формы (&НаКлиенте), а у общего модуля этот флаг не установлен, компилятор на стороне клиента просто не будет знать о существовании такого модуля.
  2. Флаг «Сервер» и «Вызов сервера»: Если ваша логика должна исполняться на сервере, недостаточно просто поставить флаг «Сервер». Чтобы клиентский код мог «достучаться» до серверного общего модуля, обязательно должен быть установлен флаг «Вызов сервера».
  3. Флаг «Глобальный»: Если этот флаг включен, к функциям модуля можно обращаться напрямую по имени функции. Если выключен — только через точку: СуммаДляНДС.РассчитатьСумму(Параметры). Мы рекомендуем не злоупотреблять глобальными модулями, чтобы не засорять глобальное пространство имен.

Причина 2: Недостаточно фактических параметров

Эта ошибка возникает, когда описание функции и ее вызов не совпадают. Разберем на примере. Если в модуле ваша функция объявлена так:


Функция РассчитатьНДС(СтрокаТЧ, Ставка) Экспорт
    // Логика расчета
КонецФункции

А вызываете вы ее вот так: РассчитатьНДС(ТекущаяСтрока), то система выдаст ошибку, так как ожидается два значения, а передано одно. Проверьте, чтобы количество аргументов при вызове точно соответствовало количеству параметров в объявлении функции (за исключением параметров со значениями по умолчанию).

Работа с контекстом: передача строки табличной части

Одной из самых частых проблем является попытка передать «всю строку» табличной части с клиента на сервер. Выясним причину, почему это вызывает сложности. На клиенте строка таблицы — это объект типа ДанныеФормыСтруктура. На сервере же часто требуется работа с объектом метаданных.

Рассмотрим правильный подход: если вам нужно выполнить расчет на сервере, не передавайте всю строку целиком, если в этом нет острой необходимости. Передавайте только нужные значения (Сумму и Ставку). Если же вы решили оставить расчет на клиенте (что предпочтительнее для простых арифметических действий, чтобы интерфейс не «подтормаживал»), используйте Элементы.ИмяВашейТаблицы.ТекущиеДанные.

Посмотрим на пример кода в модуле формы:


&НаКлиенте
Процедура ТоварыЦенаПриИзменении(Элемент)
    СтрокаТабличнойЧасти = Элементы.Товары.ТекущиеДанные;
    РассчитатьСуммуНДСНаКлиенте(СтрокаТабличнойЧасти);
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьСуммуНДСНаКлиенте(СтрокаТабличнойЧасти)
    // Передаем строку как параметр в процедуру
    Ставка = 20; // Пример фиксированной ставки
    СтрокаТабличнойЧасти.СуммаНДС = СтрокаТабличнойЧасти.Сумма * Ставка / (Ставка + 100);
КонецПроцедуры

Как правильно работать с перечислениями на клиенте

Часто программисты пытаются написать условие так: Если Строка.СтавкаНДС = Перечисления.СтавкаНДС.НДС20 Тогда.... Это приведет к ошибке «Переменная не определена: Перечисления» на клиенте. Дело в том, что объект Перечисления доступен только на сервере.

Чтобы выполнить сравнение на стороне клиента, проанализируем использование функции ПредопределенноеЗначение. Она позволяет получить ссылку на объект конфигурации без обращения к серверному контексту:


&НаКлиенте
Процедура РассчитатьНДС(СтрокаТЧ)
    Если СтрокаТЧ.СтавкаНДС = ПредопределенноеЗначение("Перечисление.СтавкаНДС.НДС20") Тогда
        Ставка = 20;
    ИначеЕсли СтрокаТЧ.СтавкаНДС = ПредопределенноеЗначение("Перечисление.СтавкаНДС.НДС10") Тогда
        Ставка = 10;
    Иначе
        Ставка = 0;
    КонецЕсли;
    
    СтрокаТЧ.СуммаНДС = СтрокаТЧ.Сумма * Ставка / (100 + Ставка);
КонецПроцедуры

Проблема бесконечного цикла («Арифметическая прогрессия»)

Если вы заметили, что при изменении суммы программа «зависает» или сумма начинает бесконечно расти, вы столкнулись с рекурсивным вызовом. Рассмотрим ситуацию: в процедуре ПриИзменении суммы вы вызываете расчет НДС, который в свою очередь снова меняет данные, вызывающие срабатывание ПриИзменении.

Важные рекомендации, чтобы этого избежать:

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

Алгоритмы расчета НДС

Проанализируем две основные формулы, которые применяются в 1С:

1. НДС сверху (когда сумма увеличивается на налог):

СуммаНДС = СуммаБезНДС * (Ставка / 100);

2. НДС в том числе (выделение из общей суммы):

СуммаНДС = СуммаСНДС * Ставка / (100 + Ставка);

Использование констант (например, просто числа 20) в коде — плохая практика. Старайтесь получать числовое значение ставки из самой ссылки на перечисление или из соответствующего реквизита, чтобы ваш код не пришлось переписывать при изменении законодательства.

Итоги и выводы

Мы разобрали основные причины ошибки «Переменная не определена». Подытожим наши действия при возникновении подобных проблем:

Соблюдение этих правил позволит вам создавать надежный и производительный код в управляемом приложении 1С.

← На главную