Перемещение одного столбца в конец другого - PullRequest
0 голосов
/ 18 ноября 2018

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

Он имеет почасовые значения для каждого месяца в первых 12 столбцах, затем дату вместе с часами в следующих 12 столбцах.

То, что я хотел бы сделать, это иметь возможность получить эти данные в таблицу, в которой первый столбец содержит дату и час (в формате Excel), а второй содержит данные. Я думал записать макрос во время процесса корректировки данных с помощью мощного запроса, а затем повторил макрос с несколькими файлами. Однако я не могу найти хороший способ переместить данные «Столбца 2» в конец «Столбца 1» и повторить это для значений и дат, используя Power Query. Есть указатели?

Также обратите внимание, что длина столбца 1 отличается от столбца 2, поскольку в январе больше значений, чем в феврале. Однако длина столбца 1 равна длине столбца 13, длина столбца 2 равна 14 и т. Д.

Я загрузил образец файла здесь

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Создайте пустой запрос с нуля (на моем компьютере я делаю это в Excel с помощью: Data > Get Data > From Other Sources > Blank Query).

Нажмите Home > Advanced Editor, скопируйте и вставьте приведенный ниже код и измените эту строку folderPath = "C:\Users\user\", напуть к родительской папке, содержащей файлы Excel.Затем нажмите Close & Load.

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

let
    folderPath = "C:\Users\user\",
    getDataFromSheet = (sheetData as table) =>
        let 
            promoteHeaders = Table.PromoteHeaders(sheetData, [PromoteAllScalars=true]),
            standardiseHeaders =
                let
                    headers = Table.ColumnNames(promoteHeaders),
                    zipWithLowercase = List.Zip({headers, List.Transform(headers, Text.Lower)}),
                    renameAsLowercase = Table.RenameColumns(promoteHeaders, zipWithLowercase)
                in
                    renameAsLowercase,
            emptyTable = Table.FromColumns({{},{}}, {"Date", "Value"}),
            monthsToLoopOver = {"januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"},    
            appendEachMonth = List.Accumulate(monthsToLoopOver, emptyTable, (tableState, currentMonth) =>
                let
                    selectColumns = Table.SelectColumns(standardiseHeaders, {currentMonth & "tim", currentMonth}, MissingField.UseNull),
                    renameColumns = Table.RenameColumns(selectColumns, {{currentMonth & "tim", "Date"}, {currentMonth, "Value"}}),
                    appendToTable = Table.Combine({tableState, renameColumns})
                in
                    appendToTable
                ),
            tableOrNull = if List.Contains(Table.ColumnNames(standardiseHeaders), "januari") then appendEachMonth else null
        in
            tableOrNull,
    getDataFromWorkbook = (filePath as text) =>
        let
            workbookContents = Excel.Workbook(File.Contents(filePath)),
            sheetsOnly = Table.SelectRows(workbookContents, each [Kind] = "Sheet"),
            invokeFunction = Table.AddColumn(sheetsOnly, "f", each getDataFromSheet([Data]), type table),
            appendAndExpand =
                let
                    selectColumnsAndRows = Table.SelectColumns(Table.SelectRows(invokeFunction, each not ([f] is null)), {"Name", "f"}),
                    renameColumns = Table.RenameColumns(selectColumnsAndRows, {{"Name", "Sheet"}}),
                    expandColumn = Table.ExpandTableColumn(renameColumns, "f", {"Date", "Value"})
                in
                    expandColumn
        in
            appendAndExpand,
    filesInFolder = Folder.Files(folderPath),
    validFilesOnly = Table.SelectRows(filesInFolder, each [Extension] = ".xlsx"),
    invokeFunction = Table.AddColumn(validFilesOnly, "f", each getDataFromWorkbook([Folder Path] & [Name])),
    appendAndExpand = 
        let
            selectRowsAndColumns = Table.SelectColumns(Table.SelectRows(invokeFunction, each not ([f] is null)), {"Name", "f"}),
            renameColumns = Table.RenameColumns(selectRowsAndColumns, {{"Name", "Workbook"}}),
            expandColumn = Table.ExpandTableColumn(renameColumns, "f", {"Sheet", "Date", "Value"})
        in
            expandColumn,
    excludeBlankDates = Table.SelectRows(appendAndExpand, each not (Text.StartsWith([Date], " "))),
    transformTypes =
        let
            dateAndHour = Table.TransformColumns(excludeBlankDates, {{"Date", each Text.Split(_, " ")}}),
            changeTypes = Table.TransformColumns(dateAndHour, {{"Workbook", Text.From, type text}, {"Sheet", Text.From, type text}, {"Date", each DateTime.From(_{0}) + #duration(0, Number.From(_{1}), 0, 0), type datetime}, {"Value", Number.From, type number}})
        in
            changeTypes
in
    transformTypes
  • Для надежности и надежности было бы хорошо, если вы создадите папку и поместите всеФайлы Excel (которые нуждаются в реструктуризации) в эту папку - и убедитесь, что больше ничего не попадает в эту папку (даже файл, который будет выполнять импорт / реструктуризацию).

  • Если вы можетене делайте этого по какой-либо причине, затем щелкните по шагу validFilesOnly в редакторе запросов и измените критерии фильтрации, чтобы таблица включала только файлы, которые вы хотите реструктурировать.

0 голосов
/ 19 ноября 2018

Вы можете довольно быстро выполнить форматирование, написав свой собственный макрос в VBA.Затем вы можете создать другой макрос для запуска макроса форматирования для нескольких файлов в папке.

Запуск одного и того же макроса Excel для нескольких файлов Excel

Вот примермакрос, который переформатирует ваши данные ближе к тому, что вы ищете.

Sub FormatBlad()
    ' create a new sheet and rename it
    Sheets.Add After:=ActiveSheet
    Sheets(Sheets.Count).Name = "Formatted"

    ' set helper variables
    Dim blad As Worksheet
    Dim format As Worksheet
    Set blad = Sheets("Blad1")
    Set ft = Sheets("Formatted")

    Dim blad_row_num As Integer
    Dim ft_row_num As Integer
    Dim month_offset As Integer
    blad_row_num = 2
    ft_row_num = 2
    month_offset = 13 ' column N - 1

    ' set column headers in formatted sheet
    ft.Range("A1").Value = "Date"
    ft.Range("B1").Value = "Value"

    ' loop through months
    For i = 1 To 12
        blad_row_num = 2
        While blad.Cells(blad_row_num, i).Value <> ""
            ft.Cells(ft_row_num, 1).Value = blad.Cells(blad_row_num, month_offset + i).Value
            ft.Cells(ft_row_num, 2).Value = blad.Cells(blad_row_num, i).Value
            blad_row_num = blad_row_num + 1
            ft_row_num = ft_row_num + 1
        Wend
    Next i
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...