Adding column to worksheet in Excel with OLEDB - excel

Hello
I'm trying to add new column to the Excel worksheet by command
ALTER TABLE [MyTable] ADD COLUMN Field_dest nvarchar
But on execution of the command got exception "Invalid operation"
I tried table name with and without $ at the end , but got the same result
My questions are
1) Is there some wrong in the command above?
2) Is command ALTER table supported for excel table ?
3) Is the alternative way to add column into excel worksheet - preferable via OLEDB ?
Thanks in advance

Alter table will not work, AFAIK, however, you can Create Table or Select Into, which will allow you to create a new sheet. I cannot get this to run against an open sheet.
Dim cn As Object
Dim scn As String
Dim sSQL As String
strFile = "C:\Docs\test.xls"
scn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
strFile & ";Extended Properties=""Excel 8.0;HDR=Yes;"""
Set cn = CreateObject("ADODB.Connection")
cn.Open scn
''Note that there is no $ on the sheet to be created
sSQL = "SELECT *,'' As NewField INTO [Sheet17] FROM [Sheet4$]"
''Jet data types
sSQL = "CREATE TABLE [Sheet8] (AText text, ANother text)"
cn.Execute sSQL
If you run against an open file, you will get an error to the effect that Sheetn does not exist.

You can use Create Table instead of Alter Table.
Just use your existing table name, then your columns adds to existing sheet
CREATE TABLE [ExistingSheet$] (ID char(255), oldField1 char(255), newField2 char(255))
it's work!

Related

Access Database Engine could not find object - object is Excel named range

This is something that has had me going round and round in circles for a while now, essentially all I would like to do is to insert the values of an Excel dynamic range into an Access table.
I have had success in doing this by referencing the range as for example, however to make things a little more self sufficient I would prefer to use a dynamic range.
The code I have is as follows:
Sub ExportDistDatatoSql()
Dim cn As ADODB.Connection
Dim STRQUERY As String
Set cn = New ADODB.Connection
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & ThisWorkbook.Path & "\uMyDB.accdb;"
.Open
End With
ssql = "INSERT INTO Crude_Prods_DB Select * from [Excel 12.0;HDR=YES;DATABASE=C:\TEST\mysheet.xlsm].[n_range]"
cn.Execute ssql
End Sub
The error I am seeing is attached and I have checked an [n_range] does exist in the workbook.
[error seen when attempting to insert data into access table from excel named range]
Any suggestions would be much appreciated.
I learned this the hard way. A dynamic range is resolved only when Excel runs, thus it doesn't exist when you just read the file.
Only a saved and fixed Named Range can be read by Access.

UDF to retrieve data from access data base

How do i create a UDF to retrieve data from the access database.
I can retrieve the data via sql query using vba & click button. the data will be in the recordset. I simply paste it to any cell.
Now my question is: How can I create a user defined function to do the same. That is to say, when I enter something like =bdh(pricing date,product tag) into any Excel cell, all the data will be returned and pasted below the cell where I entered the self-defined formula.
If you are familiar with bloomberg API, i want to build a function similar to bdh function.
Perhaps you could work around a simpler idea? For example the code snippet below depends on the user selecting two input cells to control the output. You could add a menu item to run the code.
Sub GetMSAccess()
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim selrange As Range
Set selrange = Selection
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Z:\Docs\Test.accdb"
cn.Open strCon
sSQL = "SELECT var1, var2 FROM table2 " _
& "WHERE var1='" & selrange.Cells(1, 1).Value _
& "' AND var2=" & selrange.Cells(1, 2).Value
rs.Open sSQL, cn
ActiveCell.Offset(1, 0).CopyFromRecordset rs
End Sub
For example

Excel VBA - how to query Access database using column values as a parameter?

