【问题标题】:How To Loop Nested If-Then Statements in VBA如何在 VBA 中循环嵌套的 If-Then 语句
【发布时间】:2018-06-28 19:04:22
【问题描述】:

我将尝试简化我的目标并添加我所有的 vba,因为我的 OP 不清楚。

我正在编写一个宏,用于根据特定策略(Tier1、Tier2、BPO 或 Enterprise)、毛利率范围和合同年度确定佣金百分比。这将需要在最终产品中循环遍历大约 5,000 行数据。我一直在尝试嵌套多个 If-Then 语句来实现我的目标,但是它不起作用。

下表列出了适用于每个策略的佣金率,以及我为这个嵌套的 If-Then 语句编写的代码。

希望尝试使这更简单,并通过数据循环遍历整个行。目标是让 J 列中的每个单元格返回由 i 列中的策略确定的佣金率,D 列中的年份和 Z 列中的 GM。该策略有可能改变页面下的每一行。 创建自定义函数会更好吗?

第一次写宏的任务有点疯狂。感谢我已经获得的所有反馈,并期待任何其他想法的出现。

enter image description here

enter image description here

enter image description here

我的代码:

第 I 列 = 策略

其中 D 列 = 年

其中 Z 列 = 毛利率

其中 J 列 = If-Then 的结果

其中 C 列是定义的数据集,用于确定工作簿中的行数。

Sub Define_Comm_Rate 将 LastRow 变暗 LastRow = Range("C" & Rows.Count).End(xlUp).Row

If Sheet1.Range("I2") = "BPO" And Sheet1.Range("Z2") >= 0.24 Then
    If Sheet1.Range("D2") = 1 Then
        Sheet1.Range("J2") = 0.4
    Else
        If Sheet1.Range("D2") = 2 Then
            Sheet1.Range("J2") = 0.3
        Else: Sheet1.Range("J2") = 0.15
        End If
    End If
End If

If Sheet1.Range("I2") = "BPO" And Sheet1.Range("Z2") >= 0.21 And Sheet1.Range("Z2") < 0.24 Then
    If Sheet1.Range("D2") = 1 Then
        Sheet1.Range("J2") = 0.35
    Else
        If Sheet1.Range("D2") = 2 Then
            Sheet1.Range("J2") = 0.25
        Else: Sheet1.Range("J2") = 0.1
        End If
    End If
End If

If Sheet1.Range("I2") = "BPO" And Sheet1.Range("Z2") >= 0.18 And Sheet1.Range("Z2") < 0.21 Then
    If Sheet1.Range("D2") = 1 Then
        Sheet1.Range("J2") = 0.3
    Else
        If Sheet1.Range("D2") = 2 Then
            Sheet1.Range("J2") = 0.2
        Else: Sheet1.Range("J2") = 0.05
        End If
    End If
End If

If Sheet1.Range("I2") = "BPO" And Sheet1.Range("Z2") < 0.18 Then
    If Sheet1.Range("D2") = 1 Then
        Sheet1.Range("J2") = 0.25
    Else
        If Sheet1.Range("D2") = 2 Then
            Sheet1.Range("J2") = 0.15
        Else: Sheet1.Range("J2") = 0.05
        End If
    End If
End If

If Sheet1.Range("I2") = "Enterprise24" Then
    If Sheet1.Range("D2") = "1" Then
        Sheet1.Range("J2") = 0.4
    Else
        If Sheet1.Range("D2") = 2 Then
            Sheet1.Range("J2") = 0.3
        Else: Sheet1.Range("J2") = 0.15
        End If
    End If
End If

If Sheet1.Range("I2") = "Enterprise21" Then
    If Sheet1.Range("D2") = 1 Then
        Sheet1.Range("J2") = 0.35
    Else
        If Sheet1.Range("D2") = 2 Then
            Sheet1.Range("J2") = 0.25
        Else: Sheet1.Range("J2") = 0.1
        End If
    End If
End If

If Sheet1.Range("I2") = "Enterprise18" Then
    If Sheet1.Range("D2") = 1 Then
        Sheet1.Range("J2") = 0.3
    Else
        If Sheet1.Range("D2") = 2 Then
            Sheet1.Range("J2") = 0.2
        Else: Sheet1.Range("J2") = 0.05
        End If
    End If
End If

If Sheet1.Range("I2") = "Enterprise00" Then
    If Sheet1.Range("D2") = 1 Then
        Sheet1.Range("J2") = 0.25
    Else
        If Sheet1.Range("D2") = 2 Then
            Sheet1.Range("J2") = 0.15
        Else: Sheet1.Range("J2") = 0.05
        End If
    End If
