VBA函数中的循环引用警告

时间:2017-07-10 06:23:25

标签: excel vba excel-vba

我创建了一个根据许多变量计算客户佣金的函数。

我遇到的第一个问题是循环参考错误。我明白这意味着什么,但我无法弄清楚错误的来源。

第二个问题是我的ISIN,Cena,Skaits和VK值被设置为某个单元格,但我希望它们等于当前行的值。如果这没有意义,请询问。

Private Sub CommandButton1_Click()

'Declare the variables
Dim klienta_nr As Long
Dim ISIN As String
Dim Cena As Double
Dim Skaits As Double
Dim Komisija As Double
Dim vk As String
Dim Summa As Double
Dim x As Integer

Application.ScreenUpdating = False
Set kSheet = ThisWorkbook.Sheets("komisijas")


'Set variables equal to the cell data
'-----------------------------------------------------------
'I NEED TO SET THESE TO BE EQUAL TO THE CURRENT ROW'S VALUES
'-----------------------------------------------------------
klienta_nr = Range("B2").Value
ISIN = Range("E2").Value
Cena = Range("H2").Value
Skaits = Range("I2").Value
vk = Range("D2").Value
Summa = Cena * Skaits




'---------------------------------------------------------------------------------------------
'Start Cases
'---------------------------------------------------------------------------------------------
Select Case klienta_nr

