我正在开发一个简单的 Excel VBA 应用程序来控制公司的一小部分股票。 这个想法是让包装好的盒子按货架索引。 在 Excel Database.xlsx 文件中,我们有两个表: 包装:包含包装箱的重量和尺寸; Trans:该包的目的地是货架。
示例:
包装:
| Pack_ID | SalesIDLine |
| -------- | -------- |
| 030F7D78 | SO00265293-1510|
| E2B9BD52 | SO00265293-130 |
译:
| Loc_ID | Pack_ID |
| ------ | -------- |
| D0305 | 030F7D78 |
| B0204 | E2B9BD52 |
但是每次运行查询时都会收到此错误: bof 或 eof 为 true 表示当前记录已被删除 BOF 为 false,EOF 为 true,记录计数为 -1
我尝试了这段代码:
Private Function SearchSalesID(SalesIDLine As String) As String()
Dim conn As Object
Dim cmd As Object
Dim rs As Object
Dim result() As String
Dim index As Integer
'On Error GoTo ErrorHandler
Dim filePath As String
filePath = DataBase_Path & "\" & DataBase_Name
Set conn = CreateObject("ADODB.Connection")
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & filePath & ";" & _
"Extended Properties=""Excel 12.0 XML;HDR=YES;IMEX=1"";"
Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = "SELECT Loc_ID FROM [Trans$] AS T INNER JOIN [Pack$] AS P ON T.Pack_ID = P.Pack_ID WHERE P.SalesIDLine LIKE '" & SalesIDLine & "%'"
Set rs = cmd.Execute
result = rs.GetRows
rs.Close
conn.Close
SearchSalesID = Application.Transpose(result)
Exit Function
ErrorHandler:
If Not conn Is Nothing Then
conn.Close
End If
If Not rs Is Nothing Then
rs.Close
End If
SearchSalesID = Array()
End Function
对我来说,你的代码几乎可以工作。
问题是
recordSet.GetRows
返回一个二维数组 - 即使您只得到一行和/或一列。看起来有点但违反直觉的是,第一个索引获取列号,第二个索引获取行号,但这可能就是你的原因Application.Transpose
。
但是,无论您是否使用转置,结果始终是二维的,并且您的函数定义表示它返回一个一维数组。因此,当您将
Transpose
的结果分配为函数结果时,会出现类型不匹配的情况。
根据您的需求,您需要手动创建一维数组,或者更改查询的返回类型。例如,您可以使用这段代码来代替转置
ReDim resultVector(LBound(result, 2) To UBound(result, 2))
Dim row As Long
For row = LBound(result, 2) To UBound(result, 2)
resultVector(row) = result(0, row)
Next
SearchSalesID = resultVector
现在您还需要处理一件事:如果查询不返回任何值会发生什么?我过去使用过以下功能。我使用 早期绑定,如果您不想要,请将 rs 的类型更改为
Object
。
Public Function GetDataFromRecordSet(rs As Recordset) As Variant
If rs Is Nothing Then
Exit Function
ElseIf rs.State = 0 Then ' State = 0: RS is closed
Exit Function
ElseIf rs.EOF Then
Exit Function
End If
Dim result
On Error GoTo GetDataFromRecordSet_ERROR
result = rs.Getrows
GetDataFromRecordSet = result
Exit Function
GetDataFromRecordSet_ERROR:
Debug.Print Err.Number, Err.Description
End Function
如果由于任何原因无法从记录集对象中读取任何内容,则此函数将返回 Empty 作为结果 - 在日常生活中,如果查询中没有数据,主要是这种情况。您需要考虑如何在代码中反映这一点。您可以返回
Empty
(在这种情况下,您需要将函数的返回类型更改为 Variant
),或者如果您想返回一个包含一个元素为“”的数组)...
空返回:
Private Function SearchSalesID(SalesIDLine As String) As Variant
(...)
Set rs = cmd.Execute
result = GetDataFromRecordSet(rs)
rs.Close
If IsEmpty(result) Then Exit Function
(...)
End Function
返回一个虚拟数组:
Private Function SearchSalesID(SalesIDLine As String) As Variant
(...)
Set rs = cmd.Execute
result = GetDataFromRecordSet(rs)
rs.Close
If IsEmpty(result) Then
ReDim resultVector(0 To 0) As String
Else
ReDim resultVector(LBound(result, 2) To UBound(result, 2))
Dim row As Long
For row = LBound(result, 2) To UBound(result, 2)
resultVector(row) = result(0, row)
Next
End If
SearchSalesID = resultVector
End Function