Pulling SQL info into Excel - sql-server

I have been able in the past to create connections and pull in whole tables or even just a column or two from SQL into Excel.
Now what I want to for a user to input an ID into a Userform and then the VBA to run SQL code grabbing the cooresponding ID, FirstName, LastName. It should then paste that info into the first blank row of A,B,C on the "Entry" sheet.
I am getting an error on this line of code stating: Run-time error '1004' Application-defined or object-defined error.
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:=Array("OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Data Source=xxx.xxx.xxx.xxx;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False;Initial Catalog=DBName"), Destination:=Sheets("Entry").Range("A1").End(xlDown).Offset(1, 0)).QueryTable
Most of this I do not understand it is simply some hand me down code that I am trying to re-purpose. The old code which still works is this:
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:=Array( _
"OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Data Source=xxx.xxx.xxx.xxx;Use Procedure for Prepare=1;Auto " _
, _
"Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possibl" _
, "e=False;Initial Catalog=DBName"), Destination:=Range("Database!$A$1")). _
QueryTable
The difference between these is that instead of just dropping it in one set cell with the code pulling over couple hundred thousand lines of data is I want the code to be in the first blank row and only pull over that one record. But each time it runs it needs to go to the next row.
With the old code it made an actual table which I am guessing is related to the fact that at the end it states QueryTable. I would rather just have the data and not the table format. If there is a way to change it to do this that would be great.
Also in the previous version of this the query only pulled from one table and the .SourceConnectionFile = _ link to the file. The new code will need to link to two tables so there are two files as I was unable to have it make a connection file with two tables selected. If you can help with that as well that would be great.
I am using Excel 2013 Standard and SQL Server 2012. Please let me know if you need any more info.
So This is what I have so far trying the ADO method suggested by #Kyle. The OCR is the variable input from the Userform in previous code. When this runs it gives no error but it paste no data.
Sub Code()
Sheets("Entry").Select
On Error Resume Next
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H1
Set objConnection = CreateObject("ADODB.Connection")
Set Objrecordset = CreateObject("ADODB.Recordset")
ConnectionString = "Provider=SQLOLEDB;Data Source=xxx.xxx.xxx.xxx;Initial Catalog=DBName;User ID=MyUN;Password=MyPW"
objConnection.Open
Objrecordset.Open "Select B.ID, B.Firstname, B.Lastname From TableA as A Join TableB as B on A.ID = B.ID Where A.Cardnumber =" & OCR, objConnection, adOpenStatic, adLockOptimistic, adCmdText
If Not Objrecordset.EOF Then
Sheets("Entry").Range("A1").End(xlDown).Offset(1, 0).CopyFromRecordset Objrecordset
Objrecordset.Close
Else
MsgBox "Did not Work"
End If
End Sub

So I was able to get it to work with this:
Sub Code()
Sheets("Entry").Select
Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim User_ID As String
Dim Password As String
Dim SQLStr As String
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Server_Name = "" ' Enter your server name here
Database_Name = "" ' Enter your database name here
User_ID = "" ' enter your user ID here
Password = "" ' Enter your password here
SQLStr = "SELECT B.ID, B.FirstName, B.LastName From Table A Join Table B as B on A.ID = B.ID Where A.CardNumber ='" & OCR & "'" ' Enter your SQL here
Set Cn = New ADODB.Connection
Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
rs.Open SQLStr, Cn, adOpenStatic
' Dump to spreadsheet
With Worksheets("Entry").Range("A1").End(xlDown).Offset(1, 0) ' Enter your sheet name and range here
.ClearContents
.CopyFromRecordset rs
End With
' Tidy up
rs.Close
Set rs = Nothing
Cn.Close
Set Cn = Nothing
End Sub

Related

Create refreshable Excel spreadsheet from SQL Server

I'm making an Excel report using 3 SQL Server queries one of which selects into a temp table and I want the result of these select statements into an Excel table. I am new to Excel what is a good way to display the query result as a table and be able to refresh the table with new data from these 3 queries? I've read about power query is this a good option?
my queries
Select into temp table
join temp table with table
join temp table with table
union above 2 into 1 result table
Ended up using Data->Get Data->From Database to load the SQL data into excel and the refresh button will update the table.
Can you try this?
Sub ImportFromSQLServer()
Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim User_ID As String
Dim Password As String
Dim SQLStr As String
Dim RS As ADODB.Recordset
Set RS = New ADODB.Recordset
Server_Name = "your_server_name"
Database_Name = "your_database_name"
'User_ID = "******"
'Password = "****"
SQLStr = "select distinct ID from mytable1"
Set Cn = New ADODB.Connection
Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & ";"
'& ";Uid=" & User_ID & ";Pwd=" & Password & ";"
RS.Open SQLStr, Cn, adOpenStatic
With Worksheets("Sheet1").Range("A1")
.ClearContents
.CopyFromRecordset RS
End With
RS.Close
Set RS = Nothing
Cn.Close
Set Cn = Nothing
End Sub
Also, set a reference to Microsoft ActiveX Data Objects 2.8 Library (Tools > References).

Running SQL queries from inside spreadsheet cells

I have an Excel spreadsheet with several SQL queries stored in different cells and I'd like to execute these queries on SQL Server to generate a new sheet where each cell is the query result from the original spreadsheet. The idea behind this is to preserve the sheet formatting when generating the results (conditional formatting and etc.).
Something like this:
Input spreadsheet:
Database
Information A
Information B
DB 1
SQL Query 1
SQL Query 2
DB 2
SQL Query 3
SQL Query 4
Output spreadsheet:
Database
Information A
Information B
DB 1
Result of Query 1
Result of Query 2
DB 2
Result of Query 3
Result of Query 4
I wasn't able to find ideas on how to do exactly this during my research of the subject, but I do believe it should be doable using either VBA or some scripting language.
Any thoughts on how should I approach this?
I've got it done using Power Query. It was way easier than I thought. Special thanks to Jacek Wróbel for providing the idea in the comments.
As an aside, you could do something like this.
Sub ADOExcelSQLServer()
Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim User_ID As String
Dim Password As String
Dim SQLStr As String
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Server_Name = "EXCEL-PC\SQLEXPRESS" ' Enter your server name here
Database_Name = "Northwnd" ' Enter your database name here
User_ID = "" ' enter your user ID here
Password = "" ' Enter your password here
SQLStr = "SELECT * FROM Orders" ' Enter your SQL here
Set Cn = New ADODB.Connection
Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
rs.Open SQLStr, Cn, adOpenStatic
With Worksheets("Sheet1").Range("A1:Z500")
.ClearContents
.CopyFromRecordset rs
End With
rs.Close
Set rs = Nothing
Cn.Close
Set Cn = Nothing
End Sub
That sits in a VBA Module. Of course, you could store the SQL in an Excel cell, and do this...
SQLStr = Worksheets("Sheet1").Range("A1").Value
Also, you could loop through a bunch of cells and run a bunch of SQL jobs.
Your own imagination is your only limitation.

while exporting data to excel from sql using openrowset getting error

I am getting error while exporting data from SQL to already created .xlsx file. I used openrowset.
It works fine most of times, but when the data comes in of the field as a large string, while inserting in excel it shows error as:
the statement has been terminated , string or binary data would be
truncated.
Data gets inserted in table but while inserting in excel this error comes.
Please help me find the solution.
So, going form SQL Server to Excel, you can do many things. Check out thins link:
https://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm#Introduction
Also, here is some VBA code to move data from SQL Server to Excel:
Sub ADOExcelSQLServer()
' Carl SQL Server Connection
'
' FOR THIS CODE TO WORK
' In VBE you need to go Tools References and check Microsoft Active X Data Objects 2.x library
'
Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim User_ID As String
Dim Password As String
Dim SQLStr As String
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Server_Name = "EXCEL-PC\EXCELDEVELOPER" ' Enter your server name here
Database_Name = "AdventureWorksLT2012" ' Enter your database name here
User_ID = "" ' enter your user ID here
Password = "" ' Enter your password here
SQLStr = "SELECT * FROM [SalesLT].[Customer]" ' Enter your SQL here
Set Cn = New ADODB.Connection
Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
rs.Open SQLStr, Cn, adOpenStatic
' Dump to spreadsheet
With Worksheets("sheet1").Range("a1:z500") ' Enter your sheet name and range here
.ClearContents
.CopyFromRecordset rs
End With
' Tidy up
rs.Close
Set rs = Nothing
Cn.Close
Set Cn = Nothing
End Sub

VBA sql query based off combobox