'Special klient cases


    Case 10
                '(Vācija, Francija, Nīderlandes, Itālija, Īrija) - 30 EUR MIN
                If klienta_nr = 10 And (Left(ISIN, 2) = "DE" Or Left(ISIN, 2) = "FR" Or Left(ISIN, 2) = "NL" Or Left(ISIN, 2) = "IT" Or Left(ISIN, 2) = "IE") Then
                    Komisija = Summa * 0.01
                    ActiveCell.Value = Komisija
                    End If
                If klienta_nr = 10 And Komisija <= 30 Then
                    ActiveCell.Value = 30
                    End If

                'Case where klient is special, but ISIN doesn't apply
                If klienta_nr = 10 And (Left(ISIN, 2) <> "DE" Or Left(ISIN, 2) <> "FR" Or Left(ISIN, 2) <> "NL" Or Left(ISIN, 2) <> "IT" Or Left(ISIN, 2) <> "IE") Then
                    Komisija = Summa * 0.003
                    If Komisija >= 40 Then
                        ActiveCell.Value = 40
                        End If
                End If


    Case 11 
                '(Vācija, Francija, Nīderlandes, Itālija, Īrija) - 30 EUR MIN
                If klienta_nr = 11 And (Left(ISIN, 2) = "DE" Or Left(ISIN, 2) = "FR" Or Left(ISIN, 2) = "NL" Or Left(ISIN, 2) = "IT" Or Left(ISIN, 2) = "IE") Then
                    Komisija = Summa * 0.01
                    ActiveCell.Value = Komisija
                    End If
                'Set 30 EUR Min
                If klienta_nr = 11 And Komisija <= 30 Then
                    ActiveCell.Value = 30
                    End If

        'End If


    Case 12 
                '(Ziemeļvastu, Lietuvas, Igaunijas, Vācijas, Francijas, Nīderlandes, Itālijas, Īrijas, Austijas, Beļģijas, Spānijas, Portugāles)
                If klienta_nr = 12 And (Left(ISIN, 2) = "NO" Or Left(ISIN, 2) = "SE" Or Left(ISIN, 2) = "DK" Or Left(ISIN, 2) = "FI" Or Left(ISIN, 2) = "IS" Or Left(ISIN, 2) = "LT" Or Left(ISIN, 2) = "EE" Or Left(ISIN, 2) = "DE" Or Left(ISIN, 2) = "FR" Or Left(ISIN, 2) = "NL" Or Left(ISIN, 2) = "IT" Or Left(ISIN, 2) = "IE" Or Left(ISIN, 2) = "AT" Or Left(ISIN, 2) = "BE" Or Left(ISIN, 2) = "ES" Or Left(ISIN, 2) = "PT") Then
                    Komisija = Summa * 0.002
                    ActiveCell.Value = Komisija
                    End If
                '(ASV)
                If klienta_nr = 12 And (Left(ISIN, 2) = "US") Then
                    Komisija = Summa * 0.002
                    End If
                '(Lielbritānijas)
                If klienta_nr = 12 And (Left(ISIN, 2) = "UK") Then
                    Komisija = Summa * 0.002
                    ActiveCell.Value = Komisija
                    End If
                '(Šveices)
                If klienta_nr = 12 And (Left(ISIN, 2) = "CH") Then
                    Komisija = Summa * 0.002
                    ActiveCell.Value = Komisija
                    End If
                'Set 20 [valūte] MIN
                If klienta_nr = 12 And Komisija <= 20 Then
                    ActiveCell.Value = 20
                    End If


    Case 13 
                '(Ziemeļvastu, Lietuvas, Igaunijas, Vācijas, Francijas, Nīderlandes, Itālijas, Īrijas, Austijas, Beļģijas, Spānijas, Portugāles)
                If klienta_nr = 13 And (Left(ISIN, 2) = "NO" Or Left(ISIN, 2) = "SE" Or Left(ISIN, 2) = "DK" Or Left(ISIN, 2) = "FI" Or Left(ISIN, 2) = "IS" Or Left(ISIN, 2) = "LT" Or Left(ISIN, 2) = "EE" Or Left(ISIN, 2) = "DE" Or Left(ISIN, 2) = "FR" Or Left(ISIN, 2) = "NL" Or Left(ISIN, 2) = "IT" Or Left(ISIN, 2) = "IE" Or Left(ISIN, 2) = "AT" Or Left(ISIN, 2) = "BE" Or Left(ISIN, 2) = "ES" Or Left(ISIN, 2) = "PT") Then
                    Komisija = Summa * 0.002
                    ActiveCell.Value = Komisija
                    End If
                '(ASV)
                If klienta_nr = 13 And (Left(ISIN, 2) = "US") Then
                    Komisija = Summa * 0.002
                    ActiveCell.Value = Komisija
                    End If
                '(Lielbritānijas)
                If klienta_nr = 13 And (Left(ISIN, 2) = "UK") Then
                    Komisija = Summa * 0.002
                    ActiveCell.Value = Komisija
                    End If
                '(Šveices)
                If klienta_nr = 13 And (Left(ISIN, 2) = "CH") Then
                    Komisija = Summa * 0.002
                    ActiveCell.Value = Komisija
                    End If
                'Set 20 [valūte] MIN
                If klienta_nr = 13 And Komisija <= 20 Then
                    ActiveCell.Value = 20
                    End If


    Case 14 
                '(ASV)
                If klienta_nr = 14 And (Left(ISIN, 2) = "US") Then
                    Komisija = Summa * 0.0027
                    ActiveCell.Value = Komisija
                    End If
                'Set 40 USD MIN
                If klienta_nr = 14 And Komisija <= 40 Then
                    ActiveCell.Value = 40
                    End If



    'Non-special klient cases
    Case Else
            If Not Application.Match(klienta_nr, kSheet.Range("A2:A100")) Then
              'IP2, 0.03% komisija, 40 EUR/USD Max
                 If Right(vk, 1) = 1 Or Right(vk, 1) = 8 Then
                    Komisija = Summa * 0.003
                    ActiveCell.Value = Komisija
                    End If
              'IP1, 0.1% komisija, 40 EUR/USD Max
                If Right(vk, 1) = 7 Then
                    Komisija = Summa * 0.01
                    ActiveCell.Value = Komisija
                    End If
                'Komisija MAX is 40, so anything >=40 equals 40
                If Komisija >= 40 Then
                    ActiveCell.Value = 40
                    End If
            End If
End Select
End Sub

2 个答案:

答案 0 :(得分:0)

尝试这样的事情:

在工作表中的任意位置进行选择,并使Sub循环遍历当前选择中的每一行。

Sub komisija_calc(klienta_nr As Double)

'Declare the variables
Dim ISIN As String
Dim Cena As Double
Dim Skaits As Double
Dim Komisija As Double
Dim vk As String
Dim Summa As Double
Dim x As Integer

Dim rng As Range 'Added variable

Application.ScreenUpdating = False
Set kSheet = ThisWorkbook.Sheets("komisijas")
'Getting rid off Worksheets("Order Machine").Activate

'Set variables equal to the cell data
'We'll loop over the rows in the selection instead of what you did:
'Maybe add a check to ensure the selection is only one column, otherwise you'll do more loops than neccessary:

For Each rng In Selection 'START LOOP! - Selection is still bad - you might want to get your rows in another way, the loop is for demonstration purposes.
    With Worksheets("Order Machine") 
        ISIN = .Range("E" & rng.Row).Value
        Cena = .Range("H" & rng.Row).Value
        Skaits = .Range("I" & rng.Row).Value
        vk = .Range("B" & rng.Row).Value
        Summa = Cena * Skaits

        '-----------
        'Start Cases
        '-----------
        Select Case klienta_nr
        'Special klient cases
        '... all your code here...
            .Range("A" & rng.Row).Value = Komisija 'To put the commission in column A of "Order Machine" worksheet. Change as needed.
        End Select
    End With
Next rng 'Next row in selection.
End Sub

修改 我假设你想要&#34;当前行&#34;等于ActiveCell /当前选择。然后你只需要替换:

klienta_nr = Range("B2").Value
ISIN = Range("E2").Value
Cena = Range("H2").Value
Skaits = Range("I2").Value
vk = Range("D2").Value
Summa = Cena * Skaits

使用:

klienta_nr = Range("B" & ActiveCell.Row).Value
ISIN = Range("E" & ActiveCell.Row).Value
Cena = Range("H" & ActiveCell.Row).Value
Skaits = Range("I" & ActiveCell.Row).Value
vk = Range("D" & ActiveCell.Row).Value
Summa = Cena * Skaits

当您运行此宏时,我假设您的ActiveCell与这些输入值在同一工作表上?让我们说你的activecell是&#34; S5&#34;然后这将从小区&#34; B5&#34;中获取klienta_nr。

我无法强调你应该尽量避免使用.ActivateActiveCellSelection等等。

答案 1 :(得分:0)

如果您正在编写必须从工作表单元格(也称为用户定义函数)调用的VBA函数,则必须确保函数所需的所有单元格都作为参数传递。所以(没有优化你的代码),我认为这是应该工作的:

Function komisija_calc(klienta_nr As Double, ISIN As String, Cena As Double, _
                        Skaits As Double, Vk As String, ClientNumbers As Range)

'Declare the variables
    Dim Komisija As Double
    Dim Summa As Double

    'Set variables equal to the cell data
    '-----------------------------------------------------------
    'I NEED TO SET THESE TO BE EQUAL TO THE CURRENT ROW'S VALUES
    '-----------------------------------------------------------
    Summa = Cena * Skaits


    '--------------------------------------------------------------------------
    'Loop through Column A until blank
    '-------------------------------------------------------------------------


    '---------------------------------------------------------------------------------------------
    'Start Cases
    '---------------------------------------------------------------------------------------------
    Select Case klienta_nr

        'Special klient cases


    Case 10
        '(Vacija, Francija, Niderlandes, Italija, Irija) - 30 EUR MIN
        If klienta_nr = 10 And (Left(ISIN, 2) = "DE" Or Left(ISIN, 2) = "FR" Or Left(ISIN, 2) = "NL" Or Left(ISIN, 2) = "IT" Or Left(ISIN, 2) = "IE") Then
            Komisija = Summa * 0.01
            komisija_calc = Komisija
        End If
        If klienta_nr = 10 And Komisija <= 30 Then
            komisija_calc = 30
        End If

        'Case where klient is special, but ISIN doesn't apply
        If klienta_nr = 10 And (Left(ISIN, 2) <> "DE" Or Left(ISIN, 2) <> "FR" Or Left(ISIN, 2) <> "NL" Or Left(ISIN, 2) <> "IT" Or Left(ISIN, 2) <> "IE") Then
            Komisija = Summa * 0.003
            If Komisija >= 40 Then
                komisija_calc = 40
            End If
        End If


    Case 11
        '(Vacija, Francija, Niderlandes, Italija, Irija) - 30 EUR MIN
        If klienta_nr = 11 And (Left(ISIN, 2) = "DE" Or Left(ISIN, 2) = "FR" Or Left(ISIN, 2) = "NL" Or Left(ISIN, 2) = "IT" Or Left(ISIN, 2) = "IE") Then
            Komisija = Summa * 0.01
            komisija_calc = Komisija
        End If
        'Set 30 EUR Min
        If klienta_nr = 11 And Komisija <= 30 Then
            komisija_calc = 30
        End If

        'End If


    Case 12
        '(Ziemelvastu, Lietuvas, Igaunijas, Vacijas, Francijas, Niderlandes, Italijas, Irijas, Austijas, Belgijas, Spanijas, Portugales)
        If klienta_nr = 12 And (Left(ISIN, 2) = "NO" Or Left(ISIN, 2) = "SE" Or Left(ISIN, 2) = "DK" Or Left(ISIN, 2) = "FI" Or Left(ISIN, 2) = "IS" Or Left(ISIN, 2) = "LT" Or Left(ISIN, 2) = "EE" Or Left(ISIN, 2) = "DE" Or Left(ISIN, 2) = "FR" Or Left(ISIN, 2) = "NL" Or Left(ISIN, 2) = "IT" Or Left(ISIN, 2) = "IE" Or Left(ISIN, 2) = "AT" Or Left(ISIN, 2) = "BE" Or Left(ISIN, 2) = "ES" Or Left(ISIN, 2) = "PT") Then
            Komisija = Summa * 0.002
            komisija_calc = Komisija
        End If
        '(ASV)
        If klienta_nr = 12 And (Left(ISIN, 2) = "US") Then
            Komisija = Summa * 0.002
        End If
        '(Lielbritanijas)
        If klienta_nr = 12 And (Left(ISIN, 2) = "UK") Then
            Komisija = Summa * 0.002
            komisija_calc = Komisija
        End If
        '(Šveices)
        If klienta_nr = 12 And (Left(ISIN, 2) = "CH") Then
            Komisija = Summa * 0.002
            komisija_calc = Komisija
        End If
        'Set 20 [valute] MIN
        If klienta_nr = 12 And Komisija <= 20 Then
            komisija_calc = 20
        End If


    Case 13
        '(Ziemelvastu, Lietuvas, Igaunijas, Vacijas, Francijas, Niderlandes, Italijas, Irijas, Austijas, Belgijas, Spanijas, Portugales)
        If klienta_nr = 13 And (Left(ISIN, 2) = "NO" Or Left(ISIN, 2) = "SE" Or Left(ISIN, 2) = "DK" Or Left(ISIN, 2) = "FI" Or Left(ISIN, 2) = "IS" Or Left(ISIN, 2) = "LT" Or Left(ISIN, 2) = "EE" Or Left(ISIN, 2) = "DE" Or Left(ISIN, 2) = "FR" Or Left(ISIN, 2) = "NL" Or Left(ISIN, 2) = "IT" Or Left(ISIN, 2) = "IE" Or Left(ISIN, 2) = "AT" Or Left(ISIN, 2) = "BE" Or Left(ISIN, 2) = "ES" Or Left(ISIN, 2) = "PT") Then
            Komisija = Summa * 0.002
            komisija_calc = Komisija
        End If
        '(ASV)
        If klienta_nr = 13 And (Left(ISIN, 2) = "US") Then
            Komisija = Summa * 0.002
            komisija_calc = Komisija
        End If
        '(Lielbritanijas)
        If klienta_nr = 13 And (Left(ISIN, 2) = "UK") Then
            Komisija = Summa * 0.002
            komisija_calc = Komisija
        End If
        '(Šveices)
        If klienta_nr = 13 And (Left(ISIN, 2) = "CH") Then
            Komisija = Summa * 0.002
            komisija_calc = Komisija
        End If
        'Set 20 [valute] MIN
        If klienta_nr = 13 And Komisija <= 20 Then
            komisija_calc = 20
        End If


    Case 14
        '(ASV)
        If klienta_nr = 14 And (Left(ISIN, 2) = "US") Then
            Komisija = Summa * 0.0027
            komisija_calc = Komisija
        End If
        'Set 40 USD MIN
        If klienta_nr = 14 And Komisija <= 40 Then
            komisija_calc = 40
        End If



        'Non-special klient cases
    Case Else
        If Not Application.Match(klienta_nr, ClientNumbers) Then
            'IP2, 0.03% komisija, 40 EUR/USD Max
            If Right(Vk, 1) = 1 Or Right(Vk, 1) = 8 Then
                Komisija = Summa * 0.003
                komisija_calc = Komisija
            End If
            'IP1, 0.1% komisija, 40 EUR/USD Max
            If Right(Vk, 1) = 7 Then
                Komisija = Summa * 0.01
                komisija_calc = Komisija
            End If
            'Komisija MAX is 40, so anything >=40 equals 40
            If Komisija >= 40 Then
                komisija_calc = 40
            End If
        End If
    End Select
End Function