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