SQL query with same name columns - sql

I am using excel for a macro to paste information with a sql query but in the table where I have the information in the columns I have the same repeated name and the names must be those.
The macro would be the following:
"Select [code], [name], [PCR] from [Book$B2:H]"
The table where I want to get the information would be the following:
I need the query to copy the information that is in bold but i have PCR in 3 columns so its getting only the first one.

If you're using ADO in your VBA code, then you can change the connection string to say that your data doesn't have headers. This then allows you to refer to fields by their position rather than their name. To do this, add HDR=No into the Extended Properties of the connection string.
Your SQL query could then be something like this:
SELECT F1, F2, F4, F6, F8 FROM [Book$C2:H]
Setting up the connection string would be something like this:
' Set up connection
Dim cn As Object
Set cn = CreateObject("ADODB.Connection")
' Connection string for Excel 2007 onwards .xlsm files
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & ThisWorkbook.FullName & ";" & _
"Extended Properties=""Excel 12.0 Macro;HDR=No"";"
.Open
End With
This assumes that your VBA code is in the same workbook as the data - if that's not the case, then just change the value for the Data Source. See connectionstrings.com for any other potential variations you might need to make for different types of Excel file

The easiest solution is likely to involve:
Insert a row C.
in C3: =if(C1="",B1&"."&C2,C1&"."&C2) and drag across.
But to fit into the bigger picture we would need to know about the bigger picture.

Related

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?

Sql query vba ADO

The sheet name is DATA on excel, using F4 properties in VBA instead of sheet1 I have changed it to sData.
My aql query is not returning any result.I need to extract a column from the Data Sheet of the same workbook in VBA.
My code is :
Sql = "Select productNumber from [shtData$] where produvtDesc = "&pDes&" "
'pDesc is a string variable that stores description.
Is this how we put the sheet name in sql query? I tried [Data$] as well but it doesn't work.
Please help.
Since you didn't add any code concerning the i am assuming that you set up the connection correctly.
use the sheet name you see in excel, not the F4 code (name). Use it with a trailing $ and square brackets like you did
i assume pDes doesn't contain a string in quotes. So, add quotes around your where-criterium
look here on how to set up an ado connection to excel
alternatively, this example of an sql onto an Excel is working even if your actual ado connection refers to another database:
SELECT * FROM [data$A1:E1000] IN 'C:\path\MyFile.xlsx' [Excel 12.0;HDR=YES;IMEX=0]
Edit: For an xls you need different properties, as described in the link above.
i assume your file is called data.xls and that it contains a sheet that is called data
this works if stored in a string and then used as connection string:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\data.xls;
Extended Properties="Excel 8.0;HDR=YES";
and paired with this sql
Sql = "Select productNumber from [data$] where produvtDesc = '" & pDes & "'"
since you want to use a dynamic path try
myCon.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filepath & "\data.xls;Extended Properties=""Excel 8.0;HDR=YES"";"
They key is to escape the double quotes " with a 2nd "
I think there is a typo on your pDesc variable. In the note you've called it 'pDesc' but in the SQL command string its called 'pDes'.
Also, Is it possible that you have whatever DBMS it is that you are using to be case sensitive when referring to table names (so should therefore be [DATA$])? I know most DBMS's default to case in-sensitive, but I believe it is possible to configure it to be case sensitive during the set up process...

How do I override the Header for field naming?

Using SQL to query an Excel worksheet without a header row echos the information I have found in all my research. But that isn't what I am getting. Has there been a change in Excel 2016, or is my implementation wrong?
Sub vndrrst()
Dim cn As Object
Set cn = CreateObject("adodb.connection")
strfilename = ThisWorkbook.Path
cn.ConnectionString = _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strfilename & _
";Extended Properties=""text;HDR=NO;imex=1"";"
cn.Open
Set rs = cn.Execute("select * from My_Text_File.txt where F2='04-62425'")
Set rs = Nothing
Set cn = Nothing
End Sub
The error message reads "No value given for one or more required parameters." at the Set rs statement. When I change F2 to MFGID (the actual field name given in the header of this text file), it both runs and gives accurate output in the debug window... even though HDR=No.
So, how can I use the F field names if the file has a header this time? The reason this becomes interesting is because I have many text/csv/delimited files sent to my FTP, some have headers, some don't, and some have headers sometimes.
Edit: the schema.ini file reads
[My_Text_File.txt]
Format=TabDelimited
in case it matters.
A different related question is ADO Recordset to Excel spreadsheet opens properly in Excel 2007, has a missing parameter in Excel 2013, but the motivation/project of the OP is different, and therefore the answer is irrelevant.

EXCEL ADODB Query on local worksheet not Including newly inserted records

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.

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.