При изучении разработки в среде 1С:Предприятие 8.3 начинающие специалисты часто сталкиваются с ошибкой синтаксического контроля или времени выполнения вида: {Документ.ОказаниеУслуги.МодульОбъекта(29,25)}: Переменная не определена (Мастер). Разберем детально, почему платформа не находит нужную переменную, как устроена передача данных из документа в регистры накопления и как правильно исправить эту ошибку.
Посмотрим на типовой фрагмент процедуры ОбработкаПроведения, в котором возникает данная ситуация:
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ОстаткиМатериалов.Записывать = Истина;
Движения.СтоимостьМатериалов.Записывать = Истина;
Движения.Продажи.Записывать = Истина;
Для Каждого ТекСтрокаПереченьНоменклатуры Из ПереченьНоменклатуры Цикл
// Формирование движений по регистрам остатков
// ...
// Регистр Продажи
Движение = Движения.Продажи.Добавить();
Движение.Период = Дата;
Движение.Номенклатура = ТекСтрокаПереченьНоменклатуры.Номенклатура;
Движение.Клиент = Клиент;
Движение.Мастер = Мастер;
Движение.Количество = ТекСтрокаПереченьНоменклатуры.Количество;
Движение.Выручка = ТекСтрокаПереченьНоменклатуры.Сумма;
Движение.Стоимость = ТекСтрокаПереченьНоменклатуры.Стоимость * ТекСтрокаПереченьНоменклатуры.Количество;
КонецЦикла;
КонецПроцедуры
Проанализируем строку Движение.Мастер = Мастер;. В левой части выражения (Движение.Мастер) мы обращаемся к свойству (измерению) новой строки набора записей регистра Продажи. Это измерение успешно создано в метаданных регистра.
В правой части выражения платформа ожидает получить значение, которое требуется записать в это измерение. В модуле объекта документа платформа позволяет напрямую по имени обращаться к реквизитам шапки этого документа (например, Дата, Клиент, Склад). Ошибка «Переменная не определена (Мастер)» означает, что в контексте выполняемого модуля нет ни локальной переменной с таким именем, ни реквизита шапки документа с именем Мастер.
Рассмотрим две наиболее распространенные причины этой ситуации:
Сотрудник или Сотрудники).Сотрудник, а в поле «Синоним» указано Мастер. В программном коде 1С всегда используется исключительно свойство Имя объекта метаданных.Разберем по шагам, как исправить конфигурацию в зависимости от структуры ваших метаданных.
Вариант 1. Создать или переименовать реквизит в документе
Если по логике задачи документ должен содержать информацию о мастере, выполним следующие действия:
Мастер (тип данных: СправочникСсылка.Сотрудники).Сотрудник или Сотрудники, изменим его свойство Имя на Мастер.Вариант 2. Использовать фактическое имя существующего реквизита в коде
Если реквизит документа уже создан и называется, например, Сотрудники, изменим программный код процедуры проведения, указав реальное имя реквизита шапки:
// Присваиваем измерению Мастер значение реквизита документа Сотрудники
Движение.Мастер = Сотрудники;
Рассмотрим подробнее механизм доступа к данным в модуле объекта. В момент проведения документа платформа неявно связывает модуль с контекстом текущего экземпляра документа. Записи Мастер и ЭтотОбъект.Мастер в модуле объекта эквивалентны. Использование явного указания контекста ЭтотОбъект.ИмяРеквизита делает код более наглядным и защищает от конфликтов имен с локальными переменными:
// Явное обращение к реквизитам шапки и строки табличной части
Движение.Период = ЭтотОбъект.Дата;
Движение.Клиент = ЭтотОбъект.Клиент;
Движение.Мастер = ЭтотОбъект.Мастер;
Движение.Номенклатура = ТекСтрокаПереченьНоменклатуры.Номенклатура;
Чтобы исключить опечатки и ошибки необъявленных переменных при написании модулей, рекомендуется применять встроенные механизмы среды разработки:
Если измерение регистра является обязательным для ведения аналитики (например, для расчета выработки или начисления зарплаты), необходимо гарантировать, что в документ выбрано непустое значение. Для этого у реквизита документа Мастер в палитре свойств установим свойство Проверка заполнения в значение Выдавать ошибку, либо выполним программную проверку в коде:
Если Не ЗначениеЗаполнено(ЭтотОбъект.Мастер) Тогда
ТекстСообщения = "Не указан мастер в шапке документа!";
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ТекстСообщения;
Сообщение.Поле = "Мастер";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
Возврат;
КонецЕсли;
Такой подход предотвратит запись некорректных движений с пустой аналитикой в регистры накопления.