复制工作表时出现#VALUE 错误

#VALUE error when copying sheets

我使用的 UDF 基本上是 vlookup 的简化版。这是代码:

Function SUELDOBASICO(Columna As Integer) As Double

SUELDOBASICO = Application.WorksheetFunction.VLookup(Application.Caller.Parent.Cells(Application.Caller.Row, 3), Application.Caller.Parent.Parent.Sheets("Escalas Salariales").Range("A3:DJ23"), Columna, False)

End Function

我注意到有时在复制工作表时(在同一工作簿中),我会收到 #VALUE 错误。如果我 "edit" Excel 中的单元格,不做任何更改,仅使用 F2Enter,错误就会消失。它曾经在简单地更改 windows 时发生(例如,更改为 Firefox,然后返回 Excel)。这就是为什么我在代码中大量使用 CallerParent 的原因。它几乎完全固定,除了有时复制工作表时。我似乎找不到错误的来源。 请帮忙

不需要调用者和parent。

Function SUELDOBASICO(Cell as Range, LookupRange as range, Columna As Integer) As Double

' When you call the function :
' set Cell to be  the cell in column C in the same row

' Set LookupRange to Sheets("Escalas Salariales").Range("$A:$DJ")

SUELDOBASICO =     Application.WorksheetFunction.VLookup(Cell, LookupRange, Columna, False)
End Function

单元格中的公式示例...

=SUELDO BASICO(C10,'Escalas Salariales'!$A$3:$DJ$23)

我知道这不是你的确切问题,但是,如果可能的话,我建议完全避免 VBA 如果那是一个选项并编写你的公式如下:

=VLOOKUP(INDIRECT("C"&ROW()),'Escalas Salariales'!$A:$DJ,XXXXX,false)

XXXXX 可以与您当前的 Columna 变量相同。

这将保证您的代码按需要工作。


考虑到评论中讨论的内容并尽我最大努力确保它有效,实际上我没有发现您的代码有任何问题,我只是猜测它可能与 Application.Caller 有关。

当这种事情发生在我身上时,我会尽力使用调试器找出原因 - 这通常涉及 Stop 语句,以便能够进入代码并查看发生了什么,或者Debug.Print Err.Description 种消息。

不管怎样,我都试着把每个部分都分解了,所以,至少你可以看出问题出在哪里。 为此,我重新设计了您的功能(有些矫枉过正)....

Function SUELDOBASICO(Columna As Integer) As Double

On Error GoTo ErrorCheck

Dim CellRef As Range
Dim LookupRef As Range

    Set CellRef = Cells(Application.Caller.Range("A1").Row, 3)
    Set LookupRef = Application.Caller.Worksheet.Parent.Sheets("Escalas Salariales").Range("A3:DJ23")

    SUELDOBASICO = Application.VLookup(CellRef, LookupRef, Columna, False)

    Exit Function

ErrorCheck:
    Stop
    Resume

End Function

(另请注意,我将 Application.WorksheetFunction.VLookup 更改为 Application.VLookup - 查看 this link 以获得解释)

一旦你弄明白了,我会从函数中删除错误代码,因为这不是生产代码的好主意 - 仅用于调试。

希望能给你想要的答案。

希望对您有所帮助....


更新#2:

考虑到复制 sheet 可能导致此错误,这里进行测试以查看该过程是否得到修复:

Function SUELDOBASICO(Columna As Integer) As Double

On Error GoTo ErrorCheck

Dim NumTimesErrored As Integer
Dim StartTime As Double
Dim WaitSeconds As Integer
NumTimesErrored = 0

Dim CellRef As Range
Dim LookupRef As Range

    Set CellRef = Cells(Application.Caller.Range("A1").Row, 3)
    Set LookupRef = Application.Caller.Worksheet.Parent.Sheets("Escalas Salariales").Range("A3:DJ23")

    SUELDOBASICO = Application.VLookup(CellRef, LookupRef, Columna, False)

    Exit Function

ErrorCheck:
    ' This will make it tries this "hack" up to 3 times:
    If NumTimesErrored < 3 Then
        StartTime = Now
        WaitSeconds = 1 ' Wait one second
        Loop While Now - TimeStart < TimeSerial(0, 0, WaitSeconds)
            DoEvents ' Allows all the other processes to complete
        Loop
        ' Increment the number of times you've tried this:
        NumTimesErrored = NumTimesErrored + 1
        ' Go back to the calculation step that errored
        Resume
    End If

    Stop
    Resume

End Function