
В предыдущей статье было описано, как массово находить документы за выбранный период, отменять их проведение и помечать на удаление. Это распространенная задача, а штатных средств для ее решения в программе нет. Мной была создана внешняя обработка, которая в несколько проходов последовательно удаляет доступные ей зависимости между документами, отменяет их проведение и устанавливает пометки удаления.
Однако при испытании обработки на базе с документами производства выяснилось, что существует отдельная группа объектов, с которой такой универсальный алгоритм не справляется. Проблемы возникли с завершенными этапами, производственными операциями, сменными заданиями, а при ремонтах — с отраженными в этапах расходах материалов и работ.
Документы оказались накрепко связаны между собой в замкнутые цепочки: один документ не желает меняться, пока не изменится второй, а второй — пока не изменится первый. Для разрыва таких цепочек понадобилась еще одна — «Производственная обработка».
Алгоритм «Производственной обработки»
Код обработки решает четыре задачи:
1. Подготовка сменных заданий. Обработка находит сменные задания за выбранный период, находящиеся в закрытом состоянии. Такие задания сначала переводятся из состояния Закрыто в состояние Сформировано. Это необходимо, чтобы снять ограничения, связанные с завершенными сменными заданиями, и подготовить связанные производственные объекты к дальнейшей обработке.
2. Подготовка этапов производства и устранение связанных с ними материальных зависимостей. У каждого найденного этапа очищается табличная часть РасходМатериаловИРабот, после чего этап штатными средствами конфигурации переводится из состояния Завершен в состояние Начат. Простого изменения реквизита Статус недостаточно: обработка вызывает стандартную логику 1С:ERP изменения статуса и затем записывает документ с проведением. В результате этап отображается в системе как Начат, Ожидает завершения.
3. Установка пометки удаления производственным операциям. После подготовки этапов обработка находит относящиеся к производству операции и пытается установить для них стандартную пометку удаления. Непосредственного удаления объектов из информационной базы не производится. Если штатные проверки 1С:ERP не позволяют пометить конкретную операцию на удаление, объект остается без изменения, а ошибка фиксируется для диагностики.
4. Подготовка сменных заданий к удалению. После обработки этапов и производственных операций обработка повторно ищет за выбранный период все сменные задания, находящиеся в состоянии Сформировано. При этом не имеет значения, были они переведены в это состояние текущим запуском обработки или находились в нем ранее. Найденные задания штатными средствами 1С:ERP переводятся в состояние Формируется, после чего им устанавливается стандартная пометка удаления. Если какое-либо задание не удается изменить с первого раза, обработка повторяет попытку в следующем проходе.
Для каждого действия ведется статистика: количество найденных и измененных сменных заданий, найденных и измененных этапов производства, удаленных строк расхода материалов и работ, найденных производственных операций, установленных пометок удаления и возникших ошибок.
Таким образом, «Производственная обработка» сама не выполняет физического удаления объектов из информационной базы. Ее задача — изменить состояние специфических производственных объектов и устранить блокировки, из-за которых универсальная обработка не может последовательно удалить существующие между документами зависимости.
После работы «производственной обработки» «универсальная обработка» запускается повторно: она в несколько проходов отменяет проведение оставшихся документов и устанавливает им пометки удаления.
Теперь рассмотрим, как устроена внешняя обработка, реализующая этот алгоритм.
Форма и код «производственной обработки»
Для работы обработке необходимо получить от пользователя только период, за который требуется найти связанные с производством объекты. Поэтому на форме достаточно двух реквизитов:
-
НачалоПериода — дата начала периода;
-
КонецПериода — дата окончания периода.
Для контроля результатов на форме предусмотрены две таблицы: ПроизводственныеОперации и ЭтапыПроизводства.
В таблице ПроизводственныеОперации для каждой найденной операции отображаются сама операция, связанный с ней этап производства, номер, статус, наличие пометки удаления, результат обработки и текст возникшей ошибки.
В таблице ЭтапыПроизводства отображаются найденный этап, его дата и номер, исходный статус, результат обработки и текст ошибки.
Таким образом, таблицы выполняют роль пообъектного протокола обработки. Итоговая статистика показывает общий результат выполнения команды, а таблицы позволяют увидеть, что именно произошло с каждым найденным этапом и каждой производственной операцией, и при необходимости определить объект, на котором возникла ошибка.
Результаты обработки сменных заданий в отдельную таблицу не выводятся: для них в текущем варианте обработки используется итоговая статистика.
На форме нужна одна основная команда — Обработать.
После ее выполнения обработка последовательно выполняет несколько частей алгоритма.
Сначала она ищет за выбранный период закрытые сменные задания. Найденные сменные задания переводятся из состояния Закрыто в Сформировано. Это позволяет снять ограничения, связанные с закрытыми сменными заданиями, и продолжить подготовку производственных объектов к удалению.
Затем обработка ищет за выбранный период завершенные этапы производства. У каждого найденного этапа очищается табличная часть РасходМатериаловИРабот, после чего вызывается штатная логика 1С:ERP изменения статуса и документ записывается с проведением. Если операция выполнена успешно, этап переходит из состояния Завершен в Начат, Ожидает завершения. Если система не разрешает изменение, этап остается без изменения, а ошибка фиксируется в результатах работы.
После обработки этапов выполняется поиск производственных операций. Для каждой найденной операции обработка пытается установить стандартную пометку удаления. Если штатные проверки 1С:ERP разрешают это действие, операция помечается на удаление. Если нет — объект остается без изменения, а сообщение об ошибке сохраняется для диагностики.
На заключительном этапе обработка повторно ищет за выбранный период все сменные задания в состоянии Сформировано, независимо от того, были они переведены в это состояние текущим запуском обработки или находились в нем ранее. Найденные задания штатными средствами 1С:ERP переводятся в состояние Формируется, после чего им устанавливается стандартная пометка удаления. Если какое-либо задание не удается обработать с первого раза, попытка повторяется в следующем проходе.
По окончании пользователю выводится итоговая статистика:
-
найдено сменных заданий;
-
переведено сменных заданий из состояния Закрыто в Сформировано;
-
возвращено сменных заданий в состояние Формируется;
-
помечено сменных заданий на удаление;
-
найдено завершенных этапов;
-
изменено этапов;
-
очищено этапов с расходом материалов и работ;
-
удалено строк из табличной части РасходМатериаловИРабот;
-
найдено производственных операций;
-
помечено операций на удаление;
-
количество ошибок.
Таким образом, форма обработки остается достаточно простой. Пользователю не требуется вручную выбирать отдельные сменные задания, этапы и операции или определять порядок их обработки. Он задает период и запускает команду Обработать. Обработка сама выполняет предусмотренную последовательность действий, выводит итоговую статистику и формирует пообъектный протокол обработки этапов производства и производственных операций.
При этом обработка не выполняет физического удаления производственных документов. Она изменяет состояние специфических объектов производственного контура и устраняет блокировки, мешающие работе «Универсальной обработки». После ее выполнения «Универсальная обработка» запускается повторно и продолжает отмену проведения и установку пометок удаления для оставшихся документов.
Далее приведен код обработки, а в конце статьи рассмотрена полная последовательность массового удаления документов: первый запуск «Универсальной обработки» → «Производственная обработка» → повторный запуск «Универсальной обработки» → штатные механизмы 1С:ERP.
// ВНЕШНЯЯ ОБРАБОТКА// Подготовка производственных документов к удалению.//// Назначение обработки://// 1. Найти сменные задания за выбранный период.// 2. Закрытые сменные задания штатным механизмом ERP// перевести из статуса "Закрыто" в статус "Сформировано".// Это снимает блокировку изменения производственных операций,// принадлежащих закрытым сменным заданиям.//// 3. Найти этапы производства за выбранный период.// 4. У завершенных этапов полностью очистить табличную часть// "РасходМатериаловИРабот". Это снимает отраженный в этапе// расход материалов перед последующим удалением документов.// 5. Этапы со статусом "Завершен" штатно перевести в статус "Начат".// 6. Перепровести измененные этапы.// В испытанной базе после проведения ERP переводила этапы// в состояние "Начат, Ожидает завершения".//// 7. Найти производственные операции за выбранный период.// 8. Пометить производственные операции на удаление.//// 9. Повторно найти за период все сменные задания в состоянии// "Сформировано" и штатным механизмом ERP многопроходно// перевести их из "Сформировано" в "Формируется".// 10. После успешного перехода установить сменным заданиям// стандартную пометку удаления.//// После выполнения этой обработки можно запускать основную обработку V3,// которая многопроходно отменяет проведение остальных документов// и устанавливает им пометки удаления.&НаКлиентеПроцедура ИзменитьСтатусы(Команда)// Начало периода обязательно.Если НЕ ЗначениеЗаполнено(НачалоПериода) ТогдаСообщить("Не указано начало периода.");Возврат;КонецЕсли;// Конец периода также обязателен.Если НЕ ЗначениеЗаполнено(КонецПериода) ТогдаСообщить("Не указан конец периода.");Возврат;КонецЕсли;// Проверяем корректность диапазона дат.Если НачалоПериода > КонецПериода ТогдаСообщить("Начало периода не может быть больше конца периода.");Возврат;КонецЕсли;// Вся фактическая работа с документами выполняется на сервере.Результат = ИзменитьСтатусыНаСервере();// Выводим итоговую статистику.Сообщить("Сменных заданий найдено: "+ Строка(Результат.СменныхЗаданийНайдено)+ ". Из ""Закрыто"" в ""Сформировано"": "+ Строка(Результат.СменныхЗаданийСформировано)+ ". Этапов найдено: "+ Строка(Результат.Найдено)+ ". Завершенных: "+ Строка(Результат.Завершенных)+ ". Очищен расход у этапов: "+ Строка(Результат.ЭтаповСОчищеннымРасходом)+ ". Удалено строк расхода: "+ Строка(Результат.СтрокРасходаУдалено)+ ". Переведено в ""Начат"": "+ Строка(Результат.Изменено)+ ". Операций найдено: "+ Строка(Результат.ОперацийНайдено)+ ". Операций помечено на удаление: "+ Строка(Результат.ОперацийПомечено)+ ". Сменных заданий возвращено в ""Формируется"": "+ Строка(Результат.СменныхЗаданийФормируется)+ ". Сменных заданий помечено на удаление: "+ Строка(Результат.СменныхЗаданийПомечено)+ ". Ошибок: "+ Строка(Результат.Ошибок));КонецПроцедуры&НаСервереФункция ИзменитьСтатусыНаСервере()// Итоговая статистика обработки.Результат = Новый Структура;Результат.Вставить("СменныхЗаданийНайдено", 0);Результат.Вставить("СменныхЗаданийСформировано", 0);Результат.Вставить("СменныхЗаданийФормируется", 0);Результат.Вставить("СменныхЗаданийПомечено", 0);Результат.Вставить("Найдено", 0);Результат.Вставить("Завершенных", 0);Результат.Вставить("Изменено", 0);Результат.Вставить("ЭтаповСОчищеннымРасходом", 0);Результат.Вставить("СтрокРасходаУдалено", 0);Результат.Вставить("ОперацийНайдено", 0);Результат.Вставить("ОперацийПомечено", 0);Результат.Вставить("Ошибок", 0);// Получаем таблицы формы как обычные ТаблицыЗначений.// При каждом новом запуске предыдущий протокол очищается.ТаблицаЭтапов =РеквизитФормыВЗначение("ЭтапыПроизводства");ТаблицаОпераций =РеквизитФормыВЗначение("ПроизводственныеОперации");ТаблицаЭтапов.Очистить();ТаблицаОпераций.Очистить();// Пользователь задает даты без времени.// Для поиска используем полностью первый и последний день периода.ДатаНачала = НачалоДня(НачалоПериода);ДатаОкончания = КонецДня(КонецПериода);// Здесь сохраняются ссылки только на те сменные задания,// которые эта обработка сама успешно перевела// из статуса "Закрыто" в статус "Сформировано".//// После пометки производственных операций на удаление// именно эти задания будут переведены в "Формируется".//// Сменные задания, которые до запуска обработки уже находились// в статусе "Сформировано", "Формируется" или другом статусе,// обработка автоматически возвращать в "Формируется" не будет.ПодготовленныеСменныеЗадания = Новый Массив;// ШАГ 1. ПОДГОТОВКА СМЕННЫХ ЗАДАНИЙ.//// ERP не позволяет изменять производственную операцию,// принадлежащую закрытому сменному заданию.//// Поэтому перед обработкой этапов и операций сменные задания// со статусом "Закрыто" штатно переводятся в "Сформировано".//// Статус документа непосредственно не присваивается.// Используется экспортная процедура менеджера документа://// Документы.СменноеЗадание.УстановитьСтатус()//// Это штатный механизм ERP. Внутри него ERP выполняет блокировку// сменного задания, начинает транзакцию, изменяет статус документа// и выполняет предусмотренные конфигурацией действия с регистром// "ОперацииКСозданиюСменныхЗаданий" и производственными операциями.ВыборкаСменныхЗаданий =Документы.СменноеЗадание.Выбрать(ДатаНачала,ДатаОкончания);Пока ВыборкаСменныхЗаданий.Следующий() ЦиклРезультат.СменныхЗаданийНайдено =Результат.СменныхЗаданийНайдено + 1;ПопыткаОбъектСменногоЗадания =ВыборкаСменныхЗаданий.Ссылка.ПолучитьОбъект();Если ОбъектСменногоЗадания = Неопределено ТогдаПродолжить;КонецЕсли;// Для снятия блокировки производственных операций// требуется изменить только закрытые сменные задания.Если ОбъектСменногоЗадания.Статус <>Перечисления.СтатусыСменныхЗаданий.Закрыто ТогдаПродолжить;КонецЕсли;// Выполняем штатный переход://// Закрыто -> Сформировано//// Проведенный вручную эксперимент показал,// что после этого производственные операции остаются// связанными со сменным заданием, но блокировка,// вызванная статусом "Закрыто", снимается.Документы.СменноеЗадание.УстановитьСтатус(ВыборкаСменныхЗаданий.Ссылка,Перечисления.СтатусыСменныхЗаданий.Сформировано);// Запоминаем только успешно подготовленное сменное задание.// После обработки производственных операций именно его// нужно будет перевести из "Сформировано" в "Формируется".ПодготовленныеСменныеЗадания.Добавить(ВыборкаСменныхЗаданий.Ссылка);Результат.СменныхЗаданийСформировано =Результат.СменныхЗаданийСформировано + 1;ИсключениеРезультат.Ошибок =Результат.Ошибок + 1;Сообщить("Не удалось перевести сменное задание "+ Строка(ВыборкаСменныхЗаданий.Ссылка)+ " из ""Закрыто"" в ""Сформировано"": "+ ОписаниеОшибки());КонецПопытки;КонецЦикла;// ШАГ 2. ОЧИСТКА РАСХОДА И ПОДГОТОВКА ЭТАПОВ ПРОИЗВОДСТВА.//// Производственные операции завершенного этапа ERP// не позволяет изменять.//// Поэтому завершенные этапы штатным механизмом ERP// переводятся в статус "Начат" и перепроводятся.//// В испытанной базе после проведения этап получал состояние// "Начат, Ожидает завершения", после чего связанные// производственные операции становились доступны// для установки пометки удаления.ВыборкаЭтапов =Документы.ЭтапПроизводства2_2.Выбрать(ДатаНачала,ДатаОкончания);Пока ВыборкаЭтапов.Следующий() Цикл// Считаем все найденные за период этапы.Результат.Найдено =Результат.Найдено + 1;// Строка таблицы создается только для завершенного этапа.СтрокаЭтапа = Неопределено;Попытка// Получаем объект этапа производства.ОбъектЭтапа =ВыборкаЭтапов.Ссылка.ПолучитьОбъект();Если ОбъектЭтапа = Неопределено ТогдаПродолжить;КонецЕсли;// Обрабатываем только завершенные этапы.Если ОбъектЭтапа.Статус <>Перечисления.СтатусыЭтаповПроизводства2_2.Завершен ТогдаПродолжить;КонецЕсли;Результат.Завершенных =Результат.Завершенных + 1;// Перед изменением статуса полностью очищаем фактический// расход материалов и работ этапа.//// В ручном эксперименте именно удаление строк расхода// позволило затем отменить проведение документов передачи// материалов и многопроходно разобрать ремонтную цепочку.//// На первом варианте алгоритма не различаем обычные материалы// и промежуточные узлы: поскольку весь производственный контур// готовится к удалению, очищаем табличную часть целиком.КоличествоСтрокРасхода =ОбъектЭтапа.РасходМатериаловИРабот.Количество();Если КоличествоСтрокРасхода > 0 ТогдаОбъектЭтапа.РасходМатериаловИРабот.Очистить();Результат.ЭтаповСОчищеннымРасходом =Результат.ЭтаповСОчищеннымРасходом + 1;Результат.СтрокРасходаУдалено =Результат.СтрокРасходаУдалено+ КоличествоСтрокРасхода;КонецЕсли;// Добавляем найденный завершенный этап// в таблицу результатов.//// В колонку "Этап" записывается настоящая ссылка// на документ, поэтому из формы можно работать// именно с объектом ERP, а не только с его// текстовым представлением.СтрокаЭтапа =ТаблицаЭтапов.Добавить();СтрокаЭтапа.Этап =ВыборкаЭтапов.Ссылка;СтрокаЭтапа.Дата =ВыборкаЭтапов.Дата;СтрокаЭтапа.Номер =Строка(ВыборкаЭтапов.Номер);СтрокаЭтапа.ИсходныйСтатус =Строка(ОбъектЭтапа.Статус);СтрокаЭтапа.Результат ="";СтрокаЭтапа.Ошибка ="";// Запоминаем первоначальный статус.// Он требуется штатному механизму ERP,// обрабатывающему изменение статуса этапа.СтатусДоИзменения =ОбъектЭтапа.Статус;// Получаем штатные данные заполнения,// необходимые ERP при изменении статуса этапа.ДанныеЗаполнения =УправлениеПроизводством.ДанныеЗаполненияПриИзмененииСтатуса(ОбъектЭтапа);// Меняем статус://// Завершен -> НачатОбъектЭтапа.Статус =Перечисления.СтатусыЭтаповПроизводства2_2.Начат;// Одного присваивания нового статуса недостаточно.//// Вызываем штатный механизм ERP, который приводит// связанные реквизиты этапа в состояние,// соответствующее новому статусу.УправлениеПроизводством.ЗаполнитьРеквизитыЭтапаПриИзмененииСтатуса(ОбъектЭтапа,СтатусДоИзменения,ДанныеЗаполнения);// Ключевой момент.//// Этап необходимо не просто записать, а провести.//// В испытанной базе после проведения ERP переводила// этап в состояние://// "Начат, Ожидает завершения"//// После этого связанные производственные операции// становились доступны для установки пометки удаления.ОбъектЭтапа.Записать(РежимЗаписиДокумента.Проведение);Результат.Изменено =Результат.Изменено + 1;// Фиксируем успешный результат в таблице.СтрокаЭтапа.Результат ="Переведен в Начат";СтрокаЭтапа.Ошибка ="";ИсключениеРезультат.Ошибок =Результат.Ошибок + 1;// Если строка таблицы уже была создана,// сохраняем в ней диагностическую информацию.Если СтрокаЭтапа <> Неопределено ТогдаСтрокаЭтапа.Результат ="Не изменен";СтрокаЭтапа.Ошибка =ОписаниеОшибки();КонецЕсли;// Дополнительно выводим ошибку// в стандартные сообщения 1С.Сообщить("Не удалось изменить этап "+ Строка(ВыборкаЭтапов.Ссылка)+ ": "+ ОписаниеОшибки());КонецПопытки;КонецЦикла;// ШАГ 3. ПОМЕТКА ПРОИЗВОДСТВЕННЫХ ОПЕРАЦИЙ НА УДАЛЕНИЕ.//// К этому моменту должны быть сняты две возможные// статусные блокировки производственной операции://// 1. закрытое сменное задание переведено в "Сформировано";// 2. завершенный этап производства переведен в "Начат".//// После этого производственные операции можно штатно// пометить на удаление.//// Физическое удаление документов здесь не выполняется.// Продолжают действовать все штатные проверки ERP.ВыборкаОпераций =Документы.ПроизводственнаяОперация2_2.Выбрать(ДатаНачала,ДатаОкончания);Пока ВыборкаОпераций.Следующий() ЦиклРезультат.ОперацийНайдено =Результат.ОперацийНайдено + 1;СтрокаОперации = Неопределено;Попытка// Получаем объект производственной операции.ОбъектОперации =ВыборкаОпераций.Ссылка.ПолучитьОбъект();Если ОбъектОперации = Неопределено ТогдаПродолжить;КонецЕсли;// Добавляем операцию в таблицу результатов.СтрокаОперации =ТаблицаОпераций.Добавить();СтрокаОперации.Операция =ВыборкаОпераций.Ссылка;СтрокаОперации.Этап =ОбъектОперации.Этап;СтрокаОперации.Номер =Строка(ВыборкаОпераций.Номер);СтрокаОперации.Статус =Строка(ОбъектОперации.Статус);СтрокаОперации.Помечена =ОбъектОперации.ПометкаУдаления;СтрокаОперации.Результат ="";СтрокаОперации.Ошибка ="";// Если операция уже была помечена на удаление,// повторно ее не изменяем.//// В таблице при этом показываем ее фактическое состояние.Если ОбъектОперации.ПометкаУдаления ТогдаСтрокаОперации.Помечена =Истина;СтрокаОперации.Результат ="Уже помечена на удаление";Продолжить;КонецЕсли;// Устанавливаем стандартную пометку удаления.ОбъектОперации.УстановитьПометкуУдаления(Истина);Результат.ОперацийПомечено =Результат.ОперацийПомечено + 1;// Отражаем успешный результат в таблице.СтрокаОперации.Помечена =Истина;СтрокаОперации.Результат ="Помечена на удаление";СтрокаОперации.Ошибка ="";ИсключениеРезультат.Ошибок =Результат.Ошибок + 1;// Если строка уже была создана,// сохраняем в ней диагностическую информацию.Если СтрокаОперации <> Неопределено ТогдаСтрокаОперации.Помечена =Ложь;СтрокаОперации.Результат ="Не помечена";СтрокаОперации.Ошибка =ОписаниеОшибки();КонецЕсли;Сообщить("Не удалось пометить операцию "+ Строка(ВыборкаОпераций.Ссылка)+ ": "+ ОписаниеОшибки());КонецПопытки;КонецЦикла;// ШАГ 4. ПОВТОРНЫЙ ПОИСК СМЕННЫХ ЗАДАНИЙ,// ВОЗВРАТ В "ФОРМИРУЕТСЯ" И УСТАНОВКА ПОМЕТКИ УДАЛЕНИЯ.//// ВАЖНО:// здесь нельзя использовать только массив// ПодготовленныеСменныеЗадания.//// Этот массив содержит лишь те задания, которые именно текущий// запуск обработки перевел из "Закрыто" в "Сформировано".// Если перед производственной обработкой уже запускалась V3,// часть сменных заданий может к этому моменту уже находиться// в состоянии "Сформировано". Такие задания также необходимо// подготовить к удалению.//// Поэтому на этом шаге сменные задания за выбранный период// запрашиваются заново. В работу берутся ВСЕ задания,// которые фактически находятся в состоянии "Сформировано",// независимо от того, каким предыдущим действием они были// приведены в это состояние.//// После пометки производственных операций на удаление// выполняется штатный переход://// Сформировано -> Формируется//// После успешного перехода сменному заданию устанавливается// стандартная пометка удаления.//// Используется несколько проходов. Если в текущем проходе// удалось подготовить хотя бы одно задание, оставшиеся задания// проверяются повторно.ЗапросСменныхЗаданийФормируется = Новый Запрос;ЗапросСменныхЗаданийФормируется.Текст ="ВЫБРАТЬ| СменноеЗадание.Ссылка КАК Ссылка|ИЗ| Документ.СменноеЗадание КАК СменноеЗадание|ГДЕ| СменноеЗадание.Дата МЕЖДУ &НачалоПериода И &КонецПериода| И СменноеЗадание.Статус =| ЗНАЧЕНИЕ(Перечисление.СтатусыСменныхЗаданий.Сформировано)| И НЕ СменноеЗадание.ПометкаУдаления";ЗапросСменныхЗаданийФормируется.УстановитьПараметр("НачалоПериода",НачалоПериода);ЗапросСменныхЗаданийФормируется.УстановитьПараметр("КонецПериода",КонецПериода);ВыборкаСменныхЗаданийФормируется =ЗапросСменныхЗаданийФормируется.Выполнить().Выбрать();ОставшиесяСменныеЗадания = Новый Массив;Пока ВыборкаСменныхЗаданийФормируется.Следующий() ЦиклОставшиесяСменныеЗадания.Добавить(ВыборкаСменныхЗаданийФормируется.Ссылка);КонецЦикла;Пока ОставшиесяСменныеЗадания.Количество() > 0 ЦиклУспешноЗаПроход = 0;СледующийПроход = Новый Массив;Для Каждого СсылкаСменногоЗаданияИз ОставшиесяСменныеЗадания ЦиклПопыткаОбъектСменногоЗадания =СсылкаСменногоЗадания.ПолучитьОбъект();Если ОбъектСменногоЗадания = Неопределено ТогдаПродолжить;КонецЕсли;// Состояние проверяется повторно непосредственно// перед изменением документа.Если ОбъектСменногоЗадания.Статус =Перечисления.СтатусыСменныхЗаданий.Сформировано ТогдаДокументы.СменноеЗадание.УстановитьСтатус(СсылкаСменногоЗадания,Перечисления.СтатусыСменныхЗаданий.Формируется);Результат.СменныхЗаданийФормируется =Результат.СменныхЗаданийФормируется + 1;ИначеЕсли ОбъектСменногоЗадания.Статус <>Перечисления.СтатусыСменныхЗаданий.Формируется ТогдаПродолжить;КонецЕсли;// После штатного изменения статуса объект получаем заново.ОбъектСменногоЗадания =СсылкаСменногоЗадания.ПолучитьОбъект();Если ОбъектСменногоЗадания <> НеопределеноИ НЕ ОбъектСменногоЗадания.ПометкаУдаления ТогдаОбъектСменногоЗадания.УстановитьПометкуУдаления(Истина);Результат.СменныхЗаданийПомечено =Результат.СменныхЗаданийПомечено + 1;КонецЕсли;УспешноЗаПроход =УспешноЗаПроход + 1;Исключение// Ошибка промежуточного прохода пока не считается// окончательной. После обработки других заданий// повторим попытку.СледующийПроход.Добавить(СсылкаСменногоЗадания);КонецПопытки;КонецЦикла;Если СледующийПроход.Количество() = 0 ТогдаПрервать;КонецЕсли;Если УспешноЗаПроход = 0 Тогда// Целый проход не дал результата.// Теперь ошибки считаются окончательными.Для Каждого СсылкаСменногоЗаданияИз СледующийПроход ЦиклПопыткаОбъектСменногоЗадания =СсылкаСменногоЗадания.ПолучитьОбъект();Если ОбъектСменногоЗадания = Неопределено ТогдаПродолжить;КонецЕсли;Если ОбъектСменногоЗадания.Статус =Перечисления.СтатусыСменныхЗаданий.Сформировано ТогдаДокументы.СменноеЗадание.УстановитьСтатус(СсылкаСменногоЗадания,Перечисления.СтатусыСменныхЗаданий.Формируется);КонецЕсли;ОбъектСменногоЗадания =СсылкаСменногоЗадания.ПолучитьОбъект();Если ОбъектСменногоЗадания <> НеопределеноИ НЕ ОбъектСменногоЗадания.ПометкаУдаления ТогдаОбъектСменногоЗадания.УстановитьПометкуУдаления(Истина);КонецЕсли;ИсключениеРезультат.Ошибок =Результат.Ошибок + 1;Сообщить("Не удалось подготовить сменное задание "+ Строка(СсылкаСменногоЗадания)+ " к удалению: "+ ОписаниеОшибки());КонецПопытки;КонецЦикла;Прервать;КонецЕсли;ОставшиесяСменныеЗадания =СледующийПроход;КонецЦикла;// После заполнения обычных ТаблицЗначений// записываем их обратно в реквизиты формы.ЗначениеВРеквизитФормы(ТаблицаЭтапов,"ЭтапыПроизводства");ЗначениеВРеквизитФормы(ТаблицаОпераций,"ПроизводственныеОперации");// Возвращаем клиентской процедуре итоговую статистику.Возврат Результат;КонецФункции
Алгоритм удаления документов
В результате получилась последовательность массового удаления документов производства, в которой «Универсальная обработка» запускается дважды.
1. Первый запуск «Универсальной обработки». Обработка многопроходно отменяет проведение документов и устанавливает пометки удаления там, где это уже возможно. Тем самым удаляется часть зависимостей, мешающих дальнейшей обработке производственного контура.
2. «Производственная обработка». Обработка подготавливает специфические объекты производственного контура: сменные задания, этапы производства и производственные операции. Она изменяет состояния сменных заданий и этапов производства, очищает расход материалов и работ и устанавливает пометки удаления производственным операциям и подготовленным сменным заданиям.
3. Второй запуск «Универсальной обработки». После изменений, выполненных «Производственной обработкой», «Универсальная обработка» повторно проходит по документам, отменяет проведение оставшихся документов и устанавливает им пометки удаления.
4. Штатные механизмы 1С:ERP. Очищаются ранее сформированные расчетные движения, после чего стандартная обработка «Удаление помеченных объектов» выполняет физическое удаление.
Решение тестировалось на версии платформы 1С:Предприятие 8.3.27.2130 для разработчиков, конфигурация 1С:ERP Управление предприятием 2 (2.5.25.80).
В качестве базы примера использовалась учебная база, содержащая разнообразные производственные документы, включая производственные операции, сменные задания, документы ремонта собственного оборудования и многоэтапного ремонта давальческого оборудования.
После первого запуска «Универсальной обработки», пытающейся отменить проведение и установить пометки удаления всем найденным документам выбранного периода, результат выглядел следующим образом:

Далее была запущена «Производственная обработка», которая подготовила специфические объекты производственного контура: изменила состояния сменных заданий и этапов производства, очистила расход материалов и работ и установила пометки удаления производственным операциям и подготовленным сменным заданиям.

Затем «Универсальная обработка» была запущена повторно. В результате ее работы все документы, созданные в выбранном периоде, были помечены на удаление.

Затем открываем Регламентные операции по закрытию месяца в подсистеме Финансовый результат и контроллинг и переходим в Настройки → Настройка параметров операций закрытия месяца, где включаем техническую настройку Режим отладки расчета = Да.


Жмем кнопку Сохранить и закрыть.
После этого для операции Распределение затрат и расчет себестоимости становятся доступны дополнительные параметры отладки. Для нашей задачи нужны два из них:
-
Перед расчетом очищать старые расчетные движения = Да;
-
Не выполнять расчет себестоимости = Да.
Первый параметр заставляет систему перед выполнением операции очистить ранее сформированные расчетные движения. Второй позволяет на этом остановиться: заново рассчитывать себестоимость документов, которые мы собираемся удалить, очевидно, не требуется.
Чтобы установить эти настройки, опять заходим из Регламентные операции по закрытию месяца в Настройки — Параметры операций закрытия месяца, в Операции вставляем Распределение затрат и расчет себестоимости.

