【问题标题】:Optimizing loop / nested loop优化循环/嵌套循环
【发布时间】:2021-01-21 19:45:43
【问题描述】:

我正在循环中工作,自然而然地从一个具有挑战性的开始!我有一个包含多张工作表的工作簿。每个工作表都有完成“小部件”的操作。我正在尝试遍历一系列单元格并按日期搜索以找到匹配的日期。如果该日期匹配,我想在该列的第 7 行添加标准时间。我能够通过强力代码完成这项工作,并为每一列复制并粘贴我的循环。我真的不想对每个选项卡上的所有列都这样做。

我确信有一种方法可以使用我的最后一行和最后一列的计数器来执行嵌套循环,所以一旦我完成了一列中的循环,它就会移动到下一列。我只是不确定如何到达那里。希望对此有所帮助!谢谢!

编辑:基本上我想要做的是从 I12 开始,循环到列底部以查找日期,然后计算我看到的次数以将 PPC 小时数 (I7) 相加。然后,移动到 J12,循环到列底部,移动到 K12,循环到底部,为 Assy 添加小时数。等等……

Sub Resource_Overview()
'Summary of daily tasks by worktype

'Declare the variables we'll need
Dim sht As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
Dim i As Double 'for counters, using double to add up decimals
Dim Assy, Solder, QC, Weld, Test, PPC As Double 'variables to hold std hours total
Dim a As Long

Assy = 0#
Solder = 0#
QC = 0#
Weld = 0#
Test = 0#
PPC = 0#

'Find Last Row and Column
Set sht = ActiveSheet
Set StartCell = Range("I12")
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
LastColumn = sht.Cells(StartCell.Row, sht.Columns.Count).End(xlToLeft).Column - 3 '-3 columns to not count need date or ECD info

Set sht = ActiveSheet
Set StartCell = Range("I12")
  
    For i = 12 To LastRow
        If Range("I" & i).Value = 44154 Then
            If Range("I" & 1) = "Assy" Then
                Assy = Assy + Range("I7").Value
            ElseIf Range("I" & 1) = "Solder" Then
                Solder = Solder + Range("I7").Value
            ElseIf Range("I" & 1) = "Weld" Then
                Weld = Weld + Range("I7").Value
            ElseIf Range("I" & 1) = "Test" Then
                Test = Test + Range("I7").Value
            ElseIf Range("I" & 1) = "PPC" Then
                PPC = PPC + Range("I7").Value
            ElseIf Range("I" & 1) = "QC" Then
                QC = QC + Range("I7").Value
            End If
        End If
    Next i
        
        
    For i = 12 To LastRow
        If Range("J" & i).Value = 44154 Then
            If Range("J" & 1) = "Assy" Then
                Assy = Assy + Range("J7").Value
            ElseIf Range("J" & 1) = "Solder" Then
                Solder = Solder + Range("J7").Value
            ElseIf Range("J" & 1) = "Weld" Then
                Weld = Weld + Range("J7").Value
            ElseIf Range("J" & 1) = "Test" Then
                Test = Test + Range("J7").Value
            ElseIf Range("J" & 1) = "PPC" Then
                PPC = PPC + Range("J7").Value
            ElseIf Range("J" & 1) = "QC" Then
                QC = QC + Range("J7").Value
            End If
        End If
    Next i
    
        For i = 12 To LastRow
        If Range("K" & i).Value = 44154 Then
            If Range("K" & 1) = "Assy" Then
                Assy = Assy + Range("K7").Value
            ElseIf Range("K" & 1) = "Solder" Then
                Solder = Solder + Range("K7").Value
            ElseIf Range("K" & 1) = "Weld" Then
                Weld = Weld + Range("K7").Value
            ElseIf Range("K" & 1) = "Test" Then
                Test = Test + Range("K7").Value
            ElseIf Range("K" & 1) = "PPC" Then
                PPC = PPC + Range("K7").Value
            ElseIf Range("K" & 1) = "QC" Then
                QC = QC + Range("K7").Value
            End If
        End If
    Next i
    
        For i = 12 To LastRow
        If Range("L" & i).Value = 44154 Then
            If Range("L" & 1) = "Assy" Then
                Assy = Assy + Range("L7").Value
            ElseIf Range("L" & 1) = "Solder" Then
                Solder = Solder + Range("L7").Value
            ElseIf Range("L" & 1) = "Weld" Then
                Weld = Weld + Range("L7").Value
            ElseIf Range("L" & 1) = "Test" Then
                Test = Test + Range("L7").Value
            ElseIf Range("L" & 1) = "PPC" Then
                PPC = PPC + Range("L7").Value
            ElseIf Range("L" & 1) = "QC" Then
                QC = QC + Range("L7").Value
            End If
        End If
    Next i

        For i = 12 To LastRow
        If Range("M" & i).Value = 44154 Then
            If Range("M" & 1) = "Assy" Then
                Assy = Assy + Range("L7").Value
            ElseIf Range("M" & 1) = "Solder" Then
                Solder = Solder + Range("M7").Value
            ElseIf Range("M" & 1) = "Weld" Then
                Weld = Weld + Range("M7").Value
            ElseIf Range("M" & 1) = "Test" Then
                Test = Test + Range("M7").Value
            ElseIf Range("M" & 1) = "PPC" Then
                PPC = PPC + Range("M7").Value
            ElseIf Range("M" & 1) = "QC" Then
                QC = QC + Range("M7").Value
            End If
        End If
    Next i
    
    Sheets("Sheet1").Select
    Range("B2") = PPC
    Range("B3") = Assy
    Range("B4") = Solder
    Range("B5") = QC
    
