Обрезание (сверка) базы Ключевые слова: сверка, обрезание, закрытие периода
Обрезание базы
Вы наверно частенько встречались с ситуацией что в конце концов база выростает до таких объемов что уже не выносимо с ней работать, а если она ещё и DBF то и очень опастно.
И когда я пришол недавно на новую работу, где всё работает на ТиС, то я сталкнулся с тем что пока обрезать базу. Раньше если честно я с ТиС не имел дела, и для меня було в новинку данная операция.
Вначале я стал искать в интернете готовые дешения, даже попробывал стандартную обрезку 1с "СверкаБазы" которая у меня работала 2 дня и в конеце концов у меня кончилось терпение и её убил.
Потом один умный человек подсказал мне метод её реализации (этот умный человек Рева Виталий, а в сети его знают как Матрея).
Вся идея сводилась к тому, что просто нужно на дату обреза просто "сфотографировать" остатки по всем регистрам остатка и всё.
И всё оказалось не так уж и сложно, хотя в интеренете до сихпор нету грамотных решений по данному вопросу, а если и есть то только за деньги :-)
И так начнём обрезать базу.
1. Делаем копию вашей базы, и все действия делаем только на ней.
2. В копии базы создаём новый документ, и называем его допустим "ОбрезкаБазы"
3. Создаём в документе только 1 реквизит и назовём его "РегистрОстатка", тип: Строка Длина: Неограничена
4. В модуле формы пишем следующий код
//Процедура ПриОткрытии()
Процедура ПриОткрытии()
ПриЗаписиПерепроводить(1);
//Выводим в списке все регистры Остатков
КолРег=Метаданные.Регистр();
Для Сч=1 по КолРег Цикл
Рег=Метаданные.Регистр(Сч);
Если Метаданные.Регистр(Сч).ТипРегистра = "Остатки" Тогда
СписокРег.ДобавитьЗначение(Рег.Идентификатор,Рег.Идентификатор);
КонецЕсли;
КонецЦикла;
//Устанавливаем галочки по тем регистрам по которым делалось движение
Спис = СоздатьОбъект("СписокЗначений");
Спис.УдалитьВсе();
Спис.ИзСтрокиСРазделителями(РегистрОстатка);
Для й=1 по СписокРег.РазмерСписка() Цикл
Если Спис.НайтиЗначение(СписокРег.ПолучитьЗначение(й,"")) > 0 Тогда
СписокРег.Пометка(й,1);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
//Процедура ПриЗаписи()
Процедура ПриЗаписи()
Если Проведен() = 0 Тогда
//Записываем только те регистра во которым делает движение
Спис = СоздатьОбъект("СписокЗначений");
Спис.УдалитьВсе();
Для й=1 по СписокРег.РазмерСписка() Цикл
Если СписокРег.Пометка(й) = 1 Тогда
Спис.ДобавитьЗначение(СписокРег.ПолучитьЗначение(й,""));
КонецЕсли;
КонецЦикла;
РегистрОстатка = Спис.ВСтрокуСРазделителями();
Иначе
Предупреждение("Данный документ нельзя записать !!!");
СтатусВозврата(0);
КонецЕсли;
КонецПроцедуры
А Модуле документа пишем другой код
//Процедура ОбработкаУдаленияПроведения()
Процедура ОбработкаУдаленияПроведения()
Предупреждение("Данный документ нельзя удалить !!!");
СтатусВозврата(0);
КонецПроцедуры
//Процедура ОбработкаПроведения()
Процедура ОбработкаПроведения()
//Расчитываем регистры
СписокРег = СоздатьОбъект("СписокЗначений");
СписокРег.ИзСтрокиСРазделителями(СокрЛП(РегистрОстатка));
Если Проведен() = 0 Тогда
//Пробезаем по всем регистрам, которые отмечаны галочкой
Для й=1 по СписокРег.РазмерСписка() Цикл
РегОст = Строка(СокрЛП(СписокРег.ПолучитьЗначение(й,"")));
Рег=СоздатьОбъект("Регистр."+РегОст);
Рег.Временныйрасчет(1);
РассчитатьРегистрыНа(ДатаДок);
//Присваеваем значений переменным
РегистрПроведения = Метаданные.Регистр(РегОст);
ГлавРег = Регистр.ПолучитьАтрибут(РегОст);
КолИзмерений = РегистрПроведения.Измерение();
КолРесурсов = РегистрПроведения.Ресурс();
ТЗ = СоздатьОбъект("ТаблицаЗначений");
Рег.ВыгрузитьИтоги(ТЗ);
//Делаем движение по этим остаткам, тем самым делаем полную копиб регистров на данное число
Для А=1 по ТЗ.КоличествоСтрок() Цикл
Состояние("Обрабатывается "+Строка(А)+" из "+Строка(ТЗ.КоличествоСтрок())+" значений...");
Для А1=1 по КолИзмерений Цикл
Рег=РегистрПроведения.Измерение(А1);
ГлавРЕГ.УстановитьАтрибут(Рег.Идентификатор,ТЗ.ПолучитьЗначение(А,А1));
КонецЦикла;
Для А2=1 по КолРесурсов Цикл
Рег=РегистрПроведения.Ресурс(А2);
ГлавРЕГ.УстановитьАтрибут(Рег.Идентификатор,ТЗ.ПолучитьЗначение(А,А2+КолИзмерений));
КонецЦикла;
ГлавРЕГ.ДвижениеПриходВыполнить();
КонецЦикла;
КонецЦикла;
Иначе
Предупреждение("Данный документ нельзя перепровести !!!");
СтатусВозврата(0);
КонецЕсли;
КонецПроцедуры
Вы хотите сказать, что не может быть так мало кода. А я вам отвёчу что может быть, и самое интересное что всё работает !!!
Да кстати если вы будете распространять или пользоваться данний обрезкой, большая проздьба указывать на данную статью как на источник.
Кстати это ещё не всё. После чего нужно удалить все доки. Если у вас SQL то здесь вам повезло. Делаем так, в QA выполняю данный запос, и удаляю все документы до указанной даты буквально за 20 минут (а из не мало с учётом того что в жень 300 доков, а удалять надо полтора года)
USE MyTestBase
Go
CREATE TABLE ##ID
(IDDOC char(9) primary key clustered)
Go
INSERT INTO ##ID
SELECT DISTINCT IDDOC
FROM _1SJOURN
WHERE (DATE_TIME_IDDOC < '20060530')
Go
BEGIN TRANSACTION
DECLARE Mycur cursor for
SELECT sysobjects.name,syscolumns.name
FROM syscolumns INNER JOIN
sysobjects ON syscolumns.id = sysobjects.id
WHERE (syscolumns.name = N'iddoc') OR
(syscolumns.name = N'docid')
OPEN MyCur
DECLARE @TableName varchar(20)
DECLARE @ColName varchar(20)
FETCH NEXT FROM MyCur INTO @TableName, @ColName
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ('Delete from '+@TableName+' with (tablock) where '+@ColName+' IN (Select IDDOC FROM ##ID)')
FETCH NEXT FROM MyCur INTO @TableName, @ColName
END
CLOSE MyCur
DEALLOCATE MyCur
COMMIT TRANSACTION
DROP TABLE ##ID
Но после этого я столкнулся с тем что движения остаются по удалённым документам.
В связи с этим я пременил ещё один запрос именно по регистру ПартииПаличия
use НазваниеБазы
DELETE FROM RA328
WHERE IDDOC NOT IN (SELECT IDDOC FROM _1sjourn (nolock))
после чего я в конфигураторе я сделал Тестирование и испровление ИБ
В нём я поставил все галочки и в настройках выбрал "Очищать ссылки" и "Удалять данные объекты"
Вот и вест процесс обрезки :-)
У меня он занял со всеми исправлениями часов 6. |