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