Корректировка движений регистра (Проведение без Проведения)

Вариант проведения документов по одному выбранному Регистру (для конфигураций 1с 8.1/8.2)

Исходная задача состояла в том, что надо было ввести остатки на начало года по «партиям НДС» в конфигурации «Комплексная автоматизация» и провести все документы по этому регистру. Сложность была в том, что остатки вводились с опозданием и несколько периодов были уже закрыты. Поэтому напрямую перепроводить документы было уже нельзя (из-за возможных изменений сумм себестоимости и т.д.)

Основная идея заключается в том, что движения делаются с помощью алгоритмов проведения самой конфигурации, но в результате (после перепроведения) оставляется изменение движений только по выбранному регистру.

Этот пример может пригодится, например, в аналогичных описываемому случаях ввода остатков по отдельному регистру, либо в случае изменения алгоритма проведения по определенному регистру.

Не претендуя на оригинальность самой идеи отменять транзакцию, тем не менее хочу представить работающий алгоритм (для конфигураций 1С 8.1/8.2). Возможно, кому-то пригодится в работе. Мне он помогал ещё в нескольких случаях.

В примере приводится проведение по регистру накопления «Размещение». Это регистр был добавлен в конфигурацию и не относится к типовым. Алгоритм легко переделать на другой (другие) нужный регистр. Как с любыми операциями с регистрами, и этой операцией тоже следует пользоваться аккуратно )

Текст самих процедур (8.1/8.2)

Процедура ПерепровестиДокументыПоРегистру()

    //отбираем все проведенные документы, которые могут делать движения по нужному нам
    //регистру (РегистрыНакопления.Размещение)
    //за указанный период с Дата1 по Дата2

    ИмяРегистра = «Размещение»;

    ТекстЗапроса = «ВЫБРАТЬ Документы.Ссылка ИЗ («;
    Для Каждого
Документ Из Метаданные.Документы Цикл
        Если Не
Документ.Движения.Содержит(Метаданные.РегистрыНакопления[ИмяРегистра]) Тогда
            Продолжить;
        КонецЕсли;
       
ТекстЗапроса = ТекстЗапроса + «ВЫБРАТЬ » + Документ.Имя + «.Ссылка КАК Ссылка, » +
       
Документ.Имя + «.Дата КАК Дата  ИЗ Документ.» + Документ.Имя + » КАК » + Документ.Имя +
       
» ГДЕ » + Документ.Имя + «.Дата МЕЖДУ &НачПериода И &КонПериода И «
       
+ Документ.Имя + «.Проведен ОБЪЕДИНИТЬ ВСЕ «;
    КонецЦикла;
   
ТекстЗапроса = ТекстЗапроса + «ВЫБРАТЬ NULL, NULL ) КАК Документы ГДЕ НЕ Документы.Ссылка ЕСТЬ NULL УПОРЯДОЧИТЬ ПО Документы.Дата»;
   
Запрос = Новый Запрос(ТекстЗапроса);

    Запрос.УстановитьПараметр(«НачПериода», НачалоДня(Дата1));
   
Запрос.УстановитьПараметр(«КонПериода», КонецДня(Дата2));

    Выборка = Запрос.Выполнить().Выбрать();
   
Сообщить(Выборка.Количество());
    Пока
Выборка.Следующий() Цикл
       
ОбработкаПрерыванияПользователя();
       
ДокСсылка=Выборка.Ссылка;
       
Сообщить(» «+СокрЛП(ДокСсылка));
       
ПровестиПоРегистру(ДокСсылка,ИмяРегистра);
    КонецЦикла;
КонецПроцедуры

Процедура ПровестиПоРегистру(ДокСсылка, ИмяРегистра)
   
ДокОбъект = ДокСсылка.ПолучитьОбъект();

    НачатьТранзакцию();

    ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
   
ДокОбъект.Движения[ИмяРегистра].Прочитать();
   
ТаблицаДвиженийРегистра = ДокОбъект.Движения[ИмяРегистра].Выгрузить();

    //здесь отменяем проведение документа, чтобы ничего не изменилось
    //в прошлых периодах (по другим регистрам)
   
ОтменитьТранзакцию();

    НаборЗаписей = РегистрыНакопления[ИмяРегистра].СоздатьНаборЗаписей();
   
НаборЗаписей.Отбор.Регистратор.Установить(ДокСсылка);
   
НаборЗаписей.Загрузить(ТаблицаДвиженийРегистра);
   
НаборЗаписей.Записать();
КонецПроцедуры

 

Решение похожей задачи (но другим способом) для платформы 7.7 описано в статье «Технологическое перепроведение документов» 

 

ps. (03/03/2012)

Забавно — сегодня обнаружил полный аналог этого алгоритма, описанный ранее на «Инфостарт» —  «Перепроведение документов только по выбранным регистрам» …. Похожие идеи витают в воздухе 🙂

18 Comments

  1. DrAku1a

    Хорошая идея!

    Reply
  2. Pavel777777

    Спасибо всем за поддержку моей первой статьи на «Инфостарт»

    Reply
  3. Lizi60

    Да, идея хорошая. Обязательно пригодится.

    Reply
  4. Boroda

    Хотя ЗУП в перечне и не указан, но, думаю, принцип можно использовать и при работе в этой конфигурации. Спасибо.

    Reply
  5. irishka77

    Спасибо!Очень актально

    Reply
  6. Mshaydurov
    Boroda пишет:

    Хотя ЗУП в перечне и не указан, но, думаю, принцип можно использовать и при работе в этой конфигурации. Спасибо.

    По моему использовать можно абсолютно в любой конфигурации. Даже в нетиповой самописной. Автору респект и уважуха =)

    Reply
  7. ir_en

    Спасибо, пригодится

    Reply
  8. Pavel777777

    (8) Спасибо за конструктивную критику )

    С п.1 и 3, конечно, согласен … а вот п.4 (и 2) требуют проверки всё-таки…. особенно п.2, поскольку основная «фишка» алгоритма именно в отмене транзакции каждого проведения и одновременном изменении движений.

    В любом случае — представленный код проверен на реальных данных, а оптимизировать всегда есть куда

    Reply
  9. lsp71

    Спасибо за идею.

    Reply
  10. Boroda

    Интересно, чем редакция [03.03.2012 11:13] отличается от предыдущей? Что-нибудь добавлено, кроме p/s? Или новая дата появилась только для поднятия публикации?

    Reply
  11. Pavel777777

    (14) Новая дата появилась автоматически после того, как я добавил ps. А дополнение это я считаю важным, поэтому его и добавил…. Поскольку перед размещением статьи я ничего похожего на сайте Инфостарт не нашёл …. Так что это скорее поднятие публикации-ссылки из примечания.

    Reply
  12. AlexO

    Pavel777777,

    Забавно — сегодня обнаружил полный аналог этого алгоритма, описанный ранее на «Инфостарт»

    аналог кода или аналог последовательности действий?

    Reply
  13. AlexO

    (0)

    вот из-за этого

    Если Не Документ.Движения.Содержит(Метаданные.РегистрыНакопления[ИмяРегистра])

    нужно курочить Движения в свойствах всех документов, учавствующих в доп-проведении — а это изменение конфы существенное.

    И тут — очередная «удивительная» недоработка регистров РН у 1С: ну вот зачем писать новый регистр в Движения всех отобранных видов документов, если все равно — доп-проведение через наборЗаписей напрямую, без задействования объекта «Движения»:

     НаборЗаписей = РегистрыНакопления[ИмяРегистра].СоздатьНаборЗаписей();

    А без прописки в Движения отбор в набор записей по регистратору не сработает…

    Reply
  14. Pavel777777

    (16) Аналог последовательности действий) .. в написании кода то по-любому будут отличия

    (17) Вообще предполагалось, что перепроводиться будут ТОЛЬКО документы, которые уже делают движения по выбранному регистру. Поскольку используется алгоритм проведения документа, уже предусмотренный конфигурацией.

    А поэтому — дополнительно в конфигурации только для этого перепроведения ничего менять не надо.

    Reply
  15. lsp71

    Использовал изложенную идею для создания движений по новому (нестандартному) РН. Надо было перепровести документы, начиная с 2007 года. Выяснилось:

    1. Конфа с тех времен существенно изменилась и проведение некоторых документов по всем РН невозможно из-за изменения реквизитов этих документов и процедур проведения по РН (проще говоря, текущая обработка проведения не соответствует старым данным).

    2. Проведение (а реально это перепроведение, т.е. проведение с предварительным удалением движений по РН) а потом отмена транзакции происходит очень медленно. А еще заодно запускаются процедуры модуля объекта ПередЗаписью и ПриЗаписи. Документов много, месяц деятельности «переваривался» таким алгоритмом около суток.

    Мое решение (дополняющее идею статьи): некоторые типы документов обрабатывать не описанным в статье алгоритмом, а своим, который будет:

    1. учитывать изменения конфы (т.е. очень старые и более свежие документы можно обрабатывать вообще разными алгоритмами)

    2. не будет проводить документ по всем РН, а только по одному, мне интересному

    3. не будут работать процедуры ПередЗаписью и ПриЗаписи

    В принципе, нам ведь все равно каким образом получена ТаблицаДвиженийРегистра, если она содержит правильные данные. Я написал «свои» обработки, формирующие ТаблицаДвиженийРегистра, для 3-х из 16 документов-регистраторов. Свои в кавычках из-за того, что их основой все равно были алгоритмы проведения из конфы, я лишь убрал ненужные проверки и сделал чтобы это работало не из модуля объекта, а из внешней процедуры.

    Скорость работы выросла в десятки раз (примерно в 22 раза) и ушли ошибки проведения.

    Reply
  16. Dansur

    Ловко!

    Reply
  17. Alexey_A

    Спасибо! гениальная и в то же время простая идея! я уж расстроился, думал писать целый обработчик по выправлению регистра и вспомнил, что уже когда-то пользовался этой статьей и нашел ее. огроменное человеческое спасибище!

    Reply
  18. kpp1c

    Работает!

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *