Вход | Регистрация


1С:Предприятие :: 1С:Предприятие 8 общая

Вопрос по конвертации данных

Вопрос по конвертации данных
Я
   belka4_4
 
07.11.18 - 12:06
Добрый день!

Конвертирую документ из базы УПП 1.3 с подсистемой ТОиР в ТОиР 2.0
Документ "ВЫявленные дефекты". У него есть табличная часть СписокДефектов. В ней в каждой строке есть 2 реквизита: РодительскийЭлемент и ДочернийЭлемент (названия другие, но суть не в этом), оба типа Справочник.ОбъектыРемонта.

Задача: надо перенести только те документы, объекты ремонта которых которые уже есть в ТОиР 2.0. В УПП 1.3 каждому объекту ремонта в специальный реквизит "КодВТоиР20" прописан код, если не прописан, значит этот объект не переносился. Переносить надо следующим образом:
1. Код проставлен для РодительскогоЭлемента и для ДочернегоЭлемента - переносим документ.
2. Код проставлен для РодительскогоЭлемента и не проставлен для ДочернегоЭлемента - переносим документ, но вместо ДочернегоЭлемента подставляем Родительский, т.е. дублируем в одной строке значение в двух реквизитах.
3. Код не проставлен для РодительскогоЭлемента и проставлен для ДочернегоЭлемента - переносим документ. При этом в базе-приемнике, запросом ищем родителя для этого дочернего элемента и подставляем найденный в РодительскийЭлемент. Если не нашли - документ не переносим
4. Код не проставлен для РодительскогоЭлемента и не проставлен для ДочернегоЭлемента - не переносим документ.

Логика выглядит примерно следующим образом:
Для Каждого ОР Из Источник.СписокДефектов Цикл

    Если НЕ ЗначениеЗаполнено(ОР.ОбъектРемонта.КодВТОиР20) Тогда//не заполнен родитель

        Если ЗначениеЗаполнено(ОР.ОтказавшийЭлемент.КодВТОиР20) Тогда// заполнен подчиненный

            ОР.ОтказавшийЭлемент = Справочники.торо_ОбъектыРемонта.НайтиПоРеквизиту("ТехНомер", ОР.ОтказавшийЭлемент.КодВТОиР20);
            Запрос = Новый Запрос;
            Запрос.Текст = "ВЫБРАТЬ
            |    торо_ИерархическиеСтруктурыОР.РодительИерархии КАК РодительОбъекта
            |ИЗ
            |    РегистрСведений.торо_ОбъектыРемонтаГруппы КАК торо_ОбъектыРемонтаГруппы
            |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.торо_ИерархическиеСтруктурыОР КАК торо_ИерархическиеСтруктурыОР
            |        ПО торо_ОбъектыРемонтаГруппы.ОбъектИерархии = торо_ИерархическиеСтруктурыОР.РодительИерархии
            |            И торо_ОбъектыРемонтаГруппы.СтруктураИерархии = торо_ИерархическиеСтруктурыОР.СтруктураИерархии
            |ГДЕ
            |    торо_ИерархическиеСтруктурыОР.ОбъектИерархии = &ОбъектРемонта";
            
            Запрос.УстановитьПараметр("ОбъектРемонта", ОР.ОтказавшийЭлемент);

            Результат = Запрос.Выполнить();
            Выборка = Результат.Выбрать();
            Если Выборка.Следующий Тогда
                //ОбъектРемонта = Выборка.РодительОбъекта

                ОР.ОбъектРемонта = Выборка.РодительОбъекта; 
            Иначе
                Отказ = Истина;
                Прервать;
            КонецЕсли;    
            //ОбъектРемонта = Родитель по запросу    

        Иначе
            Отказ = Истина;// ничего не заполнено, документ не грузим

            Прервать;
        КонецЕсли;    
    Иначе//заполнен родитель

        ОР.ОбъектРемонта = Справочники.торо_ОбъектыРемонта.НайтиПоРеквизиту("ТехНомер", ОР.ОбъектРемонта.КодВТОиР20);
        Если НЕ ЗначениеЗаполнено(ОР.ОтказавшийЭлемент.КодВТОиР20) Тогда// не заполнен подчинённый

            // ОтказавшийЭлемент = ОбъектРемонта

            ОР.ОтказавшийЭлемент = ОР.ОбъектРемонта;
        Иначе
            ОР.ОтказавшийЭлемент = Справочники.торо_ОбъектыРемонта.НайтиПоРеквизиту("ТехНомер", ОР.ОтказавшийЭлемент.КодВТОиР20); 
        КонецЕсли;
    КонецЕсли;

КонецЦикла;