End If

If Sheet1.Range("I2") = "Tier1" Then
    If Sheet1.Range("Z2") > 0.4 Then
        Sheet1.Range("J2") = 0.5
    Else
        If Sheet1.Range("Z2") <= 0.4 And Sheet1.Range("Z2") > 0.25 Then
            Sheet1.Range("J2") = (1 * Sheet1.Range("Z2")) + 0.1
        Else
            If Sheet1.Range("Z2") <= 0.25 And Sheet1.Range("Z2") > 0.075 Then
                Sheet1.Range("J2") = (2 * Sheet1.Range("Z2")) - 0.15
            Else
               If Sheet1.Range("Z2") <= 0.075 And Sheet1.Range("Z2") > 0 Then
                    Sheet1.Range("J2") = 0
               Else: Sheet1.Range("J2") = 0.5
               End If
            End If
        End If
    End If
End If

If Sheet1.Range("I2") = "Tier1-100" Then
    If Sheet1.Range("Z2") > 0.4 Then
        Sheet1.Range("J2") = 0.5
    Else
        If Sheet1.Range("Z2") <= 0.4 And Sheet1.Range("Z2") > 0.25 Then
            Sheet1.Range("J2") = (1 * Sheet1.Range("Z2")) + 0.1
        Else
            If Sheet1.Range("Z2") <= 0.25 And Sheet1.Range("Z2") > 0.075 Then
                Sheet1.Range("J2") = (2 * Sheet1.Range("Z2")) - 0.15
            Else
               If Sheet1.Range("Z2") <= 0.075 And Sheet1.Range("Z2") > 0 Then
                    Sheet1.Range("J2") = 0
               Else: Sheet1.Range("J2") = 0.5
               End If
            End If
        End If
    End If
End If

If Sheet1.Range("I2") = "Tier2" Then
    If Sheet1.Range("Z2") > 0.35 Then
        Sheet1.Range("J2") = 0.5
    Else
        If Sheet1.Range("Z2") <= 0.35 And Sheet1.Range("Z2") > 0.25 Then
            Sheet1.Range("J2") = (1 * Sheet1.Range("Z2")) + 0.15
        Else
            If Sheet1.Range("Z2") <= 0.25 And Sheet1.Range("Z2") > 0.05 Then
                Sheet1.Range("J2") = (2 * Sheet1.Range("Z2")) - 0.1
            Else
                If Sheet1.Range("Z2") <= 0.05 And Sheet1.Range("Z2") > 0 Then
                    Sheet1.Range("J2") = 0
                Else: Sheet1.Range("J2") = 0.5
                End If
            End If
        End If
    End If
End If


If Sheet1.Range("I2") = "Tier2-100" Then
    If Sheet1.Range("Z2") > 0.35 Then
        Sheet1.Range("J2") = 0.5
    Else
        If Sheet1.Range("Z2") <= 0.35 And Sheet1.Range("Z2") > 0.25 Then
            Sheet1.Range("J2") = (1 * Sheet1.Range("Z2")) + 0.15
        Else
            If Sheet1.Range("Z2") <= 0.25 And Sheet1.Range("Z2") > 0.05 Then
                Sheet1.Range("J2") = (2 * Sheet1.Range("Z2")) - 0.1
            Else
                If Sheet1.Range("Z2") <= 0.05 And Sheet1.Range("Z2") > 0 Then
                    Sheet1.Range("J2") = 0
                Else: Sheet1.Range("J2") = 0.5
                End If
            End If
        End If
    End If
End If

Sheet1.Range("J2").AutoFill Destination:=Sheet1.Range("J2:J" & LastRow)
Application.Calculate

结束子

【问题讨论】:

  • 我没有看到任何循环,代码都引用了特定的单元格,您没有解释“它不起作用”的意思。
  • 请不要对 cme​​ts 进行澄清。而是 edit 您的原始帖子并将说明添加到原始帖子。
  • 还有option explicit

标签: vba loops if-statement


【解决方案1】:

我将使用INDIRECTINDEXMATCH 和一些表格来提供一种非 VBA 方法。我的想法是,不要在 VBA 中使用硬编码值编码大量嵌套的 IF,而应该能够使用查找表来做到这一点。 (免责声明:这也是一个有趣的智力练习。)

