Ошибки, возникающие при использовании пользовательских функций (VBA)

#excel #vba #excel-2007

#excel #vba #excel-2007

Вопрос:

Я создал пользовательскую функцию в vba для расчета прибыли в соответствии с системой инвентаризации «Первый вход — первый выход». Прежде чем перейти к реальному коду, я хочу сделать несколько проверок, является ли ввод допустимым или нет.

 '---------------Check Information for errors----------------------
    SellSum = Application.WorksheetFunction.Sum(SellQuantity)
    BuySum = Application.WorksheetFunction.Sum(BuyQuantity)
    
    
    SellPCount = Application.WorksheetFunction.Count(SellPrice)
    SellQCount = Application.WorksheetFunction.Count(SellQuantity)
    BuyPCount = Application.WorksheetFunction.Count(BuyPrice)
    BuyQCount = Application.WorksheetFunction.Count(BuyQuantity)

    
    If SellSum > BuySum Then                                        'More sales than inventory, throw error
        FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
    End If
    
    If (BuyPCount <> BuyQCount Or SellPCount <> SellQCount) Then    'Incomplete data, throw error
        FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
    End If
'-----------------------------------------------------------------
  

И после реального кода у меня есть окончательное значение,

 FIFO_PROFIT = RunningProfit
  

Но, когда я ввел неверные данные, которые должны были вызвать ошибки, это ничего не дало. Это было похоже на то, что он просто пропустил проверку ошибок и перешел к фактическому коду.

Фактический код немного длинный, и я не верю, что он имеет к нему какое-либо отношение. Но если кто-нибудь захочет это просмотреть, https://pastebin.com/fA2pY52f

Комментарии:

1. Это я или вы перезаписываете значение FIFO_PROFIT в конце? Это не выдаст ошибку, если вы ее перезапишете, не так ли? В таком случае просто добавьте a GoTo внутри каждого из ваших операторов If, который проверяет наличие ошибки, и отредактируйте код до конца функции.

2. @EvilBlueMonkey, да, вы правы, я перезаписывал, потому что думал, что это единственный способ, которым это будет работать. Позвольте мне проверить ваше решение и сообщить вам, сработало оно или нет. 1 для быстрого реагирования

3. @EvilBlueMonkey, как именно это будет работать? Если (условие) перейти к конечной функции????

4. rtfm , доступ к которому осуществляется нажатием клавиши F1, когда курсор находится на неизвестном вам методе (CVErr), но вы можете вызвать реальную ошибку! И используйте Option Explicit !

Ответ №1:

Я бы сказал, что что-то вроде этого может сработать:

 Function FIFO_PROFIT(SellPrice As Variant, SellQuantity As Variant, BuyPrice As Variant, BuyQuantity As Variant) As Variant
'Calculate the Profit according to the FIFO method
 
 
'---------------Check Information for errors----------------------
    SellSum = Application.WorksheetFunction.Sum(SellQuantity)
    BuySum = Application.WorksheetFunction.Sum(BuyQuantity)
    
    
    SellPCount = Application.WorksheetFunction.Count(SellPrice)
    SellQCount = Application.WorksheetFunction.Count(SellQuantity)
    BuyPCount = Application.WorksheetFunction.Count(BuyPrice)
    BuyQCount = Application.WorksheetFunction.Count(BuyQuantity)
 
    
    If SellSum > BuySum Then                                        'More sales than inventory, throw error
        FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
        
        'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        GoTo FIFO_PROFIT_IS_ERROR '<--------------------ADDED CODE (1 of 3)X
        'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
    End If
    
    If (BuyPCount <> BuyQCount Or SellPCount <> SellQCount) Then    'Incomplete data, throw error
        FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
        
        'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        GoTo FIFO_PROFIT_IS_ERROR '<--------------------ADDED CODE (2 of 3)X
        'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    End If
'-----------------------------------------------------------------
 
'--------------MoreVariables--------------------------------------
Dim RunningSale As Variant
Dim RunningBuy As Variant
Dim RunningCost As Variant
Dim RunningBuyQuantity As Variant
Dim RunningSales As Variant
Dim RunningProfit As Variant
Dim Residual As Variant
Dim UsedupResidual As Variant
Dim y As Variant
 
y = 1
RunningCost = 0
Residual = 0
UsedupResidual = 0
RunningSales = 0
RunningProfit = 0
'-----------------------------------------------------------------
 
 
    For x = 1 To SellQCount
    
    If y <> 1 Then                                                                  'BUGtest
    
        RunningBuyQuantity = Residual   BuyQuantity(y).Value2
    End If
            While (RunningBuyQuantity <= SellQuantity(x).Value2 And y <= BuyQCount) 'Bugtest
                    
                If y = 1 Then
                    RunningCost = RunningCost   (BuyPrice(y).Value2 * BuyQuantity(y).Value2)
                Else
                    RunningCost = RunningCost   ((BuyPrice(y).Value2 * BuyQuantity(y).Value2)   (BuyPrice(y - 1).Value2 * Residual))
                End If
                
                Residual = 0
                RunningBuyQuantity = RunningBuyQuantity   BuyQuantity(y).Value2
                y = y   1
                
            Wend
        
        If RunningBuyQuantity > SellQuantity(x).Value2 Then
            Residual = SellQuantity(x).Value2 - RunningBuyQuantity
            UsedupResidual = BuyQuantity(y).Value2 - Residual
            RunningCost = RunningCost   (UsedupResidual * BuyPrice(y).Value2)
        End If
        
        RunningSales = SellPrice(x).Value2 * SellQuantity(x).Value2
        
        RunningProfit = RunningProfit   RunningSales - RunningCost
        
        RunningSales = 0
        RunningCost = 0
        
    Next x
    
    FIFO_PROFIT = RunningProfit
    
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
FIFO_PROFIT_IS_ERROR:     '<--------------------ADDED CODE (3 of 3) X
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
End Function
  

Я взял всю вашу функцию и добавил 3 строки кода. Я не проверял сам код, поэтому никаких оценок по этому поводу. В двух случаях (больше продаж и неполные данные) значение FIFO_PROFIT задается правильно, как вы уже делали, а затем GoTo инструкция отправляет код в строку FIFO_PROFIT_IS_ERROR, удобно расположенную в конце функции. Более подробная информация об GoTo инструкции здесь.

Опять же, вы также можете использовать Exit Function инструкцию. Для этого не потребуется третья строка FIFO_PROFIT_IS_ERROR, и она также будет работать. Это приведет к этому:

 Function FIFO_PROFIT(SellPrice As Variant, SellQuantity As Variant, BuyPrice As Variant, BuyQuantity As Variant) As Variant
'Calculate the Profit according to the FIFO method
 
 
'---------------Check Information for errors----------------------
    SellSum = Application.WorksheetFunction.Sum(SellQuantity)
    BuySum = Application.WorksheetFunction.Sum(BuyQuantity)
    
    
    SellPCount = Application.WorksheetFunction.Count(SellPrice)
    SellQCount = Application.WorksheetFunction.Count(SellQuantity)
    BuyPCount = Application.WorksheetFunction.Count(BuyPrice)
    BuyQCount = Application.WorksheetFunction.Count(BuyQuantity)
 
    
    If SellSum > BuySum Then                                        'More sales than inventory, throw error
        FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
        
        'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Exit Function '<--------------------ADDED CODE (1 of 2)X
        'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
    End If
    
    If (BuyPCount <> BuyQCount Or SellPCount <> SellQCount) Then    'Incomplete data, throw error
        FIFO_PROFIT = VBA.CVErr(XlCVError.xlErrValue)
        
        'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        Exit Function '<--------------------ADDED CODE (1 of 2)X
        'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
    End If
'-----------------------------------------------------------------
 
'--------------MoreVariables--------------------------------------
Dim RunningSale As Variant
Dim RunningBuy As Variant
Dim RunningCost As Variant
Dim RunningBuyQuantity As Variant
Dim RunningSales As Variant
Dim RunningProfit As Variant
Dim Residual As Variant
Dim UsedupResidual As Variant
Dim y As Variant
 
y = 1
RunningCost = 0
Residual = 0
UsedupResidual = 0
RunningSales = 0
RunningProfit = 0
'-----------------------------------------------------------------
 
 
    For x = 1 To SellQCount
    
    If y <> 1 Then                                                                  'BUGtest
    
        RunningBuyQuantity = Residual   BuyQuantity(y).Value2
    End If
            While (RunningBuyQuantity <= SellQuantity(x).Value2 And y <= BuyQCount) 'Bugtest
                    
                If y = 1 Then
                    RunningCost = RunningCost   (BuyPrice(y).Value2 * BuyQuantity(y).Value2)
                Else
                    RunningCost = RunningCost   ((BuyPrice(y).Value2 * BuyQuantity(y).Value2)   (BuyPrice(y - 1).Value2 * Residual))
                End If
                
                Residual = 0
                RunningBuyQuantity = RunningBuyQuantity   BuyQuantity(y).Value2
                y = y   1
                
            Wend
        
        If RunningBuyQuantity > SellQuantity(x).Value2 Then
            Residual = SellQuantity(x).Value2 - RunningBuyQuantity
            UsedupResidual = BuyQuantity(y).Value2 - Residual
            RunningCost = RunningCost   (UsedupResidual * BuyPrice(y).Value2)
        End If
        
        RunningSales = SellPrice(x).Value2 * SellQuantity(x).Value2
        
        RunningProfit = RunningProfit   RunningSales - RunningCost
        
        RunningSales = 0
        RunningCost = 0
        
    Next x
    
    FIFO_PROFIT = RunningProfit
    
End Function