Excel VBA 从数据库中读取和 Returns 数据的用户定义函数并不总是有效。为什么?
Excel VBA User Defined Function That Reads and Returns Data from a Database Doesn't Always Work. Why?
我已经将用户定义函数 (udf) 写入 运行 访问中的 select 语句,并且 return 将记录集作为数组写入 Excel 电子表格.该函数将两个字符串作为其参数:Access 数据库的连接字符串(例如“Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database1.accdb;Persist Security Info=False;”),和一个 SQL 字符串。
有时有效,有时无效。当它不起作用时,我得到一个#VALUE!我的电子表格中的错误。我不知道是什么原因导致它在不成功时失败。请帮我解决这个问题。
这是我的代码:
Function udfREADDB(connection As String, sql As String) As Variant
Dim db As ADODB.connection, rs As ADODB.Recordset, varArray() As Variant
Dim i As Integer, j As Integer ' rows & cols
Set db = New ADODB.connection
With db
.ConnectionString = connection
.ConnectionTimeout = 10
.Open
End With
' Query database
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open sql, db
ReDim varArray(0 To rs.RecordCount, 0 To rs.Fields.Count - 1)
' Read headings to array
For j = 0 To rs.Fields.Count - 1
varArray(0, j) = rs.Fields(j).Name
Next j
' Read data to array
For i = 1 To rs.RecordCount
For j = 0 To rs.Fields.Count - 1
varArray(i, j) = rs.Fields(j)
Next j
rs.MoveNext
Next i
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
udfREADDB = varArray
End Function
我试过在代码中放置一个断点。然后,当我从电子表格中的单元格调用 udf 时,代码会按预期暂停。然后我遍历代码的每个元素(每个变量),没有任何迹象表明有错误。我什至可以将直接窗格用于我的数组 varArray() 的 return 个元素,这很好。 UBound(varArray, 1) 或 UBound(varArray, 2) 也是如此。
我想知道错误是不是由路径名太长引起的,但这不会在 VBA 和电子表格中显示为错误吗?
我创建了一个包含 table 的测试数据库,其中包含 100 行和五个字段(一个整数、一个双精度数、一个字符串、一个布尔值和一个日期时间)。电子表格按预期填充了数据:我在单元格 A11:E101.
中使用公式“{=udfREADDB(A1,A2)}”和 Shift+Ctrl+Enter
当我将测试数据库粘贴到路径较长的位置时,我确实设法重现了错误。但是,当我复制一个存储在路径很长的位置的数据库并将其粘贴到 C:\ 时,我的 udf 仍然 returned #VALUE!错误,就像开始时一样。
我在 VBA 中使用了 Sub() 来调用我的函数,我使用 Debug.Print 查看创建的数组的大小,但这没有帮助,因为没有错误已生成。
我运行不知道如何解决这个问题:(
错误出现在电子表格中,因为它无法处理空值。那么,解决方案就是捕获 Null 并用其他东西替换它们; vbNullString、0 或“NULL”。我的偏好是 vbNullString。这是通过使用 IsNull() 函数实现的。 VBA 可以处理 Null,但 Excel 不能。
Function udfREADDB(connection As String, sql As String) As Variant
Dim db As ADODB.connection, rs As ADODB.Recordset, varArray() As Variant
Dim i As Integer, j As Integer ' rows & cols
Set db = New ADODB.connection
With db
.ConnectionString = connection
.ConnectionTimeout = 10
.Open
End With
' Query database
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open sql, db
ReDim varArray(0 To rs.RecordCount, 0 To rs.Fields.Count - 1)
' Read headings to array
For j = 0 To rs.Fields.Count - 1
varArray(0, j) = rs.Fields(j).Name
Next j
' Read data to array
For i = 1 To rs.RecordCount
For j = 0 To rs.Fields.Count - 1
If IsNull(rs.Fields(j)) Then
varArray(i, j) = vbNullString
Else
varArray(i, j) = rs.Fields(j)
End If
Next j
rs.MoveNext
Next i
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
udfREADDB = varArray
End Function
我已经将用户定义函数 (udf) 写入 运行 访问中的 select 语句,并且 return 将记录集作为数组写入 Excel 电子表格.该函数将两个字符串作为其参数:Access 数据库的连接字符串(例如“Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database1.accdb;Persist Security Info=False;”),和一个 SQL 字符串。
有时有效,有时无效。当它不起作用时,我得到一个#VALUE!我的电子表格中的错误。我不知道是什么原因导致它在不成功时失败。请帮我解决这个问题。
这是我的代码:
Function udfREADDB(connection As String, sql As String) As Variant
Dim db As ADODB.connection, rs As ADODB.Recordset, varArray() As Variant
Dim i As Integer, j As Integer ' rows & cols
Set db = New ADODB.connection
With db
.ConnectionString = connection
.ConnectionTimeout = 10
.Open
End With
' Query database
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open sql, db
ReDim varArray(0 To rs.RecordCount, 0 To rs.Fields.Count - 1)
' Read headings to array
For j = 0 To rs.Fields.Count - 1
varArray(0, j) = rs.Fields(j).Name
Next j
' Read data to array
For i = 1 To rs.RecordCount
For j = 0 To rs.Fields.Count - 1
varArray(i, j) = rs.Fields(j)
Next j
rs.MoveNext
Next i
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
udfREADDB = varArray
End Function
我试过在代码中放置一个断点。然后,当我从电子表格中的单元格调用 udf 时,代码会按预期暂停。然后我遍历代码的每个元素(每个变量),没有任何迹象表明有错误。我什至可以将直接窗格用于我的数组 varArray() 的 return 个元素,这很好。 UBound(varArray, 1) 或 UBound(varArray, 2) 也是如此。
我想知道错误是不是由路径名太长引起的,但这不会在 VBA 和电子表格中显示为错误吗?
我创建了一个包含 table 的测试数据库,其中包含 100 行和五个字段(一个整数、一个双精度数、一个字符串、一个布尔值和一个日期时间)。电子表格按预期填充了数据:我在单元格 A11:E101.
中使用公式“{=udfREADDB(A1,A2)}”和 Shift+Ctrl+Enter当我将测试数据库粘贴到路径较长的位置时,我确实设法重现了错误。但是,当我复制一个存储在路径很长的位置的数据库并将其粘贴到 C:\ 时,我的 udf 仍然 returned #VALUE!错误,就像开始时一样。
我在 VBA 中使用了 Sub() 来调用我的函数,我使用 Debug.Print 查看创建的数组的大小,但这没有帮助,因为没有错误已生成。
我运行不知道如何解决这个问题:(
错误出现在电子表格中,因为它无法处理空值。那么,解决方案就是捕获 Null 并用其他东西替换它们; vbNullString、0 或“NULL”。我的偏好是 vbNullString。这是通过使用 IsNull() 函数实现的。 VBA 可以处理 Null,但 Excel 不能。
Function udfREADDB(connection As String, sql As String) As Variant
Dim db As ADODB.connection, rs As ADODB.Recordset, varArray() As Variant
Dim i As Integer, j As Integer ' rows & cols
Set db = New ADODB.connection
With db
.ConnectionString = connection
.ConnectionTimeout = 10
.Open
End With
' Query database
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open sql, db
ReDim varArray(0 To rs.RecordCount, 0 To rs.Fields.Count - 1)
' Read headings to array
For j = 0 To rs.Fields.Count - 1
varArray(0, j) = rs.Fields(j).Name
Next j
' Read data to array
For i = 1 To rs.RecordCount
For j = 0 To rs.Fields.Count - 1
If IsNull(rs.Fields(j)) Then
varArray(i, j) = vbNullString
Else
varArray(i, j) = rs.Fields(j)
End If
Next j
rs.MoveNext
Next i
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
udfREADDB = varArray
End Function