При адаптации обработок загрузки данных из внешних источников (например, из файлов Excel) часто возникает задача создания документов определенного вида. Попытка скопировать алгоритм создания одного документа (например, ПоступлениеТМЦ) для формирования другого (ЗаявкаПокупателя) нередко приводит к ошибкам времени выполнения: «Поле агрегатного объекта не обнаружено». Разберем по шагам структуру документа ЗаявкаПокупателя в конфигурации «1С:Торговля и Склад 7.7» (ТиС 9.x), выясним причины частых ошибок и напишем корректный код создания и заполнения документа.
Рассмотрим типичные проблемы, с которыми сталкиваются начинающие разработчики при программном формировании документа ЗаявкаПокупателя:
КодОперации:ЗаявкаПокупателя нет реквизита КодОперации. Вместо него используется реквизит ВидОперации, который принимает значения перечисления Перечисление.ВидыОперацийЗаявок (например, Неподтвержденная, НаСклад, НаПоставку).ВидТМЦ в табличной части:ЗаявкаПокупателя отсутствует реквизит ВидТМЦ. Обращение к нему вызывает ошибку исполнения.ОсновнойПоставщик или ОсновнойТипЦенПокупки. Необходимо использовать соответствующие значения продаж, а также обязательно заполнять договор контрагента.Записать() на каждой итерации цикла обхода строк табличной части сильно замедляет работу и избыточно нагружает базу данных. Метод Записать() следует вызывать один раз после добавления всех строк.глПересчетТаблЧасти() предназначена для работы с открытой экранной формой документа. При программной обработке объекта пересчет сумм и налогов выполняется непосредственно в реквизитах табличной части.В типовой конфигурации «Торговля и Склад 7.7» предусмотрена глобальная процедура глЗаполнитьШапку, которая вызывается при интерактивном создании документов. Мы можем использовать ее для автоматической установки основных реквизитов (автор, склад, фирма, валюта, налоги и тип цен для операции «Продажа»).
Посмотрим на пример кода с автозаполнением шапки:
ДокСоздаваемый = СоздатьОбъект("Документ.ЗаявкаПокупателя");
ДокСоздаваемый.Новый();
// Заполняем типовые реквизиты шапки для операции продажи
глЗаполнитьШапку(ДокСоздаваемый, 0, "Продажа");
// Устанавливаем специфические реквизиты
ДокСоздаваемый.ВидОперации = Перечисление.ВидыОперацийЗаявок.Неподтвержденная;
ДокСоздаваемый.Контрагент = глЗначениеПоУмолчанию("ОсновнойПокупатель");
ДокСоздаваемый.Договор = ДокСоздаваемый.Контрагент.ОсновнойДоговор;
// Заполняем табличную часть из таблицы значений ТЗПРов
ТЗПРов.ВыбратьСтроки();
Пока ТЗПРов.ПолучитьСтроку() = 1 Цикл
ТекТовар = ТЗПРов.Товар;
ДокСоздаваемый.НоваяСтрока();
ДокСоздаваемый.Номенклатура = ТекТовар;
ДокСоздаваемый.Количество = ТЗПРов.Количество;
ДокСоздаваемый.Единица = ТекТовар.БазоваяЕдиница;
ДокСоздаваемый.Коэффициент = 1;
ДокСоздаваемый.Цена = ТЗПРов.Цена;
ДокСоздаваемый.Сумма = ТЗПРов.Цена * ТЗПРов.Количество;
КонецЦикла;
// Записываем документ после полного формирования
ДокСоздаваемый.Записать();
// Открываем форму созданного документа для пользователя
ОткрытьФорму(ДокСоздаваемый.ТекущийДокумент());
Если требуется полный контроль над созданием объекта без вызова стандартных глобальных функций инициализации, разберем пошаговое ручное заполнение шапки и строк документа.
Рассмотрим пример детального заполнения:
ДокСоздаваемый = СоздатьОбъект("Документ.ЗаявкаПокупателя");
ДокСоздаваемый.Новый();
// Заполнение реквизитов шапки
ДокСоздаваемый.ДатаДок = ТекущаяДата();
ДокСоздаваемый.Автор = глПользователь;
ДокСоздаваемый.Фирма = глЗначениеПоУмолчанию("ОсновнаяФирма");
ДокСоздаваемый.Склад = глЗначениеПоУмолчанию("ОсновнойСклад");
ДокСоздаваемый.ВидОперации = Перечисление.ВидыОперацийЗаявок.Неподтвержденная;
// Установка контрагента и договора
ДокСоздаваемый.Контрагент = глЗначениеПоУмолчанию("ОсновнойПокупатель");
Если ПустоеЗначение(ДокСоздаваемый.Контрагент) = 0 Тогда
ДокСоздаваемый.Договор = ДокСоздаваемый.Контрагент.ОсновнойДоговор;
КонецЕсли;
// Установка валюты и типа цен
ТипЦен = глЗначениеПоУмолчанию("ОсновнойТипЦенПродажи");
ДокСоздаваемый.ТипЦен = ТипЦен;
ДокСоздаваемый.Валюта = глРубли;
ДокСоздаваемый.Курс = глКурсДляВалюты(глРубли, ДокСоздаваемый.ДатаДок);
ДокСоздаваемый.Кратность = 1;
// Налоговые флаги
Если ПустоеЗначение(ТипЦен) = 0 Тогда
ДокСоздаваемый.СуммаВклНДС = ТипЦен.ЦенаВклНДС;
ДокСоздаваемый.СуммаВклНП = ТипЦен.ЦенаВклНП;
КонецЕсли;
ДокСоздаваемый.УчитыватьНДС = 1;
ДокСоздаваемый.УчитыватьНП = 0;
// Заполнение табличной части
ТЗПРов.ВыбратьСтроки();
Пока ТЗПРов.ПолучитьСтроку() = 1 Цикл
ТекТовар = ТЗПРов.Товар;
ДокСоздаваемый.НоваяСтрока();
ДокСоздаваемый.Номенклатура = ТекТовар;
ДокСоздаваемый.Количество = ТЗПРов.Количество;
// Если единица не задана, берем базовую
Если ПустоеЗначение(ТекТовар.БазоваяЕдиница) = 0 Тогда
ДокСоздаваемый.Единица = ТекТовар.БазоваяЕдиница;
ДокСоздаваемый.Коэффициент = ТекТовар.БазоваяЕдиница.Коэффициент;
Иначе
ДокСоздаваемый.Коэффициент = 1;
КонецЕсли;
ДокСоздаваемый.Цена = ТЗПРов.Цена;
ДокСоздаваемый.Сумма = Окр(ТЗПРов.Цена * ТЗПРов.Количество, 2);
КонецЦикла;
// Итоговая запись документа
ДокСоздаваемый.Записать();
// Открытие созданного документа
ОткрытьФорму(ДокСоздаваемый.ТекущийДокумент());
Сообщить(ТипЗначенияСтр(Переменная));, не забывая ставить точку с запятой в конце строки.