ADODB object ignoring text in excel - sql

I have a data table in excel with both numbers and text in the store number column. I need to use sql through an ADODB object in VBA to get a list of the store numbers in the column. I'm using the following to set up the ADODB.
The problem: If the query hits a number first then the field is treated as numbers and texts are ignored. and if a text is hit first the numbers are ignored.
I'm using the following to set up the ADODB. These are in the worksheet module hints me..
Public Function Query(qry As String) As ADODB.Recordset
Dim cn As ADODB.Connection '* Connection String
Dim rs As ADODB.Recordset '* Record Set
Dim sQuery As String '* Query String
Dim FileName As String
On Error GoTo QryErr
Set cn = New ADODB.Connection
FileName = ThisWorkbook.Path & "\" & ThisWorkbook.Name
cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & FileName & _
";Extended Properties=Excel 8.0;Persist Security Info=False"
cn.ConnectionTimeout = 40
cn.Open
Set rs = New ADODB.Recordset
Select Case LCase(qry)
Case "dry": sQuery = SQLDry
Case "frz": sQuery = SQLFrz
Case "fsh": sQuery = SQLFsh
Case "temp": sQuery = SQLTemp
Case Else: GoTo QryErr
End Select
rs.ActiveConnection = cn
rs.Source = sQuery
rs.Open
Set Query = rs
If Not rs Is Nothing Then Set rs = Nothing
If Not cn Is Nothing Then Set cn = Nothing
QryErr:
If Err <> 0 Then
Debug.Assert Err = 0
MsgBox Err.Description
End If
End Function
And I have the following for the SQL portion.
Private Function SQLTemp() As String
Dim Name As String
Name = Me.Name
SQLTemp = "SELECT str([" & Name & "$].Store) as Store " & _
"FROM [" & Name & "$] " & _
"GROUP BY [" & Name & "$].Store"
End Function
As you can see I've tryed converting the field to str() but it doesn't help.
How can I get the query to treat the column as text so that all values are returned. I'd like to avoid putting ' in front of all my numbers.

Asked 5 years ago! I had the same problem. The solution for me was to change the data type of the offending columns (those with "special characters" and "TEXT" datatype) to "VARCHAR", or you can remove in the query the special characters, or change the CharacterSet by means of Schema.ini, as #Tim Williams suggests (msdn.microsoft.com/en-us/library/ms709353(v=vs.85).aspx).

Related

VBA, Import CSV split by ";" to sheet

I am trying to import a CSV file split by semicolon ";" into an excel object so I can use it later on.
Ideally i would like to use ADO, DAO or ADODB so I can also run SQL queries on the object, and get sum of specific fields, or total number of fields and so on.
So far i've gotten the code below, but it does not split the data by ";", so it all comes back as 1 field instead of multiple fields that can be handled.
Sub Import()
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim f As ADODB.Field
Dim csvName, csvPath
csvPath = ActiveWorkbook.path
csvName = "fileName.csv"
conn.Open "DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=" & csvPath & ";"
rs.Open "SELECT * FROM " & csvName, conn, adOpenStatic, adLockReadOnly, adCmdText
Debug.Print rs.Fields
While Not rs.EOF
For Each f In rs.Fields
Debug.Print f.Name & "=" & f.Value
Next
Wend
End Sub
Can anyone give me an idea how I can also split the data by ";" and query it using SQL query? Or a different object that I could load a CSV into and query certain columns.
Here's example:
Public Sub QueryTextFile()
Dim rsData As ADODB.Recordset
Dim sConnect As String
Dim sSQL As String
' Create the connection string.
sConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Files\;" & _
"Extended Properties=Text;"
' Create the SQL statement.
sSQL = "SELECT * FROM Sales.csv;"
Set rsData = New ADODB.Recordset
rsData.Open sSQL, sConnect, adOpenForwardOnly, _
adLockReadOnly, adCmdText
' Check to make sure we received data.
If Not rsData.EOF Then
' Dump the returned data onto Sheet1.
Sheet1.Range("A1").CopyFromRecordset rsData
Else
MsgBox "No records returned.", vbCritical
End If
' Clean up our Recordset object.
rsData.Close
Set rsData = Nothing
End Sub
The only answer I found that was usable was to create an ini file in the current folder, and enter the delimiter in the ini file.
iniPath = activeworkbook.path & "\"
iniName = "schema.ini"
iniPathName = iniPath & iniName
If Not fso.FileExists(iniPathName) Then
fso.CreateTextFile (iniPathName)
End if