Устанавливаем в нужных местах Да и жмем кнопку Сохранить и закрыть.
После установки параметров в операциях закрытия месяца достаточно выполнить только операцию Распределение затрат и расчет себестоимости. Выполнять заново все операции закрытия месяца не обязательно.
Таким образом, мы не удаляем записи расчетных регистров непосредственно и не пытаемся обходить механизмы 1С:ERP. Наоборот, используем штатную операцию закрытия месяца для очистки созданных ею же расчетных данных.
После очистки расчетных движений запускаем штатную встроенную обработку 1С:ERP Удаление помеченных объектов.
После ее работы все документы выбранного периода были физически удалены. В базе остались только помеченные на удаление документы, относящиеся к другим периодам.
Резюме
Таким образом, последовательность «Универсальная обработка» → «Производственная обработка» → повторный запуск «Универсальной обработки» → штатные механизмы 1С:ERP позволила полностью удалить документы выбранного периода, включая связанные с производством объекты, которые первоначально блокировали работу универсального алгоритма.
Первый запуск «Универсальной обработки» удаляет доступные ему зависимости между документами и помечает на удаление документы, которые может. Затем «Производственная обработка» подготавливает специфические объекты производственного контура: сменные задания, этапы производства и производственные операции. После этого повторный запуск «Универсальной обработки» отменяет проведение оставшихся документов и устанавливает им пометки удаления.
При этом эти внешние обработки не удаляют записи регистров напрямую и не отключают контрольные механизмы конфигурации. Расчетные движения очищаются штатным механизмом закрытия месяца, а окончательное физическое удаление выполняется стандартной обработкой 1С:ERP «Удаление помеченных объектов».
ссылка на оригинал статьи https://habr.com/ru/articles/1084996/