【问题标题】:Faster way to loop through cells with If, ElseIf使用 If、ElseIf 循环遍历单元格的更快方法
【发布时间】:2013-11-18 00:35:07
【问题描述】:

我有五列的值可能是“True”、“False”、“Bill-to Not in POVA”或“Logic Code Incorrect”,需要解释这五列并返回一个不同的值基于层次结构的列。

到目前为止,我只为一次单元格开发了 If/Elseif 语句。我知道我可以遍历单元格,但是这段代码现在运行了大约 5,000 行,并且随着月份的进展可能会增加到 15,000 行。

有没有人对有效的方法提出建议?请注意,“规则”指的是我在前面的代码部分中命名的命名范围。

Sub Finalize_Formulas()

    Dim Rules As Range
    Set Rules = Range("Rules")

    Dim NumRecords As Long
    NumRecords = Workbooks("POVA Daily Reporter.xlsm").Worksheets("Paste Daily Data").Range("B" & Rows.Count).End(xlUp).Row


'First, copy and paste special (values only) so that we aren't working with formulas anymore
Cells.Copy
Cells.PasteSpecial xlPasteValues

'Now let's interpret the results in Column F based on Columns G-K (Rules 1-5)
Rules.Select
Rules(1, 1).Select
Rules(1, 1).Activate


If Rules(1, 1).OffSet(0, 1) = "True" And _
    Rules(1, 1).OffSet(0, 2) = "True" And _
    Rules(1, 1).OffSet(0, 3) = "True" And _
    Rules(1, 1).OffSet(0, 4) = "True" And _
    Rules(1, 1).OffSet(0, 5) = "True" Then
    Rules(1, 1).Value = "True"
ElseIf Rules(1, 1).OffSet(0, 1) = "Bill-to Not in POVA" Or _
    Rules(1, 1).OffSet(0, 2) = "Bill-to Not in POVA" Or _
    Rules(1, 1).OffSet(0, 3) = "Bill-to Not in POVA" Or _
    Rules(1, 1).OffSet(0, 4) = "Bill-to Not in POVA" Or _
    Rules(1, 1).OffSet(0, 5) = "Bill-to Not in POVA" Then
    Rules(1, 1).Value = "Bill-to Not in POVA"
ElseIf Rules(1, 1).OffSet(0, 1) = "Logic Code Incorrect" Or _
    Rules(1, 1).OffSet(0, 2) = "Logic Code Incorrect" Or _
    Rules(1, 1).OffSet(0, 3) = "Logic Code Incorrect" Or _
    Rules(1, 1).OffSet(0, 4) = "Logic Code Incorrect" Or _
    Rules(1, 1).OffSet(0, 5) = "Logic Code Incorrect" Then
    Rules(1, 1).Value = "Logic Code Incorrect"
ElseIf Rules(1, 1).OffSet(0, 1) = "False" Or _
    Rules(1, 1).OffSet(0, 2) = "False" Or _
    Rules(1, 1).OffSet(0, 3) = "False" Or _
    Rules(1, 1).OffSet(0, 4) = "False" Or _
    Rules(1, 1).OffSet(0, 5) = "False" Then
    Rules(1, 1).Value = "False"
Else

End If

End Sub

我主要关心的是如何让代码对“规则”范围内的每一行执行此检查。以上似乎工作正常,但是有没有一种有效的方法来循环遍历范围内的行(大约 5,000 行)或以某种方式一次评估所有内容?

我确实找到了这个解决方案,这并不完全是我所需要的,但强调了一种可能更快的遍历行的方法: https://stackoverflow.com/a/8178637/2883304

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    以 KazJaw 的回答为基础

    您不需要IF/ELSE 或循环来实现您想要的。你可以使用AUTOFILL方法来实现你想要的。

    逻辑

    如果说值在单元格G2:K2 中,那么您实际尝试的是这个公式

    =IF(COUNTIF(G2:K2,TRUE)=5,TRUE,IF(COUNTIF(G2:K2,FALSE)=5,FALSE,IF(COUNTIF(G2:K2,"Bill-to Not in POVA")=5,"Bill-to Not in POVA",IF(COUNTIF(G2:K2,"Logic Code Incorrect")=5,"Logic Code Incorrect",""))))

    只需在 VBA 中使用它。

    这是一个例子。

    假设您有来自G2:K1000 的数据,那么只需使用此代码

    Sub Sample()
    
        With ThisWorkbook.Sheets("Sheet1")
            .Range("F2:F1000").Formula = "=IF(COUNTIF(G2:K2,TRUE)=5,TRUE,IF(COUNTIF(G2:K2,FALSE)=5" & _
                                         ",FALSE,IF(COUNTIF(G2:K2,""Bill-to Not in POVA"")=5,""Bill" & _
                                         "-to Not in POVA"",IF(COUNTIF(G2:K2,""Logic Code Incorrect"")" & _
                                         "=5,""Logic Code Incorrect"",""""))))"
    
            .Range("F2:F1000").Value = .Range("F2:F1000").Value
        End With
    End Sub
    

    【讨论】:

      【解决方案2】:

      你可以试试这样的东西,而不是你的If statement

      If Application.CountIf(Range(Rules(1, 1).Offset(0,1), Rules(1, 1).Offset(0,5)), "True*") = 5 Then
          Rules(1, 1).Value = "True"
      ElseIf Application.CountIf(Range(Rules(1, 1).Offset(0,1), Rules(1, 1).Offset(0,5)), "Bill-to Not in POVA") >0 Then
          Rules(1, 1).Value = "Bill-to Not in POVA"
      ElseIf Application.CountIf(Range(Rules(1, 1).Offset(0,1), Rules(1, 1).Offset(0,5)), "Logic Code Incorrect") >0 Then
          Rules(1, 1).Value = "Logic Code Incorrect"
      ElseIf Application.CountIf(Range(Rules(1, 1).Offset(0,1), Rules(1, 1).Offset(0,5)), "False*") >0 Then
          Rules(1, 1).Value = "False"
      Else
      End If
      

      但是,请查看TrueFalse 的情况-由于我的测试,在检查CountIf condition 时需要添加星号。

      【讨论】:

      • 不,你不需要 asterix :) 试试这个?Application.CountIf(Range("G2:K2"), TRUE)
      • +1 在Application.CountIf
      猜你喜欢
      • 2021-11-18
      • 1970-01-01
      • 2019-06-05
      • 1970-01-01
      • 1970-01-01
      • 2013-12-12
      • 2021-11-07
      • 1970-01-01
      • 2019-10-15
      相关资源
      最近更新 更多