2014 年 2 月 28 日重访

2014 年 2 月 28 日重访

我在 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

另外一个选择:

  1. 选择 B 列,按CTRL+G-> Special-> Blanks->OK
  2. 输入=press ,然后CTRL+ENTER
  3. 选择 C ​​列,按CTRL+G-> Special-> Blanks->OK
  4. 类型=IF(类型=类型,类型,0)然后CTRL+ENTER
  5. 选择所有数据CopyPaste Special as Values
  6. 删除重复项。

编辑:

解释:我正在尝试利用转到空白选项。选择空白后,您可以为所有选定的空白单元格输入相同的公式。关于 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 列的值(以删除公式)特殊粘贴到其他地方,并按客户对其进行排序以删除所有多余的行。

相关内容