I would like to have a simple tool built using excel vba to update existing records and also to add new records to an access database. The goal is to use only 2 clicks to complete the action.
First Part - Resolved (Retrieve Data from Access Database): I have created a excel table that queries data from access database in a tab named "Mapping Matrix" , so everytime an update is required, will use a function to refresh the data.
So, I will update the existing data in the Sheet "Mapping Matrix", or even add new data before I will require this data to be propagated into my access database.
Second Part - Please help (Update the access database "Mapping" using the excel spreadsheet tab "Mapping Matrix")
Here is what I have done to try update existing records with that queried in Excel. However I am faced with this error message that says "The INSERT INTO statement contains the following unknown field name: 'F1'. Make sure you have typed the name correctly, and try the operation again."
Do not quite understand how to fix the error, as I have not applied F1 in the code.
Note: I will require this data to replace that in the access database (not adding on to existing data)
Thanks all in advance!
Public Sub Populate_Data()
Set cn = CreateObject("ADODB.Connection")
dbPath = "Access Database Path.mdb"
dbWb = Application.ActiveWorkbook.FullName
dbWs = Application.ActiveSheet.Name
scn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dbPath
dsh = "[" & Application.ActiveSheet.Name & "$]"
cn.Open scn
ssql = "INSERT INTO Mapping ([Field1], [Field2], [Field3]) "
ssql = ssql & "SELECT * FROM [Excel 8.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh
cn.Execute ssql
End Sub
Related
I have issues with a simple "SELECT" query that is coded as the following in Excel using VBA -
CommodityInfo = ObjAccess.CurrentProject.Connection.Execute( _
"SELECT TOP 1 Commodity FROM [" & CustomerName & "]")
It works fine. But then what I'm struggling with is using the information provided to me within the CommodityInfo variable. I can see in my Locals window that the information is there to be accessed I just wouldn't know how to use it to output the value.
Item 1 is clearly displayed so its being accessed. How do I pull out the value information from item 1 and use it as I would a string..?
Count can be used by simply stating CommodityInfo.Count, I tried doing something like ComVal = CommodityInfo(1).Value but I get the error 'Item cannot be found in the collection corresponding to the requested name or ordinal'.
Any help would be appreciated.
As noted in comments, your code is opening a recordset object, not pulling a single value.
Since field index is zero based, use 0 for first field instead of 1: ComVal = CommodityInfo(0) to pull single field value from recordset to simple variable.
Or append Execute command with field index reference to extract single field value directly to simple variable.
CommodityInfo = ObjAccess.CurrentProject.Connection.Execute( _
"SELECT TOP 1 Commodity FROM [" & CustomerName & "]")(0)
Here is alternative to pull a single value instead of opening a recordset:
CommodityInfo = ObjAccess.DLookup("Commodity", "[" & CustomerName & "]").
In my test, it ran faster.
It is possible to pull data from Access without instantiating an Access application object variable. I found this code ran fastest.
Dim cn As New ADODB.Connection
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source='your access database filepath'"
CommodityInfo = cn.Execute("SELECT TOP 1 Commodity FROM [" & CustomerName & "]")(0)
Or
Dim cn As New ADODB.Connection
cn.Open "Provider=MSDASQL.1;DSN=Excel Files;DBQ=" & ThisWorkbook.FullName & ";HDR=Yes';"
CommodityInfo = cn.Execute("SELECT TOP 1 Commodity FROM [" & CustomerName & "]" IN 'your database filepath'")(0)
I'm using the following code to export information from an excel file to an access database. It worked fine last time I used it but ever since I started it up today I've been running into the following issue.
Public Sub Export_to_ACCDB()
Set cn = CreateObject("ADODB.Connection")
dbPath = Application.ActiveWorkbook.Path & "\Newdatabase.accdb"
dbWb = Application.ActiveWorkbook.FullName
dbWs = Application.Worksheets("DATABASE").Name
scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
dsh = "[" & Application.ActiveSheet.Name & "$]"
cn.Open scn
'ssql = "INSERT INTO Database ([Column1],[Column2],[Column3]) "
ssql = ssql & "SELECT * FROM [Excel 8.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh
cn.Execute ssql '<<< The error occurs here
End Sub
I get the following error running this code:
Run-time error '-2147217900 (80040e14)':
The INSERT INTO statement contains the following unknown field name: 'F12'. Make sure you have typed the name correctly, and try the operation again.
I don't have a field name called 'F12' in either my excel file or my access database. I can't seem to figure out what's going on.
Column headers are written correctly.
Column headers do not contain spaces or other irregularities.
EDIT:
Seems like Excel thinks you got a 12th column (maybe by accidentally entering something). Mark column L and delete it #FunThomas
This seemed to be the problem. I had to delete all the columns after the last one which contained the correct fieldname. Now it's working again.
I am writing a small application in Excel 2002 and I need to store numbers in some format, it can be a string.
The tables I have a 1:1 relationship and other table is just a table of one column so using access is not necesary and having to have another file is something I'd like to avoid.
So, I want to store it in separate sheets.
However, I like the benefits of SQL for querying and I need it.
I tried using some ADODB connection strings to reach this but I cannot achieve it.
I used the following code:
Dim cn As Object, rs As Object, output As String, sql As String
'---Connecting to the Data Source---
Set cn = CreateObject("ADODB.Connection")
With cn
.Provider = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;"
.ConnectionString = "Data Source=" & ThisWorkbook.FullName & ";" & "Excel 8.0;HDR=Yes;IMEX=1"
.Open
End With
Also, do I have to use ODBC or should I use OLE DB? I don't know if OLE DB could be used to query in excel files.
Also, is it possible to do inserts with SQL using this ODBC or OlE DB?
I tried different providers in the connection string, and I checked the ADO references to be available.
Also, I get this error:
"Error 3706. The specified provider could not be found. It may not be installed properly."
Connection issue
First, there was an error in your Provider string, it should not contain the part with Data Source=C:\MyExcel.xls; since this is part of the connection string. So it should look like this:
.Provider = "Provider=Microsoft.Jet.OLEDB.4.0;"
.ConnectionString = "Data Source=" & ThisWorkbook.FullName & ";" & "Excel 8.0;HDR=Yes;IMEX=1"
ODBC vs OLEDB
I've never used ODBC, but based on this answer, you can't use it to query an Excel file, so OLEDB is the way to go.
Insert Statement
Once you have a working ADODB connection, insert query should work as hoped. I'm providing an example below that worked for me, but there is a few caveats:
I'm using the ACE.OLEDB.12.0 instead of JET.OLEDB.4.0 with Excel for Microsoft 365 MSO (Version 2112 Build 16.0.14706.20000) 64-bit on Windows 10.
I'd suggest to set Mode=ReadWrite in your connection string to avoid potential writting permission issues (but it might work even without it.).
Regarding the IMEX setting, I was having errors when it was set to IMEX=1, so I switched to IMEX=0 (see related question.
The example
With a workbook named Data.xls with the first sheet named Data and the following data :
Data for copy-paste
I can run the following:
Dim wb As Workbook
Set wb = Workbooks("Data.xls")
Dim ws As Worksheet
Set ws = wb.Worksheets("Data")
'Create connection
Dim conn As Object
Set conn = CreateObject("ADODB.Connection")
With conn
.Provider = "Microsoft.ACE.OLEDB.12.0;"
.ConnectionString = "Data Source=" & wb.FullName & ";" & "Excel 8.0;HDR=Yes;IMEX=0;Mode=ReadWrite;"
.Open
End With
'Compose the INSERT statement.
Dim query As String
Const sep = ", "
query = "INSERT INTO [" & ws.Name & "$] " & _
"(Id, Name, Age) " & _
" VALUES (" & _
4 & sep & _
"'" & "Joe" & "'" & sep & _
40 & _
")"
'Execute the statement.
conn.Execute query, adCmdText
'Close the connection
conn.Close
And it should insert the data as follow:
Should you use ACE or JET?
If JET works for you, you might as well use it. Based on this article , you should also have the 32-bit version of ACE available with Windows 7 to work with Excel 2002 (32-bit), but based on your comment it seems like it's causing some problems.
See also some interesting answer about JET vs ACE.
OK. I'm sorry for wasting everyone's time. Like a DUMMY i didn't think simple solution first. The amount of data i am dealing with isn't too large and will actually work better just exporting to an excel file (i'm pretty sure). I would like to thank all that helped (June7, Parfait, and HansUp). The support you guys (everyone on this forum) give has made my job easier by far.
I'm trying to export an Excel Table from my active excel file to an Access database file.
I was getting an error at
"con.excecute sql"
"Run-time error '-2147467259 (80004005)': [Microsoft][ODBC Microsoft Access Driver] Query input must contain at least one table or query."
Sub updateAccess()
Dim con As New ADODB.Connection
Dim connectionString As String
Dim sql, newTable As String
Filename = "C:\Desktop\Quote-Size_Contacts.accdb"
connectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" & Filename
con.Open connectionString
' Save current table ("ContactsTbl_Data") to another table ("ContactsTbl_Data_yyyymmdd_hh_mmss")
newTable = "Quote-Size_Contacts_" & Format(Date, "yyyymmdd") & "_" & Format(Now, "hhmmss")
sql = "SELECT CODE, STORE INTO " & newTable & "FROM ContactsTbl_Data"
con.Execute sql
' Delete rows of current table ("ContactsTbl_Data")
sql = "DELETE FROM ContactsTbl_Data"
con.Execute sql
' Insert new rows into current table ("ContactsTbl_Data") from my Excel Sheet
sql = "INSERT INTO ContactsTbl_Data ([CODE], [STORE]) " & _
"SELECT * FROM [Excel 8.0;HDR=YES;DATABASE=" & ThisWorkbook.FullName & "].[" & ThisWorkbook.Sheets("Sheet2").Name & "$]"
con.Execute sql
con.Close
Set con = Nothing
End Sub
EDIT::
I'm not sure standard protocol for these forums on cleaning up the code and asking more questions so i'll just put an "Edit" here.
I applied the suggestions and matched the fields it was trying to save to my access file. I now get the error: "Method 'Execute' of object '_Connection' failed"
Public Sub updateAccess()
Dim con As New ADODB.Connection
Dim connectionString As String
Dim sql, newTable As String
Filename = "C:\Desktop\Quote-Size_Contacts.accdb"
connectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source='" & Filename & "'"
con.Open connectionString
' Save current table ("ContactsTbl_Data") to another table ("ContactsTbl_Data_yyyymmdd_hh_mmss")
newTable = "Quote-Size_Contacts_" & Format(Date, "yyyymmdd") & "_" & Format(Now, "hhmmss")
sql = "SELECT Company, Contact, Initials, Position, Address, AddressContd, CityStatePost, MainNo, CellNo, FaxNo, Email INTO [" & newTable & "] FROM ContactsTbl_Data"
con.Execute sql
' Delete rows of current table ("ContactsTbl_Data")
sql = "DELETE FROM ContactsTbl_Data"
con.Execute sql
' Insert new rows into current table ("ContactsTbl_Data") from my Excel Sheet
sql = "INSERT INTO ContactsTbl_Data ([Company], [Contact], [Initials], [Position], [Address], [AddressContd], [CityStatePost], [MainNo], [CellNo], [FaxNo], [Email]) " & _
"SELECT * FROM [Excel 12.0 Xml;HDR=Yes;Database=" & ThisWorkbook.FullName & "].[" & ThisWorkbook.Sheets("Sheet2").Name & "$]"
con.Execute sql
con.Close
Set con = Nothing
End Sub
See if this helps.
Table name has hyphen (-) character so use [ ] characters to delimit. Add a space in front of FROM so text doesn't run together in compiled SQL string.
sql = "SELECT CODE, STORE INTO [" & newTable & "] FROM ContactsTbl_Data"
As for connection to Access database, don't think I've ever used or seen Driver, I use Provider:
connectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source='" & Filename & "'"
I have this tool where employee information needs to be updated. I call in the MDB data to excel in one sheet. Now I use vlookup to see what is there and change it if needed.
I have tried some tricks however some thing seems to be wrong.. please help.
Sub update()
Dim cn As Object
Dim rs As Object
Dim a As String
strFile = "D:\temp excel\EIM.mdb"
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile & ";"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
a = Sheet2.Range("D4")
strSQL = "SELECT * FROM EIM WHERE EIM.NBKID=" & a
rs.Open strSQL, cn
strSQL = "UPDATE EIM SET EIM.Person#=('" & Sheet2.Range("D5") & "')WHERE EIM.NBKID=('" & Sheet2.Range("D4")
cn.Execute strSQL
End Sub
In the above code the file EIM has a table called EIM with NBKID and Person# fields.
So sorry about not explaining the request clearly, I have this tool which allows people to update there information. I cannot use access to manipulate it as not all have access available and even it would be available I do not want to give them access to master database.
We have more than 500 employee's when ever some one moves out of one role to another or when someone leaves the organization. A manager has to request for hierarchy report which takes time to come.
Instead of going through that I want this tool to maintain record of all the employees, here nbkid is nothing but system id and person# is employee number or id.
I have a code to update the information however if someone needs to edit it due to some change to their role than I need another set of code.
By doing it in excel it is easy to manage - no additional training.
I have this button which should update the change made to the vaules updated in excel sheet. I dont want it to check if the record change, I just want it to use update.
When I run the above code I get error saying "No value given for one or more reqired parameters."
I agree as to the point of modifying the data in excel as opposed to directly in access however I just spotted that your SQL statement seems to be slightly wrong. Try changing
WHERE EIM.NBKID=('" & Sheet2.Range("D4")
to
WHERE EIM.NBKID=" & Sheet2.Range("D4")
Note the removal of the single quote mark as the original statement would have been seen as
WHERE EIM.NBKID=('123456
You are missing a space between the bracket and where:
strSQL = "UPDATE EIM SET EIM.Person#=('" & Sheet2.Range("D5") _
& "') WHERE EIM.NBKID=('" & Sheet2.Range("D4")
The single quotes are needed if NBKID is a text field:
WHERE EIM.NBKID=('" & Sheet2.Range("D4") & "'"
Or for a numeric field:
WHERE EIM.NBKID=(" & Sheet2.Range("D4")
I doubt that this is a date field, but if it was, it would take hash (#) delimiters.
Just as a point of efficiency, I am not sure why you actually opened the recordset at all. The cn.Execute line works very well by itself.
I would also write a function you could call and pass it parameters to, depending on what you are trying to do. If you passed in the ID, the strFileName and the strSQL, then you have an all-purpose function.
I have a prebaked SQL string somewhere on a key pair "SELECT * from tblFoo WHERE tblFoo.ixFoo = {key}". I then get the parameter and do a Replace on the strSQL to insert the key.
Sub Update(strFile as string, strKey As String, strPerson as string)
Dim cn As Object : Set cn = CreateObject("ADODB.Connection")
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile & ";"
cn.Open strCon
strSQL = "UPDATE EIM SET EIM.Person#="{person}" WHERE EIM.NBKID={key}"
strSQL = Replace(strSQL, {person}, strPerson, 1)
strSQL = Replace(strSQL, {key}, strKey, 1)
cn.Execute strSQL
End Sub
If speed of code greater than need for speed of execution (which is what I can gather here), then this approach alleviates all the quote/doublequote confusion
I would set aside a sheet in the book that had all the strSQL statements there, if you had a few. You could even pass this in and do the replace within Excel with its much faster native execution speed.
You now have a function you can pick up and reuse. If you are serious about using VBA, reuse heavily. It saves so much time. VBA jobs tend to place a high amount of pressure on time to produce.
I presume that you have removed error trapping to save us the hassle of reading it.