我一直在向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数据库。
非常感谢提前
答案 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)
在未能使this或this适应我的需求之后,我终于
成功使用了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