EXCEL ADODB Query on local worksheet not Including newly inserted records - sql

I am using ADODB to query data form a worksheet in the Active workbook. The data resides on it's own sheet, and has column headers. I've defined the table as an excel ListObject - excel's automatic table formatting construct.
I open the connection like this:
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ThisWorkbook.Path & "\" & _
ThisWorkbook.Name & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
cn.Open strCon
Then I can fetch a recordset using a simple SQL statement:
strSQL = "SELECT * from [sheet1$]
rs.Open strSQL, cn, 0, 1 'cursortype = adOpenForwardOnly, locktype = adOpenReadonly
This all works fine... until I insert a new row in the table on sheet1. The new row is not included in subsequent queries, even if I close, set to nothing, and re-open both the connection and recordset variables in my code.
If I save and close the workbook, and then re-open it, the new records ARE included in the query, which leads me to believe this might be a caching issue. I've searched for ADODB Cache Flush etc, but most results appear to be related to PHP or Access. I've also tried a variety of other options for Cursor Type and Lock Type, with no difference.
Can anyone suggest how I can ensure that each time I run my query I get all the rows, even after I insert new rows in the table?

Figured out a solution:
Since I'm using Excel 2010, I discovered that I can use a newer version of ADODB.
So, instead of defining my connection string like this:
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="...
I changed it to this:
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source="...
and the problem is solved. New inserts and edits are now showing up immediately after I make them. This also removes the issue of the known memory leak in OLEDB.4.0, so that's a bonus.

Related

Excel VBA SQL ADODB Not Inserting Row Into Worksheet (NO ERRORS)

My insert statement has been working, but randomly stops inserting, until I go into the workbook I'm inserting into and manually change something and save.
The db workbook currently has around 15,000 rows that have been previously inserted, but now when I run the macro, it doesn't insert anything and there are no errors. I've stepped through the code, and every line executes normally.
I need help figuring out why nothing is being inserted, when it worked before.
Sub Insert
Dim con As ADODB.Connection
Dim InsertSQL As String
InsertSQL = "INSERT INTO [Sheet1$] ([FIELD1],[FIELD2],[FIELD3],[FIELD4],[FIELD5]) VALUES( 1234567895,9350.00,#9/12/2019#,'username',#9/12/2019 10:05 AM#)"
Set con = New ADODB.Connection
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbpath & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=0""; Mode=ReadWrite;"
con.Execute InsertSQL
con.Close
End Sub
Edit:
I've set default values in the first 8 rows of my db workbook so as not to cause any limitations in data types as specified in:
This is an issue with the Jet OLEDB provider. It looks at the first 8
rows of the spreadsheet to determine the data type in each column. If
the column does not contain a field value over 256 characters in the
first 8 rows, then it assumes the data type is text, which has a
character limit of 256. The following KB article has more information
on this issue: http://support.microsoft.com/kb/281517
It's possible this issue is due to some blank rows in the worksheet, but I can't confirm.

Excel VBA Recordset SQL - No value given for required parameters

Whilst the title of this question is similar to other questions asked in the past, I could not via limited searching on Google or SE find an answer that helped me with my problem below.
I am trying to pick up data from an excel sheet for processing. After finding that a more complex SQL statement with a join gave an error, I looked deeper and found the following;
The below SQL statement runs fine:
SELECT [DNSHEET$].[DNS] FROM [DNSHEET$]
However the below SQL statement does not & this gives the error stated in title later.
SELECT [DNSHEET$].[DNK] FROM [DNSHEET$]
I use the code below for running either SQL statement - they are saved in sql1 which is defined as a string.
rs.execute(sql1), cn
Where rs is the Recordset and cn the connection.
cn is defined as:
Set cn = CreateObject("ADODB.Connection")
With cn
.provider="Microsoft.ACE.OLEDB.16.0"
.ConnectionString="Data Source=" & ThisWorkbook.Path & "\" & ThisWorkbook.Name & ";" & _ "Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
.open
End with
DNS and DNK headers are correctly named and match headers on DNSHEET sheet.
DNS is populated with string data, DNK contains integers from 1 to circa 25000.
Update: This issue has been worked around by closing and reopening the excel workbook. Then both of the SQL queries could run.
Hence another question is why this arises and how to find out what the cause of the problem is?

