I have a worksheet of data from a vendor full of products we order from them. However, none of the products are arranged or formatted in an order our website will accept to list them. For the upload, each product and variant has its own row. The variant products must be listed under the parent product, with the name of the variant moved to a different column. The images for the parent product are listed under the variants while variant images are placed inline with the variant in a different column. This is an example of how it currently looks:
I created the "Parent SKU" column to use as a "key" for where variant products need to go. I've removed a lot of columns that are unnecessary to explain the situation, but the whole row will need moved to keep the data in the other columns with the right product as well. This would be the desired result:
I'm alright with power query, and have been able to do most of this with writing the M code, though I'm stuck on inserting new rows for product images after the variants. I'm aware the amount of setup I've had to do just to get this far hasn't been efficient. Any help or further direction is greatly appreciated. I started this in PQ but if VBA would have been a better option, I can go that route but I do not remember very much about VBA from when i was last learning it.
Using Power Query:
If the extra columns are with the parent (physical) product, some editing may be required.
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{
{"Item", type text}, {"Name", type text}, {"Type", type any}, {"SKU", Int64.Type},
{"ParentSKU", Int64.Type}, {"Options", type any}, {"Variant Image URL", type any}, {"ImageURL", type text}}),
//Split the table into parents and children
//Then join the children to the parents
#"Select Main"=Table.SelectRows(#"Changed Type", each [Item]<>null),
Actives = Table.TransformColumns(#"Select Main",{{"Type", each "Physical", type text}}),
Variants=Table.SelectRows(#"Changed Type", each [Item]=null),
Join=Table.NestedJoin(Actives,"SKU",Variants,"ParentSKU","Join",JoinKind.FullOuter),
//Sort by parent name
#"Sorted Rows" = Table.Sort(Join,{{"Name", Order.Ascending}}),
//Modify the joined tables by moving entries to desired columns
#"Modify Join" = Table.TransformColumns(#"Sorted Rows", {
{"Join", (t)=>[a=Table.ReplaceValue(t,null,"Variant",(x,y,z)=>z,{"Item"}),
b=Table.ReplaceValue(a,null,each [Name],(x,y,z)=> z,{"Options"}),
c=Table.TransformColumns(b,{{"Name", each null}}),
d=Table.ReplaceValue(c,null, each [ImageURL],(x,y,z)=>z,{"Variant Image URL"}),
e=Table.TransformColumns(d,{{"ImageURL", each null}}),
f=Table.Sort(e,each [SKU])][f]}}),
//add a custom column with the two extra rows from the parent
//at the beginning and end of the child table
#"Add Rows" = Table.AddColumn(#"Modify Join", "addRows", (r)=>
[a=Record.FromList(List.FirstN(Record.FieldValues(r),4), List.FirstN(Record.FieldNames(r),4)),
b=[Item="Image",ImageURL=r[ImageURL]],
c={a} & Table.ToRecords(r[Join]) & {b}
][c]),
//Remove unneeeded columns and expand the custom column
#"Removed Columns" = Table.RemoveColumns(#"Add Rows",
{"Item", "Name", "Type", "SKU", "ParentSKU", "Options", "Variant Image URL", "ImageURL", "Join"}),
#"Expanded addRows" = Table.ExpandListColumn(#"Removed Columns", "addRows"),
#"Expanded addRows1" = Table.ExpandRecordColumn(#"Expanded addRows", "addRows",
{"Item", "Name", "Type", "SKU", "ParentSKU", "Options", "Variant Image URL", "ImageURL"}),
//Reset Data Types
#"Changed Type1" = Table.TransformColumnTypes(#"Expanded addRows1",{
{"Item", type text}, {"Name", type text}, {"Type", type text}, {"SKU", Int64.Type},
{"ParentSKU", Int64.Type}, {"Options", type text}, {"Variant Image URL", type text}, {"ImageURL", type text}})
in
#"Changed Type1"