| v8: Перепроведение документов только по одному из учетов УУ, БУ, НУ| Перепроведение документов только по одному из учетов, например для экономии скорости.
Без изменений в конфигурации. Универсально. |  | Автор статьи: Гений 1С Последняя редакция №1 от 05.04.06
 URL: http://kb.mista.ru/article.php?id=135
 |  | 
 Ключевые слова: перепроведение,проведение,учет,управленческий,бухгалтерский,налоговый,скорость,ускорение,экономия
 
 
 Мы тут изобрели способ перепроведения документов только по одному из видов учета (УПП) без вмешательства в конфу. Метод почти универсальный.
 
 Например, для перепроведения по УУ, открываем транзакцию, выставляем только галку УУ, остальные сбрасываем, проводим, смотрим в каких регистрах появились движения, эти движения запоминаем, транзакцию отменяем, приписываем документу сохраненные движения.
 
 Просто, красиво, универсально.
 
 Приведем пример функции, которая перепроводит документ по любому из 3х учетов УПП:
 
 
Функция ПерепровестиДокументПоУчету(Документ, ВидУчета, Аспект) Экспорт
    НачатьТранзакцию();
    ДокументОбъект=Документ.ПолучитьОбъект();
    Если ДокументОбъект.Метаданные().Реквизиты.Найти("ОтражатьВУправленческомУчете")<>Неопределено Тогда
        ДокументОбъект.ОтражатьВУправленческомУчете=ВидУчета=1;
    КонецЕсли;
    Если ДокументОбъект.Метаданные().Реквизиты.Найти("ОтражатьВОперУчете")<>Неопределено Тогда
        ДокументОбъект.ОтражатьВОперУчете=ВидУчета=1;
    КонецЕсли;
    Если ДокументОбъект.Метаданные().Реквизиты.Найти("ОтражатьВБухгалтерскомУчете")<>Неопределено Тогда
        ДокументОбъект.ОтражатьВБухгалтерскомУчете=ВидУчета=2;
    КонецЕсли;
    Если ДокументОбъект.Метаданные().Реквизиты.Найти("ОтражатьВНалоговомУчете")<>Неопределено Тогда
        ДокументОбъект.ОтражатьВНалоговомУчете=ВидУчета=3;
    КонецЕсли;
    Режим="Модификация"; 
    Выполнить(Аспект);
    ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
    
    НовыеДвижения=Новый Соответствие();
    
    Для Каждого Движение ИЗ ДокументОбъект.Движения Цикл
        МДР=Метаданные.НайтиПоТипу(ТипЗнч(Движение));
        ИмяРегистра=МДР.Имя;
        Режим="ОбрабатыватьРегистр"; 
        Р=истина;
        Выполнить(Аспект);
        Если Р=ложь Тогда
            Продолжить;
        КонецЕсли;
        Если Движение.Модифицированность() Тогда
            //Сообщить("Модифицирован регистр: "+ИмяРегистра);
        КонецЕсли;
        Если Движение.Количество()>0 Тогда
            //Сообщить("Есть движения по регистру: "+ИмяРегистра);
            ТЗ_Движения=Движение.Выгрузить();
            НовыеДвижения.Вставить(ИмяРегистра, ТЗ_Движения);
        КонецЕсли;
    КонецЦикла;
    ОтменитьТранзакцию();
    
    //Транзакция по записи документа и его движений
    НачатьТранзакцию();
    ДокументОбъект=Документ.ПолучитьОбъект();
    Если ВидУчета=1 Тогда
        Если ДокументОбъект.Метаданные().Реквизиты.Найти("ОтражатьВУправленческомУчете")<>Неопределено Тогда
            ДокументОбъект.ОтражатьВУправленческомУчете=истина;
        КонецЕсли;
        Если ДокументОбъект.Метаданные().Реквизиты.Найти("ОтражатьВОперУчете")<>Неопределено Тогда
            ДокументОбъект.ОтражатьВОперУчете=истина;
        КонецЕсли;
    КонецЕсли;
    Если ВидУчета=2 Тогда
        Если ДокументОбъект.Метаданные().Реквизиты.Найти("ОтражатьВБухгалтерскомУчете")<>Неопределено Тогда
            ДокументОбъект.ОтражатьВБухгалтерскомУчете=истина;
        КонецЕсли;
    КонецЕсли;
    Если ВидУчета=3 Тогда
        Если ДокументОбъект.Метаданные().Реквизиты.Найти("ОтражатьВНалоговомУчете")<>Неопределено Тогда
            ДокументОбъект.ОтражатьВНалоговомУчете=истина;
        КонецЕсли;
    КонецЕсли;
    Режим="Модификация"; 
    Выполнить(Аспект);
    ДокументОбъект.Записать();
    Для Каждого Эл Из НовыеДвижения Цикл
        ИмяРегистра=Эл.Ключ;
        ТЗ_Движения=Эл.Значение;
        Движение=ДокументОбъект.Движения[ИмяРегистра];
        Движение.Загрузить(ТЗ_Движения);
        Движение.Записать();
    КонецЦикла;
    ЗафиксироватьТранзакцию();
КонецФункции
 Параметры:
 = Документ: перепроводимый документ.
 = ВидУчета: 1 - УУ, 2 - БУ, 3 - НУ
 = Аспект: некий контролирующий код, который можно дополнительно выполнять при перепроведении.
 
 Вызов кода выполняется в следующих случаях:
 
 1. При модификации документа под управленческий учет. Иногда если документ раньше не имел признака УУ, нужно проставить какие-либо дополнительные параметры. Вызывается дважды для каждой транзакции.
 Переменные:
 = Режим: равно "Модификация";
 
 2. Если нужно защитить какой-то регистр от записи.
 Переменные:
 = ИмяРегистра: содержит имя регистра, например "Хозрасчетный".
 = Режим: равно "ОбрабатыватьРегистр";
 = Р: по умолчанию истина, если присвоить ложь, регистр модифицироваться не будет;
 
 Пример конкретной обработки перепроведения (ускорение по замерам в 3 раза, 20 часов вместо 3 суток) - обработка вызывалась из модифицированной консоли запросов для каждой строки результата запроса:
 
 
 
П=Новый Структура();
//Код запроса неважен
Рез=Запрос.Выполнить().Выбрать;
Пока Рез.Следующий() Цикл
    ВО=СтруктураСвойство(П, "ВО", Неопределено);
    Если ВО=Неопределено Тогда
        ВО=ВнешниеОбработки.Создать("P:\Обработки\ПерепроведениеПоУчетам.epf");
        П.Вставить("ВО", ВО);
    КонецЕсли;
    Сообщить(ВО);
    //Фукция ОбъектСоздатьПоРеквизитам 
    //создает ответственного, если его нет, а если есть-подставляет
    Аспект="
    |Если Режим=""Модификация"" Тогда
    |    Если ДокументОбъект.Метаданные().Реквизиты.Найти(""Оплачено"")<>Неопределено Тогда
    |       ДокументОбъект.ОтраженоВОперУчете=истина;
    |   КонецЕсли;
    |    Если ЗначениеНеЗаполнено(ДокументОбъект.Ответственный) Тогда
    |       ДокументОбъект.Ответственный=ОбъектСоздатьПоРеквизитам    (""Справочник"",""Пользователи"",Новый Структура(""Наименование"", ""Робот""));
    |   КонецЕсли;
    |КонецЕсли;
    |";
    Попытка
    ВО.ПерепровестиДокументПоУчету(Рез.Ссылка, 1, Аспект);
    Исключение
    КонецПопытки;
    Сообщить(Рез.Ссылка);
КонецЦикла;
 
 |