Да, сами объекты ремонта мы не грузим, т.к. они уже есть в базе, а ищем по реквизиту.

Код, написанный выше, разумеется не работает, это модель, т.к. вставить его некуда: ПередЗагрузкой и далее в ПКО мы не можем обратиться к Источнику по точке, а в событиях выгрузки нам не доступен приёмник, чтобы искать в нём. При конвертации свойств, мы не можем отказаться от записи объекта в целом при невыполнении каких-либо условий.

Как можно с наименьшей болью выйти из ситуации? Пока на ум приходит только в базе-источнике подгрузить в ещё один реквизит родителей и обработкой в документах поменять. А потом уже грузить готовые документы. С конвертацией знакома мало, к сожалению(
 
 
   belka4_4
 
1 - 07.11.18 - 14:35
Не могу понять это форум вымирает или конвертацию не так много 1Сников знает?..
   Йохохо
 
2 - 07.11.18 - 14:41
логику надо натянуть на предметную базу. Например местами поменять "не переносим" на "не записываем". Еще надо добавить "И" и "ИЛИ" чтобы понять, что делать с доком в ТЧ которого есть и 1, и 2, и 3, и 4, и закончили упражнение.
   belka4_4
 
3 - 07.11.18 - 14:56
(2)
По поводу ситуации, когда есть все случаи, предполагалось не записывать документ вовсе, но я думаю стоит поговорить с заказчиком и предложить отказываться только от конкретной строки (вопрос ещё что это за собой потянет).

Я правильно поняла, что предлагаете использовать конвертацию свойств, а потом в ПередЗаписью ПКО проверять, если в ТЧ нет ни одной строки, то Отказ = Истина?
   Йохохо
 
4 - 07.11.18 - 15:05
(3) в конвертации есть обработчики и на стороне источника и приемника. 1,2,4 решаются _для_строк_ТЧ_ в источнике, 3 в приемнике, просто обработайте док в приемнике после прочтения
После загрузки
Условия возникновения события
Только для платформы V8.
Событие выполняется после прочтения и установки атрибутов объекта из файла, но до его записи в информационную базу. Возможна модификация загруженного объекта.
   Cyberhawk
 
5 - 07.11.18 - 15:10
Много букв
   damas
 
6 - 07.11.18 - 15:14
мало когда отвечают(1)
в основном активность на выборе машин) или религиозность полета в космос))
   Голубушка
 
7 - 07.11.18 - 15:33
"Переносить" это выгружать или загружать?
   Голубушка
 
8 - 07.11.18 - 15:39
" т.к. вставить его некуда:" , почему вы не хотите вставить его в Алгоритм и вызывать его при выгрузке?
   Ёпрст
 
9 - 07.11.18 - 15:43
(0)
в ПередВыгрузкой шаритесь по таб части дока на предмет пунктов 1,2,4 и делаем Отказ = Истина, если условие для любой строки тч не проходит

в ПКС переопределяем значение для 1,2

для 3 делаем в После загрузки и там уже Отказ = истина.
усё
   VS-1976
 
10 - 07.11.18 - 15:45
(8) Да зачем, есть же в ПВД Произвольный алгоритм. Там запрос пишем ( определяемся с выгружаемым списком ), там же есть и указание какой ПКО вызывать. В ПКО прописываем поля и всё...
 
 Рекламное место пустует
   belka4_4
 
11 - 07.11.18 - 15:46
(4)
Получается алгоритм такой:
1.Для 1,2,4 на этапе выгрузки в ПКС подменяю элементы или отказываюсь от переноса строки
2.Для 3 на этапе загрузки нахожу родителя.
3.Перед записью проверять, есть ли строки в табличной части и если нет, то отказываться от записи.

Возможно 3 пункт будет выполняться до 2го.

(7)Повторюсь, что плохо знаю конвертацию, но зачем нам может понадобиться выгрузка без последующей загрузки? В моём понимании переносить = выгрузить из источника и загрузить в приёмник. События, которые между ними даны для удобства обработки данных по пути, нет?
   Ёпрст
 
12 - 07.11.18 - 15:47
(11) неа.. зачем выгружать объект, если 1,2,4 не выполнено ?
   Ёпрст
 
13 - 07.11.18 - 15:48
(10) либо так.
   Голубушка
 
14 - 07.11.18 - 15:48
Я правильно понимаю, что в базе выгрузки все есть, а в базе загрузки нужна проверка на наличие родителя у загружаемого элемента?
   Йохохо
 
15 - 07.11.18 - 15:51
(11) угу, например в ПКС РодительскогоЭлемента Если Пункт3() Тогда ИмяПКО = "ОбъектыРемонтаПустаяСсылка";
   belka4_4
 
