Имя: Пароль:
1C
1C 7.7
v7: Самописное восстановление ГП
0 never_sleep
 
04.06.14
07:21
Господа! )
Так как штатная восстановлялка ГП зарыта в глубинах 1С, и поправить её возможности не существует, а поправить нужно, было принято решение писать свою обработку с блекджеком и путанами. Но, чтобы не наломать дров, хотелось бы прояснить сразу несколько важных моментов.
Правильно ли я понимаю, что весь смысл восстановления ГП в простом последовательном перепроведении всех документов входящих в данную последовательность с ГП по нужную дату? Т.е. самый простой вариант такой восстановлялки основной последовательности что-то вроде этого:

ДокГП = СоздатьОбъект("Документ");
ДокГП = Последовательность.Основная.ПолучитьДокумент();
Пока ДокГП.ПолучитьДокумент()=1 Цикл
    Если ДокГП.Проведен()=1 Тогда ДокГП.Провести();
    КонецЕсли;
КонецЦикла;
Последовательность.Основная.Установить(ДокГП);

Понимаю, что не все так просто. Поэтому прошу помощи, подскажите, что важного упустил.
1 dk
 
04.06.14
08:04
Последовательность.Основная.Установить(ДокГП);
это лишнее - ГП сама переносится автоматом, если ты пропуски не делаешь
если надо быстро ГП восстанавливать, то нужно еще с перенососм ТА заморочиться
---
поищи готовые восстановлялки - тема не нова мягко говоря
2 Тюря
 
04.06.14
08:38
Написанное 100 лет назад, не монопольное восстановление.
Перем ДатаПослед;
//*******************************************
Процедура Сформировать()
    ДатаПослед=Последовательность.ОсновнаяПоследовательность.ПолучитьДату();
    ДатаАктуал=ПолучитьДатуТА();
    Док=СоздатьОбъект("Документ");
    //Док.УстановитьФильтр(1,0,,2);
    Док.ВыбратьДокументы(ДатаПослед,РабочаяДата());
    КолДокВТранз=0;
    НачатьТранзакцию();
    Пока Док.ПолучитьДокумент()=1 Цикл
     Если Док.Проведен()=0 Тогда      
         Продолжить;
     КонецЕсли;    
     КолДокВТранз=КолДокВТранз+1;    
     Если Последовательность.ОсновнаяПоследовательность.ПринадлежитПоследовательности(Док.Вид())=1 Тогда
       Сообщить(Строка(Док.ТекущийДокумент()));
//       УстановитьТаНа(Док.ТекущийДокумент());
         Если Док.Провести()<>1 Тогда
           Прервать;
         КонецЕсли;
       Последовательность.ОсновнаяПоследовательность.Установить(Док.ТекущийДокумент());
       Если КолДокВТранз>=КолДок Тогда
           ЗафиксироватьТранзакцию();
           КолДокВТранз=0;
           НачатьТранзакцию();
       Конецесли;    
     КонецЕсли;
    КонецЦикла;
  ЗафиксироватьТранзакцию();
КонецПроцедуры
    
КолДок=10;
ДатаПослед=Последовательность.ОсновнаяПоследовательность.ПолучитьДату();
НеПроверятьДатуДоговора=1;
3 Тюря
 
