Почему возникает ошибка «Переменная не определена (ДанныеЗаполнения)» при вводе на основании в 1С?

Программист 1С v8.3 (Обычные формы) Бухгалтерский учет
← На главную

При разработке механизмов автоматического заполнения документов в системе 1С:Предприятие программисты часто сталкиваются с ситуацией, когда стандартный конструктор ввода на основании генерирует код, который при выполнении выдает ошибку: «Переменная не определена (ДанныеЗаполнения)». Особенно часто это происходит в конфигурациях на обычных формах, таких как БГУ 1.0 или УПП 1.3.

В данной статье мы подробно разберем причины возникновения этой ошибки, выясним, почему данные могут не переноситься даже при отсутствии ошибок в коде, и научимся правильно настраивать метаданные для корректной работы механизма «Ввод на основании».

Причина 1: Несоответствие имен параметров процедуры

Проанализируем структуру процедуры ОбработкаЗаполнения. В разных версиях платформы и в зависимости от того, как был запущен конструктор, первый параметр этой процедуры может называться по-разному. В старых редакциях платформы (8.0, 8.1 и ранних 8.2) стандартным именем было Основание. В современных версиях (8.3) конструктор по умолчанию использует имя ДанныеЗаполнения.

Ошибка возникает тогда, когда в заголовке процедуры указано одно имя, а внутри тела кода — другое. Рассмотрим пример ошибочного кода:


Процедура ОбработкаЗаполнения(Основание, ТекстЗаполнения, СтандартнаяОбработка)
    // ОШИБКА: Используется ДанныеЗаполнения, хотя в параметрах выше указано Основание
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.РасчетСтоимостиУслуг") Тогда
        Контрагент = ДанныеЗаполнения.Контрагент;
    КонецЕсли;
КонецПроцедуры

Выясним, как это исправить. Нам необходимо обеспечить строгое соответствие. Если мы решили использовать ДанныеЗаполнения, то и в скобках после названия процедуры должно стоять именно это слово. Исправленный вариант будет выглядеть так:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.РасчетСтоимостиУслуг") Тогда
        // Теперь переменная определена и содержит ссылку на документ-основание
        Контрагент = ДанныеЗаполнения.Контрагент;
        Учреждение = ДанныеЗаполнения.Учреждение;
    КонецЕсли;
КонецПроцедуры

Причина 2: Проблема пустой переменной (Undefined)

Иногда после исправления имени переменной программист замечает, что ошибка исчезла, но данные в новом документе все равно не заполняются. При проверке отладчиком оказывается, что переменная ДанныеЗаполнения имеет значение Неопределено. Разберем по шагам, почему это происходит:

  1. Способ создания документа: Процедура ОбработкаЗаполнения вызывается всегда при создании нового объекта. Если вы просто нажали кнопку «Создать» (или «Добавить») в списке документов, платформа вызывает эту процедуру, но не передает в нее никакой объект-основание. В этом случае переменная будет пустой, и условие Если ТипЗнч(...) просто не сработает.
  2. Программное создание документа: Если вы создаете документ из кода, используя метод СоздатьДокумент(), автоматического заполнения не произойдет. Чтобы механизм сработал, необходимо явно вызвать метод Заполнить(), передав в него ссылку на документ-источник.

Рассмотрим пример правильного программного вызова:


НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
// Явный вызов процедуры ОбработкаЗаполнения
НовыйДокумент.Заполнить(СсылкаНаСчетНаОплату); 
НовыйДокумент.Записать();

Причина 3: Настройка метаданных в конфигураторе

Для того чтобы кнопка «Ввести на основании» появилась в интерфейсе и корректно передавала данные, необходимо проверить настройки в дереве метаданных. Выясним, на что обратить внимание:

Во-первых, откроем документ-приемник (тот, который мы создаем). На вкладке «Ввод на основании» в поле «Является основанием для» (или в списке вводимых на основании объектов в зависимости от версии) должен быть отмечен документ-источник.

Во-вторых, проверим документ-источник. У него в списке «Вводится на основании» должен быть указан наш документ-приемник. Если эта связь настроена только в одну сторону, стандартные команды платформы могут вести себя некорректно, передавая пустые ссылки в процедуру заполнения.

Особенности работы с табличными частями

При переносе данных из табличных частей важно помнить, что обращение к ним происходит через точку от объекта-основания. Рассмотрим типичный цикл заполнения, который генерирует конструктор:


Для Каждого ТекСтрокаИзИсточника Из ДанныеЗаполнения.Услуги Цикл
    НоваяСтрока = Услуги.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, ТекСтрокаИзИсточника);
КонецЦикла;

Здесь Услуги без префикса — это табличная часть текущего (нового) документа, а ДанныеЗаполнения.Услуги — это табличная часть документа, на основании которого мы строим новый объект. Обязательно проверяйте наличие и идентичность имен колонок в обеих табличных частях.

Рекомендации по отладке

Если вы не понимаете, что происходит в момент создания документа, воспользуйтесь простым приемом. Добавьте в начало процедуры ОбработкаЗаполнения диагностическое сообщение:

Сообщить("Тип передаваемых данных: " + ТипЗнч(ДанныеЗаполнения));

Это позволит вам сразу увидеть, передает ли платформа ссылку на документ или, возможно, структуру параметров. В сложных конфигурациях, таких как БГУ 1.0, в ДанныеЗаполнения может передаваться Структура, если ввод на основании инициирован специальной обработкой. В таком случае ваше условие ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка...") не сработает, и код заполнения будет пропущен.

Важный совет: Если вы уже начали править код, созданный конструктором, старайтесь больше не запускать конструктор для этой процедуры. Он полностью перезаписывает содержимое между своими тегами-комментариями, и вы рискуете потерять все свои исправления, включая исправленные имена переменных.

← На главную