I have an Excel worksheet that has a list of about 1000 Item Numbers in column A on Sheet1. Currently, I import Sheet1 into an Access table named ItemNumbers and run the following query:
SELECT MyTable.ItemNumber, MyTable.ItemName, MyTable.ItemPrice
FROM [ItemNumbers] INNER JOIN MyTable ON [ItemNumbers].ItemNumber = MyTable.ItemNumber
ORDER BY MyTable.ItemNumber;
And then I copy/paste the output to Sheet2.
How can I do this in VBA in Excel and put the results in a recordset? I can figure out how to loop through the recordset and put the results in Sheet2. I'm just not sure on the code to run the query.
I have the following so far. It just needs to be modified to use the values in Sheet1 Column A.
Dim cn As Object
Dim rs As Object
Dim strSql As String
Dim strConnection As String
Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\MyDatabase.accdb"
strSql = "SELECT MyTable.ItemNumber, MyTable.ItemName, MyTable.ItemPrice " & _
"FROM MyTable " & _
"WHERE WHERE (((MyTable.ItemNumber)= ??? IS IN Sheet1!A:A ??? )) " & _
"ORDER BY MyTable.ItemNumber;"
cn.Open strConnection
Set rs = cn.Execute(strSql)
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
Thanks!!!
If I understand right; what you ask is to join a table from Access with a table in Excel (ADODB).
Check this link from SO, and see if it's helpful:
Selecting 2 tables from 2 different databases (ACCESS)
I haven't tried to combine Access and Excel before, but my guess is that it will work for Excel as well.
An alternate way (and that will certainly work):
Run the query without the WHERE clause and store the result in a
recordset;
Store the data from the Excel sheet that you require in a dictionary,
where the ItemNumber (PK?) is the key;
Run through the recordset, and check with the typical dictionary Exists function
if the ItemNumber from each record is available in the dictionary;
If the record is availabe, store the
recordset values in a separate array (or dictionary) that you can
use for further manipulation, (or perform direct actions if that's what you want to do).

How to retrieve data from Excel with ADODB connection if the first line of the worksheet does not have the column name?

I use the following type of code to retrieve data from some Excel Workbooks (path is a Parameter)
Dim strSQL As String, conStr as String
Dim cnn As New ADODB.Connection
Dim rs As New ADODB.Recordset
conStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & path & "';" & _
"Extended Properties=""Excel 12.0;HDR=YES;IMEX=1;"";"
strSQL = "SELECT [Field1], [Field2] FROM [Worksheet$] WHERE [Thing1] > 1"
cnn.open conStr
rs.Open query, cnn, adOpenStatic, adLockOptimistic, adCmdText
That code works fine if the names of the fields are on the first row of the worksheet. The problem is that I need to retrieve data from a worksheet that the data table begins on another row (Row 10).
Is there a way to specify the first row of my data table?
See this Microsoft page. You can use something like:
strSQL = "SELECT [Field1], [Field2] FROM [Worksheet$$A10:B43] WHERE [Thing1] > 1"
Use a named or unnamed range in your query:
strQuery = "SELECT * FROM MyRange"
strQuery = "SELECT * FROM [Sheet1$A1:B10]"
See these Microsoft support articles for more information:
How To Use ADO with Excel Data from Visual Basic or VBA
ExcelADO demonstrates how to use ADO to read and write data in Excel workbooks
You can query a range of cells starting from row 10:
"SELECT * FROM [Worksheet$A10:S100] WHERE [Thing1] > 1"
What can be tough is finding what the end of the range should be. You could put in a ridiculously large number, but then you'd have to add special handling for the rows of NULL at the end.

Is it possible to create a VBA QueryTable outer join between a CSV file and a worksheet?

I'm creating an excel workbook to manage my personal finances. My banks provide transaction data in CSV format and I found a way to import that data into excel using a QueryTable (using a "TEXT" connection.)
I'd like to automatically apply transaction category rules to each imported transaction. I have a worksheet with two columns - a string to match against the transaction "details" provided in my bank's CSV file and the category to apply to the matching transactions.
Is it possible to create an outer join between the CSV data and the categories worksheet and dump the resulting table into another worksheet?
For example (SQL pseudocodeish): SELECT csv.date, csv.details, csv.debit, csv.credit, ws.category FROM [csvfile] csv LEFT OUTER JOIN [worksheet] ws ON csv.details ~= ws.details
~= above would be some kind of string match. I can figure out the SQL, my question is really how to combine the CSV file and worksheet in the same QueryTable.
Excel will open CSV files without blinking, but you can use a connection string, if you prefer. It is even possible to write a query that compares an existing worksheet or named range with a text file using an Excel connection. All you need is a little VBA.
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
'Note HDR=Yes, that is, first row contains field names '
'and FMT delimted, ie CSV '
strCon="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\Docs\;" _
& "Extended Properties=""text;HDR=Yes;FMT=Delimited"";"
cn.open strcon
'You would not need delimiters ('') if last field is numeric: '
strSQL="SELECT FieldName1, FieldName2 FROM The.csv " _
& " WHERE LastFieldName='SomeTextValue'"
rs.Open strSQL, cn
Worksheets("Sheet3").Cells(2, 1).CopyFromRecordset rs
You can use any suitable Jet SQL queries against the connection, just be careful about case sensitivity. For example, working with a connection to the current workbook:
Dim cn As Object
Dim rs As Object
Dim strFile As String
Dim strCon As String
Dim strSQL As String
Dim s As String
Dim i As Integer, j As Integer
''This is not the best way to refer to the workbook
''you want, but it is very convenient for notes
''It is probably best to use the name of the workbook.
strFile = ActiveWorkbook.FullName
''Note that if HDR=No, F1,F2 etc are used for column names,
''if HDR=Yes, the names in the first row of the range
''can be used.
''This is the Jet 4 connection string, you can get more
''here : http://www.connectionstrings.com/excel
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile _
& ";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 strCon
strSQL = "SELECT * " _
& "FROM [Sheet1$] a " _
& "LEFT JOIN [Text;FMT=Delimited;HDR=Yes;" _
& "DATABASE=C:\Docs].Import.txt b " _
& "ON a.[Id]=b.[Id] "
rs.Open strSQL, cn, 3, 3
''Pick a suitable empty worksheet for the results
Worksheets("Sheet3").Cells(2, 1).CopyFromRecordset rs
''Tidy up
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
It is possible to create an OUTER JOIN referencing disparate data sources (csv, Excel, Access, txt, SQL, Oracle, etc) using ISAM Names in an ADO query. The results are held in a recordset that can be published back to Excel or another datasource as desired. Google "SQL ISAM Names" to find my other posts on the topic.
I am sure a little more info would help clear up my confusion but I don't believe it is possible to set up a SQL query against a CSV as Excel will not recognise it as a Data Source.
Have you thought about simply loading the csv into Excel and generating a pivot table/lookups on the data?

Resources