Connecting to Access 2016 from Excel 2016 with VBA - vba

I'm very new to VBA, and I've been trying to write some code in Excel 2016 that will, when a button is pressed, take a range of cells and write them to a table that I've set up in an Access 2016 database. I'm working out of an .xlsm workbook right now.
I've been basing my code off of the bulk-insert method (building an SQL "INSERT INTO" statement) that the submitter posted as an edit to this previous StackOverflow question Using Excel VBA to export data to MS Access table .
So far, here is the VBA I have written (or at least the part of it dealing with the importing into Access). When I run it, I get the error "Run-time error '-2147467259 (80004005)': Could not find installable ISAM.". I think the issue is in my connection string, which I've been having trouble with since I can't find any examples of properly-formatted connection strings on the Internet that use Access 2016 and Excel 2016 (mostly older versions).
' Set up the transfer into Access
Dim dbPath As String, dbWb As String, dbWs As String, scn As String, dsh As String, ssql As String
Set cn = CreateObject("ADODB.Connection")
dbPath = Application.ActiveWorkbook.Path & "\MyDatabase.accdb"
dbWb = Application.ActiveWorkbook.FullName
dbWs = Application.ActiveSheet.Name
scn = "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" & dbPath
dsh = "[" & Application.ActiveSheet.Name & "$]" & "Data2" 'Data2 is the named range of data to be written to Access
' Open the connection with Access
cn.Open scn
' Create an SQL "Insert" statement using the name dsh developed earlier
ssql = "INSERT INTO DataPortfolio ([Field1], [Field2], [Field3]) "
ssql = ssql & "SELECT * FROM [Excel 16.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh
' Execute the SQL statement
cn.Execute ssql
Can anyone see where I may be going wrong? I assume it's in the connection string (scn), but I'm not sure.
Any help is appreciated! Many thanks.

Related

Insert Query/Select Query works in access, but not in vba

I have created a query that works great with no errors in Access, and while trying to translate this to my vba setup I can't figure out why I am not getting any values, even though the query clearly works in access, and causes no errors on the VBA side.
Pulling my hair out here, I have created a side table to see if I could "pseudo-insert" the calculated value, but I get the same issue as above - insert works with no errors in access, goes through in vba with no issues, but doesn't actually insert any data.
I have copied the string queries while pausing code to make sure EVERYTHING matches up between the Access query that works and the VBA query, and haven't found any differences.
I read somewhere since I am trying to pull a "first line" data piece that there may be some HDR setting that I could change, but when I tried to apply any fixes I found they opened another instance of excel and opened a dialogue box.
Please let me know what I am doing wrong here.
Public Function PullNextLineItemNumB(QuoteNum) As Integer
Dim strQuery As String
Dim ConnDB As New ADODB.Connection
Dim myRecordset As ADODB.Recordset
Dim QuoteModifiedNum As String
ConnDB.Open ConnectionString:="Provider = Microsoft.ACE.OLEDB.12.0; data
source=" & ThisWorkbook.Path & "\OEE Info.accdb"
'Query to try and make Access dump the value "18" into the table so I can
grab it after the query is finished, sidestepping excel not working
strQuery = "INSERT INTO TempTableColm (TempColm) SELECT
MAX(MID([Quote_Number_Line],InStr(1,[Quote_Number_Line]," & Chr(34) & "-"
& Chr(34) & ")+1)) AS MaxNum from UnifiedQuoteLog where Quote_Number_Line
like '" & QuoteNum & "*'"
ConnDB.Execute strQuery
'Original query, returns "18" as expected in Access, and null or empty in
the recordset
strQuery = "SELECT MAX(MID([Quote_Number_Line],InStr(1,
[Quote_Number_Line]," & Chr(34) & "-" & Chr(34) & ")+1)) from
UnifiedQuoteLog where Quote_Number_Line like '" & QuoteNum & "*'"
Set myRecordset = ConnDB.Execute(strQuery)
Do Until myRecordset.EOF
For Each fld In myRecordset.Fields
Debug.Print fld.Name & "=" & fld.Value
Next fld
myRecordset.MoveNext
Loop
myRecordset.Close
Set myRecordset = Nothing
ConnDB.Close
Set ConnDB = Nothing
End Function
Actual output from access is "18" which is expected, output from excel's vba recordset is always null or empty string.
It appears I solved the problem, while looking into this apparently the excel operator using ADODB with access is % for LIKE and NOT * (because reasons). As soon as I made that change everything started working.
Can someone explain why that is a thing? I really want to understand why this was a design choice.

