Страницы: 1
RSS
Из плоской таблицы в кросс(перекрестную)-таблицу, Форматирование таблицы для импорта через CSV
 
Добрый день!

Нужна помощь и совет. Долгое время не могу найти оптимальное решение. Особенно актуально для тех кто импортирует прайс листы на сайты через CSV.

Есть плоская таблица в которой имеются характеристики товаров и их значения, но для импорта на ресурсы необходимо ее преобразовать в перекрестную таблицу где характеристика будет в заголовке столбца, а ее значения под ними.

Через
Power Query можно реализовывать подобное (через столбец сведения), но выбирать можно всего 2 столбца для преобразования, а характеристик может быть 100и в таблицах.

Обратите внимание что вся сложность в том что характеристики по строкам могут отличаться.(в столбцах они могут не совпадать)
 
вы бы хоть в другом файле показали какой итоговый результат вы хотите получить, может это поможет тому, кто захочет вам помочь
 
Никита Колюбанов, макросом можно перебрать все характеристики - получив список уникальных, затем заполнить массив шапкой наименование и уникальные характеристики, после ч его пройтись по строкам и по столбца с 2 столбца с шагом 2 и сравнить характеристику с каждой уникальной и подставить в нужный столбец и все...если правильно понял, е о согласен с NEW, нужно увидеть желаемый результат.
пусть наугад, вывел результат просто ниже и правее:
Код
Sub mrshkei()
Dim arr, arr2, i As Long, lr As Long, lcol As Long, j As Long, n As Long, col As New Collection
lr = Cells(Rows.Count, 1).End(xlUp).Row
lcol = Cells(1, Columns.Count).End(xlToLeft).Column
arr = Range(Cells(1, 1), Cells(lr, lcol))
For i = LBound(arr) + 1 To UBound(arr)
    For n = 2 To UBound(arr, 2) - LBound(arr) + 1 Step 2
        On Error Resume Next
        col.Add arr(i, n), arr(i, n)
    Next n
Next i
ReDim arr2(1 To lr, 1 To col.Count + 1)
For j = 1 To col.Count
    arr2(1, 1) = "Наименование"
    arr2(1, j + 1) = col(j)
Next j
For i = LBound(arr) + 1 To UBound(arr)
arr2(i, 1) = arr(i, 1)
x = UBound(arr, 2) - LBound(arr) + 1
    For n = 2 To x Step 2
        For j = 1 To col.Count
                If col(j) = arr(i, n) Then arr2(i, j + 1) = arr(i, n + 1): Exit For
        Next j
    Next n
Next i
Cells(lr + 3, 3).Resize(UBound(arr2), col.Count + 1) = arr2
End Sub
Изменено: Mershik - 06.10.2021 20:55:27
Не бойтесь совершенства. Вам его не достичь.
 
Добрый вечер.

Направляю файл пример к чему нужно прийти. Заранее спасибо.
 
Цитата
Mershik написал:
arr2(1, 1) = "Íàìåíîâàíèå"
краказябли вышли в одной строке

Никита Колюбанов,Что-то я в исходном файле не нашёл хотя бы вот эти названия
Фильтр Aquaviva D723 S700B
Фильтр Jazzi Pool S-Series Д1200 шпульная навивка 56 м3/ч
Фильтр Jazzi Pool S-Series Д400 шпульная навивка 6 м3/ч

куда "Корпус фильтра" делся?

Вы предлагаете просто так записать вам информацию из головы?
Я к чему. Обычно, люди говорят - ребята, у меня есть вот такая таблица, а из НЕЁ же хотелось бы получить вот такую - мы отрываем оба файла и смотрим глазами какая информация куда перенеслась и думаем, как это можно реализовать. У вас же... оп и новые данные
Изменено: New - 06.10.2021 00:02:14
 
Вот что в итоге получиться должно именно по данным наименованиям. Если будет получаться  колонки без дублей сделать будет вообще отлично.
 
Добрый день.
Вариант предоставил.

Исходил из структуры (Наименование Характеристика значение)
Не претендую на оптимальность.
 
Спасибо. Только я не совсем понял каким именно образом Вы этого достигли. Можно пожалуйста прокомментировать, как Вы это сделали не вручную же....
Можно в личку. Заранее спасибо.
 
Чуть более короткий вариант:
Код
let
  src = Excel.CurrentWorkbook(){[ Name = "Таблица1" ]}[Content],
  typed = Table.TransformColumnTypes (
    src,
    {
      { "Наименование", type text },
      { "Характеристика", type text },
      { "Значение", type text },
      { "Характеристика2", type text },
      { "Значение3", type any },
      { "Характеристика3", type text },
      { "Значение4", Int64.Type },
      { "Характеристика4", type text },
      { "Значение5", type any }
    }
  ),
  unpivot = Table.UnpivotOtherColumns ( typed, { "Наименование" }, "Атрибут", "Характеристика_tmp" )[[Наименование], [Характеристика_tmp]],
  toClmns = Table.ToColumns ( unpivot ) & { List.Skip ( unpivot[Характеристика_tmp] ) },
  trans = List.Transform ( toClmns, ( x ) => List.Alternate ( x, 1, 1, 1 ) ),
  toTbl = Table.FromColumns ( trans, { "Наименование", "Характеристика", "Значение" } ),
  pivot = Table.Pivot ( toTbl, List.Distinct ( toTbl[Характеристика] ), "Характеристика", "Значение" )
in
  pivot
 
Никита Колюбанов, а что Вам не подошло в макросе в #3?
New, ага, спасибо исправил)
Не бойтесь совершенства. Вам его не достичь.
 
Mershik, все супер, Огромное спасибо. Макрос помог.
surkenny, если честно пока еще плаваю в данном коде и не понимаю как применить если мне нужно будет еще добавить сотни характристик и их значений.

Огромное спасибо Всем за труды.
 
Никита Колюбанов, да все равно, сколько характеристик. Если структура сохранится (1-ый столбец наименование, 2/3 - хар1/знач1, 3/4 - хар2/знач2 и тд), то будет работать;)
Код
let
  src = Csv.Document (
    File.Contents ( "C:\Downloads\Исходный пример.csv" ), 
    [ Delimiter = ";", Encoding = 1251, QuoteStyle = QuoteStyle.None ]
  ), 
  promHeads = Table.PromoteHeaders ( src, [ PromoteAllScalars = true ] ), 
  unpivot = Table.UnpivotOtherColumns ( promHeads, { "Наименование" }, "Атрибут", "Характеристика_tmp" )[[Наименование], [Характеристика_tmp]], 
  toClmns = Table.ToColumns ( unpivot ) & { List.Skip ( unpivot[Характеристика_tmp] ) }, 
  trans = List.Transform ( toClmns, ( x ) => List.Alternate ( x, 1, 1, 1 ) ), 
  toTbl = Table.FromColumns ( trans, { "Наименование", "Характеристика", "Значение" } ), 
  pivot = Table.Pivot ( toTbl, List.Distinct ( toTbl[Характеристика] ), "Характеристика", "Значение" )
in
  pivot
Вместо "C:\Downloads\" путь к папке с файлом изначальных данных.
Изменено: surkenny - 06.10.2021 23:03:07
 
Может, такой вариант понятнее. Потестите, какой шустрее на большом наборе данных;)
Код
let
  src = Csv.Document (
    File.Contents ( "C:\Downloads\Исходный пример.csv" ),
    [ Delimiter = ";", Encoding = 1251, QuoteStyle = QuoteStyle.None ]
  ),
  promHeads = Table.PromoteHeaders ( src, [ PromoteAllScalars = true ] ),
  toClmns = Table.ToColumns ( promHeads ),
  charac = List.Combine ( List.Alternate ( toClmns, 1, 1 ) ),
  value = List.Combine ( List.Alternate ( List.Skip ( toClmns ), 1, 1 ) ),
  name = List.Repeat ( List.First ( toClmns ), ( List.Count ( toClmns ) - 1 ) / 2 ),
  toTbl = Table.FromColumns ( { name, charac, value }, { "Наименование", "Характеристика", "Значение" } ),
  pivot = Table.Pivot ( toTbl, List.Distinct ( toTbl[Характеристика] ), "Характеристика", "Значение" )
in
  pivot
Изменено: surkenny - 07.10.2021 06:56:49
Страницы: 1
Наверх