При разработке в среде 1С:Предприятие 8.3 начинающие программисты часто сталкиваются с ситуацией, когда написанный код кажется логичным, но система выдает ошибку «Переменная не определена» или сообщает о «недостаточном количестве фактических параметров». Особенно часто это проявляется при попытке вынести расчеты (например, суммы НДС) в отдельный общий модуль или при работе с событиями табличной части. В этой статье мы подробно разберем, почему возникают такие ошибки, как правильно передавать данные между клиентом и сервером и как корректно работать с перечислениями.
Рассмотрим ситуацию, когда вы создали общий модуль с именем СуммаДляНДС, написали там функцию, но при попытке вызвать ее из модуля формы документа система «не видит» этот модуль. Проанализируем настройки, которые определяют видимость программного кода:
&НаКлиенте), а у общего модуля этот флаг не установлен, компилятор на стороне клиента просто не будет знать о существовании такого модуля.СуммаДляНДС.РассчитатьСумму(Параметры). Мы рекомендуем не злоупотреблять глобальными модулями, чтобы не засорять глобальное пространство имен.Эта ошибка возникает, когда описание функции и ее вызов не совпадают. Разберем на примере. Если в модуле ваша функция объявлена так:
Функция РассчитатьНДС(СтрокаТЧ, Ставка) Экспорт
// Логика расчета
КонецФункции
А вызываете вы ее вот так: РассчитатьНДС(ТекущаяСтрока), то система выдаст ошибку, так как ожидается два значения, а передано одно. Проверьте, чтобы количество аргументов при вызове точно соответствовало количеству параметров в объявлении функции (за исключением параметров со значениями по умолчанию).
Одной из самых частых проблем является попытка передать «всю строку» табличной части с клиента на сервер. Выясним причину, почему это вызывает сложности. На клиенте строка таблицы — это объект типа ДанныеФормыСтруктура. На сервере же часто требуется работа с объектом метаданных.
Рассмотрим правильный подход: если вам нужно выполнить расчет на сервере, не передавайте всю строку целиком, если в этом нет острой необходимости. Передавайте только нужные значения (Сумму и Ставку). Если же вы решили оставить расчет на клиенте (что предпочтительнее для простых арифметических действий, чтобы интерфейс не «подтормаживал»), используйте Элементы.ИмяВашейТаблицы.ТекущиеДанные.
Посмотрим на пример кода в модуле формы:
&НаКлиенте
Процедура ТоварыЦенаПриИзменении(Элемент)
СтрокаТабличнойЧасти = Элементы.Товары.ТекущиеДанные;
РассчитатьСуммуНДСНаКлиенте(СтрокаТабличнойЧасти);
КонецПроцедуры
&НаКлиенте
Процедура РассчитатьСуммуНДСНаКлиенте(СтрокаТабличнойЧасти)
// Передаем строку как параметр в процедуру
Ставка = 20; // Пример фиксированной ставки
СтрокаТабличнойЧасти.СуммаНДС = СтрокаТабличнойЧасти.Сумма * Ставка / (Ставка + 100);
КонецПроцедуры
Часто программисты пытаются написать условие так: Если Строка.СтавкаНДС = Перечисления.СтавкаНДС.НДС20 Тогда.... Это приведет к ошибке «Переменная не определена: Перечисления» на клиенте. Дело в том, что объект Перечисления доступен только на сервере.
Чтобы выполнить сравнение на стороне клиента, проанализируем использование функции ПредопределенноеЗначение. Она позволяет получить ссылку на объект конфигурации без обращения к серверному контексту:
&НаКлиенте
Процедура РассчитатьНДС(СтрокаТЧ)
Если СтрокаТЧ.СтавкаНДС = ПредопределенноеЗначение("Перечисление.СтавкаНДС.НДС20") Тогда
Ставка = 20;
ИначеЕсли СтрокаТЧ.СтавкаНДС = ПредопределенноеЗначение("Перечисление.СтавкаНДС.НДС10") Тогда
Ставка = 10;
Иначе
Ставка = 0;
КонецЕсли;
СтрокаТЧ.СуммаНДС = СтрокаТЧ.Сумма * Ставка / (100 + Ставка);
КонецПроцедуры
Если вы заметили, что при изменении суммы программа «зависает» или сумма начинает бесконечно расти, вы столкнулись с рекурсивным вызовом. Рассмотрим ситуацию: в процедуре ПриИзменении суммы вы вызываете расчет НДС, который в свою очередь снова меняет данные, вызывающие срабатывание ПриИзменении.
Важные рекомендации, чтобы этого избежать:
ТоварыСуммаПриИзменении) вручную из кода другой процедуры. Выносите логику расчета в отдельную процедуру (как в примере выше РассчитатьСуммуНДСНаКлиенте) и вызывайте именно ее.Проанализируем две основные формулы, которые применяются в 1С:
1. НДС сверху (когда сумма увеличивается на налог):
СуммаНДС = СуммаБезНДС * (Ставка / 100);
2. НДС в том числе (выделение из общей суммы):
СуммаНДС = СуммаСНДС * Ставка / (100 + Ставка);
Использование констант (например, просто числа 20) в коде — плохая практика. Старайтесь получать числовое значение ставки из самой ссылки на перечисление или из соответствующего реквизита, чтобы ваш код не пришлось переписывать при изменении законодательства.
Мы разобрали основные причины ошибки «Переменная не определена». Подытожим наши действия при возникновении подобных проблем:
Функция... и месте ее вызова.ПредопределенноеЗначение().Соблюдение этих правил позволит вам создавать надежный и производительный код в управляемом приложении 1С.