我在一个单元格中有这个公式:
=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函数的同一工作表,是不允许的?
答案 0 :(得分:3)
这只是Excel的内置行为。从工作表调用的函数(通常在Excel术语中称为UDF - 用户定义的函数)除了返回值之外不能对工作表执行任何操作。
在上面的代码中,似乎还有其他错误。
Set destination.Value = ChannelCode
应该失败,因为您正在使用语法将对象变量设置为对象引用。如果你有一个错误处理程序,它将捕获错误。 (Excel只会终止任何使错误无法处理的UDF。)该行应为:
destination.Value = ChannelCode
但是,由于UDF对细胞没有副作用的规则,您的例程仍然会失败。请注意,即使您确实有错误处理程序,也不会捕获它。当UDF尝试修改单元时,VBA不会引发错误;它只是停止UDF并返回一个#VALUE!错误。
在您的情况下,看起来您可以重写函数以返回包含所需值的数组,而不是尝试修改调用单元格右侧和下方的单元格。 (或者您可以从某个宏而不是UDF调用您的函数。)
编辑:
就返回数组而言,有一个ADO方法 - GetRows
- 将从RecordSet中返回一个: