Отмена проведения и проведение документов при переносе данных с использованием конвертации данных.


В статье описано, как добиться оптимальной записи с отменой проведения или проведением перенесенных документов  при написании правил обмена в системе Конвертации Данных (КД).

При переносе данных между базами часто возникает ситуация, когда движения документов переносить не требуется, а перенесенные документы следует проводить в базе-приёмнике. Например, в базе-источнике ведется управленческий учет, а в базе-приемнике  регламентированный.  Если при переносе не учитывать свойство «Проведен» документа, то можно получить в приемнике проведенные документы, у которых данные в движениях и в объекте не соответствуют друг другу.

 В правилах конвертации объектов (ПКО) в обработчике «Перед загрузкой» существуют параметры «РежимЗаписи» и «РежимПроведения», указание которых обеспечивает необходимый режим записи объекта, но в этом случае, запись происходит во время загрузки данных и если, по каким-то причинам, документ не запишется, загрузка данных будет прервана. Правильней записывать новые документы в конце загрузки, когда все перенесенные объекты уже будут в базе — приемнике.

Несколько основных моментов:

  1. Нам необходим параметр конвертации с типом «Таблица значений», куда можно будет записывать ссылки на документ и информацию о том, что с документом делать. Создать параметр на вкладке «Параметры» конвертации – не получится, но его спокойно можно создать программным способом. После использования наш параметр следует удалить, в противном случае при использовании управляемой формы обработки система будет выдавать сообщение об ошибке, т.к. управляемая форма не использует таблицу значений. Несмотря на сообщение об ошибке, обработка все действия выполнит, но нервировать пользователей подобными сообщениями не следует.
  2. Для анализа, новый это объект или существующий в обработке используется параметр ОбъектНайден.
  3. Для анализа состояния ранее записанного объекта в приемнике используем обращение к его ссылке (Объект.Ссылка).
  4. Для записи ссылки нового для приемника документа нам необходимо документ записать. Чтобы избежать повторной записи документа обработкой обмена следует выставить параметр ОбъектМодифицирован в значение Ложь.
  5. Обработка обмена данными при записи документа обнуляет перенесенную пометку удаления. Это необходимо учитывать.
  6.  Для решения стоящей задачи наиболее удобно использовать обработчики событий конвертации в целом. Но нам необходимо определить – объект  — это документ, и если документ – то проводится ли он. Для идентификации документа используем параметр обработчика ИмяТипаОбъекта.

 

I. Первый, более простой, случай: требуется оставлять в базе-приемнике документы непроведенными.

      Подразумевается, что пользователи в базе-приемнике проверят документы и потом их проведут. Если не переносить движения и просто указать в свойстве «Проведен»  — «Значение = Ложь», то можем получить при повторном переносе документы внешне не проведенные, но с движениями. К этому получим справедливое возмущение пользователей, которые не смогут понять результатов отчетов.

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

1. В обработчике «Перед загрузкой данных» конвертации создаем параметр с типом значений «Таблица значений».  В колонку «Действие» строкой будем записывать – что делать с документом: просто отменять проведение или еще проставлять пометку на удаление.

     ТаблицаДокументов = Новый ТаблицаЗначений;
     ТаблицаДокументов.Колонки.Добавить(«Ссылка»);
     ТаблицаДокументов.Колонки.Добавить(«Действие»);
     Параметры.Вставить(«ТаблицаДокументов»,ТаблицаДокументов);

2. В обработчике «После загрузки объекта» конвертации, определяем найден ли объект, является ли объект документом, проводится ли он, и если в приемнике он проведен, то только тогда помещаем ссылку на него в наш параметр ТаблицаДокументов.

    Если ОбъектНайден
        И ИмяТипаОбъекта = «Документ»
        И
Объект.Метаданные().Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить
        И Объект.Ссылка.Проведен Тогда
        
НоваяСтрока = Параметры.ТаблицаДокументов.Добавить();
        
НоваяСтрока.Ссылка = Объект.Ссылка;
        Если
ПараметрыОбъекта.Получить(«ПометкаУдаления») Тогда
            
НоваяСтрока.Действие = «Удаление»;
        Иначе
            