How to copy data from non-linked to linked table in Access 2010 using VBA

So what I'm trying to do is to either copy data from an Access local table to a linked table on a SQL Server. I'd like this to work via a macro so it can be triggered upon opening a report. Or I could just bypass the linked table and insert directly to the remote server.
What I'm having a difficult time finding is the proper syntax to accomplish this. It should be very easy but apparently it's not.
Public Sub CopyPT()
Dim strSQL As String
Dim strConnect As String
Dim strDatabase As String
Dim strTableName As String
ODBC_String = "ODBC;DRIVER={SQL Server};SERVER=aaa;DATABASE=bbb;UID=ccc;PWD=ddd;" _
& "LANGUAGE=us_english;TRUSTED_CONNECTION=No"
' Id also like to truncate the Destination table here too
strSQL = "SELECT * INTO dbo_DESTINATION_TABLE IN [" & ODBC_String & "]" _
& " FROM [ACCESS_LOCAL_TABLE];"
DoCmd.RunSQL strSQL
MsgBox "Success!"
End Sub
Either I need to get the proper format for the IN statement, which doesn't appear to have ODBC option, or I need another method to copy to the linked table. Such a simple copy and paste line by line macro - which I also can't find anywhere since most sane people would just write a query.
Thanks!

Error Running Crosstab Queries in Excel

I have an issue running an SQL query on an excel spreadsheet which I'm looking for some help on:
I'm using Excel and Access 2007 on a windows xp machine sp3.
I recently found this post which showed me how to run an Access crosstab query on a worksheet in excel.
http://datapigtechnologies.com/blog/index.php/running-crosstab-queries-in-excel/
I am running the below code in excel and attempting to pivot (crosstab) my data.
Everything was running perfectly well. But when I set my excel workbook to read-only, which I need to do, I suddenly started to get errors.
When I run the below code with the workbook as read-only, I get the following error:
External table is not in the expected format.
-2147467259 (80004005)
Dim Myconnection As adodb.Connection
Dim Myrecordset As adodb.Recordset
Dim Myworkbook As String
Dim strSQL As String
Set Myconnection = New Connection
Set Myrecordset = New Recordset
'Identify the workbook you are referencing
Myworkbook = Application.ThisWorkbook.FullName
'Open connection to the workbook. This is where I get the first error.
Myconnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Myworkbook & ";" & _
"Extended Properties=Excel 8.0;" & _
"Persist Security Info=False"
'Build SQL Statement. This statement runs perfectly well when I copy and paste it into Access
strSQL = "TRANSFORM Last(Field1) AS LastOfField1 " & _
"SELECT Field7, Field6 AS CLIENT, [Field2], [Field3], [Field4], Field5 " & _
"FROM [RawData$A1:K1000] " & _
"GROUP BY Field7, Field6, [Field2], [Field3], [Field4], Field5 " & _
"ORDER BY Field6 " & _
"PIVOT Field8 ;"
'Load the Query into a Recordset
Myrecordset.Open strSQL, Myconnection, adOpenStatic
So, I read a post which suggested I try changing my connection string. So I changed it to the following:
Myconnection.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & Myworkbook & ";" & _
"Extended Properties=Excel 12.0;" & _
"Persist Security Info=False"
After I changed it, the connection opened, however, I then got at error on the following line:
'Load the Query into a Recordset
Myrecordset.Open strSQL, Myconnection, adOpenStatic
No value given for one or more required parameters.
-2147217904
There are no parameters in my query and I've checked all the field names and they are spelt correctly. The SQL is good when run in MS Access.
After some investigation, if I change my sql to a standard select query, it runs. So maybe this connections string does not like crosstab queries.
Also, I work in a controled IT environment so I can't run any registry fixes, if needed.
I'm a bit stuck now. Any help would be appreciated.
Just a quick idea. As far as you have a macro in Excel file I believe it's saved as .xlsm. Therefore I think you need the following type of ConnectionString (change where required):
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsm;
Extended Properties="Excel 12.0 Macro;"
Source: www.ConnectionStrings.Com

ado in excel, inserting records into access database

First time asker, usually I can find the answer by searching, but my google-fu seems weak today.
I have an excel workbook connecting to an access 2003 database to insert usage records
The code i'm using is:
sdbpath = ThisWorkbook.Path & "\Data.mdb"
sCommand = "INSERT INTO Usage VALUES('" & Environ("Username") & "',#" & Now() & "#)"
Dim dbCon As New ADODB.Connection
Dim dbCommand As New ADODB.Command
dbCon.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sdbpath & "; Jet OLEDB:Database Password=TestPass;"
dbCommand.ActiveConnection = dbCon
dbCommand.CommandText = sCommand
dbCommand.Execute
dbCon.Close
The code fails on the line dbCommand.Execute with run-time error '-2147217900 (80040e14)' : Automation error.
The database its trying to insert the record into contains one table, usage, with two columns - UserID and AccessDate, formatted as text and DateTime respectively.
The odd part is the connection string seems OK, since it fails after the connection is already open, yet if I take the sCommand value before the execute is run, then paste it into a query in access and execute that - it runs fine!
In case it was access struggling with the datetime format i've tried switching it to text (and the hashtags in the code) but that still fails. I've also tried specifying the column names too.
Can anyone shed some light on what i'm doing wrong? I've never had so much trouble with a very simple bit of SQL.
Thanks in advance!
In Access we need to specify the field-names. Even so, I found that I needed to wrap the table-name in square brackets before it would insert:
sCommand = "INSERT INTO [Usage] (UName, SomeDate) VALUES ('" & Environ("Username") _
& "',#" & Now() & "#)"

Update SQL database through excel VBA

First off I understand the process of having a user update a db via excel runs alot of risks, I appreciate any advise against this method but lets speculate that I have the perfect user who never makes mistakes :)
So firstly I've managed to access a stored procedure via vba in excel to pull data based on a parameter in a particular cell. Now if I wanted to update these fields how would I go about doing this?
My first suggestion would be to create a stored procedure that updates based on all the fields in spreadsheet. If this is the right avenue to follow how would I loop through all the rows?
Any other suggestions people could offer would be greatly appreciated.
Some notes on updating SQL Server. This [ODBC;FileDSN=z:\docs\test.dsn] can be any valid connection string.
Dim cn As Object, rs As Object
Dim scn As String, sSQL As String, sFile As String
sFile = ActiveWorkbook.FullName
scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sFile _
& ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
''Late binding, so no reference is needed
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open scn
sSQL = "SELECT * INTO [ODBC;FileDSN=z:\docs\test.dsn].FromXL " _
& "FROM [Sheet8$]"
cn.Execute sSQL, recs
Debug.Print recs
sSQL = "INSERT INTO [ODBC;FileDSN=z:\docs\test.dsn].FromXL " _
& "SELECT * FROM [Sheet8$]"
cn.Execute sSQL, recs
Debug.Print recs
sSQL = "UPDATE [ODBC;FileDSN=z:\docs\test.dsn].FromXL x " _
& "INNER JOIN [Sheet8$] w " _
& "ON x.ID = w.ID SET x.Field =w.field"
cn.Execute sSQL, recs
Debug.Print recs
rs.Open "SELECT * FROM [ODBC;FileDSN=z:\docs\test.dsn].FromXL", cn
Debug.Print rs.GetString
You have to familiarize yourself with Microsofts COM Object. My VBA is rusty so watch out.
str t = Range("A1:A4").Value
If you are doing a lot of dynamic processing you should make yourself a wrapper method to some of the microsoft stubs.
function getValue(str location)
return Range(location + ":" + location).Value
end function
I've done large VBA projects before and reading values from the front end is a costly operation. You should set up objects to hold these values so you never have to read the same value more than once.
Lastly, you need lots and lots of validation, from everything between checking the database to make sure the user has the latest version to making sure that the spreadsheet isn't in print view (because this affects the range being able to read).
Verifying the version is important because you are going to need to release fixes and you need to verify that those fixes are being used.