从单元格调用的Excel VBA公式在写入工作表单元格时停止处理VBA或遇到App-Defined错误

时间:2010-12-07 17:52:46

标签: excel vba worksheet-function

我在一个单元格中有这个公式:

=GetData("Channel_01","Chicago")

执行此代码:

Public Function GetData(ChannelCode As String, Key As String) As String
    Dim sql As String
    Dim cmd As New ADODB.Command
    Dim outputTo As Range
    Set outputTo = Application.Caller    
    sql = "select * from ChannelData WHERE ChannelCode = ? AND Key1 = ?"
    Set cmd = getCommand(sql, ChannelCode, Key)
    Dim rs As ADODB.Recordset
    Set rs = cmd.Execute
    WritePivotRecordset ChannelCode, rs, outputTo.Offset(1, 0)
End Function

Public Sub WritePivotRecordset(ChannelCode As String, rs As ADODB.Recordset, destination As Range)
    Dim i As Integer
    '*** WHEN THIS LINE OF CODE IS REACHED AND EXECUTES, PROCESSING STOPS
    Set destination.Value = ChannelCode
    For i = 1 To rs.Fields.Count - 1    'skip first field
        destination.Offset(0, i).Value = rs.Fields(i).Name
    Next
    destination.Offset(1, 0).CopyFromRecordset rs
End Sub

问题出现在这一行:

'*** WHEN THIS LINE OF CODE IS REACHED AND EXECUTES, PROCESSING STOPS
    Set destination.Value = ChannelCode

是否设置此调用电子表格recalc,它会终止正在执行的VBA线程或类似的东西?我是这么认为的,所以我在写任何输出之前尝试了这个:

Application.Calculation = xlCalculationManual

但现在在同一行代码中我得到: 应用程序定义或对象定义的错误。

从VBA函数写入调用VBA函数的同一工作表,是不允许的?

1 个答案:

答案 0 :(得分:3)

这只是Excel的内置行为。从工作表调用的函数(通常在Excel术语中称为UDF - 用户定义的函数)除了返回值之外不能对工作表执行任何操作。

在上面的代码中,似乎还有其他错误。

Set destination.Value = ChannelCode 

应该失败,因为您正在使用语法将对象变量设置为对象引用。如果你有一个错误处理程序,它将捕获错误。 (Excel只会终止任何使错误无法处理的UDF。)该行应为:

destination.Value = ChannelCode 

但是,由于UDF对细胞没有副作用的规则,您的例程仍然会失败。请注意,即使您确实有错误处理程序,也不会捕获它。当UDF尝试修改单元时,VBA不会引发错误;它只是停止UDF并返回一个#VALUE!错误。

在您的情况下,看起来您可以重写函数以返回包含所需值的数组,而不是尝试修改调用单元格右侧和下方的单元格。 (或者您可以从某个宏而不是UDF调用您的函数。)

编辑:

就返回数组而言,有一个ADO方法 - GetRows - 将从RecordSet中返回一个:

code critique - am I creating a Rube Goldberg machine?