答案1
您的示例中最大的复杂性来自于单元格不相邻且您有两个维度的情况,否则解决这个问题会非常容易。但是,我认为一个非常简单的 VBA 解决方案应该可以工作。此代码做出以下假设:工作表名为“Sheet1”,总计分别收集在 A 列和 B 列中,您的数据从 D 列开始,并且必须始终相应地增加 3 列。
在代码的第一部分,确定了最后一列的值,因此无论您有 5 个还是 50 个案例,您都不必担心调整任何内容。它还初始化了存储输出所需的总行数。以这种方式进行是有利的,因为也可以涵盖以下情况,例如,Fails 的最后两个值为空但 Dates 存在,反之亦然。在下一步中,代码以 3 为步长循环遍历每一列,从 i = 4(D 列)开始到最后一列 - 1(因为参考点是 Date 列),计算行数作为 Dates 和 Fails 的最大值,收集相应的信息并将其分别复制到 A 列(1)和 B 列(2),最后更新总行数,这是将每组新案例复制到已经存在的案例下方所必需的。
当然,这种方法对于行号在不同案例中变化的情况同样有效。如果您希望将结果存储在不同的工作表中,则可以轻松扩展此方法以在插入信息之前始终移动工作表,但由于您已指出数据从 D 列开始,我认为可以假设总数分别位于 A 列和 B 列中。
Sub Stack_Columns()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim i, lastColumn, lastRow, totalRow As Integer
Set ws = ThisWorkbook.Worksheets("Sheet1")
lastColumn = ws.Cells(1, Columns.Count).End(xlToLeft).Column
totalRow = 1
For i = 4 To lastColumn - 1 Step 3
lastRow = Application.Max(ws.Cells(Rows.Count, i).End(xlUp).Row, ws.Cells(Rows.Count, i + 1).End(xlUp).Row)
ws.Range(ws.Cells(2, i), ws.Cells(lastRow, i)).Copy Destination:=ws.Cells(totalRow + 1, "A")
ws.Range(ws.Cells(2, i + 1), ws.Cells(lastRow, i + 1)).Copy Destination:=ws.Cells(totalRow + 1, "B")
totalRow = totalRow + lastRow - 1
Next
Application.ScreenUpdating = True
End Sub