将一列移到另一列的末尾

时间:2018-11-18 20:21:19

标签: excel vba powerquery

我有一堆excel文件,它们的格式很奇怪,我想为其创建一个自动导入脚本,因此我可以轻松地以正确的格式将这些数据放入工作表中。

在前12列中每个月都有小时值,在接下来的12列中有日期和小时。

我想做的是能够将这些数据保存到一个表中,其中第一列具有日期和小时(以excel格式),第二列包含该数据。我的想法是在通过功率查询调整数据的过程中记录一个宏,然后在多个文件中重复该宏。但是,我似乎找不到一种很好的方法来使“第2列”的数据移动到“第1列”的末尾,并使用Power Query对值和日期重复该操作。有指针吗?

还请注意,第1列的长度与第2列的长度不同,因为1月份的值比2月份多。但是,列1s的长度与列13相同,列2s的长度与14相同,依此类推。

我已经上传了一个示例文件here

2 个答案:

答案 0 :(得分:1)

您可以通过在VBA中编写自己的宏来快速进行格式化。然后,您可以创建另一个宏,以对文件夹中的多个文件运行格式化宏。

Run same excel macro on multiple excel files

以下是一个宏示例,该宏将重新格式化您的数据,使其更接近您要查找的内容。

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

答案 1 :(得分:1)

从头开始创建空白查询(在我的计算机上,我通过Data > Get Data > From Other Sources > Blank Query在Excel中执行此操作)。

单击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步骤并修改过滤条件,以使该表仅包含要重组的文件。