如何在VBA中循环嵌套的If-Then语句

时间:2018-06-28 19:04:22

标签: vba loops if-statement

由于操作不明确,我将尝试简化目标并添加所有vba。

我正在编写一个宏,该宏将用于根据特定策略(一级,二级,业务流程外包或企业),毛利率范围和合同年确定佣金百分比。这将需要在最终产品中遍历约5,000行数据。我一直在尝试嵌套多个If-Then语句以实现我的目标,但是它不起作用。

下表是适用于每种策略的佣金率的表格,然后是我为此嵌套的If-Then语句编写的代码。

试图简化此过程,并使其遍历数据的整个行。目标是让J列中的每个单元格返回由i列中的策略,D列中的year和Z列中的GM确定的佣金率。该策略具有改变页面下每一行的潜力。 创建一个自定义函数会更好吗?

金达第一次完成宏作家的疯狂任务。感谢我已经获得的所有反馈,并期待其他任何想法。

enter image description here

enter image description here

enter image description here

我的代码:

第I列=策略

D列=年

Z列=毛利率

第J列= If-Then的结果

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

子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

结束子

2 个答案:

答案 0 :(得分:0)

我将使用INDIRECTINDEXMATCH和一些表格来提供非VBA方法。我的想法是,与其在VBA中用硬编码的值编码许多嵌套的IF,不如使用查找表来做到这一点。 (免责声明:这也是一种有趣的智力练习。)

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

enter image description here

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

enter image description here

此INDEX公式包含3个主要部分:

  1. INDIRECT(I2)-这将返回包含名为“ BPO”的表的数组-因此,您知道自己正在查看适合该特定策略的表。
  2. MATCH(Z2,INDIRECT(I2&"["&Z$1&"]"),-1)-这将在表格Z [毛利]中对照表格(BPO)查找您在Z列中的毛利率。 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。的结果,包括这些内容以表明已返回正确的佣金值。请注意,“年列” 不是第二年或第三年,而是BPO表中的第二列或第三列,即分别是第一年或第二年。

答案 1 :(得分:0)

感谢所有输入/反馈。

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

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