16 - 07.11.18 - 15:52
(12) У нас же может быть несколько строк. Если в строке ДочернийЭлемент с кодом, то мы грузим документ, просто потом заменяем в этой строке Родительский.

Я думаю, что в итоге решим с заказчиком грузить по принципу: если в строке можно понять ху из ху, то грузим строку и при необходимости меняем данные. Если в итоге в документе 0 строк - не грузим документ.
   VS-1976
 
17 - 07.11.18 - 15:53
(11) Тебе нужно строки не все выгружать?
В общем в Произвольном алгоритме, можно создать ТаблицуЗначения. В эту таблицу значения можно запихнуть ещё таблицу значения с названием поля к примеру Товары. Это будет табличная часть. В ПКО описываются реквизиты и Табличная часть, в Табличной части так же описываешь какие реквизиты переносить и всё
   Йохохо
 
18 - 07.11.18 - 15:54
(16) это надо было раньше сделать. И нет ничего страшного выгрузить и не загружать, если данных в источнике недостаточно для принятия решения
   belka4_4
 
19 - 07.11.18 - 15:55
(14) В базе выгрузки много хлама, всё тащить не надо - только по тем объектам, которые есть в приемнике. Да, бОльшую часть проверок можно сделать в базе выгрузки. Но проверить, а можем ли мы в 3 пункте найти родителя, или его и в приёмнике нет, а это значит, что грузить смысла нет, мы можем только выполнив запрос в приёмнике.
   VS-1976
 
20 - 07.11.18 - 15:57
(19) В моём варианте можно в источнике всё сразу отфильтровать, и грузить уже готовое...
   Йохохо
 
21 - 07.11.18 - 15:58
(20) нельзя п3, не путай
   Голубушка
 
22 - 07.11.18 - 15:59
В этих ПКО ставим галку не создавать если не найден. "Поля для поиска"  Код и КодРодителя , прописываем это  в поля поиска, посмотри в "информация по обработчикам", там хорошо объясняют.

Т.е. при загрузке получаем док с пустыми строками, проверяем это в обработчике "После загрузки" ПКО документа и устанавливаем Отказ= Истина. Документ не загрузится и лишние Дочерние и Родительские тоже.
   VS-1976
 
23 - 07.11.18 - 16:00
(21) Это ещё с чего? запросом можно всё сопоставить. Ты же выборку делаешь, к примеру из плана обмена, всё сращиваешь и фильтруешь. Почему вдруг нельзя родителя сопоставить с дочерней таблицей?
   belka4_4
 
24 - 07.11.18 - 16:00
(18) На самом деле документы в основном с одной строкой в табличной части (других по крайней мере не видела), но чисто теоретически могут быть с несколькими, а заказчик хочет быстрее и действовать по принципу "выгрузи что-нибудь", а потом посмотрим будут ли ошибки. Поэтому и появилось это "не грузить" вовсе, но я так не хочу =D.
   Йохохо
 
25 - 07.11.18 - 16:01
(24) если тебя забесплатно засадят за сверку, что будешь делать? это риторический вопрос
   Голубушка
 
26 - 07.11.18 - 16:08
1)Родители в базе выгрузки и базе загрузки одни? Но в базе загрузки они не полные так?
2)В базе выгрузки элементы все с родителями ?

Проверки можно организовать и на одной стороне и на другой.
Если у вас можно отсечь неверные документы в базе выгрузки, то напишите ПВД со способом "Произвольный алгоритм", определите выборку выгрузки.
   belka4_4
 
27 - 07.11.18 - 16:25
(22) Я в принципе кроме документа ничего не создаю - везде стоит не создавать если не найден и не заменять свойства у существующих объектов. Надо только создать документ и подтянуть в него ссылки из уже существующих справочников.
Т.е. все нужные Родительские и Дочерние уже есть.

(25) Сверять будет заказчик. Но вот если что не так, то исправлять мне, а исправлять хуже, чем сразу сделать нормально.
   belka4_4
 
28 - 07.11.18 - 16:28
(26)
В базе источнике нет информации о том, кто является родителем для элемента в базе приемнике, и в принципе структура справочников разная. В базе-приемнике иерархия зашита в двух регистрах. Поэтому я и думала в крайнем случае данные о родителях в приёмнике загрузить обработкой в источник и отсекать их сразу.
   Йохохо
 
29 - 07.11.18 - 16:34
проблемточканет
   belka4_4
 
30 - 13.11.18 - 11:37
Добрый день!
Решение в итоге такое:
В табличной части документа добавила 2 ПКС для родителя и подчинённого примерно следующего вида:

