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