【问题标题】:How to get an access query into excel vba as a range如何将访问查询作为范围访问excel vba
【发布时间】:2012-10-12 11:11:31
【问题描述】:

好的,所以我有这个函数,它使用我传递给它的查询字符串来查询数据库。 目前它在工作表中输出查询结果。 如何获得函数以将结果作为可在 VBA 中用于执行计算等的范围?然后我将如何引用这个范围?例如。获取结果中的“名称”列。

Function Access_Data(query As String)
 'Requires reference to Microsoft ActiveX Data Objects xx Library

Dim Cn As ADODB.Connection, Rs As ADODB.Recordset
Dim MyConn, sSQL As String

Dim Rw As Long, Col As Long, c As Long
Dim MyField, Location As Range

 'Set destination
Set Location = Sheets(1).Range("a1")
 'Set source
MyConn = "S:\Docs\Harry\Engine Client\Engine3.accdb"
 'Create query
sSQL = query

 'Create RecordSet
Set Cn = New ADODB.Connection
With Cn
    .Provider = "Microsoft.ACE.OLEDB.12.0"
    .Open MyConn
    Set Rs = .Execute(sSQL)
End With

 'Write RecordSet to results area
Rw = Location.Row
Col = Location.Column
c = Col
Do Until Rs.EOF
    For Each MyField In Rs.Fields
        Cells(Rw, c) = MyField
        c = c + 1
    Next MyField
    Rs.MoveNext
    Rw = Rw + 1
    c = Col
Loop
Set Location = Nothing
Set Cn = Nothing

结束函数

【问题讨论】:

    标签: excel vba ms-access


    【解决方案1】:
    Function Access_Data(query As String)
     'Requires reference to Microsoft ActiveX Data Objects xx Library
    
    Dim Cn As ADODB.Connection, Rs As ADODB.Recordset
    Dim MyConn, sSQL As String
    
    Dim Rw As Long, c As Long
    Dim MyField, Result
    
     'Set source
    MyConn = "S:\Docs\Harry\Engine Client\Engine3.accdb"
     'Create query
    sSQL = query
    
     'Create RecordSet
    Set Cn = New ADODB.Connection
    With Cn
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .CursorLocation = adUseClient
        .Open MyConn
        Set Rs = .Execute(sSQL)
    End With
    
     'Write RecordSet to results
    Redim Result(1 To Rs.RecordCount, 1 To Rs.Fields.Count)
    Rw = 1
    Do Until Rs.EOF
        c = 1
        For Each MyField In Rs.Fields
            Result(Rw, c) = MyField
            c = c + 1
        Next MyField
        Rs.MoveNext
        Rw = Rw + 1
    Loop
    Set Cn = Nothing
    
    Access_Data = Result
    End Function
    

    这将返回一个多维数组。范围必须引用工作表的某些部分:您不能创建“不可见”范围。 (尽管您可以使工作表的一部分不可见,但如果这就是您所追求的。)

    访问结果:

    Dim v, i As Long
    v = Access_Data("select ID, Name from somewhere")
    For i = 1 To UBound(v, 1)
        MsgBox v(i, 1) & " / " & v(i, 2)
    Next
    

    【讨论】:

    • 非常感谢。这就是我所追求的。那么,如果我想访问数组,我该怎么做呢?假设我的查询返回 2 列:ID 和名称。如何循环遍历 vba 脚本中的 2 列数据?
    • 完美,谢谢。我假设这些列将按照它们在查询中调用的顺序排列在数组中。再次感谢您的帮助
    • 我试过你的例子,当它说“Redim Result(1 to Rs.Rec.....”时,vba给我一个“内存不足”错误。任何想法为什么这样可以吗?
    • 当查询结果中的行数未知时可能会发生这种情况:尝试将rs.MoveLast: rs.MoveFirst放在该行之前,让它“预览”结果并计算行数。
    • 我明白了。显然它需要.CursorLocation = adUseClient,如上所示。
    【解决方案2】:

    示例如何从 SQL Server 读取数据并将结果插入工作表(此处使用集成安全性)。如果在插入新数据之前目标工作表为空,则使用 UsedRange 属性来引用它。或者算一下,rng是最左上角的单元格。

    Option Explicit
    
    ' Add reference to Microsoft ActiveX Data Objects Lib
    
    Public Sub main(): On Error GoTo Err_handler
    
        Dim cn As ADODB.Connection
        Set cn = New ADODB.Connection
    
        cn.ConnectionString = "Provider=SQLOLEDB;Data Source=MYSUPERSERVER;Initial Catalog=MYSUPERDATABASE;Integrated Security=sspi"
        cn.Open
    
        Dim rs As ADODB.Recordset
        Set rs = New ADODB.Recordset
    
        rs.ActiveConnection = cn
        rs.Open "SELECT * FROM MyTable"
    
        Dim fld As ADODB.Field
        Dim rng As Range
        Set rng = [a1]
        For Each fld In rs.Fields
            rng.Value = fld.Name
            Set rng = rng.Offset(0, 1)
        Next fld
    
        Set rng = rng.Offset(1, -rs.Fields.Count)
        rng.CopyFromRecordset rs
    
        rs.Close
        cn.Close
        Set rs = Nothing
        Set cn = Nothing
    
        Exit Sub
    
        Err_handler:
        MsgBox Err.Description
    
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-27
      • 2016-08-28
      相关资源
      最近更新 更多