Страницы: Пред. 1 2
RSS
Выгрузка XML (сложная архитектура) в Excel средствами Power Query
 
Андрей Лящук, спасибо за способ
Только хотел бы обойтись только Power Query
 
Виктор А, вы бы свою тему создали, глядишь народ бы и подтянулся. Так как
Цитата
2.6. Один вопрос - одна тема. Не следует в открываемой теме обозначать и задавать сразу несколько вопросов.
Вы уверены, что теперь все, кому нужен импорт данных из Xml через Power Query должны писать именно в эту тему?
 
Цитата
Андрей VG написал:
писать именно в эту тему?
Нет, только со сложной архитектурой)
Позже, может, открою тему
В принципе, тема открыта еще до рождения Power Query :D  
 
исправил свой пост, вместо Stylesheet2 должно быть Stylesheet
 
Андрей Лящук, Сижу разбираю предложенный вариант - нашел много интересных для себя примеров решений для задач которые я обычно делаю набором кнопок. Буду пробовать.
 
состряпал тут на днях xsl для проверки скорости
xslt.xslt

на всех 4-x файлах примеров (XML файл.xml, XML файлM.xml, XML файлP.xml, XML-файл.xml) отработал за 4 сек
Код
let
    Source    = Table.SelectRows(Folder.Files("J:\laragon\www\xml"), each ([Extension] = ".xml") and not[Attributes][NotContentIndexed]),
    GetTables = 
        Table.FromRecords(
            Table.CombineColumns(
                Source,
                {"Folder Path", "Name"},
                (a)=>
                    [
                        filepath=a{0}&a{1},
                        table=Table.SelectRows(
                            Web.Page(Web.Contents(Text.Replace("http://localhost"&Text.Split(a{0},"www"){1}&a{1},"\","/"))),
                            each [Id]="ds300"
                        ){0}[Data]
                    ],
                "a"
            )[a]
        ),
    Expand    = Table.ExpandTableColumn(GetTables, "table", {"f18", "Место реализации", "f20", "f20_value", "f19", "Товарная группа", "Товар", "Количество", "Закупка", "Сумма закупки", "Продажа", "Сумма продажи"})
in
    Expand
Изменено: Андрей Лящук - 09.04.2020 04:59:32
 
Андрей Лящук, День добрый. Когда загрузил все файлы (итоговое количество строк более 1 000 000) то на этом шаге
Код
Pivot   = Table.Pivot(Expand, List.Distinct(Expand[Атрибут]), "Атрибут", "Значение"),
выдало 53 ошибки. Стал - выяснил что есть записи в которых не по 2 шт, а по 3.
Во вложении файл в котором одна из записей в тройном количестве.
Вот здесь попробовал найти решение. Предложенное решение работает, но только для тройных записей - где их две, конечно же нет (так как я некорректно сформировал свой вопрос).

UPD Исходный файл не выкладываю ибо он очень тяжел.

Текущий работающий код, с учетом исправлений:
Код
let
    fnParentValuesRecursive = (src as table, ParentField as text, ChildField as text, ValueField as text) => let
        Inital  = Table.FromColumns({Table.Column(src,ChildField)},{"child"}),
        fn = (optional table as nullable table, optional depth as nullable number) => 
            let
                t = if table = null then Inital else table,
                d = if depth = null then 1 else depth,
                AddedColumn = Table.AddColumn(t, "x", each
                    let 
                        Child   = [child],
                        Filter  = Table.SelectRows(src,(r)=>Record.Field(r,ChildField)=Child),
                        Select  = Table.SelectColumns(Filter,{ValueField,ParentField}),
                        Renamed = Table.RenameColumns(Select,{{ValueField,"val"&Text.From(d)},{ParentField,"child"}}),
                        Dummy   = #table({"child","x"},{})
                    in if Table.RowCount(Filter)>0 then @fn(Renamed,d+1) else Dummy),
                DistinctColumns = List.Distinct(List.Combine(List.Transform(AddedColumn[x],Table.ColumnNames))),
                AllColumns      = if d>1  then Table.ColumnNames(AddedColumn[x]{0}) else DistinctColumns,
                NeededColumns   = List.Select(AllColumns,each Text.StartsWith(_,"val")),
                Expand          = Table.ExpandTableColumn(AddedColumn,"x",NeededColumns),
                Combine         = Table.CombineColumns(Expand,List.Reverse(NeededColumns),(a)=>Text.TrimStart(Text.Combine(List.RemoveNulls(a),"|"),{"|"}),"val")
            in Combine
    in Table.RenameColumns(fn(),{{"child",ChildField},{"val",ValueField}}),
     
    Source = Text.Replace(Text.Replace(Text.Replace(Text.Replace(Text.Replace(Text.FromBinary(File.Contents("C:\D2A\SH.xml")),"\","\\"),"#(cr,lf)","\n"),"<","<"),">",">"),""",""),
    DataSet = Xml.Tables(Web.Page("<script>
                    document.write('<table><tr><th>xml</th></tr><tr><td>"&Source&"'
                        .replace(/(\<[frg])(\d+)/g,'$1 n=""$2""')
                        .replace(/(\<\/*[frg])\d+(\>)/g,'$1$2')+'</td></tr></table>')
              </script>"){0}[Data]{0}[xml]){1}[Table],
    Date = Date.From(Table.SelectRows(DataSet,each [Fields]{0}[f]{0}[#"Attribute:Id"]="_Rpt_Period_Object")[Records]{0}[r]{0}[#"Attribute:f21"]{0}),
    Groups = let
        a = Table.Combine(List.Transform(List.RemoveNulls(DataSet[Groups]),each _{0}[g]))[[DataSet],[#"Attribute:pKey"]],
        b = Table.ReplaceValue(a,null,null,(a,b,c)=>
                let 
                    rec=a{0}[Records]{0}[r] 
                in 
                    if a{0}[Fields]{0}[f]{[#"Attribute:Id"="_GrpTreePerent_"]}?=null 
                        then rec 
                        else fnParentValuesRecursive(Table.Buffer(rec),"Attribute:f2","Attribute:f0","Attribute:f1")
            ,{"DataSet"}),
        c = Table.ExpandTableColumn(Table.NestedJoin(b,"Attribute:pKey",DataSet{[#"Attribute:Id"="300"]}[Fields]{0}[f],"Attribute:Id","a"),"a",{"Attribute:n"}),
        d = Table.ExpandTableColumn(c, "DataSet", {"Attribute:f0", "Attribute:f1"})
    in d,
    Records = Table.SelectColumns(DataSet{[#"Attribute:Id"="300"]}[Records]{0}[r],List.Transform({1,2,9,18,19,34},each "Attribute:f"& Text.From(_))),
    Unpivot = Table.Unpivot(Records, {"Attribute:f18", "Attribute:f19"}, "Атрибут", "Значение"),
    Replace = Table.ReplaceValue(Unpivot,"Attribute:f","",Replacer.ReplaceText,{"Атрибут"}),
    Nested  = Table.NestedJoin(Replace,{"Атрибут","Значение"},Groups,{"Attribute:n","Attribute:f0"}," "),
    Expand  = Table.ExpandTableColumn(Table.RemoveColumns(Nested,{"Значение"}), " ", {"Attribute:f1"}, {"Значение"}),
    Pivot   = Table.ReplaceValue(Table.Pivot(Expand, List.Distinct(Expand[Атрибут]), "Атрибут", "Значение"),".",",",Replacer.ReplaceText,{"Attribute:f9"}),
    Merge   = Table.CombineColumns(Pivot,{"Attribute:f1", "Attribute:f2", "Attribute:f9"},(a)=>
                  [ Количество=Number.From(a{2}),
                    Закупка=Number.From(a{0})/10000,
                    #"Сумма закупки"=Количество*Закупка,
                    Продажа=Number.From(a{1})/10000,
                    #"Сумма продажи"=Количество*Продажа,
                    Дата=Date ]
              ,"x"),
    Expand1 = Table.ExpandRecordColumn(Merge, "x", {"Количество", "Закупка", "Сумма закупки", "Продажа", "Сумма продажи","Дата"}),
    Renamed = Table.RenameColumns(Expand1,{{"Attribute:f34", "Товар"}, {"18", "Место реализации"}, {"19", "Товарная группа"}})
in
    Renamed
Изменено: mitox - 09.04.2020 14:31:32
 
Андрей Лящук, А что означала эта ошибка?
Цитата
mitox написал:
DataFormat.Error: Сбой обработки XML. Введенные данные недопустимы или не поддерживаются. (Внутренняя ошибка: "", шестнадцатеричное значение 0x07, является недопустимым знаком., строка 1, позиция 1943.)Сведения:

Она снова воспроизвелась при выгрузке файла из программы, но в другом отчете. Сам хочу найти - подскажите пожалуйста (сижу сравниваю данные - вижу что структура справочников различная: первый отчет был о продажах, а текущий об остатках на складе)
Цитата
DataFormat.Error: Сбой обработки XML. Введенные данные недопустимы или не поддерживаются. (Внутренняя ошибка: "<", шестнадцатеричное значение 0x3C, является недопустимым для атрибута знаком., строка 1, позиция 81158.)
Сведения:

UPD Причем файлы двух Предприятий отрабатывает нормально, а одного - выдает эту ошибку...
UPD2 "позиция 81158" - как найти эту позицию?
Изменено: mitox - 19.04.2020 20:28:17
 
там в файле была строка
Код
<f37 Parent="210\7" Id="$SertKeep" Type="17" Size="0"/>
javascript выражение \7 интерпретировал как символ c кодом 7
видимо у вас в фале есть
Код
&lt;
если так, то нужно заменять на
Код
&amp;lt
Попробуйте вариант с xslt, возможно вы уже пробовали и он не работал - я как-то забыл указать что для него нужно задать режим совместимости IE >=9
в приложенном архиве есть reg файл для выполнения необходимых изменений в реестре
Изменено: Андрей Лящук - 19.04.2020 21:23:31
 
Андрей Лящук,  Спасибо. Да. В данных были "&lt;"

Цитата

</DataSet>                                                                                                        

<DataSet Id="">                                                                                                

                                          <Fields>                                                                    

                                                                 <f0 Id="Lookup_Key" Type="7" Size="4"/>

                                                                 <f1 Id="Lookup_Value" Type="16" Size="0"/>

                                          </Fields>                                                                  

                                          <Records>                                                                

                                                                 <r0 f0="0" f1="любое"/>            

                                                                 <r1 f0="1" f1="&gt; 0"/>              

                                                                 <r2 f0="2" f1="= 0"/>                    

                                                                 <r3 f0="3" f1="&lt; мин. запаса"/>

                                                                 <r4 f0="4" f1="&gt;= мин. запасу"/>

                                                                 <r5 f0="5" f1="&lt;= макс. запасу"/>

                                                                 <r6 f0="6" f1="&gt; макс. запаса"/>

                                                                 <r7 f0="7" f1="соотв. правилам запасов"/>

                                                                 <r8 f0="8" f1="не соотв. правилам запасов"/>

                                               </Records>


Заменой на "&amp;lt" не лечилось, но вылечилось заменой на "".
UPD - изменял этот текст и обратил внимание что данное сочетание автоматически изменяется на "<"...
Изменено: mitox - 20.04.2020 06:46:28
 
лучше таки заменить &gt; на больше, &lt; на меньше
 
Андрей Лящук, Да. Согласен. Теперь я знаю что такое &gt и &lt )))
 
Андрей Лящук, День добрый.
Сижу разбираю. Обратил внимание что в Records содержится еще одна группировка данных, которая не отражается в справочниках Groups, но содержится во второй (!) строчке Records (если открывать в эксель).

Начал разбирать и понял что на самом первом этапе Sourse данный справочник собран в отдельную группу, а строки Records не содержат ключа по которому можно прицепить наименование из справочника. Потом вспомнил что на этапе выбора группировки программа спросила как группировать, и то что не выбрал - попало во вторую строку ((( видимо безнадега... Вот сам и ответил на свой вопрос...
 
Цитата
Андрей Лящук написал:
и шаг Groups на случай, если в группе 53 не будет иерархии parent-child, как в последних 2х xml
День добрый.
Ломаю голову второй день над еще одной выгрузкой из того же ПО. Ее структура отличается от предыдущих тем что ID задается идентичным в двух группировках (равен 1), а Parent - различный (105 и 210/209). В предыдущих файлах все было наоборот (ID - разные 52 и 53, а Parent - один: 107._ObjLst). Сответственно не могу понять как изменить шаг Groups.

Не сочтите за наглость - буду премного благодарен если поможете, я все излазил, пытаясь сам поправить код. Нужные группировки в f32 и f42. Понятно что если это решаемая задача.
Изменено: mitox - 03.05.2020 11:31:16
Страницы: Пред. 1 2
Наверх