VBA:循环遍历行,如果满足条件,则汇总某些行

时间:2013-10-30 20:17:49

标签: excel vba excel-vba

在学习VBA的过程中,我一直在使用论坛几周。但现在我被困住了,需要帮助。所以这是我的问题:

我有一个包含多个工作表的工作簿。为简单起见,我们假设我有两个工作表。一个包含大量原始数据材料,一个格式很好,将成为接收表。

原始数据表如下所示:我有8列,我需要检查每一行中的两个条件(列B和E)并总结列H中的值。 B列包含不同的名称,E列包含工作状态,例如:准备好或说话。我确实有大约3.000行和一组约20个不同的名称,具有不同的状态。总而言之,让我们说100行,名称为#34; Smith"和地位#34;说话"没有特别的顺序。我现在需要总结名称" Smith"的每一行中的所有数字(H列)。和地位#34;说话"之后,我希望将名称(列B),状态(列E)和总和(列H)写入动态范围内同一工作簿的单元格中,从I3开始。 :K3。我必须承认,我完全处于黑暗中。 我真的希望你们可以帮我一些代码和/或指引我走向正确的方向。最重要的是,我希望你也可以解释你的代码所做的事情,这样我就能理解它并学习。先谢谢你们!

到目前为止,这是我的代码:

Private Sub SumNumbers()

Dim tbl As Worksheet
Dim x As Integer
Dim lrow As Long
Dim lastname As String
Dim astatus As String
Dim number As Integer
Dim counter As Integer

Set wb = ThisWorkbook
Set tbl = wb.Sheets("Sheet1")
lrow = tbl.Cells(Rows.Count, "B").End(xlUp).Row
lastname = tbl.Cells("C2:C" & lrow).Text
astatus = tbl.Cells("E2:E" & lrow).Text
number = tbl.Cells("H2:H" & lrow)

For x = 2 To lrow

    If lastname = "Smith" And astatus = "Talking" Then
        counter = counter + number
    End If

Next x

End Sub

4 个答案:

答案 0 :(得分:2)

你很接近,但你需要在循环中单独测试每个单元格。像这样:

Sub Macro1()
    Dim tbl As Worksheet
    Dim x As Integer
    Dim lrow As Long
    Dim lastname As String
    Dim astatus As String
    Dim number As Integer
    Dim counter As Integer: counter = 3

    Set wb = ThisWorkbook
    Set tbl = wb.Sheets("Sheet1")
    lrow = tbl.Cells(Rows.Count, "B").End(xlUp).Row

    For x = 2 To lrow
        If tbl.Range("C" & x) = "Smith" And tbl.Range("E" & x) = "Talking" Then
            Range("I" & counter).Value = Range("C" & x)
            Range("J" & counter).Value = Range("E" & x)
            Range("K" & counter).Value = Range("H" & x)
            counter = counter + 1
        End If
    Next x
End Sub

根据@Tim评论,您可以使用SumIfs返回符合以下多个条件的“H”列总数:

=SUMIFS(H:H,C:C,"=Smith",E:E,"=Talking")

答案 1 :(得分:0)

到目前为止,我找到了一种能够为我完成工作的方法,但这似乎很混乱,因为我必须手动完成每个案例。所以现在我正在寻找一种更简单,更优雅的方法来做到这一点。如果你能给我一些代码或指出我正确的方向,我将非常感激。

到目前为止,这是我的代码:

For Each cell In Range("H2:H" & lrow)
   cell.Offset(0, 1).Value = cell.Value + cell.Offset(-1, 1).Value
      If cell.Offset(0, -6).Value = "Smith" And cell.Offset(0, -3).Value = "Talking" Then
      cell.Offset(0, 2).Value = cell.Value
      End If

      If cell.Offset(0, -6).Value = "Smith" And cell.Offset(0, -3).Value = "Ready" Then
         cell.Offset(0, 3).Value = cell.Value
      End If

      If cell.Offset(0, -6).Value = "Smith" And cell.Offset(0, -3).Value = "Not Ready" Then
      cell.Offset(0, 4).Value = cell.Value
      End If
Next

如前所述,这是一种我希望简化的解决方法。它查找条件“Smith”和状态“Talking”,“Ready”和“Not Ready”,并将H Column的值放入列的各个单元格中,以便在后面的过程中求和。那么,有没有办法让它更优雅?

答案 2 :(得分:0)

确实是波特兰亚军!我的逻辑很简单。我已经为每个具有特定状态的名称记录了活动列表。例如“Smith”(B列)和“Talking”(C列)和数字(H列)。我需要在条件名称和状态相等的每一行中总结H列中的数字。假设我有10k行。其中2k的名称为“Smith”。但其中只有500人拥有“史密斯”的名字和“会说话”的状态。所以我需要找出一种更简单的方法来总结这些数字。还有一些行名称为“Smith”,但状态为“Ready”。这里的困难是,这些线基本上是随机顺序。

所以表格看起来像这样:

Row    Name     Status      Number     
2      Smith    Talking     105
3      Smith    Talking     67
4      Smith    Ready       75
5      Smith    Talking     94
6      Jones    Ready       89
7      Jones    Talking     224
8      Jones    Not Ready   75
9      Jones    Talking     99

因此,在这种情况下,第1行将被阻止标题,数据将从第2行开始。对于“Smith”和“Talking”,代码需要将行2,3和5的数量相加条件“史密斯”和“说话”。第4行为“史密斯”和“准备好”。第7行和第9行为“琼斯”和“说话”等。

我能做的是创建一个新工作表,并将A列中所有名称的列表和所有状态列表放入B列并引用它。这样可以省去在代码中使用确切名称和状态的麻烦,但不能解决我的问题。

答案 3 :(得分:0)

一个。获取所有唯一名称并放置在新列中:这将是用于搜索每一行的数组。

B中。为状态设置另一个数组,因为您知道状态是什么。

℃。为Name Array设置外循环
对于数组中的每个项目

d。嵌套循环查看每一行并搜索每个状态

℃。当状态匹配时,另一个嵌套循环将在一个名为“总时间”的新列中添加时间和位置。