Как программно создать и заполнить документ «Закрытие заказов покупателей» в 1С:УПП

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

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

Выясняем причину: почему в табличной части программно видно только три колонки

При первом знакомстве с документом ЗакрытиеЗаказовПокупателей в конфигураторе разработчик может испытать недоумение. Открыв интерактивную форму документа в режиме «1С:Предприятие», мы видим множество информативных колонок: «Сумма заказа», «Осталось отгрузить», «Осталось оплатить», «Размещено», «Резерв», «Просрочено» и другие. Однако, попытавшись обратиться к табличной части Заказы программно, мы обнаруживаем, что в ней физически присутствуют всего три колонки:

  1. ЗаказПокупателя — ссылка на закрываемый документ;
  2. ПричинаЗакрытияЗаказа — ссылка на элемент справочника причин закрытия;
  3. НомерСтроки — стандартное системное поле.

Проанализируем эту ситуацию. Все остальные многочисленные поля, отображаемые на форме, являются виртуальными (расчетными). Они не хранятся в базе данных для этого документа, так как это привело бы к избыточному дублированию информации и нарушению принципов нормализации данных. Расчет этих показателей происходит динамически «на лету» в момент открытия формы или при интерактивном подборе заказов. Программа делает запросы к остаткам регистров накопления:

Таким образом, при программном создании документа нам не требуется заполнять эти виртуальные поля. Для успешного проведения документа системе необходимы только сам заказ и причина его закрытия. При последующем интерактивном открытии созданного нами документа платформа автоматически рассчитает и отобразит всю необходимую информацию на форме.

Разбор типичных ошибок при заполнении табличной части

Рассмотрим ситуацию, когда при выполнении программного кода строки добавляются, но реквизит ЗаказПокупателя остается пустым. Выясним причину, почему это происходит. Проанализируем типичный фрагмент кода, вызывающий проблемы:


// Проблемный вариант заполнения
Для каждого стр из Результат цикл
    ЗаказыЗакрывающиеся = Закрытие.Заказы.Добавить();
    ЗаказыЗакрывающиеся.ЗаказПокупателя = стр.ДокументРез;
    ЗаказыЗакрывающиеся.ПричинаЗакрытияЗаказа = СсылкаНаПричину;
КонецЦикла;

Если после выполнения строки ЗаказыЗакрывающиеся.ЗаказПокупателя = стр.ДокументРез; значение остается пустым, то в 99% случаев проблема заключается в несоответствии типов данных. Платформа «1С:Предприятие» строго типизирует колонки табличных частей. Если колонка ожидает ссылку типа ДокументСсылка.ЗаказПокупателя, а ей присваивается значение другого типа (например, строка, уникальный идентификатор или ссылка на документ другого вида), то система не выдает ошибку времени выполнения, а просто «тихо» очищает поле, записывая туда ПустаяСсылка.

Посмотрим на возможные причины несоответствия типов:

Для гарантированного решения этой проблемы рекомендуется явно типизировать получаемые из запроса данные и оптимизировать обращение к табличной части документа.

Правильный алгоритм программного создания документа

Разберем по шагам правильную методику создания и заполнения документа. Чтобы код работал стабильно и быстро, особенно в контексте регламентного задания на сервере, необходимо придерживаться следующих правил:

  1. Создавать объект документа непосредственно через менеджер документов: Документы.ЗакрытиеЗаказовПокупателей.СоздатьДокумент().
  2. Выносить обращение к табличной части за пределы цикла, чтобы избежать лишних обращений к свойствам объекта на каждой итерации.
  3. Обязательно заполнять такие системные реквизиты, как Организация, Дата, ВидОперации и ОтражатьВУправленческомУчете.
  4. Использовать явную проверку типов перед записью в табличную часть.

Рассмотрим оптимальный шаблон кода для автоматического заполнения документа:


// Создаем новый документ
НовыйДокумент = Документы.ЗакрытиеЗаказовПокупателей.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Организация = ВыбраннаяОрганизация;
НовыйДокумент.ВидОперации = Перечисления.ВидыОперацийЗакрытиеЗаказовПокупателей.ЗакрытиеЗаказов;
НовыйДокумент.Комментарий = "Автоматическое закрытие заказов регламентным заданием от " + ТекущаяДата();

// Заполняем признаки отражения в учете
НовыйДокумент.ОтражатьВУправленческомУчете = Истина;

// Получаем ссылку на табличную часть один раз перед циклом
ТабличнаяЧастьЗаказы = НовыйДокумент.Заказы;

Для Каждого СтрокаДанных Из РезультатВыборки Цикл
    
    // Проверяем тип данных перед добавлением
    Если ТипЗнч(СтрокаДанных.ЗаказПокупателя) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        
        НоваяСтрокаТЧ = ТабличнаяЧастьЗаказы.Добавить();
        НоваяСтрокаТЧ.ЗаказПокупателя = СтрокаДанных.ЗаказПокупателя;
        НоваяСтрокаТЧ.ПричинаЗакрытияЗаказа = СсылкаНаПричинуЗакрытия;
        
    КонецЕсли;
    
КонецЦикла;

// Записываем и проводим документ
Попытка
    НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
    ЗаписатьВЛог("Документ успешно проведен: " + НовыйДокумент.Ссылка);
Исключение
    // Если провести не удалось, записываем только объект, чтобы не потерять данные
    НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
    ЗаписатьВЛог("Не удалось провести документ. Ошибка: " + ОписаниеОшибки());
КонецПопытки;

Важность выбора правильного вида операции

Проанализируем бизнес-логику процесса закрытия заказов. В документе ЗакрытиеЗаказовПокупателей предусмотрено несколько видов операций (перечисление ВидыОперацийЗакрытиеЗаказовПокупателей). Крайне важно выбрать правильный вид операции для вашего регламентного задания:

Важно: ошибочный выбор вида операции при автоматическом закрытии может привести к искажению управленческой отчетности и потере заказов из плана продаж.

Особенности проведения в фоновом режиме

Поскольку автоматическое закрытие обычно выполняется в рамках регламентного задания, необходимо учитывать технические нюансы серверного выполнения:

Применяя описанные подходы, мы сможем создать надежный, быстродействующий и безопасный механизм автоматического закрытия заказов покупателей в конфигурациях на базе обычных форм платформы «1С:Предприятие 8».

← На главную