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