首先,创建一个类似于您已有的佣金表的表格,并将其命名为您的特定策略,例如“BPO”,在公式 > 名称管理器下。我在名为“表格”的单独工作表上创建了我的。请注意,我在第 1 行中使用了 1 作为您的最大(和不切实际)毛利率。我还在单元格B1C1D1 中分别添加了 1、2 和 3。您需要为您的其他策略创建类似的表,并将它们放在 BPO 表下。

然后在数据选项卡的 J 列中,输入以下公式:=INDEX(INDIRECT(I2),MATCH(Z2,INDIRECT(I2&amp;"["&amp;Z$1&amp;"]"),-1),MATCH(D2,Tables!$A$1:$D$1,1))

这个 INDEX 公式有 3 个主要部分:

  1. INDIRECT(I2) - 这将返回包含您命名为“BPO”的表的数组 - 因此您知道您正在查看适合该特定策略的表。
  2. MATCH(Z2,INDIRECT(I2&amp;"["&amp;Z$1&amp;"]"),-1) - 这会在 Z 列中对照表 (BPO) 查找您的毛利率,查看列 [毛利率]。 MATCH(匹配类型)的最后一个参数是-1,表示它找到大于或等于您的毛利率的最小值(注意在表格中,毛利率是按降序排列的)。例如,如果您的毛利率为 0.22,则 MATCH 将返回 0.2399。
  3. MATCH(D2,Tables!$A$1:$D$1,1) - 查找年份,并尝试找到小于或等于它的最大值。因此,如果年份是 1、2 或 3,则 MATCH 将分别返回 1、2 或 3,但如果年份大于 3,则 MATCH 将返回 3。

第二个屏幕截图中的 AB 和 AC 列只是上面 2.3. 的结果,包括在内以表明正在返回正确的佣金值。请注意,“年列”不是第 2 年或第 3 年,而是 BPO 表中的第 2 列或第 3 列,即分别为第 1 年或第 2 年。

【讨论】:

  • 感谢您的反馈 BigBen。我最初将此文件构建为索引匹配和 IfStatement 公式,这些公式被拖到所有单元格中。问题是,对于工作簿中的所有其他公式,即使向下拖动公式也需要 10 分钟才能更新工作簿。再次谈论引用 4 个基础数据选项卡的 5,000 行数据。我一定会试试你的想法!!
【解决方案2】:

感谢所有输入/反馈。

由于需要合并其他销售计划的复杂性以及需要随时添加/删除销售计划的灵活性,我最终编写了一个自定义函数。

Function Commissions(Strategy As String, GM As Variant, YR As Variant) As Variant


If Strategy = "BPO" And GM >= 0.24 And YR = 1 Then
    Commissions = 0.4
ElseIf Strategy = "BPO" And GM >= 0.24 And YR = 2 Then
    Commissions = 0.3
ElseIf Strategy = "BPO" And GM >= 0.24 And YR >= 3 Then
    Commissions = 0.15
ElseIf Strategy = "BPO" And GM >= 0.21 And GM < 0.24 And YR = 1 Then
    Commissions = 0.35
ElseIf Strategy = "BPO" And GM >= 0.21 And GM < 0.24 And YR = 2 Then
    Commissions = 0.25
ElseIf Strategy = "BPO" And GM >= 0.21 And GM < 0.24 And YR >= 3 Then
    Commissions = 0.1
ElseIf Strategy = "BPO" And GM >= 0.18 And GM < 0.21 And YR = 1 Then
    Commissions = 0.3
ElseIf Strategy = "BPO" And GM >= 0.18 And GM < 0.21 And YR = 2 Then
    Commissions = 0.2
ElseIf Strategy = "BPO" And GM >= 0.18 And GM < 0.21 And YR >= 3 Then
    Commissions = 0.05
ElseIf Strategy = "BPO" And GM < 0.18 And YR = 1 Then
    Commissions = 0.25
ElseIf Strategy = "BPO" And GM < 0.18 And YR = 2 Then
    Commissions = 0.15
ElseIf Strategy = "BPO" And GM < 0.18 And YR >= 3 Then
    Commissions = 0.05
''all other strategies continued below....''

End If
End Function

【讨论】:

  • Select Case 在这里可能会更干净,而不是 ElseIf
  • 谢谢,我必须调查一下。我以前从未使用过 Select Case。
  • 抱歉,我在手机上查看此内容,但没有在屏幕上看到您的其他标准。 ElseIf 可能是更好的方法:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 1970-01-01
  • 2017-10-30
  • 1970-01-01
相关资源
最近更新 更多