VBA-SQL UPDATE/INSERT/SELECT to/from Excel worksheet

China☆狼群 提交于 2019-12-01 04:18:20

I'm posting the solution here since I can't mark his comment as the answer.


Thanks to @Jeeped in the comments, I now feel like an idiot. It turns out three of my field names were using reserved words ("name", "date", and "in"). It always seems to be a subtle detail that does me in...

I renamed these fields in my worksheet (table) and altered the appropriate code. I also had to Cast the input strings into the proper data types. I'm still working the rest of the details out, but here's the new query:

qry = "INSERT INTO <tbl> (empName, empDay, inTime, outTime, vac, sales)" & vbNewLine & _
                  "VALUES (CStr('<name>'), CDate('<date>'), CDate('<in>'), CDate('<out>'), " & _
                      "CBool('<vac>'), CDbl(<sales>));"

I needed the CDate() (instead of the #*#) so I could pass in a string. So CDate('<date>') instead of #<date>#

Consider using a relational database as backend instead of a worksheet for your project. You can continue to use the UI spreadsheet as a frontend. As a Windows product, the Jet/ACE SQL Engine can be a working solution plus it allows multiple user with simultaneous access (with record-level locking). Additionally, Jet/ACE comes equipped with its own SQL dialect for Database Definition Language (DDL) and Database Maniupulation Language (DML) procedures. And Excel can connect to Jet/ACE via ADO/DAO objects. The only difference of Jet/ACE compared to other RDMS is that it is a file level database (not server) and you cannot create a database using SQL. You must first create the database file using VBA or other COM defined language.

Below are working examples of VBA scripts (Clients and Orders tables) in creating a database with DAO, creating tables with ADO, executing action queries, and copying a recordset to worksheet. Integrate these macros into your project. Use error handling and debug.Print to help develop your app. If you do not have MS Access installed, the .accdb file will show in directory but with blank icon. There will be no user interface to manage the file except via code.

Sub CreateDatabase()
On Error GoTo ErrHandle
    Dim fso As Object
    Dim olDb As Object, db As Object
    Dim strpath As String
    Const dbLangGeneral = ";LANGID=0x0409;CP=1252;COUNTRY=0"

    strpath = "C:\Path\To\Database\File.accdb"

    ' CREATE DATABASE '
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set olDb = CreateObject("DAO.DBEngine.120")

    If Not fso.FileExists(strpath) Then
        Set db = olDb.CreateDatabase(strpath, dbLangGeneral)
    End If

    Set db = Nothing
    Set olDb = Nothing
    Set fso = Nothing

    MsgBox "Successfully created database!", vbInformation
    Exit Sub

ErrHandle:
    MsgBox Err.Number & " - " & Err.Description, vbCritical
    Exit Sub
End Sub

Sub CreateTables()
On Error GoTo ErrHandle
    Dim strpath As String, constr As String
    Dim objAccess As Object
    Dim conn As Object

    strpath = "C:\Path\To\Database\File.accdb"

    ' CONNECT TO DATABASE '
    constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strpath & ";"
    Set conn = CreateObject("ADODB.Connection")
    conn.Open constr

    ' CREATE TABLES (RUN ONLY ONCE) '
    conn.Execute "CREATE TABLE Clients (" _
                    & " ClientID AUTOINCREMENT," _
                    & " ClientName TEXT(255)," _
                    & " Address TEXT(255)," _
                    & " Notes TEXT(255)," _
                    & " DateCreated DATETIME" _
                    & ");"

    conn.Execute "CREATE TABLE Orders (" _
                    & " OrderID AUTOINCREMENT," _
                    & " ClientID INTEGER," _
                    & " Item TEXT(255)," _
                    & " Price DOUBLE," _
                    & " OrderDate DATETIME," _
                    & " Notes TEXT(255)" _
                    & ");"

    ' CLOSE CONNECTION '
    conn.Close
    Set conn = Nothing

    MsgBox "Successfully created Clients and Orders tables!", vbInformation
    Exit Sub

ErrHandle:
    MsgBox Err.Number & " - " & Err.Description, vbCritical
    Exit Sub

End Sub

Sub RetrieveDataToWorksheet()
On Error GoTo ErrHandle
    Dim strpath As String, constr As String
    Dim conn As Object, rs As Object
    Dim fld As Variant

    strpath = "C:\Path\To\Database\File.accdb"

    ' OPEN CONNECTION '
    constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strpath & ";"
    Set conn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")

    conn.Open constr
    rs.Open "SELECT * FROM Clients" _
             & " INNER JOIN Orders ON Clients.ClientID = Orders.ClientID;", conn

    ' COPY FROM RECORDSET TO WORKSHEET '
    Worksheets(1).Activate
    Worksheets(1).Range("A4").Select

    ' COLUMN NAMES '
    For Each fld In rs.Fields
        ActiveCell = fld.Name
        ActiveCell.Offset(0, 1).Select
    Next

    ' ROW VALUES '
    Worksheets(1).Range("A5").CopyFromRecordset rs

    ' CLOSE RECORDSET AND CONNECTION '
    rs.Close
    conn.Close

    Set conn = Nothing
    Set rs = Nothing
    Exit Sub

ErrHandle:
    MsgBox Err.Number & " - " & Err.Description, vbCritical
    Exit Sub
End Sub

Sub ActionQueries()
On Error GoTo ErrHandle
    Dim strpath As String, constr As String
    Dim conn As Object

    strpath = "C:\Path\To\Database\File.accdb"

    ' OPEN CONNECTION '
    constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strpath & ";"
    Set conn = CreateObject("ADODB.Connection")
    conn.Open constr

    ' APPEND QUERY '
    conn.Execute "INSERT INTO Clients (ClientID, ClientName)" _
                    & " VALUES (" & Worksheets(1).Range("A2") & ", '" & Worksheets(1).Range("B2") & "');"

    conn.Execute "INSERT INTO Orders (ClientID, Item, Price)" _
                    & " VALUES (" & Worksheets(1).Range("A2") & ", " _
                    & "'" & Worksheets(1).Range("C2") & "', " _
                    & Worksheets(1).Range("D2") & ");"

    ' UPDATE QUERY '
    conn.Execute "UPDATE Clients " _
                    & " SET Address = '" & Worksheets(1).Range("E2") & "'" _
                    & " WHERE ClientID = " & Worksheets(1).Range("A2") & ";"

    ' DELETE QUERY '
    conn.Execute "DELETE FROM Orders " _
                    & " WHERE ClientID = " & Worksheets(1).Range("A2") & ";"

    ' CLOSE CONNECTION '
    conn.Close
    Set conn = Nothing

    MsgBox "Successfully updated database!", vbInformation
    Exit Sub

ErrHandle:
    MsgBox Err.Number & " - " & Err.Description, vbCritical
    Exit Sub
End Sub
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!