При изучении основ разработки в системе «1С:Предприятие 8» по методикам М.Г. Радченко, начинающие программисты часто сталкиваются с трудностями при выносе логики в общие модули. Типичная ситуация: код написан правильно с точки зрения синтаксиса, но система выдает ошибку Переменная не определена (Элементы) или расчеты в пользовательском режиме просто не срабатывают. В этой статье мы подробно разберем, как правильно разделять код между модулем формы и общим модулем, а также обеспечим корректную работу событий.
Рассмотрим ситуацию, когда разработчик пытается поместить обработчики событий (например, ПриИзменении) напрямую в общий модуль. Система выдает ошибку компиляции, так как объект Элементы является свойством управляемой формы. Он доступен только «внутри» формы. Общий модуль — это независимая единица, которая «не знает», какая форма его вызывает и какие кнопки или таблицы на ней расположены.
Проанализируем ошибочный код в общем модуле:
&НаКлиенте
Процедура МатериалыКоличествоПриИзменении(Элемент)
СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные; // ОШИБКА: Элементы не определены
РаботаСДокументами.РассчитатьСумму(СтрокаТабличнойЧасти);
КонецПроцедуры
Выясним причину: общий модуль не имеет прямого доступа к экранным формам. Чтобы решить эту проблему, мы должны четко разделить ответственность между модулями. В модуле формы мы оставляем обработку интерфейсных событий и получение данных, а в общем модуле — только математический расчет.
Разберем, как должна выглядеть процедура в общем модуле (например, с именем РаботаСДокументами). Она должна принимать строку данных как параметр, чтобы быть независимой от конкретной формы. Обязательно убедитесь, что в свойствах общего модуля установлены флажки Клиент (управляемое приложение) и Сервер, а также стоит флаг Экспорт в самой процедуре.
// В общем модуле РаботаСДокументами
Процедура РассчитатьСумму(СтрокаТабличнойЧасти) Экспорт
// Проверяем, что строка не пустая, чтобы избежать ошибок
Если СтрокаТабличнойЧасти <> Неопределено Тогда
СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
КонецЕсли;
КонецПроцедуры
Теперь перейдем в модуль формы документа. Здесь мы будем использовать коллекцию Элементы, чтобы получить текущую строку, в которой пользователь изменил данные. Рассмотрим, как вызвать процедуру из общего модуля:
&НаКлиенте
Процедура МатериалыКоличествоПриИзменении(Элемент)
// Получаем строку, в которой произошло изменение
СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;
// Вызываем процедуру из общего модуля, передавая ей строку
РаботаСДокументами.РассчитатьСумму(СтрокаТабличнойЧасти);
КонецПроцедуры
&НаКлиенте
Процедура МатериалыЦенаПриИзменении(Элемент)
СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;
РаботаСДокументами.РассчитатьСумму(СтрокаТабличнойЧасти);
КонецПроцедуры
Иногда возникает ситуация: код написан в модуле формы, ошибок нет, при изменении количества сумма считается, а при изменении цены — нет. Проанализируем, почему это происходит. Самая частая причина заключается в том, что процедура в коде есть, но она не «связана» с самим полем на форме.
Разберем по шагам, как проверить событийную механику:
Цена (колонку табличной части).ПриИзменении.МатериалыЦенаПриИзменении. Если поле пустое, код не выполнится, даже если он написан правильно.Рассмотрим несколько профессиональных нюансов, которые помогут сделать ваш код более надежным:
Принцип DRY (Don't Repeat Yourself). Использование одной процедуры РассчитатьСумму для разных событий (изменение цены, изменение количества, изменение скидки) — это правильный подход. Если завтра формула расчета изменится (например, добавится НДС), вам нужно будет внести правку только в одном месте — в общем модуле.
Типы данных. Обратите внимание, что когда мы передаем ТекущиеДанные в общий модуль, мы передаем объект типа ДанныеФормыЭлементКоллекции. Это ссылка на данные. Поэтому, когда внутри общего модуля мы меняем значение СтрокаТабличнойЧасти.Сумма, оно мгновенно отображается на экране пользователя в форме документа.
Контекст компиляции. Если вы планируете вызывать расчеты не только с клиента, но и с сервера (например, при программном заполнении документа), убедитесь, что ваш общий модуль имеет флаг Сервер. В управляемом приложении разделение контекстов крайне важно для производительности и стабильности программы.
Таким образом, для успешного решения задачи по книге Радченко необходимо помнить: Элементы живут только в форме, общий модуль — это склад функций, а палитра свойств — это мост, который соединяет интерфейс с вашим кодом.