Hirdetés

Új hozzászólás Aktív témák

  • Mutt

    senior tag

    válasz Mutt #54559 üzenetére

    ChatGPT-val és Copilot-tal is rápróbálkoztam a problémára.
    Ez volt az inputom:
    i have an Excel table, in the first column of each row you can find the product name. the next two columns contain a quantity and an unit price, the other next 2 columns contain another quantity and unit price. there could be up-to 5 quantity and unit price pairs in the row, sometimes there is only 1 quantity and price pair. I would like to rearrange this data into a columnar format, where the first column contains the product name, the second a quantity and the third a price. where there are more quantity and unit price pairs they should be in a new row

    Mindkettő előbb Power Query-t, majd VBA-t javasolt. A megoldások teljesen azonosak, szövegezésben térnek csak el.

    1) PQ-esetén egy Unpivot/Elemiértékre bontás után egy oszlop felosztás és majd egy Pivot/Kinyerés. M-kódot nem adtak, de a lépéseket megadták. Itt talán abba tudnék belekötni, hogy igazán kezdőknek kicsivel több infót lehetett volna adni az oszlop felosztásnál. Azonban előny, hogy minden lépés a szerkeszőben egérkattintással elérhető.

    Az M-kód pedig ez lett:
    let
        Forrás = Excel.CurrentWorkbook(){[Name="Táblázat1"]}[Content],
        #"Többi oszlop elemi értékekre bontva" = Table.UnpivotOtherColumns(Forrás, {"Part Number"}, "Attribútum", "Érték"),
        #"Oszlop felosztása pozíció alapján" = Table.SplitColumn(#"Többi oszlop elemi értékekre bontva", "Attribútum", Splitter.SplitTextByPositions({0, 1}, false), {"Attribútum.1", "Attribútum.2"}),
        #"Oszlop elforgatva" = Table.Pivot(#"Oszlop felosztása pozíció alapján", List.Distinct(#"Oszlop felosztása pozíció alapján"[Attribútum.1]), "Attribútum.1", "Érték", List.Sum),
        #"Oszlopok eltávolítva" = Table.RemoveColumns(#"Oszlop elforgatva",{"Attribútum.2"})
    in
        #"Oszlopok eltávolítva"

    Előtte azért én is megcsináltam az M-kódomat, de én megint más logikát használtam.
    Én azt akartam, hogy a mennyiség és ár párok együtt maradjanak, de az újabb párok új sorokba kerüljenek. Ehhez a List.Split függvényt használom.

    Az én M-kódom ez lett:
    let
        Forrás = Excel.CurrentWorkbook(){[Name="Táblázat1"]}[Content],
        #"Sorok csoportosítva" = Table.Group(Forrás, {"Part Number"}, {{"Adatok", each List.Split(
        List.RemoveNulls(
            List.Skip(
                    Table.ToRows(_){0}
            , 1)
        ) , 2)}}),
        #"Kibontott Adatok" = Table.ExpandListColumn(#"Sorok csoportosítva", "Adatok"),
        #"Kinyert értékek" = Table.TransformColumns(#"Kibontott Adatok", {"Adatok", each Text.Combine(List.Transform(_, Text.From), ":"), type text}),
        #"Oszlop felosztása elválasztó alapján" = Table.SplitColumn(#"Kinyert értékek", "Adatok", Splitter.SplitTextByEachDelimiter({":"}, QuoteStyle.Csv, false), {"Scale Qty", "Scale Price"}),
        #"Típus módosítva1" = Table.TransformColumnTypes(#"Oszlop felosztása elválasztó alapján",{{"Scale Qty", Int64.Type}, {"Scale Price", type number}})
    in
        #"Típus módosítva1"

    Ennek a kódnak a lényegi része csak kézi bevitellel érhető el, mivel nincs olyan menűpont a PQ szerkesztőben ahol pár általam használt függvény elérhető lenne. Egymásba ágyazott függvények vannak, ugrás tábla - record - lista között; ez talán túlsok.

    Végeredmény: az AI jobban teljesített szerintem mint én. Tisztább, elemi lépésekből álló kódot adott. Míg én itt is túlbonyolítottam.

    2) VBA megoldás, a kód hiba nélkül le fut első alkalommal, de sajna egyik sem nézi hogy adott névvel létezik-e már munkalap, így másodjára elhasal. A ChatGPT kicsit hagyományosabb előbb létrehozza az összes változót, míg a Copilot feladatonként/taskonként megy végig (pl. adatokat tartalmazó munkalap "rögzítése" és változói, majd az eredményeket tartalmazó lap létrehozása és változói) és gyorsan előtte definiálja a változót és dolgozik is vele azonnal.

    Copilot kódja:
    Sub RearrangeData()
        Dim ws As Worksheet
        Set ws = ThisWorkbook.Sheets("Sheet1") ' Adjust sheet name as needed
        
        Dim lastRow As Long, i As Long, colOffset As Long
        Dim destRow As Long
        destRow = 2 ' Start from row 2 on output sheet
        Dim output As Worksheet
        Set output = ThisWorkbook.Sheets.Add
        output.Name = "Reformatted"
        output.Cells(1, 1).Value = "Product Name"
        output.Cells(1, 2).Value = "Quantity"
        output.Cells(1, 3).Value = "Price"
        lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
        For i = 2 To lastRow
            For colOffset = 0 To 4 ' Up to 5 quantity-price pairs
                If ws.Cells(i, 2 + colOffset * 2).Value <> "" Then
                    output.Cells(destRow, 1).Value = ws.Cells(i, 1).Value
                    output.Cells(destRow, 2).Value = ws.Cells(i, 2 + colOffset * 2).Value
                    output.Cells(destRow, 3).Value = ws.Cells(i, 3 + colOffset * 2).Value
                    destRow = destRow + 1
                End If
            Next colOffset
        Next i
    End Sub

    Végeredmény: a kód műkődik, lehetne finomítani hibakezeléssel és with - end with párosokkal.

    3) A ChatGPT javasolt képletet is, a Copilot alapból nem (kérésre adott, What Excel formulas can I use for this task?).
    A képletek INDEX - MÓDUS/MOD - SOR/ROW kombinációjával operálnak, már a másodiktól fejfájást kaptam.

    A ChatGPT (első sor) és Copilot (második) ezt javasolja pl. a mennyiségek kikeresésére (új munkalapon B2 cellába kell írni az útmutató szerint).
    =IFERROR(INDEX(Sheet1!$B$2:$K$100, INT((ROW()-2)/5)+1, (MOD(ROW()-2,5)*2)+1), "")
    =        INDEX(Sheet1!$B$2:$K$100, INT((ROW()-1)/5)+1, MOD(ROW()-1,5)*2+1)

    ChatGPT előnye, hogy hibakezelést is végez. Illetve a végén a MOD(ROW ... részben van plusz zárójel, ami kell ha tényleg B2-ből indul a képlet. B1 esetén a Copilot eredménye helyes.

    Végeredmény: Ahogy látszik itt van már hibalehetőség, ami elég nehezen nyomozható ki. Itt a másik gond, hogy fixen 5 elemenként ugrik a képlet, de a mintánkban van olyan eset ahol nincs 5 adat-párunk, itt 0-kat kapunk amit majd kézzel szűrni kell.

    4) ChatGPT javasolt dinamikus képletet (LET - LAMBDA - MAP), Copilot nem (kérésre ő is adott: can you show me solution with dynamic array formulas (like LET - LAMBDA - MAP)? )

    Itt egyértelműen a ChatGPT győzőtt. Az első kódja egyből működött:

    =LET(
        data;A2:K7;
        products; INDEX(data;;1);
        pairs; DROP(data;;1);
        rows; ROWS(products);
        maxPairs; COLUMNS(pairs)/2;
        total; rows * maxPairs;
        rowIndex; SEQUENCE(total);
        prodRow; INDEX(products; INT((rowIndex - 1)/maxPairs) + 1);
        qCol; INDEX(pairs; INT((rowIndex - 1)/maxPairs) + 1; (MOD(rowIndex - 1; maxPairs) * 2) + 1);
        pCol; INDEX(pairs; INT((rowIndex - 1)/maxPairs) + 1; (MOD(rowIndex - 1; maxPairs) * 2) + 2);
        FILTER(HSTACK(prodRow; qCol; pCol); qCol <> "")
    )

    A Copilot olyan képletet adott, amiben eleve hiba van és a függvény paraméterek sincsenek a helyükön. Ez a sor tiszta katyvasz:
    HSTACK(IF(qty="";SEQUENCE(ROWS(qty);1;;#REF!);prod); qty; price);

    Kértem javítást, elmagyaráztam neki hogy rosszul gondolja a paraméter átadásokat, de 2 újabb rossz változat után feladtam a harcot vele.
    Ez az utolsó változata, ami nagyon hibás.
    =LET(
        data; A2:K7;
        products; INDEX(data;;1);
        details; DROP(data;;1);
        numRows; ROWS(data);
        qtyCols; CHOOSE({1;3;5;7;9};1;3;5;7;9);
        priceCols; CHOOSE({2;4;6;8;10};2;4;6;8;10);
        getRow; LAMBDA(r;
            LET(
                prod; INDEX(products; r);
                qtys; INDEX(details; r; qtyCols);
                prices; INDEX(details; r; priceCols);
                valid; FILTER(HSTACK(prod; qtys; prices); qtys<>"")
            )
        );
        final; MAP(SEQUENCE(numRows); getRow);
        VSTACK({"Product";"Quantity";"Price"}; final)
    )

    Végeredmény: ChatGPT a nyerő, mivel 1 db függvénnyel megoldotta amit én 2-vel értem el.

    Összeségében műkődik az AI segítség, ebben a feladatban tudott volna segíteni hiszen nem volt olyan bonyolult, talán legközelebb is hasznos lesz.

    üdv

Új hozzászólás Aktív témák