![2014 年 2 月 28 日重访](https://linux22.com/image/1306423/2014%20%E5%B9%B4%202%20%E6%9C%88%2028%20%E6%97%A5%E9%87%8D%E8%AE%BF.png)
我在 Excel 中有一个数据转储,其中包含两个不同值的年度客户数据。数据为每一年和每个客户的值提供了一个单独的行。即它看起来像这样:
我只能在 2009 年为客户 1 设定值 A 的行,以及单独行对于值 B相同的客户在相同的年。
在某些情况下,没有值 A 或值 B。在上面的例子中,您可以看到客户 1 在 2011 年没有值 B,因此没有为此生成行。并且,虽然示例中没有显示,但有些客户在一年中没有这两个值的数据(因此该客户在那一年没有行)。在这种情况下,该客户在那一年没有行是可以接受的。
我想把它放到一个工作表中,其中有一行为了两个都每年和每个客户的价值。即,我希望数据如下所示:
创造该结果的最有效方法是什么?
答案1
这是 VBA,或者您可以在工作表上运行的宏。您必须按alt+F11调出 Visual Basic for Application 提示,转到您的工作簿并将right click - insert - module
此代码粘贴到其中。然后,您可以通过按 来从 VBA 中运行该模块F5。此宏名为“test”
Sub test()
'define variables
Dim RowNum as long, LastRow As long
'turn off screen updating
Application.ScreenUpdating = False
'start below titles and make full selection of data
RowNum = 2
LastRow = Cells.SpecialCells(xlCellTypeLastCell).Row
Range("A2", Cells(LastRow, 4)).Select
'For loop for all rows in selection with cells
For Each Row In Selection
With Cells
'if customer name matches
If Cells(RowNum, 1) = Cells(RowNum + 1, 1) Then
'and if customer year matches
If Cells(RowNum, 4) = Cells(RowNum + 1, 4) Then
'move attribute 2 up next to attribute 1 and delete empty line
Cells(RowNum + 1, 3).Copy Destination:=Cells(RowNum, 3)
Rows(RowNum + 1).EntireRow.Delete
End If
End If
End With
'increase rownum for next test
RowNum = RowNum + 1
Next Row
'turn on screen updating
Application.ScreenUpdating = True
End Sub
这将通过排序电子表格并结合连续行匹配客户和年份的行,并删除现在为空的行。电子表格必须按照您呈现的方式排序,即按客户和年份升序排列,这个特定的宏不会查看连续行以外的内容。
编辑 - 完全有可能我的with statement
完全不需要,但它不会伤害任何人。
2014 年 2 月 28 日重访
有人在另一个帖子中使用了这个答案问题当我回去时,我觉得这个 VBA 很差。我重做了它 -
Sub CombineRowsRevisited()
Dim c As Range
Dim i As Integer
For Each c In Range("A2", Cells(Cells.SpecialCells(xlCellTypeLastCell).Row, 1))
If c = c.Offset(1) And c.Offset(,4) = c.Offset(1,4) Then
c.Offset(,3) = c.Offset(1,3)
c.Offset(1).EntireRow.Delete
End If
Next
End Sub
2016 年 5 月 4 日重访
再次询问如何将多行的值合并为一行?有一个模块,但需要变量解释而且它还是相当差的。
Sub CombineRowsRevisitedAgain()
Dim myCell As Range
Dim lastRow As Long
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
For Each myCell In Range(Cells("A2"), Cells(lastRow, 1))
If (myCell = myCell.Offset(1)) And (myCell.Offset(0, 4) = myCell.Offset(1, 4)) Then
myCell.Offset(0, 3) = myCell.Offset(1, 3)
myCell.Offset(1).EntireRow.Delete
End If
Next
End Sub
但是,根据问题的不同,最好step -1
使用行号,这样就不会跳过任何内容。
Sub CombineRowsRevisitedStep()
Dim currentRow As Long
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For currentRow = lastRow To 2 Step -1
If Cells(currentRow, 1) = Cells(currentRow - 1, 1) And _
Cells(currentRow, 4) = Cells(currentRow - 1, 4) Then
Cells(currentRow - 1, 3) = Cells(currentRow, 3)
Rows(currentRow).EntireRow.Delete
End If
Next
End Sub
答案2
另外一个选择:
- 选择 B 列,按CTRL+G->
Special
->Blanks
->OK
- 输入
=
press ↑,然后CTRL+ENTER - 选择 C 列,按CTRL+G->
Special
->Blanks
->OK
- 类型
=IF(
按←类型=
按←按↓类型,
按↓类型,0)
然后CTRL+ENTER - 选择所有数据
Copy
和Paste Special as Values
- 删除重复项。
编辑:
解释:我正在尝试利用转到空白选项。选择空白后,您可以为所有选定的空白单元格输入相同的公式。关于 OP 的问题,数据看起来像持续的空白,即:Value A
空白列CustomerID
与上方非空白行具有相同的内容。同样,Value B
空白列CustomerID
与下方非空白行具有相同的内容。
答案3
最有效的方法是将所有数据转储到数据透视表中,并将“客户”放入行标签中,然后跟进其他列。如果您想按年份查看细分情况,可以将“年份”放入列标题中
可以在 Excel 2010 中的“插入”下找到数据透视表
答案4
每个人都为此使用了大量 VBA 代码或复杂的函数。我有一种方法,虽然只需一秒钟就能实现,但更容易理解,而且很容易根据各种其他可能性进行调整。
在上面给出的示例中,将这 (4) 个函数分别粘贴到单元格 E2、F2、G2 和 H2 中(F&G 函数参考上面的单元格):
=IF(D2=D3, A2, IF(D2<>D1, A2, ""))
=IF(D2=D3, MAX(B2:B3), IF(D2<>D1, B2, ""))
=IF(D2=D3, MAX(B2:B3), IF(D2<>D1, IF(C2=0,"",C2),""))
=IF(D2=D3, D2, IF(D2<>D1, D2, ""))
将这些公式拖到尽可能远的位置。每当有 2 行时,它都会生成一行数据,使单行不受影响。将 EFGH 列的值(以删除公式)特殊粘贴到其他地方,并按客户对其进行排序以删除所有多余的行。