НоваяСтрока.Действие = «Отмена»;
        КонецЕсли;
    ИначеЕсли 
ПараметрыОбъекта <> Неопределено И Лев(Строка(ТипЗнч(Объект)),8) = «Документ»  Тогда
        
Объект.ПометкаУдаления = ПараметрыОбъекта.Получить(«ПометкаУдаления»); //Пометка удаления у новых объектов и непроведенных старых
    КонецЕсли;

3. В обработчике «После загрузки данных» конвертации отменяем проведение у записанных документов, проставляем при необходимости пометку на удаление и удаляем наш параметр. При желании отследить процесс удаления код обработчика может выглядеть так:

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

     Если Не ПустаяСтрока(ТекстСообщенияОтмены) Тогда
         
Сообщить(«Отменено проведение документов:» + Символы.ПС + ТекстСообщенияОтмены);
     КонецЕсли;
     Если Не
ПустаяСтрока(ТекстСообщенияОшибки) Тогда
         
Сообщить(«Ошибки при отмене проведения: «+ Символы.ПС + ТекстСообщенияОшибки);
     КонецЕсли;
     
Параметры.Удалить(«ТаблицаДокументов»);

II. Требуется обеспечить проведение документов в базе-приемнике при переносе.

   В этом случае необходимо помимо пометки удаления передавать значение свойства «Проведен» в параметр «Проведен» и данный параметр анализировать в обработчике «После загрузки объекта» (Рис.2).

1. «Перед загрузкой данных» Повторяем создание параметра конвертации, как в первом примере

ТаблицаДокументов = Новый ТаблицаЗначений;
ТаблицаДокументов.Колонки.Добавить(«Ссылка»);
ТаблицаДокументов.Колонки.Добавить(«Действие»);
Параметры.Вставить(«ТаблицаДокументов»,ТаблицаДокументов);

2. «После загрузки объекта»  После загрузки мы должны уже работать с объектами, которые еще не записаны в базе. Документы можно выделить по типу значения, а новый объект, перед внесением в таблицу параметра, необходимо предварительно записать. Не забываем установить параметр «ОбъектМодифицирован» в «Ложь». 

Если ИмяТипаОбъекта = «Документ»
   
И Объект.Метаданные().Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить Тогда

    Если Не ОбъектНайден  Тогда
       
Объект.Записать();
       
ОбъектМодифицирован = Ложь;
    КонецЕсли;

    НоваяСтрока Параметры.ТаблицаДокументов.Добавить();
   
НоваяСтрока.Ссылка = Объект.Ссылка;

    Если ПараметрыОбъекта.Получить(«Проведен»)  Тогда
       
НоваяСтрока.Действие = «Проведение»;
    ИначеЕсли
ПараметрыОбъекта.Получить(«ПометкаУдаления»)  Тогда
       
НоваяСтрока.Действие = «Удаление»;
    Иначе
       
НоваяСтрока.Действие = «Отмена»;
    КонецЕсли;
КонецЕсли;

3. «После загрузки данных» После загрузки мы должны пропустить запись документа, если он не проведен в базе-источнике и в базе приемника. Также необходимо проследить за пометкой удаления.

ТекстСообщенияЗаписи = «»;
ТекстСообщенияОшибки = «»;

Для каждого СтрокаТч Из Параметры.ТаблицаДокументов Цикл


    Если
СтрокаТч.Действие = «Отмена»  И Не СтрокаТч.Ссылка.Проведен Тогда
        Если
СтрокаТч.Ссылка.ПометкаУдаления Тогда  //Для снятия пометки удаления
           
Попытка
               
ДокОбъект = СтрокаТч.Ссылка.ПолучитьОбъект();
               
ДокОбъект.ПометкаУдаления = Ложь;
               
ДокОбъект.Записать();
            Исключение
            КонецПопытки;
        КонецЕсли;

        Продолжить;

    КонецЕсли;

    Если СтрокаТч.Действие = «Проведение» Тогда
       
РежимЗаписи = РежимЗаписиДокумента.Проведение;
    Иначе
       
РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения;
    КонецЕсли;

    Попытка
        ДокОбъект = СтрокаТч.Ссылка.ПолучитьОбъект();
        Если (
СтрокаТч.Действие <> «Удаление» Или  СтрокаТч.Ссылка.Проведен) Тогда
           
ДокОбъект.Записать(РежимЗаписи);
           
ТекстСообщенияЗаписи = ТекстСообщенияЗаписи +?(РежимЗаписи = РежимЗаписиДокумента.Проведение,
           
«Проведен «,«Отменено проведение «)
            +
Строка(СтрокаТч.Ссылка) + Символы.ПС;
        КонецЕсли;

        Если СтрокаТч.Действие = «Удаление» Тогда
           
ДокОбъект.ПометкаУдаления = Истина;
           
ДокОбъект.Записать();
        ИначеЕсли
СтрокаТч.Ссылка.ПометкаУдаления Тогда
           
ДокОбъект.ПометкаУдаления = Ложь;
           
ДокОбъект.Записать();
        КонецЕсли;
    Исключение    

    ТекстСообщенияОшибки = ТекстСообщенияОшибки Строка(СтрокаТч.Ссылка)+ » : «+ОписаниеОшибки()+ Символы.ПС;

    КонецПопытки;
КонецЦикла;

Если Не ПустаяСтрока(ТекстСообщенияЗаписи) Тогда
   
Сообщить(ТекстСообщенияЗаписи);
КонецЕсли;

Если Не ПустаяСтрока(ТекстСообщенияОшибки) Тогда
   
Сообщить(«Ошибки при отмене проведения: «+ Символы.ПС + ТекстСообщенияОшибки);
КонецЕсли;
Параметры.Удалить(«ТаблицаДокументов»);

 

36 Comments

  1. K_A_O

    Конечно же, такой подход имеет право на жизнь.

    Однако в большинстве случаев достаточно параметра РежимЗаписи и установки флажка «Режим отладки» в обработке загрузки. В этом режиме загрузка прерываться не будет.

    Reply
  2. iov

    (0) в КД проведен — в ложь.

    Если перегружаем все подряд — то дополнительный реквизит — проводить = истина.

    после загрузки — проводим все что нужно через попытку что не провелось — сообщаем пользователю.

    Вариант?

    Reply
  3. ARL

    (2)Вариантов всегда масса 🙂 Показан один из них, реализованный у меня лично. У меня регулярный перенос по плану обмена. Проводить все подряд — в моем случае не допустимо.

    Reply
  4. iov

    (3)тык у меня тоже не все подряд — а только то что проведено в основной … Но именно через попытку — потому как даже режим записи= истина не гарантирует корректности проводок (а порой документ проведен/не проведен а движений есть/нет). Но не суть на больших объемах (много данных или много обменов или и то и другое) обмен приходится делать через такие хитрости и извраты…. Но как говорится ваше решение имеет право на жизнь. И оно пригодится в ряде решений других задач.

    Reply
  5. ARL

    (4) В примерах все проводится через попытку. Только оператор открывается перед ПолучитьОбъект(), т.к. мы можем пытаться манипулировать с ранее записанным объектом, а он может быть кем-нибудь заблокирован.

    Reply
  6. iov

    (5) дааа есть такие гады… дай ткнуть в документ … 🙂

    Reply
  7. fomix

    Возможно у автора описка в тексте публикации. Событие «После загрузки данных» выполняется самым последним после загрузки данных из файла обмена, когда файл уже закрыт и только один раз! А потому правильнее будет, если таблица значений создается в событии «Перед загрузкой данных», которое выполняется первым перед началом загрузки данных из файла и только один раз, после открытия файла для чтения. В данном обработчике как раз и могут быть инициализированы переменные, которые впоследствии предполагается использовать.

    Reply
  8. ARL

    (7)Точно, описался. Несколько раз проверял, а такую очевидную ляпу пропустил. Благодарю за замечание, исправляю.

    Reply
  9. fomix

    Еще ошибка в обоих фрагментах текста обработчика «После загрузки данных»:

    ….

    Попытка

    …..

    Исключение

    ТекстОшибки = ТекстСообщенияОшибки + Строка(СтрокаТч.Ссылка) + » : «+ ОписаниеОшибки() + Символы.ПС;

    КонецПопытки;

    нужно исправить на:

    ТекстСообщенияОшибки = ТекстСообщенияОшибки + Строка(СтрокаТч.Ссылка) + » : «+ ОписаниеОшибки() + Символы.ПС;

    Reply
  10. ARL

    (9)Исправил

    Reply
  11. fomix

    Тут еще по теме всплыли мыслишки. Для проверки принадлежности загружаемого объекта к типу «Документ» заменить нижеприведенные конструкции в обработчиках «После загрузки объекта» конвертации:

    >> Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Объект.Ссылка))

    >> Лев(Строка(ТипЗнч(Объект)),8) = «Документ»

    на более простую:

    << Если ИмяТипаОбъекта = «Документ» …

    Reply
  12. ARL

    Так будет и проще, и правильней. Не обратил внимание на данный параметр обработчика в свое время. В «своем» обмене уже поменял.

    Reply
  13. Manonegro

    У меня выдает ошибку:

    Ошибка в глобальном обработчике события ПослеЗагрузкиОбъекта (конвертация)

    Значение не является значением объектного типа (Получить)

    Я, так понимаю, ПараметрыОбъекта = Неопределено.

    Или свойства ПометкаУдаления и Проведен нужно передавать в параметр? Тогда для переноса из 7.7 не подходит, ибо в параметр переносить нельзя. Есть другой способ передать эти свойства? Например, через глобальные параметры?

    Reply
  14. 88wau24ru

    (12) Помогите разобраться новичку,

    В обработчике «Перед загрузкой данных» конвертации

    В обработчике «После загрузки объекта» конвертации

    В обработчике «После загрузки данных» конвертации

    Это глобальные обработчики, которые находятся на закладке «Основная» Конвертации, и они будут отрабатывать только для тех объектов у которых ПКС ПометкаУдаления и Проведен заменены на параметры??? А если не заменять на параметры то все будет как обычно(без параметров)?
    ,

    В общем глупый вопрос, все написано в описании, невнимательно прочитал… спасибо за копипаст… работает

    Reply
  15. LexSeIch

    Мир этому дому!

    Автору плюс, fomix — то же плюс. Статья интересная — пока бегло прочитал — позже разберусь внимательней. Спасибо!

    Reply
  16. swimdog

    Пригодилось. Я делал похожий механизм, но проводил сразу после загрузки.

    Reply
  17. swimdog

    А зачем надо Проведен и ПометкаУдаления передавать через параметр? Почему нельзя просто Объект.Проведен и Объект.ПометкаУдаления?

    И ПометкаУдаления снимается обработкой, наверное, в том случае, когда в обработке по загрузке установлен флажок «Объекты, выгруженные по ссылке, загружать без пометки на удаление».

    Reply
  18. ARL

    (17)

    А зачем надо Проведен и ПометкаУдаления передавать через параметр? Почему нельзя просто Объект.Проведен

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

    Пример: вы передали свойство «Проведен» при обмене. Но при проведении — документ не провелся, а свойство — осталось. Получим проведенный документ без движений.

    когда в обработке по загрузке установлен флажок «Объекты, выгруженные по ссылке, загружать без пометки на удаление»

    Надо пробовать. Вроде как написано — для объектов по ссылке, а не напрямую.

    Я заметил,к примеру, что при загрузке обработкой в управляемой форме — проблем с пометкой не возникало.

    А к статье надо относиться как примеру методики работы с конвертацией, а использовать или нет — это уже в каждом конкретном случае надо определять.

    Reply
  19. knigina

    Моя тема. Как новичок, которому приходилось довольствоваться штатным обменом УТ 10.3-БП 3.0, не знала как подступить к переносу без проведения документов. Спасибо автору. И отдельное спасибо от меня 88wau24ru за правильно заданный (для меня!) вопрос…и ответ. В результате что-то у меня даже получилось. Буду разбираться дальше.

    Reply
  20. RSConsulting

    Ругается на строку «Если ПараметрыОбъекта.Получить(«Проведен») Тогда».

    Ошибка: «Значение не является значением объектного типа (Получить)»

    Версия конвертации 2.1.8.1

    Reply
  21. RSConsulting

    Заменил код в обработчике После загрузки объекта на

    Если ИмяТипаОбъекта = «Документ»
    И Объект.Метаданные().Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить Тогда
    
    Если Не ОбъектНайден  Тогда
    Объект.Записать();
    ОбъектМодифицирован = Ложь;
    КонецЕсли;
    
    НоваяСтрока =  Параметры.ТаблицаДокументов.Добавить();
    НоваяСтрока.Ссылка = Объект.Ссылка;
    
    Если Объект.Проведен  Тогда
    НоваяСтрока.Действие = «Проведение»;
    ИначеЕсли Объект.ПометкаУдаления Тогда
    НоваяСтрока.Действие = «Удаление»;
    Иначе
    НоваяСтрока.Действие = «Отмена»;
    КонецЕсли;
    КонецЕсли;

    Показать

    Заработало!

    Reply
  22. ARL

    (20) Вы пропустили момент

    В этом случае необходимо помимо пометки удаления передавать значение свойства «Проведен» в параметр «Проведен» и данный параметр анализировать в обработчике «После загрузки объекта» (Рис.2).

    (21) Заработало, но некорректно. Возможно, что в новой базе документ не проведется, а свойство «Проведен» останется. Получим проведенный документ без движений. Пользователи скажут «спасибо».

    Reply
  23. damirxan

    Все работает.

    Спасибо за решение по проведению документов через Параметр.

    Reply
  24. KliMich

    Спасибо! Переносил через КД из ПУБ 7.7 в БП 3.0.

    Только при переносе из 1с 7.7 «передача данных в параметр» не работают….

    Сделал как в посте 21. RSConsulting — все сработало!

    Reply
  25. Nik777x

    Спасибо, пригодилось. Автору респект.

    Reply
  26. kida1

    Автору Спасибо!

    хорошо бы добавить снятие с проведения

    (22) Добавьте в исключение в «После загрузки данных» не просто ТекстОшибки, а снятие с проведения

     Если СтрокаТч.Действие = «Проведение» Тогда
    ДокОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
    КонецЕсли;
    ТекстОшибки = ТекстСообщенияОшибки + Строка(СтрокаТч.Ссылка)+ » : «+ОписаниеОшибки()+ Символы.ПС;

    Reply
  27. le_

    Покажите, плз, как параметры объекта передаются из источника (Проведение/Удаление/Отмена).

    Reply
  28. ARL

    (27) Открыть форму свойства, выбрать переключатель «Передавать данные в параметр» и ввести название параметра в поле ввода «Параметр». На рисунках именно это показано.

    Reply
  29. le_

    (28) Спасибо! Рисунки-то я не посмотрел… А нельзя ли как-то глобальные параметры создать для всех документов?..

    Reply
  30. romku

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

    В обработчике после загрузки написать примерно так:

    Если Объект.Проведен Тогда
    попытка
    Объект.Записать(РежимЗаписиДокумента.Проведение);
    исключение
    
    конецпопытки
    иначе
    попытка
    Объект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
    исключение
    КонецПопытки
    КонецЕсли;

    Показать

    Reply
  31. ARL

    (30) Если в базе-приемнике документ не проведется, то получится проведенный документ без движений. И в случае с пометкой на удаление — может появиться помеченный на удаление документ, но с движениями, сформированными ранее.

    Reply
  32. romku

    (31) ну это можно обработать в исключении, сбросить эти реквизиты.

    Reply
  33. ARL

    (32) Вы указали на частный случай, а случаи разные бывают 🙂 при переносе. Пример: при загрузке документов обработка прекращает работать по ошибке. Правила оказались недоработанными для какого-то редкого сочетания реквизитов. Все перенесенные до ошибки документы оказываются «проведенными» и без движений.

    Reply
  34. zShamaNz

    (21) Почему-то оригинальный вариант глючил, а этот взлетел.

    Reply
  35. acanta

    +Добавляем в конфигурацию конвертация данных кнопочку, которая все эти процедуры добавляет и параметры переставляет для текущего объекта метаданных.

    Reply
  36. Crazy Professor
    Reply

Leave a Comment

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