在Excel中使用VBA访问SQLite数据库

时间:2017-02-28 12:46:58

标签: vba excel-vba sqlite excel

我一直在向VBA添加MS Access数据库,以便对船只进行一些分析。但是,数据库现在已更改为SQlite,我不知道如何从VBA访问。我已经尝试过使用GitHub的SQLiteForExcel,但我不知道它是如何工作的,即使是这些例子也是如此。我访问Access数据库的代码如下:( db_path是我的Access数据库的超链接)

Sub query_db()

On Error GoTo Errorhandler
Dim v_db As DAO.Database
Dim rst As DAO.Recordset
Dim vessels_db As Variant
Dim strSQL As String
Dim i As Long
Dim ws As Worksheet

Set ws = Worksheets("results")
ws.Select

vessels_db = [db_path]
Set v_db = OpenDatabase(vessels_db)


Worksheets("results").Select
[x_0].Select
Range(Selection, Selection.Offset(40000, 1)).ClearContents

strSQL = " SELECT Vessels.vsl_name, Vessels.dwt FROM Vessels " & _
          " GROUP BY Vessels.vsl_name, Vessels.dwt ORDER BY Vessels.vsl_name ; "
Set rst = v_db.OpenRecordset(strSQL)
...

有没有人知道如何使用SQLiteForExcel更改此代码,以便我可以访问SQLite数据库。

非常感谢提前

3 个答案:

答案 0 :(得分:12)

MS Access'默认引擎,Jet / ACE和SQLite共享相同的质量,因为它们是文件级数据库,其中数据库文件位于磁盘级别的目录中,而不是服务器级数据库(SQL Server,Oracle,MySQL,Postgres)。

要在后端数据库之间进行流畅的交换,请考虑使用ADO在Excel中连接数据库。现在您使用DAO,这是MS Access的默认连接层。

您需要的第一件事是下载SQLite ODBC Driver,一个与您的版本匹配的版本(最有可能是SQLite 3)和Windows位级别(32/64位)。相比之下,您的计算机很可能已经安装了MS Access ODBC驱动程序。完成后,只需设置连接字符串:

<强> SQLite的

Dim conn As Object, rst As Object

Set conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")

' OPEN CONNECTION
conn.Open "DRIVER=SQLite3 ODBC Driver;Database=C:\Path\To\SQLite\Database.db;"

strSQL = "SELECT Vessels.vsl_name, Vessels.dwt FROM Vessels " & _
         " GROUP BY Vessels.vsl_name, Vessels.dwt ORDER BY Vessels.vsl_name ; "

' OPEN RECORDSET
rst.Open strSQL, conn

' OUTPUT TO WORKSHEET
Worksheets("results").Range("A1").CopyFromRecordset rst
rst.Close

' FREE RESOURCES
Set rst = Nothing: Set conn = Nothing

MS Access

作为比较,使用ADO,您只需简单地切换引用ODBC驱动程序的连接字符串,以用于不同的数据库后端。请注意,数据库源是一个目录路径:

Dim conn As Object, rst As Object

Set conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")

' OPEN CONNECTION
conn.Open "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\Path\To\Access\DB.accdb;"

strSQL = "SELECT Vessels.vsl_name, Vessels.dwt FROM Vessels " & _
         " GROUP BY Vessels.vsl_name, Vessels.dwt ORDER BY Vessels.vsl_name ; "

' OPEN RECORDSET
rst.Open strSQL, conn

' OUTPUT TO WORKSHEET
Worksheets("results").Range("A1").CopyFromRecordset rst
rst.Close

' FREE RESOURCES
Set rst = Nothing: Set conn = Nothing

答案 1 :(得分:1)

很好的解决方案,谢谢Parfait!

只需做一个小小的快速校正,您实际上需要进行以下操作:

rst.Open strSQL, conn, 1, 1

这样,完整的解决方案将是:

Dim conn As Object, rst As Object

Set conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")

' OPEN CONNECTION
conn.Open "DRIVER=SQLite3 ODBC Driver;Database=C:\Path\To\SQLite\Database.db;"

strSQL = "SELECT Vessels.vsl_name, Vessels.dwt FROM Vessels GROUP BY Vessels.vsl_name, Vessels.dwt ORDER BY Vessels.vsl_name ;"

' OPEN RECORDSET
rst.Open strSQL, conn, 1, 1

' OUTPUT TO WORKSHEET
Worksheets("results").Range("A1").CopyFromRecordset rst
rst.Close

' FREE RESOURCES
Set rst = Nothing: Set conn = Nothing

这将使rst包含您从查询中获得的整个表。

答案 2 :(得分:0)

在未能使thisthis适应我的需求之后,我终于
成功使用了here的Marcus Mangelsdorf的改进。
没有显示他的代码-它在链接中。我只是把它放在自己的模块中
名为“ WSHreturn”,将其更改(以及功能名称/ Args)以返回 外壳对象,并移动/添加了其他代码以进行挖掘。这很容易设置 很快并且将成为LINQ的基础吗?类型功能。

Sub VBALimposterQ()
    'With >1 field, SQLite default delim is Pipe "|"
    Const sqlInit As String = "c:\users\user\sqlite3.exe :memory:"
    Const sqlCreat As String = "CREATE Table Nums (n1 INTEGER NOT NULL, n2 INTEGER NOT NULL);"
    Const sqlIns0   As String = "INSERT INTO Nums VALUES (33,99);"
    Const sqlIns1   As String = "INSERT INTO Nums VALUES (11,22);"
    Const sqlIns2   As String = "INSERT INTO Nums VALUES (44,55);"
    Const sqlQry   As String = "SELECT RowId, n1, n2 from Nums;"
    Dim Ax, Axi, i, S
    Dim sqlShell As Object  'REF: Windows Script Host Object Model
    Set sqlShell = WSHreturn.getWShell(sqlInit) 'Qualifying Mssr. Mangelsdorf's code
    With sqlShell                   'with module name I gave it. 
        .StdIn.Write sqlCreat       'Thx Mathieu Guindon!
        .StdIn.Write sqlIns0
        .StdIn.Write sqlIns1
        .StdIn.Write sqlIns2
        .StdIn.Write sqlQry
        
        .StdIn.Close
        S = .StdOut.ReadAll
        Ax = Split(S, vbCrLf, , vbTextCompare)
        .Terminate
    End With
    
    For i = 0 To UBound(Ax)
        Axi = Ax(i)
        Debug.Print Axi
    Next i
End Sub