04.06.14
08:41
Монопольное
Перем ДатаПослед;
//*******************************************
Процедура Сформировать()
    ДатаПослед=Последовательность.ОсновнаяПоследовательность.ПолучитьДату();
    ДатаАктуал=ПолучитьДатуТА();
    Док=СоздатьОбъект("Документ");
    //Док.УстановитьФильтр(1,0,,2);
    Док.ВыбратьДокументы(ДатаПослед,РабочаяДата());
    КолДокВТранз=0;
    НачатьТранзакцию();
    Пока Док.ПолучитьДокумент()=1 Цикл
     Если Док.Проведен()=0 Тогда      
         Продолжить;
     КонецЕсли;    
     КолДокВТранз=КолДокВТранз+1;    
     Если Последовательность.ОсновнаяПоследовательность.ПринадлежитПоследовательности(Док.Вид())=1 Тогда
       Сообщить(Строка(Док.ТекущийДокумент()));
       УстановитьТаНа(Док.ТекущийДокумент());
         Если Док.Провести()<>1 Тогда
           Прервать;
         КонецЕсли;
       Последовательность.ОсновнаяПоследовательность.Установить(Док.ТекущийДокумент());
       Если КолДокВТранз>=КолДок Тогда
           ЗафиксироватьТранзакцию();
         КолДокВТранз=0;
           НачатьТранзакцию();
       Конецесли;    
     КонецЕсли;
    КонецЦикла;
  ЗафиксироватьТранзакцию();
КонецПроцедуры
    
КолДок=100;
ДатаПослед=Последовательность.ОсновнаяПоследовательность.ПолучитьДату();
4 peal
 
04.06.14
08:46
Еще можно заморочиться на обработку ожидания вместо цикла и запускать во время работы остальных пользователей, медленно но верно за пару недель обычно пару лет восстановить
5 varelchik
 