Sumproduct in Excel VBA using function arguments as source

I'm trying to write a VBA function that takes the function arguments as the source and then runs SQL commands on it. The SQL command I'm currently trying to implement as a first step is the equivalent of Excel's sumproduct() function, which in SQL would be something along the lines of "SELECT SUM(A * B)".
I modified some code from another site that used SQL to convert an Excel table into a single column, and modified it to calculate a sumproduct, but I'm having trouble converting the subroutine into a function.
Current working code:
Sub doSQL()
Dim strCon As String
Dim oneSQL As String
' refer to 'microsoft activex data objects library'
Dim cn As Object
Dim rs As Object
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source='" & ThisWorkbook.FullName & "';" & _
"Extended Properties='Excel 12.0;HDR=No;IMEX=1';" ' HDR=No means no headers (field names)
cn.Open strCon ' open connection
'-------------------------------------------------------------------------------
' F1, F2, F3 are the default fieldnames when no headers are included with data
oneSQL = "SELECT sum(F1 * F2) FROM [Sheet1$B:D] where F1 not like '' AND F2 not like ''"
rs.Open oneSQL, cn ' get recordset
Sheets("Sheet1").Range("A:A").ClearContents
Sheets("Sheet1").Range("A1").CopyFromRecordset rs ' copy recordset to worksheet
'-------------------------------------------------------------------------------
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub
The end result is that cell A1 returns the equivalent of sumproduct(B3:B5,C3:C5).
My attempt to convert it into a function:
Function SQL_sumproduct(A As Variant, B As Variant) As Double
Dim strCon As String
Dim oneSQL As String
' refer to 'microsoft activex data objects library'
Dim cn As Object
Dim rs As Object
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source='" & ThisWorkbook.FullName & "';" & _
"Extended Properties='Excel 12.0;HDR=No;IMEX=1';" ' HDR=No means no headers (field names)
cn.Open strCon ' open connection
oneSQL = "SELECT sum(A * B)"
rs.Open oneSQL, cn ' get recordset
'-------------------------------------------------------------------------------
' Sheets("Sheet1").Range("A:A").ClearContents
' Sheets("Sheet1").Range("A3").CopyFromRecordset rs ' copy recordset to worksheet
'-------------------------------------------------------------------------------
SQL_sumproduct = rs
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Function
I end up getting an error because the code does not recognise the function arguments A and B as a source.
Could anyone give me some guidance as to how the "Data Source" parameter can be modified to recognise the function arguments?
The SQL statement in oneSQL = "SELECT sum(A * B)" is looking for fields named "A" and "B" (regardless of what is passed into the function in the parameters A and B). This is because A and B are enclosed in double-quotes.
To incorporate the parameters into the SQL statement, you would write this instead:
oneSQL = "SELECT sum(" & A & " * " & "B)"
Having A and B outside the double quotes causes them to be replaced with their values. & is the string concatenation operator which joins all of the pieces together.
Note: when dynamically constructing an SQL statement from any kind of external input, consider the possibility of SQL injection - see here and here

Pull and push data from and into sql databases using Excel VBA without pasting the data in Excel sheets

I want to use Excel vba to pull data from one database (server) and then push the same to another (local). However, I don't want to paste the data in any excel sheets during the process as this slows down the Excel a lot. How can I do this? Below is my work so far. I have highlighted where my code stops with error - Wrong number of arguments or invalid property assignment
Sub get_data_temp()
Dim cn As Object
Dim rs As Object
Dim strConnection As String
Dim server, port, id, pass As String
Dim strSQL As String
'get data from server (MS SQL based)
strSQL = Range("query_1").Value
server = Range("db_server").Value
port = Range("db_port").Value
id = Range("db_id").Value
pass = Range("db_pass").Value
Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=SQLOLEDB;Data Source=" & server & "," & port & ";User ID=" & id & ";Password=" & pass & ";"
cn.Open strConnection
Set rs = cn.Execute("SET NOCOUNT ON;" & strSQL)
'connect to ms access to import data
Dim xcn As Object
Dim xrs As Object
Dim xdbpath As String
Dim xstrConnection As String
Dim xdb_name As String
Dim xstrSQL As String
''''''''the code stops at the line below'''''''''''''
xstrSQL = "insert into crm_main select * from " & rs
''''''''the code stops at the line above'''''''''''''
xdb_name = "temp.accdb"
xdbpath = ThisWorkbook.Path & Application.PathSeparator & xdb_name
Set xcn = CreateObject("ADODB.Connection")
xstrConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & dbpath
xcn.Open xstrConnection
xcn.Execute(xstrSQL)
cn.Close
Set cn = Nothing
xcn.Close
Set xcn = Nothing
End Sub

