ВНИМАНИЕ: Использование на рабочей базе на свой страх и риск! Лучше сначала проверить интерактивно на копии базы! Обязательно создавайте архивные копии!!!
- Получить остатки по регистрам “ЦеныНоменклатуры” и “ЦеныНоменклатуры25”, если включено формирование цен 2.5 на каждый конец года, если в периоде 01.01-31.12 года есть документы “УстановкаЦенНоменклатуры”;
- Сформировать остатки по регистру ЦеныНоменклатуры, если дата перехода на цены 2.5 > периода формирования цен; Иначе на конец года формируем остатки по регистру ЦеныНоменклатуры25;
- На основании периодов обработки (например, 31.12.2017 – 31.12.2018) сформировать новые документы, каждый по одному виду цен, заполненные Срезом Последних цен на конец периода “Год” по логике предыдущего пункта. При этом для разгрузки документов установки цен, не устанавливать цены на товары, у которых они на срез последних по периоду равны нулю или пустые. Провести документы.
- Помнить, что если таблица документа содержит более 99 999 строк, то при сохранении будет ошибка и документ не проведётся. Максимальное количество строк документа в результате действий обработки установить в 99 900 строк (и так медленно открывается документ с таким количеством строк);
Описание решений
1. Запросы к ценам номенклатуры выполняются макетами СКД, для каждого регистра он свой, никакого "ОБЪЕДИНИТЬ"
2. Разбиваем результаты по годам;
3. В первую очередь документы "Установка цен номенклатуры" формируются на конец года каждого периода по одному виду цены, в них вносятся остатки только с ценой отличной от нуля. При этом максимальное количество строк документа 99 999, и если строк в запросе больше, то разбиваем по нескольким документам с ограничением в 99 900 строк;
4. Затем распроводятся документы за период, которые не были созданы в шаге 3;
5. В итоге распроведенные документы помечаются на удаление;
В обработке реализовано фоновое задание, которым, например, настроив на 08.03.ТекущегоГода, можно обработать предыдущий текущему год в фоне без падений сервера 1С
Существует возможность запустить интерактивно очистку пошагово (например мне так больше нравится, пошагово), то есть вторая команда - открытие формы обработки.
Весь рабочий код расположен в модуле обработки, так как реализовано фоновое задание:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
Наименование = ЭтотОбъект.Метаданные().ПолноеИмя();
Синоним = ЭтотОбъект.Метаданные().Синоним;
Синоним = ?(ЗначениеЗаполнено(Синоним), Синоним, Наименование);
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
ПараметрыРегистрации.Вставить("Наименование", Синоним);
ПараметрыРегистрации.Вставить("Версия", "1.0.0.1");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
ПараметрыРегистрации.Вставить("Информация", Наименование);
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд,
"Запуск свертки ""Цен Номенклатуры""", //представление команды в пользовательском интерфейсе
"ВыполнитьОперацииВФоновомЗадании", //идентификатор команды; любая строка, уникальная в пределах данной обработки
ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода());
ДобавитьКоманду(ТаблицаКоманд,
"Открыть настройки " + ?(ЗначениеЗаполнено(Синоним), Синоним, Наименование), //представление команды в пользовательском интерфейсе
"ОткрытьНастройки_"+Наименование, //идентификатор команды; любая строка, уникальная в пределах данной обработки
ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы());
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
Функции выполнения запланированного фонового задания (все значения по-умолчанию, ДатаФормирования = КонецГода(ТекущаяДатаСеанса() - 1Год)):
Функция ВыполнитьКоманду(ИдентификаторКоманды) Экспорт
Если ИдентификаторКоманды = "ВыполнитьОперацииВФоновомЗадании" Тогда
ВыполнитьОперацииВФоновомЗадании();
КонецЕсли;
КонецФункции
Процедура ВыполнитьОперацииВФоновомЗадании() Экспорт
ЗапускСвертки();
ЗаполнитьДанныеЗаПериод(Истина);
ОбработатьДанныеВМодулеОбъекта();
КонецПроцедуры
Особенности алгоритма следующие, разобью по процедурам:
Процедура ЗаполнитьДанныеЗаПериод(ФоноваяЗадача = Ложь) Экспорт
Если НЕ ЗначениеЗаполнено(ЭтотОбъект.ДатаФормирования) Тогда
ЭтотОбъект.ДатаФормирования = КонецГода(ТекущаяДатаСеанса()- 60 * 60 * 24 * 365);
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| УстановкаЦенНоменклатуры.Ссылка КАК ДокументЦен,
| КОНЕЦПЕРИОДА(УстановкаЦенНоменклатуры.Дата, ГОД) КАК ПериодДокумента,
| ЛОЖЬ КАК Обработан
|ИЗ
| Документ.УстановкаЦенНоменклатуры КАК УстановкаЦенНоменклатуры
|ГДЕ
| УстановкаЦенНоменклатуры.Проведен
| И НЕ УстановкаЦенНоменклатуры.Комментарий ПОДОБНО ""%Автоматическая свертка установок цен номенклатуры за прошлые периоды%""
| И УстановкаЦенНоменклатуры.Дата МЕЖДУ &ДатаНачалаПериода И &ДатаОкончанияПериода";
Запрос.УстановитьПараметр("ДатаОкончанияПериода", ЭтотОбъект.ДатаФормирования);
Запрос.УстановитьПараметр("ДатаНачалаПериода", ?(ФоноваяЗадача, Дата(1,1,1), НачалоГода(ЭтотОбъект.ДатаФормирования)));
ЭтотОбъект.ТаблицаДокументов.Загрузить(Запрос.Выполнить().Выгрузить());
КонецПроцедуры
Данная процедура заполняет таблицу обработки к удалению. Фоновое задание передает в нее "Истина", в результате чего заполняем таблицу документами с начала времен по указанный период, не являющихся автоматически созданными текущей обработкой. Если же вызов произошел из формы обработки, то указывается начало периода - начало года к ДатеФормирования.
В дальнейшем циклом по заполненной таблице проходит длительная процедура распроведения и пометки на удаление документов "ОбработатьДанныеВМодулеОбъекта()". Для интерактивного использования на форме результат работы процедуры - "Обработан", булево, не редактируется интерактивно.
Процедура ЗапускСвертки(ФоноваяЗадача = Ложь) Экспорт
// Некоторый код формирования периодов
Попытка
ИспользуютсяЦены25 = Константы.ИспользуетсяЦенообразование25.Получить();
ДатаНачала25 = КонецГода(Константы.ДатаПереходаНаЦенообразование25.Получить());
Исключение
ИспользуютсяЦены25 = Ложь;
ДатаНачала25 = Дата(2099,12,31);
КонецПопытки;
Для Каждого ДатаОбработки Из ТаблицаДат Цикл
Если ДатаОбработки.ЕстьАвтоматЗаГод Тогда
Продолжить;
КонецЕсли;
Если ИспользуютсяЦены25 И ДатаНачала25 <= ДатаОбработки.ДатаОкончанияПериода Тогда
ТаблицаЦен = ВернутьТаблицуЗначенийПоМакету(МакетВходящиеЦены, ДатаОбработки.ДатаОкончанияПериода);
Иначе
ТаблицаЦен = ВернутьТаблицуЗначенийПоМакету(МакетВходящиеЦены, ДатаОбработки.ДатаОкончанияПериода);
КонецЕсли;
ТаблицаВидовЦен = ТаблицаЦен.Скопировать(,"ВидЦены");
ТаблицаВидовЦен.Свернуть("ВидЦены");
ОшибкаЗаписи = Ложь;
МассивСозданныхДоков = Новый Массив;
КонстантаСтрокВДок = 99900;
Для Каждого ВидЦены Из ТаблицаВидовЦен Цикл
ЦеныКЗагрузке = ТаблицаЦен.Скопировать(Новый Структура("ВидЦены",ВидЦены.ВидЦены));
ВсегоДокументов = Окр(ЦеныКЗагрузке.Количество() / КонстантаСтрокВДок ,0);
ВсегоДокументов = ?(ВсегоДокументов=0,1,ВсегоДокументов);
КоличествоСтрок = ЦеныКЗагрузке.Количество() / ВсегоДокументов;
Для х = 1 По ВсегоДокументов Цикл
//Далее код формирования документа
КонецПроцедуры
Реализация заполнения в запуске свертки следующая: если строк в результате больше, чем 99 900, то бьем по максимально этому количеству строк и создаем некоторое кратное количество документов.
Виды цен получаем из результатов запроса, что снижает количество формируемых "Пустых" документов.
В предыдущих версиях УТ11.5 нет регистра ЦеныНоменклатуры25 и Константы "ИспользуетсяЦенообразование25", поэтому для обратной совместимости реализовано через Попытка ... Исключение.
ВНИМАНИЕ: Использование на рабочей базе на свой страх и риск! Лучше сначала проверить интерактивно на копии базы! Обязательно создавайте архивные копии!!!
Проверена на конфигурации УТ 11.4.12.71; УТ 8.3.25.1374
Версии платформы: 8.3.25.1374; 8.3.24.1548; 8.3.24.1342; 8.3.23.1912; 8.3.23.1865.
Проверено на следующих конфигурациях и релизах:
- Управление торговлей, редакция 11, релизы 11.4.12.71
- 1С:ERP Управление предприятием 2, релизы 2.4.1.211
- 1С:Комплексная автоматизация 2, релизы 2.4.3.126