04.06.14
10:32
Держи.
Процедура Выполнить()
    //СкладыСвоб=0;
    //глСкладыПрихода=0;
    //глЗапретМаршЛисты=0;
    //ОбработкаОжидания("ОбработкиОжиданияДляВыхода",0);
    Счетчик=20;
    Блокировано=1;
    Для н=1 По Счетчик Цикл
        глПауза(1);
        ФайлБлокировкиЦН=СоздатьОбъект("BinaryData");
        ИмяФайлБлокировкиЦН=КаталогИБ()+"lock.dat";
        Стат=ФайлБлокировкиЦН.ПодключитьсяКФайлу(ИмяФайлБлокировкиЦН,0);
        Если Стат=1 Тогда
            Блокировано=0;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    Если Блокировано=1 Тогда
        Возврат;
    КонецЕсли;
    ЗаписьЖурналаРегистрации("Начало "+ТекущееВремя());
    глЗапросСоединениеВыход=0;
    Запрос=глСоединение();
    УсловиеПоследовательностей="";
    ТекстПоследовательностей=фПоследовательности(УсловиеПоследовательностей);
    Если ТекстПоследовательностей="" Тогда
        Возврат;
    КонецЕсли;
    ТексГраницы="
    |select
    |j.date_time_iddoc iddoc,
    |j.iddoc [Док $Документ],
    |j.iddocdef Док_вид
    |from _1sjourn j (nolock)
    |WHERE left(j.date_time_iddoc,14) in
    |(
    |select
    |left(min(DATE_TIME_DOCID),14)
    |from _1SSTREAM (nolock)
    |WHERE id IN ("+ТекстПоследовательностей+")
    |)";
    Структура=Запрос.ВыполнитьСкалярный(ТексГраницы);
    ИДД=Структура.Получить(1);
    НачПозиция=Структура.Получить(2);
    //Сообщить(ИДД);
    //Сообщить(НачПозиция);
    //Сообщить(Структура.Количество());
    
    НачПозиция="";
    //Возврат;
    //Сообщить(НачПозиция);
    //Возврат;
    Время="";
    Если ТипЗначенияСтр(НачПозиция)="Документ" Тогда
        Запрос.УстановитьТекстовыйПараметр("НачДата",СформироватьПозициюДокумента(НачПозиция,0));
    Иначе
        ч=0;м=0;с=0;
        ДатаПосл=Последовательность.ПолучитьАтрибут("ОсновнаяПоследовательность").ПолучитьДату();
        Последовательность.ПолучитьАтрибут("ОсновнаяПоследовательность").ПолучитьВремя(ч,м,с);
        ВремяПосл=(ч*3600+м*60+с)*10000;
        Время=_IdToStr(ВремяПосл);
        Запрос.УстановитьТекстовыйПараметр("НачДата",Формат(ДатаПосл,"Д ГГГГММДД")+Время);
    КонецЕсли;
    Если фПозиция=1 Тогда
        Запрос.УстановитьТекстовыйПараметр("КонДата",ПолучитьДатуТА());
    Иначе
        Запрос.УстановитьТекстовыйПараметр("КонДата",ДатаВосстановления);
    КонецЕсли;
    Текст="
    |SET NOCOUNT ON
    |select
    |j.iddoc [Док $Документ],
    |j.iddocdef Док_вид
    |from _1SJourn j (NOLOCK)
    |WHERE
    |j.closed &1=1
    |--and j.ismark=0
    |and j.date_time_iddoc between :НачДата AND :КонДата~
    |and ("+УсловиеПоследовательностей+")
    |ORDER BY
    |j.date_time_iddoc
    |";
    ТЗ=СоздатьОбъект("ТаблицаЗначений");
    ТЗ=Запрос.ВыполнитьИнструкцию(Текст);
    //ТЗ.ВыбратьСтроку();
    //Возврат;
    Всего=ТЗ.КоличествоСтрок();
    Счетчик=1;
    Тран=0;
    Если Регистрировать=0 Тогда
        Текст="
        |update Служебная
        |set value=1
        |WHERE
        |id='lock_mod'
        |";
        Запрос.ВыполнитьСкалярный(Текст);
    КонецЕсли;
    Если КвоВТранзакции>0 Тогда
        НачатьТранзакцию();
    КонецЕсли;
    глГрупповаяОбработка=1;
    глПроведение=1;
    НеРегистрироватьИзмененияМОД=1;
    ТЗ.ВыбратьСтроки();
    лДок=СоздатьОбъект("Документ");
    НачатьЛогирование();
    Путь=глВернутьПараметрСтрПоКоду("ПутьКиев");
    Если ПустоеЗначение(Путь)=0 Тогда
        УдЗапрос=глСоединение("SQL",СокрЛП(Путь));
    Иначе
        УдЗапрос=глСоединение();
    КонецЕсли;
    //Стат=УдЗапрос.Подготовить("insert into НеВыгружатьМОД (id,dataprov) values(?,?)");
    //Если Стат=0 Тогда
    //    Сообщить(УдЗапрос.ПолучитьОписаниеОшибки());
    //    Возврат;
    //КонецЕсли;
    //УдЗапрос.ДобПараметр(1,14,13,0);
    //УдЗапрос.ДобПараметр(1,8,0,0);
    Пока ТЗ.ПолучитьСтроку() = 1 Цикл
        лДок.НайтиДокумент(ТЗ.Док);
        Если фВыводитьИнформацию=1 Тогда
            Если ПустоеЗначение(Форма.Параметр)=1 Тогда
                Сообщить("Проведение :"+Строка(лДок)+" "+лДок.ПолучитьВремя());
            КонецЕсли;
            ЗаписьЖурналаРегистрации("Проведение :"+Строка(лДок)+" "+лДок.ПолучитьВремя(),,,лДок.ТекущийДокумент());
        КонецЕсли;
        Инфо="Обработано "+Строка(Окр(Счетчик/Всего*100,2))+" %
        |Транзакция "+Строка(Тран);
        Если лДок.Провести()=0 Тогда
            глПроведение=0;
            Если КвоВТранзакции>0 Тогда
                НеРегистрироватьИзмененияМОД=0;
                ОтменитьТранзакцию();
            КонецЕсли;
            ФайлБлокировкиЦН.Закрыть();
            Возврат;
        КонецЕсли;
        //УдЗапрос.УстПараметр(1,"'"+глМетаДата.ЗначениеВДлиннуюСтрокуБД(лДок.ТекущийДокумент())+"'");
        //УдЗапрос.УстПараметр(2,ТекущаяДата());
        УдЗапрос.УстановитьТекстовыйПараметр("ВыбДок",лДок.ТекущийДокумент());
        УдЗапрос.УстановитьТекстовыйПараметр("ВыбДата",ТекущаяДата());
        УдЗапрос.ВыполнитьСкалярный("insert into НеВыгружатьМОД (id,dataprov) values(:ВыбДок~,cast(:ВыбДата as smalldatetime))");
        Если КвоВТранзакции>0 Тогда
            Если Счетчик%КвоВТранзакции=0 Тогда
                ЗафиксироватьТранзакцию();
                Тран=Тран+1;
                лДок=0;
                глПауза(5);
                //База=СоздатьОбъект("ODBCDataBase");
                //База.ReconnectNative();
                лДок=СоздатьОбъект("Документ");
                НачатьТранзакцию();
            КонецЕсли;
        КонецЕсли;
        Счетчик=Счетчик+1;
        Форма.Обновить();
    КонецЦикла;
    Если ПустоеЗначение(Форма.Параметр)=1 Тогда
        Предупреждение("Восстановление завершено!",20);
    КонецЕсли;
    ЗаписьЖурналаРегистрации("Восстановление завершено "+ТекущееВремя());
    Если КвоВТранзакции>0 Тогда
        ЗафиксироватьТранзакцию();
    КонецЕсли;
    ФайлБлокировкиЦН.Закрыть();
    Текст="
    |update Служебная
    |set value=0
    |WHERE
    |id='lock_mod'
    |";
    Запрос.ВыполнитьСкалярный(Текст);
    глПроведение=0;
    ЗаписьЖурналаРегистрации("Окончание "+ТекущееВремя());
    ЗакончитьЛогирование();
    Если ПустоеЗначение(Форма.Параметр)=0 Тогда
        глВыходВопрос=1;
        ЗавершитьРаботуСистемы(0);
    КонецЕсли;
    НеРегистрироватьИзмененияМОД=0;
КонецПроцедуры    // Выполнить
6 Тюря
 
04.06.14
11:00
(5) силен )))
для какой конфы ?
7 varelchik
 
04.06.14
13:13
(6) для любой.
главное шоб была как минимум база SQL и 1С++.
этого фатит.
8 varelchik
 
04.06.14
13:14
(6) если интересно стучись в аську.
9 Ёпрст
 
04.06.14
13:18
мод есть не у всех, смысл в файле "для блокировки" не ясен
10 torgm
 
04.06.14
14:19
(3) Писал подобное, + добавочный вариант не прерывать перепроведение при ошибках а продолжать, чтобы разом потом проанализировать все косяки , чохом исправить и заново перепровести...
11 varelchik
 
04.06.14
14:39
(9) ще какой смысл.
можно восстанавливать во время работы, но блокируя определенные обработки которые занимаються тежеловесными весчами.
ну дык от туда можно много чего по убирать.
это я просто все текст выложил, влом было чистить.
12 varelchik
 
04.06.14
14:39
я ж ее по мере надобности допиливал.
13 Ёпрст
 
04.06.14
14:45
если есть мод, всё делается проще - перепровод в копии и потом заливка последних изменений туда ну и замена баз местами. Можно хоть года перепроводить
14 Тюря
 
04.06.14
14:48
(13) ++++
зачем канителиться с таким кодом.
С УРИБ можно и с простым кодом или даже типовым.
15 varelchik
 
04.06.14
15:22
(14)(13) не нравится код?
ну так каждый под себя делает.
а предложил, оскорблять то зачем?
16 varelchik
 
04.06.14
15:23
(13) а видал загрузку МОД-а?
нуну затолкай год я посмотрю скоко времений уйдет.
17 Тюря
 
04.06.14
15:35
(15) я не хотел обидеть, извиняюсь
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс