При разработке и доработке документов в платформе 1С:Предприятие 7.7 начинающие разработчики часто сталкиваются с ошибкой «Переменная не определена» при попытке обратиться к элементу диалога или переменной формы из процедуры ОбработкаПроведения. Разберем архитектурные особенности платформы 1С 7.7, выясним причину такого поведения и рассмотрим правильные варианты реализации логики.
Проанализируем ситуацию: на форме документа создан элемент диалога (например, поле выбора субсчета Счет62), но в дереве метаданных конфигуратора сам реквизит у документа отсутствует. При попытке сформировать проводку в модуле документа возникает ошибка времени выполнения:
Операция.Дебет.Счет = Счет62;
// {Документ.ПередачаОС.Модуль Документа(75)}: Переменная не определена (Счет62)
В платформе 1С 7.7 модуль формы и модуль документа — это два изолированных контекста. Переменные формы и элементы диалога инициализируются исключительно при интерактивном открытии окна пользователем. Модуль документа не имеет прямого доступа к элементам управления формы.
Кроме того, документ может проводиться программно (из внешних обработок, при групповом перепроведении, восстановлении последовательности или переносе данных). В этих случаях форма документа вообще не создается. Если бы логика проведения зависела от переменных формы, система не смогла бы сформировать проводки.
Разберем по шагам стандартный и наиболее надежный способ решения задачи:
ПередачаОС).Счет62) и назначим ему тип Счет.Основной (или соответствующий план счетов).ОбработкаПроведения обратимся к реквизиту напрямую и добавим обязательную проверку на заполненность:
Процедура ОбработкаПроведения()
Если ПустоеЗначение(Счет62) = 1 Тогда
Сообщить("Не указан счет расчетов с контрагентом!", "!");
СтатусВозврата(0);
Возврат;
КонецЕсли;
Операция.Новая();
Операция.Дебет.Счет = Счет62;
// Заполнение остальных субконто и суммы проводки
Операция.Записать();
КонецПроцедуры
Рассмотрим альтернативную ситуацию: если пользователю не требуется каждый раз вручную выбирать субсчет на форме, правильнее определять его программно непосредственно в модуле документа.
Посмотрим на примеры получения счета:
Операция.Дебет.Счет = СчетПоКоду("62.1");
Если Контрагент.ЮрФизЛицо = Перечисление.ЮрФизЛицо.ФизЛицо Тогда
Операция.Дебет.Счет = СчетПоКоду("62.1");
Иначе
Операция.Дебет.Счет = СчетПоКоду("62.2");
КонецЕсли;
Если для удобства интерфейса требуется ограничить выбор конкретным списком субсчетов через элемент управления «Список значений», свяжем его с реквизитом документа:
СчетУчета типа Счет.ПриЗаписи присваиваем выбранный элемент списка реквизиту документа:
// В модуле формы документа
Процедура ПриЗаписи()
СчетУчета = СписокСубсчетов.ПолучитьЗначение(СписокСубсчетов.ТекущаяСтрока());
КонецПроцедуры
В этом случае при проведении документа в модуле проведения значение СчетУчета будет гарантированно доступно и сохранено в базе данных.