VBA 上的 case 语句问题

Issue with case statement on VBA

我是 VBA 的新手,我在尝试编写案例陈述时遇到问题。

我希望代码做什么的概述

我需要根据两个标准分配不同的费率:风险状况和价值。

如果风险状况是外国主动、外国平衡、本地主动、本地平衡,则费用如下:

如果风险状况是本地固定收益或外国固定收益,费用如下:

下面是我的一组数据的例子:

Account No Risk Profile Value
2345 Foreign Assertive 5,000,000
2346 Foreign Assertive 25,000,000
2347 Local Assertive 100,000,000
2348 Foreign Balanced 46,000,000
2349 Local Balanced 30,000,000
2350 Foreign Fixed Income 19,000,000
2351 Local Fixed Income 4,000,000
2352 Local Fixed Income 150,000,000

我的预期结果如下:

Account No Risk Profile Value Fee
2345 Foreign Assertive 5,000,000 0.80%
2346 Foreign Assertive 25,000,000 0.60%
2347 Local Assertive 100,000,000 0.20%
2348 Foreign Balanced 46,000,000 0.40%
2349 Local Balanced 30,000,000 0.60%
2350 Foreign Fixed Income 19,000,000 0.40%
2351 Local Fixed Income 4,000,000 0.60%
2352 Local Fixed Income 150,000,000 0.20%

下面是我写的,但它不起作用:

Sub FeeTest()

Dim RiskProLR As Long, x As Long, Value As Long

Dim Fee As Range

Dim RiskPro As String


Set Fee = Range("C1").Offset(0, 1)

Fee.Value = "Fee"

RiskProgLR = Range("B" & Rows.Count).End(xlUp).Row

 For x = 2 To RiskProLR

    Value = Range("C" & x).Value
    RiskPro = Range("B" & x).Value

    Select Case Value & RiskPro
  
        Case Is = RiskPro = "Foreign Assertive", RiskPro = "Local Assertive", RiskPro = "Foreign Balanced", _
        RiskPro = "Local Balanced" & Value <= 15000000
        Range("D" & x).Value = "0.8%"
    
        Case Is = RiskPro = "Foreign Assertive", RiskPro = "Local Assertive", RiskPro = "Foreign Balanced", _
        RiskPro = "Local Balanced" & Value > 15000000 & Value <= 30000000
        Range("D" & x).Value = "0.6%"
    
        Case Is = RiskPro = "Foreign Assertive", RiskPro = "Local Assertive", RiskPro = "Foreign Balanced", _
        RiskPro = "Local Balanced" & Value > 30000000 & Value <= 60000000
        Range("D" & x).Value = "0.4%"
        
        Case Is = RiskPro = "Foreign Assertive", RiskPro = "Local Assertive", RiskPro = "Foreign Balanced", _
        RiskPro = "Local Balanced" & Value > 60000000
        Range("D" & x).Value = "0.2%"
        
        Case Is = InvestProg = "Foreign Fixed Income", InvestProg = "Local Fixed Income" & PortValue <= 15000000
        Range("D" & x).Value = "0.6%"
        
        Case Is = InvestProg = "Foreign Fixed Income", InvestProg = "Local Fixed Income" & Value > 15000000 & Value <= 30000000
        Range("D" & x).Value = "0.4%"
        
        Case Is = InvestProg = "Foreign Fixed Income", InvestProg = "Local Fixed Income" & PortValue > 30000000
        Range("D" & x).Value = "0.2%"
    
        
    End Select

 
Next x


End Sub
  1. 请在模块顶部插入 Option Explicit 以帮助您强制声明所有变量,它还可以帮助您捕捉拼写错误,例如 RiskProgLR

  2. Multiple conditions for Select 语句有不同的实现方式,例如看这个answer

  3. 不要使用与现有对象同名的变量命名 属性。例如Value

  4. 建议您完全限定您的范围(例如 Range("C1").Offset(0, 1) 应该类似于 ThisWorkBook.Sheets("Sheet1").Range("C1").OffSet(0,1),或者创建一个如下所示的变量并 Set 这样你可以只引用变量),不这样做会导致 VBA 假设你指的是 ActiveSheet,这可能不是你想要的。

试试这个修改后的代码,我假设 InvestProg 实际上是 RiskPro:

Sub FeeTest()

    Dim RiskProLR As Long, x As Long, feeValue As Long
    Dim feeRng As Range
    Dim RiskPro As String
    
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")
    
    Set feeRng = ws.Range("C1").Offset(0, 1)
    
    feeRng.Value = "Fee"
    
    RiskProLR = ws.Range("B" & ws.Rows.Count).End(xlUp).Row
    For x = 2 To RiskProLR
    
        feeValue = ws.Range("C" & x).Value
        RiskPro = ws.Range("B" & x).Value
        
        Dim feeRate As String
        feeRate = vbNullString
        
        Select Case RiskPro
            Case "Foreign Assertive", "Foreign Balanced", "Local Assertive", "Local Balanced"
                Select Case True
                    Case feeValue <= 15000000
                        feeRate = "0.8%"
                    Case (feeValue > 15000000 And feeValue <= 30000000)
                        feeRate = "0.6%"
                    Case (feeValue > 30000000 And feeValue <= 60000000)
                        feeRate = "0.4%"
                    Case feeValue > 60000000
                        feeRate = "0.2%"
                End Select
            Case "Local Fixed Income", "Foreign Fixed Income"
                Select Case True
                    Case feeValue <= 15000000
                        feeRate = "0.6%"
                    Case (feeValue > 15000000 And feeValue <= 30000000)
                        feeRate = "0.4%"
                    Case feeValue > 30000000
                        feeRate = "0.2%"
                End Select
        End Select
        
        If feeRate <> vbNullString Then ws.Range("D" & x).Value = feeRate
    Next x
End Sub

我同意雷蒙德吴的一般评论,因此不再重复。

您可能会发现下面的代码,它的功能更简单:

Sub FeeTest()

Dim RiskProLR As Long, x As Long, Value As Long

Dim Fee As Range

Dim RiskPro As String


Set Fee = Range("C1").Offset(0, 1)

Fee.Value = "Fee"

RiskProLR = Range("B" & Rows.Count).End(xlUp).Row

 For x = 2 To RiskProLR

    Value = Range("C" & x).Value
    RiskPro = Range("B" & x).Value

    Select Case RiskPro
  
        Case "Foreign Assertive", "Local Assertive", "Foreign Balanced", "Local Balanced"
            Select Case Value
                Case Is <= 15000000
                    Range("D" & x).Value = "0.8%"
                Case 15000000 To 30000000
                    Range("D" & x).Value = "0.6%"
                Case 30000000 To 60000000
                    Range("D" & x).Value = "0.4%"
                Case Else
                    Range("D" & x).Value = "0.2%"
            End Select
            
        Case "Foreign Fixed Income", "Local Fixed Income"
            Select Case Value
                Case Is <= 15000000
                    Range("D" & x).Value = "0.6%"
                Case 15000000 To 30000000
                    Range("D" & x).Value = "0.4%"
                Case Else
                    Range("D" & x).Value = "0.2%"
            End Select
        
    End Select

 
Next x


End Sub

使用 Case x To y 来指定范围更容易键入并且更易读。请注意,范围有效重叠是可以的。 VBA 将使用符合条件的第一种情况,例如,如果某个值正好是 30,000,000,则它落在 15,000,000 到 30,000,000 范围内,而不是 30,000,000 到 60,000,000 范围内。案例陈述的顺序在这里很重要。

另请注意 Case Else 的使用。无需指定最后金额。