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, Аспект);
Исключение
КонецПопытки;
Сообщить(Рез.Ссылка);
КонецЦикла;
|