Камешки в стандартной свертке комплексной Ключевые слова: свертка, комплексная, ускорение
Вопрос свертки уже вызывает оскомину, но регулярно всплывает. Расскажу свою историю для тех, кому это интересно. Вариант комплексной конфигурации – вариант торговли несколько проще, и для него просто опускается часть фрагментов.
Стандартная свертка на серьёзной базе (прядка 2- 3 гигабайт) идет несколько суток. У меня она проходила на тестовой базе от 70 до 94 часов, в зависимости от загруженности машины параллельными задачами (Р4, 3.0, 1гб оперативки, САТА). Естественно, такое время на живой базе получить нереально – никто на такой срок базы не отдаст, поэтому необходимо ускорять.
Прошу прощения за занудливость, но кому-то это может пригодиться, а кому сильно влом, тот и сам все знает.
Первоначально исходил из Возможно ли ускорить типовую свертку ТиС ?. – цитирую:
NS
11 - 08.08.04 - 13:57 Раз в 10-ть ускоряется легко....
1) Сдвигается ПО дату свертки
2) Через ВыгрузитьИтоги() - формируем доки ввода остатков (не проводим, документы в конец дня, предварительно запоминаем последний документ, который надо удалить)
3) Сдвигаем ТА совсем назад.
4) В транзакции по 100 документов - помечаем документы на удаление (по последний, запомненный в предыдущем пункте)
5) Сдвигаем ТА на начало дня свертки
6) Проводим документа ввода остатков
7) Сдвигаем ТА обратно вперед
NS
12 - 08.08.04 - 15:02 Видимо никому неинтересно...
Можно значительно ускорить и небольшой правкой типовой свертки (не писать свою)
Gary
13 - 08.08.04 - 15:27 (12) Спасибо ! Именно это я и сделал практически, потому и не смотрел на форум :-)
Gary
14 - 08.08.04 - 15:29 Взял из обработки с proclub.ru "свертка ИБ" документ "унив.движение по регистру" (как оказалось не все остатки нужны), заполнил его и своей обработкой поичкал документы, правда, по 500 шт, про ТА - упустил, но и так получается вроде
NS
15 - 08.08.04 - 15:33 (13) Там во первых нужно убрать удаление периодики,
Запрос переписать под выгрузитьИтоги...
Убрать провети в момент ввода остатков
Удаление делать в транзакции по 100, и с предварительным сдвигом ТА назад.
Потом сдвинуть ТА вперед, перепровести доки ввода остатков, и еще раз Та вперед.
В принципе за час - переписывается легко, и остается весь их бред с контролями.
Именно так я и сделал – изменил стандарную по этому принципу: сдвинул ТА на дату свертки, передвинул (руками) БИ на последний квартал сворачиваемого периода, отказался от «их бреда с контролями», обошел удаление периодики и вставил транзакции при удалении документов.
После устранения мелких камешков (счет КМС имеет 2 одинаковых субконто, но по нему нет проводок). Процесс прошел за 7-8 часов. Но проверка результатов удручила. НДС поплыл на 2-3 миллиона за квартал. Иными словами «их бред» был не полным бредом.
Сделал подробные печати с указанием выполняемого этапа и с выводом даты и времени сообщения. Выяснил, что после возврата всех проверок на место, но сохранив транзакции и сдвижку ТА и БИ получил общее время работы 26 часов, причем 18-20 часов идет на контроль допустимости удаления пар накладная-счет/фактура. Дополнительно к этому, нельзя отказываться от удаления периодики. Дело в том, что некоторые периодические реквизиты, которые существенно используются при проведении документов, устанавливаются удаляемыми документами. При удалении этих документов естественно удаляется и история периодических реквизитов.
Попутно еще раз убедился в сильной чувствительности результатов свертки к чистоте исходной базы – в ней не должно быть нераспределенных партий или непроводимых при восстановлении ГП документов.
Полученное время – 26 часов заметно лучше 70-90 часов, но также неудовлетворительно – требуется подготовительно- заключительное время, включающее выгрузку-загрузку базы до и после свертки, контроль корректности результатов в сравнении с исходной базой. А такое сравнение можно более ли менее достоверно провести только после восстановления ГП на свернутой базе.
Выход найден в том, чтобы на выходных подготовить базу восстановлением ГП.
После этого подготовленная база грузится на место и в копию, которая предоставляется бухгалтерам в качестве уже готовой базы прошлого года. А в рабочей базе жестко закрывается прошлый год от всякого вмешательства и она отдается для работы в течение недели. Еще одна копия подготовленной базы используется для свертки в течение рабочей недели так, чтобы результаты самых трудоемких процессов были сохранены на диске. При этом есть время и для контроля результатов этой, в данном случае пробной свертки, что нелишне. А затем на следующих выходных опять снимается рабочая база и на ней запускается тот же процесс свертки, но в варианте использования сохраненных на диске результатов, что позволяет ускорить процесс еще примерно в 3-4 раза.
В окончательном виде порядок действий был таков:
1. Восстанавливаем ГП от начала жизни.
2. Удаляем из плана счетов счет КМС и после этого выполняем удаление помеченных объектов (обязательно!).
3. Удаляем из справочника ФизЛиц периодический реквизит «СтатусНеРезидента» (еще один камешек потом можно вернуть, все равно иностранцев в моей базе нет)
4. Устанавливаем БИ руками на последний квартал сворачиваемого периода в меню Операции/УправлениеБИ
5. Модифицируем стандартную свертку следующим образом:
А) для управления ТА:
//Изменение ТА
РабочаяДата(обДатаСвертки);
СтараяТА=ПолучитьДатуТА();
УстановитьТАпо(обДатаСвертки);
//
Если фрмВыполнитьСверткуОиБУ = 1 Тогда
обВыполнитьСверткуОиБУ();
КонецЕсли;
// Восстановление ТА
УстановитьТАпо(СтараяТА);
Б) для включения механизма транзакций меняем процедуру удаления документов:
Процедура оуУдалениеДокументов(СворачиваемыеДокументы)
Перем Док;
Док = СоздатьОбъект("Документ");
СчетчикДокументов = 0;
СчетчикУдаленныхДокументов = 0;
пфДобавитьСообщение(" ");
//Сдвигаем ТА назад и Начинаем транзакцию
УстановитьТАпо(Дата(1980,1,1));
НачатьТранзакцию();
//КонецВставки
СворачиваемыеДокументы.ВыбратьСтроки();
Пока СворачиваемыеДокументы.ПолучитьСтроку() = 1 Цикл
Если СворачиваемыеДокументы.Документ.Выбран()=1 Тогда
Если Док.НайтиДокумент(СворачиваемыеДокументы.Документ) <> 1 Тогда
Продолжить;
КонецЕсли;
Если Док.Проведен()=1 Тогда
Док.СделатьНеПроведенным();
КонецЕсли;
Если СворачиваемыеДокументы.Операция = 1 Тогда
// удаляем документ из ИБ
Док.Удалить(0);
СчетчикУдаленныхДокументов = СчетчикУдаленныхДокументов + 1;
ИначеЕсли СворачиваемыеДокументы.Операция = 2 Тогда
// удаляем только табличную часть документа не удаляя его самого т.к. на него есть ссылки в объектах
// и эти ссылки могут понадобится для операций с ИБ после даты свертки
Если (Док.КоличествоСтрок() > 0) Тогда
Док.УдалитьСтроки();
КонецЕсли;
Если ГлЕстьРеквизитШапки("ФлагСвертки",Док.Вид())=1 Тогда
Док.ФлагСвертки = 1;
КонецЕсли;
Док.Комментарий = "Свернут обработкой Свертка ИБ " + ТекущаяДата();
Док.Записать();
СчетчикДокументов = СчетчикДокументов + 1;
КонецЕсли;
//Вставляем фиксацию транзакции через 100 документов и начинаем новую, информационное сообщение
ккк=СчетчикУдаленныхДокументов+СчетчикДокументов;
Если ккк % 100 = 0 Тогда
пфОбновитьСообщение("Обработано "+Док.ДатаДок+" "+ккк);
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
КонецЕсли;
//Конец вставки
//пфОбновитьСообщение("Документов свернуто: "+Формат(СчетчикДокументов,"Ч5")
//+", документов удалено: "+Формат(СчетчикУдаленныхДокументов,"Ч5"));
КонецЕсли;
КонецЦикла;
//Окончательно фиксируем транзакцию после всех удалений
ЗафиксироватьТранзакцию();
КонецПроцедуры // оуУдалениеДокументов(СворачиваемыеДокументы)
В) В процедуреобСверткаОУ вносим изменение, для того, чтобы самый длительный процесс – контроль допустимости удаления пар накладная –счет/фактура сохранить на диске (здесь оператор
оуПодготовкаСпискаСсылок(СсылкиНаДокументы);
взят в условный оператор, который на первом этапе сохраняет результаты на диск, а на втором этапе вместо расчета считывает результаты с диска):
Если СтандартнаяСвертка=1 Тогда
оуПодготовкаСпискаСсылок(СсылкиНаДокументы);
СписокПараметров=СоздатьОбъект("СписокЗначений");
Текст=СоздатьОбъект("Текст");
Ном=0;
СсылкиНаДокументы.ВыбратьСтроки();
Пока СсылкиНаДокументы.ПолучитьСтроку()=1 Цикл
Ном=Ном+1;
СписокПараметров.УдалитьВсе();
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(СсылкиНаДокументы.ДокументИБ));
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(СсылкиНаДокументы.ОбъектИБ));
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(СсылкиНаДокументы.Атрибут));
Стр=СписокПараметров.ВСтрокуСРазделителями();
Текст.ДобавитьСтроку(Стр);
КонецЦикла;
Текст.Записать("S:\свертка\СсылкиНаДокументы.txt");
Сообщить(" - Выгрузка СсылкиНаДокументы ЗАВЕРШЕНА !!! выгружено "+Ном+" строк");
Иначе
СписокПараметров=СоздатьОбъект("СписокЗначений");
Текст=СоздатьОбъект("Текст");
Текст.Открыть("S:\свертка\СсылкиНаДокументы.txt");
Для Ном=1 по Текст.КоличествоСтрок() Цикл
Стр=Текст.ПолучитьСтроку(Ном);
Если СтрДлина(Стр) = 0 Тогда
Продолжить;
КонецЕсли;
СписокПараметров.УдалитьВсе();
СписокПараметров.ИзСтрокиСРазделителями(Стр);
СсылкиНаДокументы.НоваяСтрока();
СсылкиНаДокументы.ДокументИБ=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(1));
СсылкиНаДокументы.ОбъектИБ=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(2));
СсылкиНаДокументы.Атрибут=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(3));
КонецЦикла;
Сообщить(" - Загрузка СсылкиНаДокументы ЗАВЕРШЕНА !!! загружено "+Ном+" строк");
КонецЕсли;
Г) выполняем такую модифицированную свертку – примерно 26 часов. Восстанавливаем в ней ГП и контролируем совпадение с исходной несвернутой по регистрам и состоянию бухгалтерского учета.
После этого на выходные снимаем работающую базу и запускаем ту же свертку в режиме использования сохраненных на диске результатов. Время 6-7 часов. После этого на свернутой базе восстанавливаем ГП и проверяем результаты, сравнивая с исходной несвернутой базой.
Заключительный этап теперь со всеми подготовительно-заключительными этапами, восстановлением ГП и контролями укладывается в 1,5 суток, что уже вполне приемлемо в реальной жизни.
Дополнительно к указанным изменениям в процедурах выдачи сообщений делаем изменения для лучшего контроля хода работы:
//Состояние(Сообщение);
Сообщить(""+ТекущееВремя()+" - "+ТекущаяДата()+" - "+Сообщение);
Д) Кроме указанного напоролся на потерю некоторых периодических реквизитов в справочникеОС – стандартная сверка здесь некорректна. Пришлось выгрузить-загрузить эту периодику своей обработкой, которая написана на основе соответствующих фрагментов стандартной свертки:
Процедура обДобавитьЗначениеВИБ(Д, Кол, Элемент, Значение, Тип,Длина,Точность)
П = СоздатьОбъект("Периодический");
П.ИспользоватьОбъект(Кол, Элемент);
П.ДатаЗнач = Д;
Если Тип <> "" Тогда
П.НазначитьТип(Тип,Длина,Точность);
КонецЕсли;
П.Значение = Значение;
П.Записать();
КонецПроцедуры // обДобавитьЗначениеВИБ
// Сохраняет переодические реквизиты, чтобы записать их после удаления
// документов, которые более не нужны
//
Процедура обЗапомнитьПериодическиеЗеквизиты(Идентификатор)
СписокПараметров=СоздатьОбъект("СписокЗначений");
Текст=СоздатьОбъект("Текст");
КоличествоСтрок=Текст.КоличествоСтрок();
Если КоличествоСтрок>0 Тогда
Для От=1 По КоличествоСтрок Цикл
Текст.УдалитьСтроку(От);
КонецЦикла;
КонецЕсли;
Ном=0;
обДатаСвертки=Дата(2005,12,31);
Справ=СоздатьОбъект("Справочник."+Идентификатор);
МетаСправочник=Метаданные.Справочник(Справ.Вид());
Справ.ВыбратьЭлементы(0);
П = СоздатьОбъект("Периодический");
Пока Справ.ПолучитьЭлемент() =1 Цикл
Элемент=Справ.ТекущийЭлемент();
Для А=1 По МетаСправочник.Реквизит() Цикл
Реквизит = МетаСправочник.Реквизит(А);
Если Реквизит.Периодический = 0 Тогда
Продолжить;
КонецЕсли;
Если Реквизит.ИзменяетсяДокументами = 0 Тогда
Продолжить;
КонецЕсли;
Если (Элемент.ЭтоГруппа()=1) и (Реквизит.Использование="ДляЭлемента") Тогда
Продолжить;
КонецЕсли;
Если (Элемент.ЭтоГруппа()=0) и (Реквизит.Использование="ДляГруппы") Тогда
Продолжить;
КонецЕсли;
П.ИспользоватьОбъект(Реквизит.Идентификатор, Элемент);
П.ОбратныйПорядок();
П.ВыбратьЗначения();
ДатаЗ=ПолучитьПустоеЗначение();
Значение=ПолучитьПустоеЗначение();
Документ=ПолучитьПустоеЗначение();
Пока П.ПолучитьЗначение() = 1 Цикл
ДатаЗ=П.ДатаЗнач;
Значение=П.Значение;
Документ=П.ТекущийДокумент();
Если ДатаЗ<=обДатаСвертки Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если ПустоеЗначение(Документ)=1 Тогда
Продолжить;
КонецЕсли;
Тип=Реквизит.Тип;
Длина=Реквизит.Длина;
Точность=Реквизит.Точность;
Если (ТипЗначенияСтр(Значение) = "Справочник") или (ТипЗначенияСтр(Значение)="Перечисление") Тогда
Тип = ТипЗначенияСтр(Значение)+"."+ Значение.Вид();
КонецЕсли;
//обДобавитьЗначениеВИБ(обДатаСвертки, Реквизит.Идентификатор,Элемент, Значение, Тип,Длина,Точность)
Ном=Ном+1;
СписокПараметров.УдалитьВсе();
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(обДатаСвертки));
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(Реквизит.Идентификатор));
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(Элемент));
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(Значение));
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(Тип));
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(Длина));
СписокПараметров.ДобавитьЗначение(ЗначениеВСтрокуВнутр(Точность));
Стр=СписокПараметров.ВСтрокуСРазделителями();
Текст.ДобавитьСтроку(Стр);
КонецЦикла;
КонецЦикла;
Текст.Записать("S:\Nofelet\свертка\ПериодикаОС.txt");
Сообщить(" - Выгрузка ПериодикаОС ЗАВЕРШЕНА !!! выгружено "+Ном+" строк");
КонецПроцедуры // обЗапомнитьПериодическиеЗеквизиты
//*******************************************
Процедура Сформировать()
обЗапомнитьПериодическиеЗеквизиты("ОсновныеСредства");
КонецПроцедуры
//*******************************************
Процедура Загрузить()
СписокПараметров=СоздатьОбъект("СписокЗначений");
Текст=СоздатьОбъект("Текст");
Текст.Открыть("S:\Nofelet\свертка\ПериодикаОС.txt");
Если Текст.КоличествоСтрок()=0 Тогда
Предупреждение("Файл пустой!");
//Возврат;
КонецЕсли;
Для Ном=1 по Текст.КоличествоСтрок() Цикл
Стр=Текст.ПолучитьСтроку(Ном);
Если СтрДлина(Стр) = 0 Тогда
Продолжить;
КонецЕсли;
СписокПараметров.УдалитьВсе();
СписокПараметров.ИзСтрокиСРазделителями(Стр);
обДатаСвертки=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(1));
РеквизитИдентификатор=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(2));
Элемент=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(3));
Значение=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(4));
Тип=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(5));
Длина=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(6));
Точность=ЗначениеИзСтрокиВнутр(СписокПараметров.ПолучитьЗначение(7));
Если Найти(Тип,"Перечисление")>0 Тогда
Перечисл=Перечисление.ПолучитьАтрибут(СтрЗаменить(Тип,"Перечисление.",""));
Для н=1 По Перечисл.КоличествоЗначений() Цикл
Если ""+Значение=""+Перечисл.ЗначениеПоНомеру(н) Тогда
Значение=Перечисл.ЗначениеПоНомеру(н);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
//УстановитьРеквизитСправочника(Элемент, РеквизитИдентификатор, Значение, обДатаСвертки, Тип);
обДобавитьЗначениеВИБ(обДатаСвертки, РеквизитИдентификатор,Элемент, Значение, Тип,Длина,Точность);
Сообщить(""+Элемент+" - "+Значение+" - "+РеквизитИдентификатор+" - "+Тип+" - "+Длина+" - "+Точность);
КонецЦикла;
Сообщить(" - Загрузка СсылкиНаДокументы ЗАВЕРШЕНА !!! загружено "+Ном+" строк");
КонецПроцедуры
//****************************************************************
После окончания всех работ вернуть на место «СтатусНеРезидента» и КМС.
Ну вот, пожалуй и все.
Надеюсь, кому нибудь это поможет. |