При работе в 1С:ERP Управление предприятием часто возникает ситуация, когда в системе накапливается огромное количество старых документов Заказ поставщику (например, за прошлые периоды 2018–2019 годов), которые по разным причинам не были закрыты вручную. Оставлять их в статусе «К поступлению» или «В работе» нельзя, так как они искажают отчетность, влияют на доступные остатки и создают «шум» в регистрах накопления. В этой статье мы подробно разберем, как автоматизировать процесс закрытия таких заказов с помощью внешней обработки, используя возможности типового механизма конфигурации.
Проанализируем ситуацию: простое программное изменение реквизита Статус в значение Закрыт недостаточно. Документ Заказ поставщику в ERP делает движения по множеству регистров (например, Заказы поставщикам, Расчеты с поставщиками, Движения Номенклатура — Документы заказа). Если заказ выполнен не полностью, ручная смена статуса без корректировки остатков по регистрам приведет к тому, что невыполненные строки «зависнут» в системе как ожидаемые поставки.
Именно поэтому мы будем использовать типовой Помощник закрытия заказов. Он автоматически отменяет неотработанные строки, корректирует расхождения и корректно обнуляет регистры. Наша задача — программно передать ему список нужных документов.
Рассмотрим процедуру получения ссылок на документы, которые подлежат закрытию. Типичная ошибка начинающих разработчиков — попытка передать ДокументОбъект с сервера на клиент. Напомним, что объекты (типа ДокументОбъект.ЗаказПоставщику) существуют только в памяти сервера. На клиент мы должны возвращать только ссылки или массивы ссылок.
Создадим функцию, которая отберет заказы по конкретному менеджеру за определенный период:
&НаСервере
Функция ПолучитьСписокЗаказовДляЗакрытия()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗаказПоставщику.Ссылка КАК Ссылка
|ИЗ
| Документ.ЗаказПоставщику КАК ЗаказПоставщику
|ГДЕ
| ЗаказПоставщику.Проведен = ИСТИНА
| И ЗаказПоставщику.ПометкаУдаления = ЛОЖЬ
| И ЗаказПоставщику.Менеджер = &Менеджер
| И ЗаказПоставщику.Дата МЕЖДУ &НачалоПериода И &КонецПериода
| И ЗаказПоставщику.Статус <> ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказовПоставщикам.Закрыт)";
Запрос.УстановитьПараметр("Менеджер", Справочники.Пользователи.НайтиПоНаименованию("Якушевич Михаил Михайлович"));
Запрос.УстановитьПараметр("НачалоПериода", НачалоДня('20180101'));
Запрос.УстановитьПараметр("КонецПериода", КонецДня('20191231'));
РезультатЗапроса = Запрос.Выполнить();
// Возвращаем массив ссылок, который легко передается на клиент
Возврат РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецФункции
Выясним, какие параметры ожидает форма Обработка.ПомощникЗакрытияЗаказов.Форма.ФормаЗакрытия. Это ключевой момент, так как от этих флагов зависит логика обработки строк. Разберем основные ключи структуры:
СписокЗначений, содержащий ссылки на закрываемые документы.Истина, система установит признак отмены для всех строк, по которым не было фактического поступления.Закрыт.Посмотрим на реализацию основной клиентской процедуры:
&НаКлиенте
Процедура ЗапуститьМассовоеЗакрытие(Команда)
МассивСсылок = ПолучитьСписокЗаказовДляЗакрытия();
Если МассивСсылок.Количество() = 0 Тогда
ПоказатьПредупреждение(, "Заказы для закрытия не найдены.");
Возврат;
КонецЕсли;
СписокЗаказовКЗакрытию = Новый СписокЗначений;
СписокЗаказовКЗакрытию.ЗагрузитьЗначения(МассивСсылок);
СтруктураЗакрытия = Новый Структура;
СтруктураЗакрытия.Вставить("Заказы", СписокЗаказовКЗакрытию);
// В качестве инициатора можно указать первый заказ из списка или саму обработку
СтруктураЗакрытия.Вставить("ДокументИнициатор", МассивСсылок[0]);
СтруктураЗакрытия.Вставить("ОтменитьНеотработанныеСтроки", Истина);
СтруктураЗакрытия.Вставить("СкорректироватьЦены", Истина);
СтруктураЗакрытия.Вставить("ЗакрыватьЗаказы", Истина);
// Открываем типовую форму помощника ERP
ОткрытьФорму("Обработка.ПомощникЗакрытияЗаказов.Форма.ФормаЗакрытия",
СтруктураЗакрытия,
ЭтаФорма,
Истина,
,
,
Неопределено,
РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
В процессе разработки мы можем столкнуться с тем, что система требует перепровести документ перед закрытием. Это происходит, если Модифицированность формы документа или его состояние не соответствуют ожиданиям помощника.
Проанализируем ситуацию с ошибкой XDTO или ошибкой передачи объекта. Как мы выяснили ранее, никогда не пытайтесь вернуть Выборка.Ссылка.ПолучитьОбъект() из серверной функции на клиент. Если вам нужно провести документ перед закрытием, делайте это строго на сервере в отдельном цикле:
&НаСервере
Процедура ПровестиЗаказыПередЗакрытием(МассивСсылок)
Для Каждого Ссылка Из МассивСсылок Цикл
ОбъектДок = Ссылка.ПолучитьОбъект();
Если Не ОбъектДок.Проведен Тогда
Попытка
ОбъектДок.Записать(РежимЗаписиДокумента.Проведение);
Исключение
ЗаписьЖурналаРегистрации("МассовоеЗакрытие", УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось провести заказ: " + Ссылка + " Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Обратите внимание: если вы закрываете документы за 2018–2019 годы, скорее всего, период редактирования закрыт. В этом случае обычная запись не сработает. Вам потребуется либо временно открыть период (что не всегда возможно в рабочей базе), либо использовать специализированные методы обхода проверок, однако использование типового Помощника закрытия все равно инициирует стандартные механизмы проведения, поэтому контроль дат запрета остается обязательным условием.
Рассмотрим более детально, что еще можно передать в структуру закрытия для более тонкой настройки процесса в 1С:ERP:
СкорректироватьМерныеТоварыПоПриемке — критически важный параметр для торговых организаций. Если по заказу на 100 метров ткани пришло 100.2 метра (в пределах допуска), этот флаг позволит корректно «схлопнуть» остаток.ТаблицаТоваровПриход / ТаблицаТоваровРасход — эти таблицы используются в сложных схемах, где задействованы возвраты или корректировки приобретений. При массовом закрытии старых «хвостов» их обычно не заполняют, доверяя автоматике помощника.Если заказов тысячи, открытие формы помощника для каждого из них или даже для всех сразу может привести к зависанию интерфейса или блокировкам таблиц базы данных. В таких случаях мы рекомендуем:
ЗакрытиеЗаказовСервер.ЗакрытьЗаказы() в последних версиях ERP).Подводя итог, можно сказать, что использование типового помощника закрытия через ОткрытьФорму с подготовленной структурой параметров — это самый безопасный способ массового приведения базы 1С:ERP в порядок, так как он гарантирует соблюдение всей бизнес-логики, заложенной вендором.