СтруктураПараметров = Новый Структура("ИД, КодРодителя");
СтруктураПараметров.ИД = ОбъектКоллекции.ID;
СтруктураПараметров.КодРодителя = ОбъектКоллекции.ОбъектРемонта.РАЦ_КодВТОиР20;

Значение = ЗначениеВСтрокуВнутр(СтруктураПараметров);


В ПКО в событии ПослеЗагрузки обрабатываю:


ТЧСписокДефектовПараметры = ПараметрыОбъекта["СписокДефектовТабличнаяЧасть"];

Если Не ТЧСписокДефектовПараметры = Неопределено Тогда
    МассивКУдалению = Новый Массив;
    
    //ИндексСтроки = 0;

    Для Каждого Стр Из ТЧСписокДефектовПараметры Цикл
        СтруктураПараметровРодителя = ЗначениеИзСтрокиВнутр(Стр.КодРодителяСтруктура);
        СтруктураПараметровПодчиненного = ЗначениеИзСтрокиВнутр(Стр.КодЭлементаСтруктура);
        
        //Найдем строку в загруженном документе

        СтрокаДефектов = Объект.СписокДефектов.Найти(СтруктураПараметровРодителя.ИД, "ID");
        //СтрокаДефектов = Объект.СписокДефектов[ИндексСтроки]; //Можно было отказаться от структуры и искать строку через индекс, т.к. обработчик перебирает их подряд

        Если СтрокаДефектов = Неопределено Тогда Отказ = Истина; Продолжить; КонецЕсли;
        //Если в строке условие удаления, то добавим строку в массив к удалению

        Если НЕ ЗначениеЗаполнено(СтруктураПараметровРодителя.КодРодителя) Тогда// родитель не заполнен

            Если ЗначениеЗаполнено(СтруктураПараметровПодчиненного.КодЭлемента) Тогда// заполнен подчиненный

                Запрос = Новый Запрос;
                Запрос.Текст = "ВЫБРАТЬ
                |    торо_ИерархическиеСтруктурыОР.РодительИерархии КАК РодительОбъекта
                |ИЗ
                |    РегистрСведений.торо_ОбъектыРемонтаГруппы КАК торо_ОбъектыРемонтаГруппы
                |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.торо_ИерархическиеСтруктурыОР КАК торо_ИерархическиеСтруктурыОР
                |        ПО (торо_ОбъектыРемонтаГруппы.ОбъектИерархии = торо_ИерархическиеСтруктурыОР.РодительИерархии)
                |            И (торо_ОбъектыРемонтаГруппы.СтруктураИерархии = торо_ИерархическиеСтруктурыОР.СтруктураИерархии)
                |ГДЕ
                |    торо_ИерархическиеСтруктурыОР.ОбъектИерархии = &ОбъектРемонта";
                
                Запрос.УстановитьПараметр("ОбъектРемонта", СтрокаДефектов.ОтказавшийЭлемент);
                
                Результат = Запрос.Выполнить();
                Выборка = Результат.Выбрать();
                Если Выборка.Следующий() Тогда
                    СтрокаДефектов.ОбъектРемонта = Выборка.РодительОбъекта; 
                    //Сообщить("Не заполнен родитель, найден по подчинённому");

                Иначе
                    //Сообщить("Не заполнен родитель, не найден по подчинённому");

                    МассивКУдалению.Добавить(СтрокаДефектов);
                КонецЕсли;    
            Иначе
                //Сообщить("Не заполнен родитель, не заполнен подчинённый");

                МассивКУдалению.Добавить(СтрокаДефектов);
            КонецЕсли;
        Иначе//заполнен родитель

            Если НЕ ЗначениеЗаполнено(СтруктураПараметровПодчиненного.КодЭлемента) Тогда// не заполнен подчинённый

                //Сообщить("Заполнен родитель, не заполнен подчинённый");

                СтрокаДефектов.ОтказавшийЭлемент = СтрокаДефектов.ОбъектРемонта;
            Иначе
                //Сообщить("Заполнен родитель, заполнен подчинённый");

            КонецЕсли;
        КонецЕсли;         
        //ИндексСтроки = ИндексСтроки + 1;

    КонецЦикла;
    
    Для Каждого Стр Из МассивКУдалению Цикл
        Объект.СписокДефектов.Удалить(Стр);
    КонецЦикла;
КонецЕсли;


Комментарии "Сообщить" оставила для себя.
   belka4_4
 
31 - 13.11.18 - 11:38
И проверка там же в ПослеЗагрузки:
Если Объект.СписокДефектов.Количество() = 0 Тогда
    Сообщить("Не грузим документ");
    Отказ = Истина;
КонецЕсли;


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует