КД 2.0: Конвертация справочника "План счетов" в счет плана счетов (7.7)





Иногда встречаются еще такие конфигурации на платформе 7.7, в которых вместо плана счетов есть справочник "План счетов", в котором абы как заведены элементы. Рано или поздно, при работе с такими ИБ, возникает необходимость переводить это всё хотя бы на типовую конфигурацию 7.7. И в этом случае резко встает вопрос — как настраивать правила конвертации? стандартный способ переноса справочников для этой ситуации не подходит, поиск по коду счета не выполняется. К тому же, документации по конвертации 7.7 — 7.7 крайне мало. Мой вариант решения этой проблемы Вы сможете увидеть далее

Дано:
1. Источник — Самописная конфигурация на базе БП Б-г знает каких годов, назовем ее «ТК Северный». В конфигурации присутствует документ «Выписка» с реквизитами таб.части «Приход» и «Расход» типа Число.
2. Приемник — БП 4.5 на платформе 7.7, в ней тоже присутствует документ «Выписка» с реквизитами таб.части «Приход» и «Расход».
3. В документе «Выписка», как в источнике, так и в приемнике, есть реквизит «КоррСчет» (в источнике «КорСчет», с одной «Р»), в источнике это справочник «ПланСчетов», в приемнике — счет плана счетов «Основной»

Как известно, при конвертации данных, когда источник является конфигурацией на платформе 7.7, можно передавать произвольные данные через дополнительные XML-узлы. Таким образом в книге Бояркина и Филатова описан способ передачи значений периодических реквизитов (кому интересно, стр. 143).
Мы используем этот алгоритм, только не совсем так, как описано в книге, вернее, не совсем для этих целей.
Алгоритм действий следующий: по скольку при конвертации данных 7.7- 7.7 не работают половина фишек и возможностей КД, конвертацию документа «Выписка» придется разбить на два этапа:
1) Перенос данных самого документа (шапки) и табличной части без установки реквизита «КоррСчет».
2) Перенос реквизита «КоррСчет».  При этом будут запомнены и сохранены в дополнительный XML-узел значения реквизита «КорСчет» документа-источника, а затем будет прочитан дополнительных XML-узел с кодами счетов.
Второй этап нужен только потому, что в 7.7 не работает обработчик «ПослеЗагрузки». При попытке совместить эти два ПКО в обработчике «ПриЗагрузке» Объект.КоличествоСтрок() возвращает 0, что логично, так как объект еще не записан, и даже вызов метода Записать(), ровно как и ОткрытьФормуМодально(Объект,,0) не дают совершенно ничего. А в обработчике «ПослеЗагрузки» не доступны дополнительные XML-узлы.

При использовании второго ПКО объект будет уже записан в базу на момент, когда будет выполняться второе ПКО, что позволит решить нашу проблему с поиском счета в ИБ.

Gentlemen, start your engines
Первым делом, создадим правило конвертации объекта (ПКО) для документа «Выписка», приемником в котором является документ «Выписка» ИБ-приемника
ПКО

(рис.1)

 ПКО

(рис.2) — табличная часть

Обратите внимание, что на рис.2 для реквизитов Субконто1 и Субконто2 правило конвертации свойства (ПКС) не задано. Что это означает? это означает, что Субконто1 и Субконто2 могут быть различных типов, и мы не можем заранее знать и указать конкретное ПКС. Если не указывать ПКС, система попытается автоматически подобрать подходящее. То есть достаточно, чтобы в наборе правил конвертации присутствовало ПКО с источником и приемником такими, какие попадутся при выгрузке.
Этим правилом мы перенесем все нужные реквизиты шапки документа, его табличную часть, но без реквизита «КоррСчет»

Далее, создадим ПКО «Выписка_СтрокиТЧ». Внешний вид на (рис.3)

ПКО

В обработчик «ПриВыгрузке» ПКО «Выписка_СтрокиТЧ» пишем

Если Источник.ВыбратьСтроки() = 1 Тогда

    УзелСпискаСчетов = СоздатьУзел(«СчетаПроводок»);

    Пока Источник.ПолучитьСтроку()=1 Цикл

        Значение = Источник.КорСчет//КорСчет с одной буквой «Р»

        Если ПустоеЗначение(Значение) = 0 Тогда

            КодСчета = СокрЛП(Значение.Код);

            КодВБазеПриемнике = «»;

            Если КодСчета = «060» Тогда

                КодВБазеПриемнике = «60.1»;

            ИначеЕсли КодСчета = «062» Тогда

                КодВБазеПриемнике = «62.1»;

            ИначеЕсли КодСчета = «044» Тогда

                КодВБазеПриемнике = «44.1.1»;

            ИначеЕсли КодСчета = «66.3» Тогда

                КодВБазеПриемнике = «66.3»;

            Иначе

                //Дополняем по факту

                Сообщить(«!! Не указано соответствие для счета <«+КодСчета+«>. Обратитесь к разработчику!»);

            КонецЕсли;

        КонецЕсли;

        Если КодВБазеПриемнике <> «» Тогда

            УзелЗначения = СоздатьУзел(«Счет»);

            УстановитьАтрибут(УзелЗначения, «Код», КодВБазеПриемнике);

            ДобавитьПодчиненный(УзелСпискаСчетов, УзелЗначения);

        КонецЕсли;

    КонецЦикла;

    ДобавитьПодчиненный(Приемник, УзелСпискаСчетов);

КонецЕсли;

В обработчик «ПриЗагрузке» ПКО «Выписка_СтрокиТЧ» пишем //Славьте лапти, что хотя бы «ПриЗагрузке» в 7.7 работает

УзлыСчетов= Узел.ВыбратьУзлы(«СчетаПроводок»);

Счет = СоздатьОбъект(«Счет.Основной»);

СпНайденныхСчетов = СоздатьОбъект(«СписокЗначений»);

Для СчУзлов = 0 По УзлыСчетов.КоличествоУзлов 1 Цикл

    КонкретныйУзел = УзлыСчетов.ПолучитьУзел(СчУзлов);
   
Выборка = КонкретныйУзел.ВыбратьУзлы(«Счет»);

    Для Сч =0 По Выборка.КоличествоУзлов 1 Цикл

        УзелЗначения = Выборка.ПолучитьУзел(Сч);

        Код = УзелЗначения.ПолучитьАтрибут(«Код»);

        Если Счет.НайтиПоКоду(Код) = 1 Тогда
           
СпНайденныхСчетов.ДобавитьЗначение(Счет.ТекущийСчет());
        Иначе
           
Сообщить(«Не найден счет по коду <«+Код+«>! Срочно обратитесь к разработчику!»,«!!!»);
        КонецЕсли;

    КонецЦикла;

КонецЦикла;

СколькоСчетов = СпНайденныхСчетов.РазмерСписка();

Если СколькоСчетов > 0 Тогда

    СколькоСтрок = Объект.КоличествоСтрок();

    Если СколькоСтрок <> СколькоСчетов Тогда

        Сообщить(«Для документа «+ Объект +» количество строк и количество счетов различаются: «+ СколькоСтрок + » <> «+ СколькоСчетов);

    Иначе

        Если Объект.ВыбратьСтроки()= 1 Тогда

            Пока Объект.ПолучитьСтроку()=1 Цикл

                НайденныйСчет = СпНайденныхСчетов.ПолучитьЗначение(Объект.НомерСтроки);

                Объект.КоррСчет = НайденныйСчет.ТекущийСчет();

           
КонецЦикла;
        КонецЕсли;

   
КонецЕсли;
КонецЕсли;

Кстати. Рекомендую использовать переписанную под КД 2.1.3.1 обработку , которая позволяет использовать GCOMP. Экономит кучу времени. Помнится мне, что я что-то в ней менял для работы в КД 2.1.5.1, поэтому свою прикрепляю к публикации.

Теперь создадим правила выгрузки данных (ПВД) для наших ПКО «Выписка» и «Выписка_СтрокиТЧ»
В обработчик «ПередОбработкой» каждого пишем код

ВыборкаДанных = СоздатьОбъект(«СписокЗначений»);
ВходящиеПараметрыАлгоритма = СоздатьОбъект(«СписокЗначений»);
ВходящиеПараметрыАлгоритма.ДобавитьЗначение(Правило, «Правило»);
ВходящиеПараметрыАлгоритма.ДобавитьЗначение(ВыборкаДанных, «ВыборкаДанных»);
ПолучитьВыборкуДокументов(, ВходящиеПараметрыАлгоритма);

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

При загрузке данных сперва отрабатывает ПКО «Выписка», загружаются документы и их табличные части, затем отрабатывает правило «Выписка_СтрокиТЧ», которое подгружает значения поля «КоррСчет». Не забываем убедиться в этом, проверив значения реквизита «Порядок выполнения». То правило, где значение меньше, выполняется раньше. У меня для ПКО «Выписка» это соответственно 150, а для ПКО «Выписка_СтрокиТЧ» соответственно 200.

Итог вы можете видеть на рис.4 — «было»

 Было

и рис.5. — «стало». Здесь на скриншот не попала последняя строка, где контрагент «Теплотехника» и число в графе «приход», но она там точно есть, поверьте)

Стало

Буду рад любым замечаниям и предложениям. Да, это велосипед, и, господа, пожалуйста, давайте не будем превращать коменты к публикации в обсуждение «зачем тебе конвертация 7.7 — 7.7, давно пора валить на восьмерку». Просто вот есть такие требования, такая задача и вот такое сугубо мое решение.

Буду рад, если кому-то пригодится, а так же дополнениям и исправлениям ошибок.

В публикации для раскраски кода использована Разукрашка 

25 Comments

  1. volha-77

    Что-то я не поняла, Вы рекомендуете использовать доработанную обработку для выгрузки, но она же для 8-ки. А статья вроде про перенос 7.7.

    Reply
  2. demon_infernal

    (1) volha-77,

    Обработка, приложенная к публикации, заменяет собой одноименную обработку из конфигурации «Конвертация Данных» v2.1.5.1, которая на платформе 8.2. Выгружает правила конвертации и сама собирает готовые к использованию обработки V77exp.ert и V77Imp.ert для платформы 7.7 (при условии установленного GCOMP).

    Reply
  3. volha-77

    (2) спасибо, получилось

    Reply
  4. volha-77

    А еще не подскажете, как сделать, чтобы в обработке загрузки для 7.7 не генерировался вызов функции ЗафиксироватьОшибку? всегда приходится закомменчивать

    Reply
  5. demon_infernal

    (4) volha-77, не понял, зачем комментировать эти вызовы? Никогда ничего подобного не делал, все работало.

    Чем Вам мешает вызов этой функции?

    Reply
  6. volha-77

    просто эта фукнция в генерируемой обработке загрузки не определена, а только вызывается (может дело в версии конвертации — у меня 2.0.26.1, более новую не нашла, доступа к ИТС нет)

    Reply
  7. volha-77

    и программа не проходит синтаксический контроль

    Reply
  8. demon_infernal

    (7) volha-77,

    ну конечно, у вас очень старая версия. Хотя и в новых версиях не все гладко с переносом 7.7 — 7.7… Могу порекомендовать обновить КД хотя бы на 2.1.5.1 (я начал свое знакомство с КД именно этой версии, и никогда подобных ситуаций, как у Вас, не случалось)

    Reply
  9. volha-77

    нашла выход — добавила заглушку этой фукнции в глобальный модуль конфигурации-приемника. А еще можно вопрос? как перенести остатки с помощью документа Операция из 7.7 в 7.7 с помощью КД2 ? В ПКС семерочной операции не видна табличная часть (самое важное — счета, суммы) — т.е. все примеры из книг не действуют. Это вообще возможно сделать?

    Reply
  10. demon_infernal

    (9) volha-77,

    ну как это «примеры из книг не действуют», когда Бояркин&Филатов, страница 147 ?

    Как раз там описан способ переноса проводок из документа «Операция» 7.7, который не имеет табличной части, в документ «операция» 8.х. Адаптировать решение под 7.7 не составит большого труда.

    Reply
  11. volha-77

    (10) спасибо за ответ. Но что-то я все равно не догоняю. В том примере переопределяется КоллекцияОбъектов восьмерки-приемника из проводок источкика-семерки. Делается все это как обычно до выгрузки. У меня приемник — семерка, там не будет коллекции объектов, т.к. док. Операция не имеет табличной части. Тут наверно другой какой-то подход нужен.

    Reply
  12. demon_infernal

    (11) volha-77, на диске, прилагаемом к Б&Я, есть пример конвертации 7.7 — 7.7 (в приложении). Открыл, посмотрел — там используется событие «ПослеЗагрузки» документа «Операция», но я почему то всегда был уверен, что в 7.7 это не работает.

    В любом случае, вы можете подсмотреть там способ переноса проводок в документ «Операция». Принцип такой: на этапе выгрузки формируем собственный XML-блок, записываем в него проводки, на этапе загрузки этот XML-блок читаем. В этой статье как раз я описываю подобный случай, посмотрите выше.

    Так, кстати, любые данные можно перенести, для которых не подходят стандартные варианты конвертации.

    Reply
  13. volha-77

    (12) Спасибо большое за помощь!

    Reply
  14. volha-77

    Еще образовался вопрос. Я переношу счета документов, как написано в Вашей статье. Если у правила есть источник и приемник, то все получилось. Подскажите, пожалуйста, как быть, если у документа нет источника (в базе приемнике создается документ ВводДолга на основании выборки из бух. итогов). Т.е. обработчик ПередОбработкой у 1-го правила выгрузки данных уже заполнен, и плюс еще проблема в том, что для алгоритма ПолучитьВыборкуДокументов должен быть источник выборки, а у меня его нет.

    Reply
  15. demon_infernal

    (14) volha-77, алгоритм ПолучитьВыборкуДокументов заполняет переданный вторым параметром список значений, который в событии «ПередОбработкой» ПВД помещается в переменную «ВыборкаДанных». Это специальная переменная для именно этого события, подробнее в справке.

    Смысл в чем: алгоритм этот в том виде, в каком он представлен в типовых правилах, вам и не нужен.

    Можно сделать так: в ПВД назначается ПКО, в обработчике «ПередОбработкой» пишется примерно следующее:

    ВыборкаДанных = СоздатьОбъект(«ТаблицаЗначений»);

    Идентификаторы колонок таблицы должны соответствовать наименованиям ПКС в ПКО, по которому будет происходить выгрузка.

    Далее с помощью запроса, или как угодно еще, эта таблица заполняется, и все.

    Или, как вариант, посмотрите в сам алгоритм «ПолучитьВыборкуДокументов» и вместо запроса к документам вставьте свой запрос, который формирует нужную таблицу с данными из итогов.

    Reply
  16. volha-77

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

    ВыборкаДанных = СоздатьОбъект(«СписокЗначений»);

    ВходящиеПараметрыАлгоритма = СоздатьОбъект(«СписокЗначений»);

    ВходящиеПараметрыАлгоритма.ДобавитьЗначение(Правило, «Правило»);

    ВходящиеПараметрыАлгоритма.ДобавитьЗначение(ВыборкаДанных, «ВыборкаДанных»);

    ПолучитьВыборкуДокументов(, ВходящиеПараметрыАлгоритма);

    и плюс функции ПолучитьВыборкуДокументов тоже требуется объект выборки, а у меня его нет.

    Reply
  17. demon_infernal

    (16) volha-77, я себе представляю это так:

    Нужно создать два ПВД и два ПКО (с одинаковыми полями поиска), источник пустой, приемник — документ ВводДолга.

    Первым ПВД выгружаем весь документ, кроме реквизита «Счет».

    Вторым ПВД выгружаем только номера строк и значения «Счет». Доп.узлы можно попробовать формировать во втором ПВД в событии «ПослеВыгрузки».

    Reply
  18. volha-77

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

    Reply
  19. demon_infernal

    (18) volha-77, сейчас еще подумал — нет, не надо в ПВД ничего делать.

    Проблема в чем была? В том, что если у ПКО объект-источник — это определяемая в событии «ПереодОбработкой» ПВД таблица значений — у вас чего то не срабатывало. И, как я понял, проблема в том, что у вас не получается адаптировать алгоритм ПолучитьВыборкуДокументов к запросу к бухитогам.

    Вы пишите, что алгоритму ПолучитьВыборкуДокументов требуется объект выгрузки. Не знаю, в моем варианте не требуется никакой объект.. На всякий случай, привожу текст алгоритма ПолучитьВыборкуДокументов, который я использую:

    // Получает для выгрузки выборку документов с учетом отбора по балансодержателю в пределах периода
    //
    // Входящие данные:
    //  Правило — Правило выгрузки документа, т. е. параметр ПВД Правило
    //  ВыборкаДанных — СписокЗначений, состоящий из документов, подлежащих выгрузке
    //
    // ИсходящиеДанные:
    //  Нет
    //
    
    
    Правило = ВходящиеДанные.Получить(«Правило»);
    ВыборкаДанных = ВходящиеДанные.Получить(«ВыборкаДанных»);
    
    
    Если (Параметры.ПериодОкончание >= Параметры.ПериодНачало) Тогда
    
    // Получить имя документа
    Префикс = «ДокументСсылка.»;
    ПрефиксДлина = СтрДлина(Префикс);
    ИмяДокумента = Сред(Правило.ОбъектВыборки, ПрефиксДлина + 1);
    
    
    ВыборкаЗапрос = СоздатьОбъект(«Запрос»);
    
    НачДата = Параметры.ПериодНачало;
    КонДата = Параметры.ПериодОкончание;
    
    ТекстЗапроса =
    »
    |Период с НачДата по КонДата;
    |ОбрабатыватьДокументы все;
    |Обрабатывать НеПомеченныеНаУдаление;
    |Без итогов;
    |ТекущийДокумент = Документ.» + ИмяДокумента + «.ТекущийДокумент;
    |ВыбраннаяФирма = Документ.» + ИмяДокумента + «.Фирма;
    |Группировка ТекущийДокумент упорядочить по ТекущийДокумент.ДатаДок;
    |»;
    
    Если (ВыборкаЗапрос.Выполнить(ТекстЗапроса) = 1) Тогда
    
    Пока (ВыборкаЗапрос.Группировка() = 1) Цикл
    
    ТекущийДокумент = ВыборкаЗапрос.ТекущийДокумент;
    ВыборкаДанных.ДобавитьЗначение(ТекущийДокумент);
    
    КонецЦикла;
    
    КонецЕсли;
    КонецЕсли;
    

    Показать

    В ПВД в событии «ПередОбработкой» алгоритм вызываю так:

    ВыборкаДанных = СоздатьОбъект(«СписокЗначений»);

    ВходящиеПараметрыАлгоритма = СоздатьОбъект(«СписокЗначений»);

    ВходящиеПараметрыАлгоритма.ДобавитьЗначение(Правило, «Правило»);

    ВходящиеПараметрыАлгоритма.ДобавитьЗначение(ВыборкаДанных, «ВыборкаДанных»);

    ПолучитьВыборкуДокументов(, ВходящиеПараметрыАлгоритма);

    Мне вобще уже кажется, что можно вместо двух ПВД и двух ПКО обойтись одним ПВД и одним ПКО.. Выложите свои правила обмена, и если получится — md*шники исходной и результирующих баз, я попробую сам.

    Reply
  20. volha-77

    (19) спасибо за ответ. можно я Вам мд-шники на e-mail отправлю? Мой адрес volha-77@mail.ru. Напишите что-нибудь туда пож., а я обратно скину. Правила выкладываю.

    Reply
  21. volha-77

    отправила

    Reply
  22. M_Volkov

    Столкнулся с проблемой при обмене 7-них баз одной конфигурации: не переносятся не предопределенные счета, созданных не в конфигураторе. Эта проблема решаема КД2?

    Reply
  23. demon_infernal

    Решаема. Для плана счетов нужно создать ПКС для реквизита «код» (или любого другого реквизита, по которому нужно искать счет в базе-приемнике) и указать, что по нему производится поиск.

    Reply
  24. M_Volkov

    (23) Не помогает!? Создал новое ПКО Основной (старое ПКО с заполненой вкладкой «Конвертация значений» переименовал в ОсновнойПредопределенный) с ПКС: Код, Наименование, ПометкаУдаления, с поиском по коду, с пустой вкладкой «Конвертация значений». Ошибки выгрузки: «Значение не найдено: 80.1″… исчезли, но не предопределенные счета не переносятся, в документах счета пустые!?

    Reply
  25. M_Volkov

    (23) Смотрю файл выгрузки, где счет предопределенный:

    — <Свойство Имя=»КоррСчет» Тип=»ПланСчетовСсылка.Основной»>

    <Значение>86.3</Значение>

    </Свойство>

    а где нет:

    — <Свойство Имя=»КоррСчет» Тип=»ПланСчетовСсылка.Основной»>

    — <Ссылка Нпп=»42″>

    — <Свойство Имя=»Код» Тип=»Строка»>

    <Пусто />

    </Свойство>

    </Ссылка>

    </Свойство>

    Дописал в ПКС_Основной_Код_ПередВыгрузкойСвойства

    Значение = Источник.Код;

    стало:

    — <Свойство Имя=»КоррСчет» Тип=»ПланСчетовСсылка.Основной»>

    — <Ссылка Нпп=»10″>

    — <Свойство Имя=»Код» Тип=»Строка»>

    <Значение>80.1</Значение>

    </Свойство>

    </Ссылка>

    </Свойство>

    но не предопределенные счета не грузятся, пустые!? Что прописать в ПКО_Основной_ПослеЗагрузкиОбъекта?

    Reply

Leave a Comment

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