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