End Sub

【问题讨论】:

    标签: arrays vba loops nested nested-loops


    【解决方案1】:

    所以你可以建立你的范围:

    Range(A1:D1) -> Range(Cells(A1), Cells(D1)) -> 
    
    Range(Cells(row number, column number), Cells(row number, column number)) -> 
    
    Range(Cells(1, 1), Cells(1, 4))
    

    如果范围是“A1”。我们可以写Range(Cells(1, 1), Cells(1, 1)) 或使用单元格引用Cells(1,1)。

    要使用循环构建范围,您可以将一些数字替换为代表循环值的字母,即列/行号。

    没有测试,但我想你会明白逻辑:

    Sub Resource_Overview()
    'Summary of daily tasks by worktype
    
    'Declare the variables we'll need
    Dim sht As Worksheet
    Dim LastRow As Long
    Dim LastColumn As Long
    Dim StartCell As Range
    Dim i As, j As Long 'I always use long
    Dim Assy, Solder, QC, Weld, Test, PPC As Double 'variables to hold std hours total
    Dim a As Long
    
    Assy = 0#
    Solder = 0#
    QC = 0#
    Weld = 0#
    Test = 0#
    PPC = 0#
    
    'Find Last Row and Column
    Set sht = ActiveSheet
    Set StartCell = Range("I12")
    LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
    LastColumn = sht.Cells(StartCell.Row, sht.Columns.Count).End(xlToLeft).Column - 3 '-3 columns to not count need date or ECD info
    
    Set sht = ActiveSheet
    
    For i = 9 To LastColumn 'Set from which column number you want the loop to start from
        For j = 12 To LastRow
            If Cells(j,i).Value = 44154 Then
                If Cells(1,i).Value = "Assy" Then
                    Assy = Assy + Cells(7,i).Value
                ElseIf Cells(1,i).Value = "Solder" Then
                    Solder = Solder + Cells(7,i).Value
                ElseIf Cells(1,i).Value = "Weld" Then
                    Weld = Weld + Cells(7,i).Value
                ElseIf Cells(1,i).Value = "Test" Then
                    Test = Test + Cells(7,i).Value
                ElseIf Cells(1,i).Value = "PPC" Then
                    PPC = PPC + Cells(7,i).Value
                ElseIf Cells(1,i).Value = "QC" Then
                    QC = QC + Cells(7,i).Value
                End If
            End If
        Next j
    Next i
    
        
    Sheets("Sheet1").Range("B2") = PPC
    Sheets("Sheet1").Range("B3") = Assy
    Sheets("Sheet1").Range("B4") = Solder
    Sheets("Sheet1").Range("B5") = QC
    
    End Sub
    

    【讨论】:

    • 这非常有效!花了我几次阅读它,但我现在明白了。非常感谢,这是一个巨大的帮助!
    • 很高兴它起作用了:)。如果您有任何其他问题或想要更多详细信息,请随时询问。是的,我第一次制作循环时,要了解这个概念是一个挑战,但通过培训你会掌握它!如果您认为它解决了您的问题/问题How does accepting an answer work?,请随时接受答案。祝你编码愉快!
    • 一旦我的声望达到 15,我肯定会给答案 +1。我确实有另一个问题涉及在我的代码中添加另一个循环。在我以文本格式 (44154) 调用日期的地方,我想从 Sheet1 中提取它,并让单元格 B1 成为日期,第二天为 B2,第二天为 B3,等等,直到我整整一周(7天)。我尝试添加另一个循环,但它一直跳过我们刚刚解决的主循环,哈哈。我认为它搞砸了,因为我试图引用不同的工作表,也许?
    • 谢谢!我会建议你一个新问题(也许一些模拟数据作为日期会变得更加棘手......),但是你是对的关于工作表参考。您没有引用工作表,这会导致工作表之间出现“问题”/不稳定的代码,因为代码也不知道您也引用了哪个工作表(即Cells(j,i).Value -> ws.Cells(j,i).Value)。我最初的想法是做第三个循环,循环日期列/范围(即在For j 之后,做For k),然后检查Cells(j,i).Value = 44154 -> Cells(j,i).Value = Cells(k,"B").Value。根据您的设置,其他解决方案可能更有效:)
    • 谢谢!如果我遇到困难,我会尝试解决这个问题并发布另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 2012-01-27
    • 2015-05-29
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多