VBA: Querying data in dynamic named range

I create named range that covers data I need to query using ADODB
SourceWB.Names.Add Name:=SOME_RANGE_NAME, RefersTo:=SOME_RANGE
I setup a connection run SQL query
sConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sSourceName_ & "; Extended Properties=""Excel 12.0 Macro;HDR=YES"";"
Set oConn_ = New ADODB.Connection
oConn_.Open sConn
Dim oRs As New ADODB.Recordset
oRs.Open sSQL, oConn_, adOpenStatic, adLockReadOnly, adCmdText
The SQL query is
SELECT * FROM [SOME_RANGE_NAME] WHERE ....
The problem is: these commands are in cycle, where every time there may be other range referenced by SOME_RANGE_NAME. If the range is changing within one sheet, everything is ok. As soon the SOME_RANGE_NAME references range in other sheet I get the following error:
no value given for one or more required parameters
The solution was proper closing of connections!

My oledb connection works on a workbook but not on the other

So i have this code in two different workbooks, two different files. They are even in the same folder in the same computer.
strFile = "Z:\service\climatizacion.mdb"
strCon = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & strFile
Set cn = CreateObject("ADODB.Connection")
cn.Open strCon
strSQL = "SELECT codigorep, cantidad, precio, descripcion FROM cotizacion WHERE codigorep = " & lngInput & ";"
Set rs = CreateObject("ADODB.RECORDSET")
rs.Open Source:=strSQL, ActiveConnection:=cn, CursorType:=adOpenDynamic, LockType:=adLockOptimistic
In one of the workbooks it works perfect, it selects all the data i need from the database.
On the other it gives me the Runtime error 3001 (The application is using arguments that are of the wrong type, are out of acceptable range, or are in conflict with one another) when I try to open the recordset.
I figured through this code that the connection was the problem (I may be wrong)
If cn.State = adStateOpen Then
MsgBox "connected"
Else
MsgBox "not connected"
End If
I cannot find the difference between these workbooks that can make this connection or the entire code work or make it stop working.
All the variables are declared, the tables exist, i can open them through access with no problems, the database is located on a pc on my local network.
The database is an mdb file, from access 97. And i'm running this on excel 2003, both workbooks, and both were created by me with the same excel 2003.
Thank you in advance for taking the time to read this :D

Validate data before uploading through SSIS

I have a SSIS package to upload data from Excel file into an Sql Server 2005 table.
The excel file will have varied lines of data ranging from 20k - 30k lines.
The upload works fine, when all the data are correct. But obviously fails when there is a small problem even in a single row. Examples like mandatory values presented null, inconvertable values (data type mismatch) etc.
I want to validate the excel file before the upload and want to tell the user which row and column has got the error...
Any idea as to how to accomplish this, without consuming much time and resources.
Thanks
It might be easiest to load into a temporary table that does not have any mandatory values etc and check that before appending it to the main table.
EDIT re comment
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
''This is not necessarily the best way to get the workbook name
''that you need
strFile = Workbooks(1).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"";"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
''Note that HDR=Yes
''Pick one:
strSQL = "SELECT Frst, Secnd FROM TheRange WHERE SomeField Is Null" ''Named range
strSQL = "SELECT Frst, Secnd FROM [Sheet1$C3:C67] WHERE Val(Secnd)=0" ''Range
strSQL = "SELECT Frst, Secnd FROM [Sheet1$] WHERE First<Date()" ''Sheet
rs.Open strSQL, cn
Sheets("Sheet2").Cells(2, 1).CopyFromRecordset rs
I have recently been working on a number of similar packages in SSIS and the only way that I have been able to get around this is to have a holding table similar Remou's suggestion.
This table is extremely generic, where all fields are NULLable and VARCHAR(255). I then have a validation Stored Procedure that checks things such as typing, the existance of data etc before I move the data into a "live" situation. Although it may not be the most elegant of solutions, it gives you alot of control of the way you check the data and also means that you shouldn't have to worry about converting the file(s) to .CSV first.