I've been searching hard the past few days and have come across numerous examples that outline what I'm trying to do. However, I can't seem to get this working. I have a combobox that populates data (a company name) from a table when the form initializes. I then want to take the value chosen in the combo box and run another query to cross reference an id number in that same table.
Private Sub CommandButton1_Click()
Dim myCn As MyServer
Set myCn = New MyServer
Dim rs As ADODB.recordset
Set rs = New ADODB.recordset
Dim sqlStr As String
Dim CompField As String
'CompField = ComboBox1.Value
sqlStr = "SELECT DISTINCT [acctno] FROM client WHERE [company] = '" & ComboBox1.Text & "'"
'sqlStr = "Select DISTINCT [company] FROM client;"
' sqlStr = "SELECT DISTINCT [acctno] FROM client WHERE [company] = " & UserForm1.ComboBox1.Value & ";"
'sqlStr = "SELECT DISTINCT [acctno] FROM client WHERE [company] = " & UserForm1.ComboBox1.Text & ";"
'sqlStr = "SELECT DISTINCT [acctno] FROM client WHERE [company] = 'Company XYZ';"
'sqlStr = "SELECT DISTINCT [acctno] FROM client WHERE company = " & CompField & ""
rs.Open sqlStr, myCn.GetConnection, adLockOptimistic, adCmdText
MsgBox sqlStr
'MsgBox ComboBox1.Value
'MsgBox rs(0)
rs.Close
myCn.Shutdown
Set rs = Nothing
Set myCn = Nothing
End Sub
Currently with the combobox value encased in single quotes i get the entire sql string returned. If I remove the single quotes I get a syntax error referencing part of the combobox value. All other efforts have resulted in run-time errors that have led me nowhere.
I know my query works because I've tested it in SQL Studio and if I hard code a text value in this code I also get the Account ID I'm looking for. Not sure what I'm missing here.
Well I figured it out. I was expecting to be able to MsgBox the variable assigned to the SQL query and see my results. But it doesn't work that way. I had to use ADO GetString method for that and assign another variable. Oh and you were right about escaping, I had to add delimters to properly handle the ComboBox value in the query which ultimately looked like this
sqlStr = "SELECT DISTINCT [acct_no] FROM client WHERE [company] = " & Chr(39) & Me.ComboBox1.Value & Chr(39)
Thanks for your help on this

SQL query that uses a range in excel as the criteria

I use external data from an SQL query in excel to pull data onto a spreadsheet then the spreadsheet can be sent to one of my colleges in say the sales department and they can view the queried information.
I want to be able to have a cell that they can enter data into and press a refresh button.
So I need to do some thing like this:
SELECT Customer.CustomerCode, Customer.Name,
OrderHeader.OrderType, OrderHeader.OrderNumber
FROM Customer INNER JOIN
OrderHeader ON Customer.CustomerID = OrderHeader.CustomerID
WHERE (OrderHeader.OrderType = 2) AND (OrderHeader.OrderNumber = Range("A1").Value)
Not sure how or if this is possible and the reason I need to do this is because i'm going through lines from all the Quotes and if there is over 65536 then i'll have a problem.
This is what I have at the moment the SQL is different but that doesn't matter
The easiest way is to pull the values for the parameters into VBA, and then create the SQL statement as a string with the parameter values, and then populate the commandtext of the query.
Below is a basic example of the parameter in cell A1.
Sub RefreshQuery()
Dim OrderNo As String
Dim Sql As String
' Gets value from A1
OrderNo = Sheets("Sheet1").Range("A1").Value
'Creates SQL Statement
Sql = "SELECT Customer.CustomerCode, Customer.Name, " & _
"OrderHeader.OrderType , OrderHeader.OrderNumber " & _
"FROM Customer " & _
"INNER Join OrderHeader ON Customer.CustomerID = OrderHeader.CustomerID " & _
"WHERE (OrderHeader.OrderType = 2) And (OrderHeader.OrderNumber = " & OrderNo & ") "
With ActiveWorkbook.Connections(1).ODBCConnection
.CommandText = Sql
.Refresh
End With
End Sub
This assumes you have the query in Excel to begin with, and that it's the only query. Otherwise you'll have to define the name of the query as below:
With ActiveWorkbook.Connections("SalesQuery").ODBCConnection
I hope that helps :)
Further to #OWSam's example using ODBC, we can also use ADO to pull back query results from SQL Server. Using ADO, you cannot use windows verification and you will need the user to input their password somehow, to be able to run the query.
Personally I create a userform which has UserName and Password. Username pre-populated using Environ, and then they can type their password into the relevant TextBox.
Sub sqlQuery()
Dim rsConn As ADODB.Connection, rsData As ADODB.Recordset
Dim strSQL As String, winUserName As String, pwd As String
winUserName = UCase(Environ("username"))
pwd = "mypassword" 'password needed here.
strSQL = "SELECT * FROM mydatabase" 'query
Set rsConn = New ADODB.Connection
With rsConn
.ConnectionString = "Provider = sqloledb;" & _
"Data Source = [server name here];" & _
"Initial Catalog = [initial database];" & _
"Integrated Security=SSPI;" & _
"User ID = " & winUserName & ";" & _
"Password = " & pwd & ";"
.Open
End With
Set rsData = rsConn.Execute(strSQL)
Range("A1").CopyFromRecordset rsData
End Sub
Edit: You must go into references and turn on the Microsoft ActiveX Data Objects Recordset 6.0 library (or equivalent within your VBE).

Resources