Очистка треков за период (АгентПлюс, AgentPlus), ускорение работы и исправление ошибок. Новый метод обработки записей регистра сведений

Обработка «Очистка Треков За Период» входит в поставку программного комплекса АгентПлюс мобильная торговля и предназначена для удаления записей регистра сведений за период по выбранным торговым агентам (Далее ТА). Предложен нестандартный метод удаления записей регистра сведений.

Стимулом к внесению исправлений в обработку является желание исправить ошибки и сократить время работы.

Платформа 1С:Предприятие 8.3 (8.3.12.1440)

Обработка кпкОчисткаТрековЗаПериод входит в поставку программного комплекса АгентПлюс мобильная торговля и предназначена для удаления записей регистра сведений за период по выбранным торговым агентам (Далее ТА).

 

Стимулом к внесению исправлений в обработку является желание исправить ошибки и сократить время работы.

 

Ошибка.

В обработке есть цикл формирования списка по выбранным ТА. Но в цикле нет проверки на то, что является выбранным , а что нет.

 

Было:

Для Каждого СтрокаМас Из МассивАгентов Цикл
СписАгентов.Добавить(СтрокаМас);
КонецЦикла; 

 

Стало:

 Для Каждого СтрокаТаб Из ТаблицаАгентов Цикл
Если СтрокаТаб.Пометка Тогда
СписАгентов.Добавить(СтрокаТаб.Агент);
КонецЕсли;
КонецЦикла;

 

 

Кроме того в Процедуре ЗаполнитьТаблицуАгентов Испльзуется запрос к РС кпкСведенияАгента, что не дает возможности получить весь список ТА когда либо работавших на предприятии. Поэтому вносились изменения и в процедуру ЗаполнитьТаблицуАгентов.

 

Было:

 

    ВыборкаРегистра = РегистрыСведений.кпкСведенияАгента.Выбрать();
Пока ВыборкаРегистра.Следующий() Цикл
СтрАгента     = ТаблицаАгентов.Добавить();
СтрАгента.Агент   = ВыборкаРегистра.Объект;
СтрАгента.Пометка = Истина;
КонецЦикла;

 

Стало:

Процедура ЗаполнитьТаблицуАгентов() Экспорт

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| кпкСведенияПоГПСТрекам.Агент КАК Агент,
| кпкСведенияПоГПСТрекам.Агент.Наименование КАК Наименование
|
|ИЗ
| РегистрСведений.кпкСведенияПоГПСТрекам КАК кпкСведенияПоГПСТрекам
|
|СГРУППИРОВАТЬ ПО
| кпкСведенияПоГПСТрекам.Агент
|
|УПОРЯДОЧИТЬ ПО
| Наименование
|
|";

ВыборкаРегистра = Запрос.Выполнить().Выбрать();

ТаблицаАгентов.Очистить();
Пока ВыборкаРегистра.Следующий() Цикл
СтрАгента         = ТаблицаАгентов.Добавить();
СтрАгента.Агент   = ВыборкаРегистра.Агент;
СтрАгента.Пометка = Истина;
КонецЦикла;
КонецПроцедуры

 

Изменения коснулись и главной процедуры ВыполнитьОчисткуТреков. Дело в том, что авторами предложен метод удаления записей регистров по одной используя Менеджер. Этот метод чрезвычайно медленный и в случае удаления за длительный период обработка выполняется чрезвычайно долго.

 

Было:

Процедура ВыполнитьОчисткуТреков() Экспорт

МассивАгентов = ТаблицаАгентов.ВыгрузитьКолонку("Агент");
СписАгентов = Новый СписокЗначений;

Для Каждого СтрокаМас Из МассивАгентов Цикл
СписАгентов.Добавить(СтрокаМас);
КонецЦикла;

Запрос = Новый Запрос("ВЫБРАТЬ РАЗРЕШЕННЫЕ
| кпкСведенияПоГПСТрекам.Период,
| кпкСведенияПоГПСТрекам.Агент,
| кпкСведенияПоГПСТрекам.ДатаСоздания,
| кпкСведенияПоГПСТрекам.Широта,
| кпкСведенияПоГПСТрекам.Долгота,
| кпкСведенияПоГПСТрекам.Ключ
|ИЗ
| РегистрСведений.кпкСведенияПоГПСТрекам КАК кпкСведенияПоГПСТрекам
|ГДЕ
| кпкСведенияПоГПСТрекам.Период МЕЖДУ &НачПериод И &КонПериод
| И кпкСведенияПоГПСТрекам.Агент В(&СписокАгентов)");

Запрос.УстановитьПараметр("НачПериод",     НачалоДня(НачПериода));
Запрос.УстановитьПараметр("КонПериод",     КонецДня(КонПериода));
Запрос.УстановитьПараметр("СписокАгентов", СписАгентов);

ВыборкаГПС = Запрос.Выполнить().Выбрать();

Менеджер = РегистрыСведений.кпкСведенияПоГПСТрекам.СоздатьМенеджерЗаписи();

Пока ВыборкаГПС.Следующий() Цикл
Менеджер.Период       = ВыборкаГПС.Период;
Менеджер.Агент        = ВыборкаГПС.Агент;
Менеджер.Ключ         = ВыборкаГПС.Ключ;
Менеджер.Прочитать();

Если Менеджер.Выбран() Тогда
Менеджер.Удалить();
КонецЕсли;
КонецЦикла;

КонецПроцедуры //ВыполнитьОчисткуТреков()

 

Стало:

 

Процедура ВыполнитьОчисткуТреков() Экспорт

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

Сообщить("Начало Выполнения      "+ТекущаяДата());

Запрос = Новый Запрос("ВЫБРАТЬ РАЗРЕШЕННЫЕ *
|
|ИЗ
| РегистрСведений.кпкСведенияПоГПСТрекам КАК кпкСведенияПоГПСТрекам
|ГДЕ
|
| НЕ
| (кпкСведенияПоГПСТрекам.Период МЕЖДУ &НачПериод И &КонПериод
| И кпкСведенияПоГПСТрекам.Агент В(&СписокАгентов))
|
|");

Запрос.УстановитьПараметр("НачПериод",     НачалоДня(НачПериода));
Запрос.УстановитьПараметр("КонПериод",     КонецДня(КонПериода));
Запрос.УстановитьПараметр("СписокАгентов", СписАгентов);

ТЗ = Запрос.Выполнить().Выгрузить();
Сообщить("Запрос Выполнен       "+ТекущаяДата());

Запрос2 = Новый Запрос("ВЫБРАТЬ РАЗРЕШЕННЫЕ
| кпкСведенияПоГПСТрекам.Период,
| кпкСведенияПоГПСТрекам.Агент,
| кпкСведенияПоГПСТрекам.ДатаСоздания,
| кпкСведенияПоГПСТрекам.Широта,
| кпкСведенияПоГПСТрекам.Долгота,
| кпкСведенияПоГПСТрекам.Ключ
|ИЗ
| РегистрСведений.кпкСведенияПоГПСТрекам КАК кпкСведенияПоГПСТрекам
|ГДЕ
| кпкСведенияПоГПСТрекам.Период МЕЖДУ &НачПериод И &КонПериод
| И кпкСведенияПоГПСТрекам.Агент В(&СписокАгентов)");

Запрос2.УстановитьПараметр("НачПериод",     НачалоДня(НачПериода));
Запрос2.УстановитьПараметр("КонПериод",     КонецДня(КонПериода));
Запрос2.УстановитьПараметр("СписокАгентов", СписАгентов);

ВыборкаГПС = Запрос2.Выполнить().Выбрать();

Сообщить("Записий К Удалению: "+ВыборкаГПС.Количество());
Сообщить("Останется Записей:  "+ТЗ.Количество());

Если (ТЗ.Количество() > 100000) Тогда
Сообщить("Записей к удалению "+ВыборкаГПС.Количество()+"     "+ТекущаяДата());
//Запрос 2 т.е. Оригинал

Менеджер = РегистрыСведений.кпкСведенияПоГПСТрекам.СоздатьМенеджерЗаписи();
Сообщить("Работает Оригинальный способ   "+ТекущаяДата());
Счетчик = 1;
Сч100 =1;
Пока ВыборкаГПС.Следующий() Цикл
Менеджер.Период       = ВыборкаГПС.Период;
Менеджер.Агент        = ВыборкаГПС.Агент;
Менеджер.Ключ         = ВыборкаГПС.Ключ;
Менеджер.Прочитать();

Если Менеджер.Выбран() Тогда
Менеджер.Удалить();
КонецЕсли;
Если Сч100 = 1000 Тогда
Сообщить("Обработано:  " +Счетчик+"--  "+ТекущаяДата());
Сч100= 0;
КонецЕсли;
Счетчик = Счетчик +1;
Сч100=Сч100+1;
ОбработкаПрерыванияПользователя();
КонецЦикла;
Сообщить("Обработано:  " +(Счетчик-1)+"--  "+ТекущаяДата());

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

КонецПроцедуры //ВыполнитьОчисткуТреков()

Некоторые пояснения.

  1. Предложен и реализован метод при котором переписываются только те записи РС, которые действительно необходимо оставить в РС.
  2. Опытным путем было получено ориентировочное число записей в 100000 при котором обработка не завершается ошибкой нехватки памяти.
  3. В случае если число записей РС , которые необходимо оставить в РС превышает 100000, обработка иcпользует оригинальный метод удаления, т.е. по записям с использованием Менеджера.

 

Выигрыш во времени колоссальный:  удаление более 1го миллиона записей оригинальным методом длится более 5часов, удаление предложенным методом длится не более 2х минут.

 

Прошу знатоков высказать свое мнение  по поводу предложенного метода работы с РС.

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *