You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MS Access列表框绑定Sqlite的ADODB记录集仅显示单条记录如何解决

Access绑定SQLite ADODB记录集后Listbox仅显示第一条的故障原因及修复方案

故障核心原因

  • Access原生Listbox的Recordset属性仅对本地ACE/Jet引擎的DAO记录集、或者客户端游标类型的ADODB记录集兼容,你当前使用的adOpenKeyset属于服务端游标,SQLite ODBC返回的该类游标无法被Listbox正确遍历所有行。你看到RecordCount返回100是因为adOpenKeyset游标本身可以正确统计行数,但Listbox遍历逻辑不兼容该类外部服务端游标,只能读取到游标当前指向的第一条记录。
  • 你设置RowSourceType = "Table/Query"时,Access默认会尝试用本地数据库引擎解析行来源,和你绑定的外部SQLite的ADODB记录集不匹配,也会导致只能读取到首行记录。
  • 你在赋值完Recordset后立刻释放了Rst和Cnn对象,外部ADODB记录集依赖活动的连接和对象引用,提前释放会导致记录集后续遍历失败。

修复方案

方案1:调整ADODB记录集属性,适配Listbox绑定

修改记录集游标参数,改用客户端静态游标即可正常绑定,修改后代码如下:

Private Sub cdRefresh_Click()
    Dim Cnn As Object, Rst As Object
    Dim cnString As String, SqlStr As String
    
    cnString = "DRIVER=SQLite3 ODBC Driver;Database=E:\Sample Data\Sales1.db"
    Set Cnn = VBA.CreateObject("ADODB.Connection")
    ' 新增:设置连接使用客户端游标
    Cnn.CursorLocation = 3 ' adUseClient
    SqlStr = "Select * From Sales Limit 100;"
    Cnn.Open cnString
    Set Rst = VBA.CreateObject("ADODB.Recordset")
    With Rst
        Set .ActiveConnection = Cnn
        .Source = SqlStr
        .LockType = 3 '' adLockOptimistic
        ' 游标类型改用静态游标,兼容性更好
        .CursorType = 3 '' adOpenStatic
        .Open
    End With
    Debug.Print "records #"; Rst.RecordCount
    With Me.List0
        .RowSource = ""
        .RowSourceType = "Table/Query"
        .ColumnCount = Rst.Fields.Count
        .ColumnHeads = True
        Set .Recordset = Rst
    End With
    ' 注意:不要立刻释放Rst和Cnn,可将其设为窗体级变量避免被自动回收
    ' Set Rst = Nothing
    ' Set Cnn = Nothing
End Sub

方案2:遍历记录集填充值列表,兼容性最高

不需要维持连接和处理游标兼容问题,适合数据量不大的场景:

Private Sub cdRefresh_Click()
    Dim Cnn As Object, Rst As Object
    Dim cnString As String, SqlStr As String
    Dim fld As Object, rowStr As String
    
    cnString = "DRIVER=SQLite3 ODBC Driver;Database=E:\Sample Data\Sales1.db"
    Set Cnn = VBA.CreateObject("ADODB.Connection")
    SqlStr = "Select * From Sales Limit 100;"
    Cnn.Open cnString
    Set Rst = VBA.CreateObject("ADODB.Recordset")
    With Rst
        Set .ActiveConnection = Cnn
        .Source = SqlStr
        .LockType = 3 '' adLockOptimistic
        .CursorType = 1 '' adOpenKeyset
        .Open
    End With
    Debug.Print "records #"; Rst.RecordCount
    With Me.List0
        ' 改用值列表类型
        .RowSourceType = "Value List"
        .ColumnCount = Rst.Fields.Count
        .ColumnHeads = True
        ' 清空旧内容
        .RowSource = ""
        ' 填充列标题
        For Each fld In Rst.Fields
            rowStr = rowStr & fld.Name & ";"
        Next
        .AddItem Left(rowStr, Len(rowStr) - 1)
        ' 遍历所有记录填充行
        Do While Not Rst.EOF
            rowStr = ""
            For Each fld In Rst.Fields
                rowStr = rowStr & Nz(fld.Value, "") & ";"
            Next
            .AddItem Left(rowStr, Len(rowStr) - 1)
            Rst.MoveNext
        Loop
    End With
    ' 可正常释放资源
    Rst.Close
    Cnn.Close
    Set Rst = Nothing
    Set Cnn = Nothing
End Sub

内容的提问来源于stack exchange,提问作者Leo Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:06:07