将单行(名称,开始日期,结束日期)转换为多行

时间:2019-10-08 07:26:24

标签: excel vba

我有3列(名称,开始日期,结束日期)的多行数据,我希望每天将其转换为一行。

我尝试通过记录来记录宏(插入n行),但是我无法使其循环。

what i have

what i would like

2 个答案:

答案 0 :(得分:0)

如果您使用两个工作表,并使用Sheet1作为Source和Sheet2作为目标,则以下将通过使用嵌套的For Loop来实现您期望的效果:

Sub Process_Dates()
Dim wsSource As Worksheet: Set wsSource = ThisWorkbook.Worksheets("Sheet1")
Dim wsDestination As Worksheet: Set wsDestination = ThisWorkbook.Worksheets("Sheet2")
'declare and set the worksheets you are working with, amend as required

LastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row
'get the last row with data on Column A, from Source worksheet

For i = 2 To LastRow
    strName = wsSource.Cells(i, "A").Value
    StartD = wsSource.Cells(i, "B").Value
    EndD = wsSource.Cells(i, "C").Value
    xDays = DateDiff("d", StartD, EndD)
    'get the number of days between Start Date and End Date
    For x = 0 To xDays
    'loop through the number of days between Start and End
        NextRow = wsDestination.Cells(wsDestination.Rows.Count, "A").End(xlUp).Offset(1, 0).Row
        'get the next available row on Destination worksheet
        wsDestination.Cells(NextRow, 1).Value = strName
        wsDestination.Cells(NextRow, 2).Value = DateAdd("d", x, StartD)
    Next x
Next i
End Sub

更新:

如果不希望将数据移动到另一个工作表中,而是将行插入同一工作表中,那么以下操作将达到您想要的结果:

Sub Process_Dates()
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
'declare and set the worksheet you are working with, amend as required

LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
'get the last row with data on Column A
i = 2
'set variable to iterate through rows starting with Row 2
While i <= LastRow
    strName = ws.Cells(i, "A").Value
    StartD = ws.Cells(i, "B").Value
    EndD = ws.Cells(i, "C").Value
    xDays = DateDiff("d", StartD, EndD)
    'get the number of days between Start Date and End Date
    For x = 1 To xDays
    'loop through the number of days between Start and End
        ws.Rows(i + x).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
        'get the next available row on Destination worksheet
        ws.Cells(i + x, 1).Value = strName
        ws.Cells(i + x, 2).Value = DateAdd("d", x, StartD)
        LastRow = LastRow + 1
        'increment LastRow as new row has been inserted
    Next x
    i = (i + xDays) + 1
    'increment the i variable to go to the next row to split
Wend
End Sub

答案 1 :(得分:0)

您可以使用Excel 2010+中的Power QueryGet & Transform轻松完成此操作 可以使用GUI来完成所有操作(输入自定义列的公式除外)

  • 从表/范围
  • 将日期列的数据类型设置为whole number
  • 添加一个自定义列,该列由从StartEnd的一系列数字组成,作为列表
    • ={[Start]..[End]}
  • 提取成行
  • 删除开始和结束列
  • 将数据类型设置为日期

M代码

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Name", type text}, {"Start", Int64.Type}, {"End", Int64.Type}}),
    #"Added Custom" = Table.AddColumn(#"Changed Type", "Dates", each {[Start]..[End]}),
    #"Expanded Dates" = Table.ExpandListColumn(#"Added Custom", "Dates"),
    #"Removed Columns" = Table.RemoveColumns(#"Expanded Dates",{"Start", "End"}),
    #"Changed Type1" = Table.TransformColumnTypes(#"Removed Columns",{{"Dates", type date}})
in
    #"Changed Type1"

enter image description here