Query Access database and return all records to Excel

I am working on a macro whereby the user enters a search term which is used to query an Access Database. My question is how do I return those records to Excel in separate rows?
For example, a database contains home address information. If the user searches for a zip code, the records that are selected would go into row 1, 2, 3, etc. for as many home addresses as are returned in the query.
Below is some example code - the part I am missing is clearly marked.
I appreciate any help!
Sub DatabaseQuery()
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim stDB As String, stSQL As String, stProvider As String
Dim SearchTerm As String
stDB = "Data Source= C:\Database.accdb" ' Change accordingly
stProvider = "Microsoft.ACE.OLEDB.12.0"
With cn
.ConnectionString = stDB
.Provider = stProvider
.Open
End With
SearchTerm = Range("A1").Value ' Change accordingly
stSQL = "SELECT Field1, Field2, Field3 " & _
"FROM Table1 WHERE Field4= '" & SearchTerm & "'"
rs.Open stSQL, cn, adOpenStatic
' *** Put all the records in Sheet2! *** Help me! :)
cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub
You need to tell us which version of Access you're using, as it would change a couple things.
Also, why is there even mention of a connection string? I don't see you saying you're using VB.NET. All I see is MS Access & Excel - Office applications.
When Access exports something to Excel, it would pretty much mimic the same look it did as if you looked at the Data in a DataSheet.
If you are using Access, check out this code I wrote as a starting point:
outputFileName = CurrentProject.Path & "\Reports\YourReportName.xlsx"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "YourName", outputFileName, True
If you are using a different front end, you need to tell us in your question. Otherwise, how are we supposed to help you? By guessing? That's a good way to not get an answer.
I have learned there is more than 1 way to do this. The following does work for me.
Sub DatabaseQuery()
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim stDB As String, stSQL As String, stProvider As String
Dim SearchTerm As String
stDB = "Data Source= C:\Database.accdb" ' Change accordingly
stProvider = "Microsoft.ACE.OLEDB.12.0"
With cn
.ConnectionString = stDB
.Provider = stProvider
.Open
End With
SearchTerm = Range("A1").Value ' Change accordingly
stSQL = "SELECT Field1, Field2, Field3 " & _
"FROM Table1 WHERE Field4= '" & SearchTerm & "'"
rs.Open stSQL, cn, adOpenStatic
Sheets("Sheet2").Range("A1").CopyFromRecordset rs
cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub

UDF to paste recordset data in VBA

Basically, I have managed to retrieve the data from database to recordset by means of
rs=db.openrecordset(sql). How do I paste the data in the cell by UDF? Someone suggested array formula. Then how do i change recordset data to array? I know i can use copyfromrecordset . But it is not functioning in the UDF .
Thank you.
This is working for me with Excel 2003, ADO 2.8:
Function getArray(strSql As String) As Variant
Dim rs As ADODB.Recordset
Dim i As Integer
getArray = ""
Set rs = getRs(strSql)
With rs
.MoveFirst
Do
For i = 0 To .Fields.Count - 1
getArray = getArray & CStr(.Fields(i).Value) & " "
Next i
getArray = getArray & vbLf
.MoveNext
Loop Until .EOF = True
.Close
End With
Set rs = Nothing
End Function
It loops through all the rows/fields of a recordset and returns an "array" of values. It can be used as a workbook function without CSE.
This is how I'm making my db connection:
Function getRs(strSql As String) As ADODB.Recordset
Dim strCn As String
strCn = "Provider=sqloledb;Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security=SSPI;"
Set getRs = New ADODB.Recordset
getRs.Open strSql, strCn, adOpenStatic, adLockReadOnly
End Function
And this is a sample of how I could retrieve some data using getArray() based on criteria from one cell and return the results into another (single) cell.
Function getEmpDataByLastName(strLastName As String) As Variant
Dim strSql As String
strSql = ""
strSql = strSql & "SELECT BusinessEntityID, PersonType, FirstName, COALESCE(MiddleName,'') AS MiddleName "
strSql = strSql & "FROM Person.Person "
strSql = strSql & "WHERE LastName = '" & strLastName & "' "
strSql = strSql & "ORDER BY FirstName "
getEmpDataByLastName = getArray(strSql)
End Function