How return multi-result (2 tables) from sql-query into Excel Worksheet? - vba

I have sql query which returne 2 tables with different structure as a result.
I nee somehow to wrote code in VBA/VSTO to get this 2 table from that sql-query.
What should i start from?
Is it possible at all?

The short answer is yes, it's possible. You'll need to use code a bit like that below:
Sub ConnectionExample6()
Dim cnn As ADODB.Connection
Dim rs As ADODB.Recordset
Set cnn = New ADODB.Connection
' Open a connection by referencing the ODBC driver.
cnn.ConnectionString = "driver={SQL Server};" & _
"server=MySqlServer;uid=MyUserName;pwd=MyPassword;database=pubs"
cnn.Open
' Create a Recordset by executing an SQL statement.
Set rs = cnn.Execute("Select * From authors")
' Show the first author.
MsgBox rs("au_fname") & " " & rs("au_lname")
' Close the connection.
rs.Close
End Sub
Source is here:
https://msdn.microsoft.com/en-us/library/ms807027.aspx
Try to use this, then come back and tell us if you have problems.

Related

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!

MS Access VBA code

I am new to MS Access and would like to type EmployeeID in the text box 1 (text_in) and after the button is pressed the result query (one unique value e.g. employee first name taken from the table) is printed out in the text box2 (text_out).
So far have the following code:
Private Sub btn_get_data_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
'declaration of database on recordset objects
Dim strSQL As String
Dim a As String
a = text_in.Value
Set db = CurrentDb
Set rs = db.OpenRecordset("Employee")
strSQL = "SELECT Employee.FirstName FROM Employee WHERE Employee.EmployeeId=" & a
Set db = Nothing
Set rs = Nothing
End Sub
I have tried searching for a solution in many places but I cannot understand the structure that is used in MS access VBA to implement query from regular SQL language.
Guys, thank you very much! It took me one more hour to sucessfully implement both solutions into my database file. As I wrote I am completely new to Ms-access I am learning using some tutorials but my level is still low. Thank you very much once again.
Private Sub btn_get_data_Click()
on error goto errorCatch
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT Employee.FirstName FROM Employee WHERE Employee.EmployeeId=" & Me.text_in.Value & ";"
Set rs = db.OpenRecordset(strSql, DbOpenDynaset)
If rs.RecordCount > 0 Then
debug.print; rs!FirstName
Me.text_out.Value = rs!FirstName
End if
Cleanup:
Set db = Nothing
Set rs = Nothing
Exit Sub
errorCatch:
debug.print; err.Number
debug.print; Err.Description
GoTo Cleanup
End Sub
I cant tell what youre after is this. You need to be better at utilizing recordsets and how to use a string value as your sql statement.
You also didnt need to create a variable to store the textbox value in- you can use it directly in your sql statement.
Also it is very important to have good error handling as hanging recordset objects can be quite a pain in the ass.
EDIT - Ill expand on other ways to use string sql statements within VBA
DoCmd.RunSQl strSql
Or
DoCmd.Execute strSql
Both of these are great for UPDATE's or INSERT's.
Then, like Gustav pointed out, you have various D functions that are basically compact queries with some limitations. However, they often save you the trouble of having to do all the typing that is involved with opening,utlizing and closing records sets. Even though the D functions seem limited, I have often nested a few to get join results out of. Just a matter of imagination.
Look at this nifty site for function details -
https://www.techonthenet.com/access/functions/index.php
You don't need a query to do this. Just set the ControlSource of text2:
=DLookup("FirstName","Employee","EmployeeId=" & [text_in] & "")

How Can I Limit an .OpenDataSource in Word Mail Merge to Only 1 Record Using VBA?

Word 2013, SQL Server 2014
I have a Word Mail Merge template that was originally created for a licensing application that uses an .ini file and an Excel file to generate one certificate from a dataset of many.
I want to make the Word Template work on it's own. I was able to wire up a .udl file to make a connection to the database but it gives me all the tables, then I pick one, then it gives me a document for each row in that table when I only need one.
How can I limit/filter the document that comes from the template to only use a specific table and a specific row (license_id) I request?
Sub AutoNew()
'THIS RETURNS ALL ROWS AFTER I PICK A TABLE
With ThisDocument.MailMerge
.OpenDataSource Name:="C:\Users\or0146575\Desktop\xxx.udl"
.Execute
End With
End Sub
I would wire up the below code to only return 1 row if I knew how.
Dim sql As String
sql = "SELECT full_name, BigLicenseType, LicNosDisplay, expiration_date FROM OpCerts WHERE person_id= 30012"
I decided to take a totally different route and hope it doesn't detract from my points.
Using a datasource file like a .udl or .odc was bringing back all records AND required selecting the table at runtime and I couldn't get the sql to work.
I decided to make the connection with good old ADODB (Microsoft ActiveX Data Objects 2.5 Library in Tools > References) and assign the values to the mailmerge fields or DOCVARIABLE fields or Bookmarks, which ever will work. No sense in using mailmerge for just one record. I hope this helps someone.
Sub AutoNew()
Dim strWhat As String
strWhat = InputBox("Enter License ID", "OpCert Wall Certificate")
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Set conn = New ADODB.Connection
conn.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=DWS_Licenses;Data Source=WPDHSCLR16C"
conn.Open
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandText = "SELECT full_name, BigLicenseType, LicNosDisplay, expiration_date FROM OpCerts WHERE person_id=" & CInt(strWhat)
Dim rs As ADODB.Recordset
Set rs = cmd.Execute() 'Execute stored procedure.
'THIS WILL BE CHANGED TO BOOKMARK(S) PROBABLY IF DOCVARIABLES DOESN'T WORK
ActiveDocument.Variables("expiration_date").Value = rs(3)
'PUT full_name, BigLicenseType, LicNosDisplay TAGS HERE
rs.Close
Set rs = Nothing
Set cmd = Nothing
conn.Close
Set conn = Nothing
End Sub

Weird ODBC error

I'm using an Access front-end for an Microsoft SQL back-end.
The problem I'm facing, is that I'm inserting data with an adodb connection. I use this on multiple forms. On the first form it works, on the second form it works, on the third form it also works. But on the fourth form I get an: 'ODBC: Call failed' error.
You might think I made some kind of typing error, but that is not the issue. When I start with form four I can insert the data.
So long story short, after 3 inserts on different form, I get that odbc error. I don't know what the problem is.
Dim Query As String
Dim rs As ADODB.Recordset
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
Query = "SELECT MAX(ID) From dbo_Controle"
rs.Open Query, CurrentProject.Connection
rs.MoveFirst
ID = rs.Fields(0).Value
Query = "INSERT INTO dbo_Controle VALUES (" & ID + 1 & ",'" & Me.txtControleTime & "')"
Set cn = CurrentProject.Connection
Debug.Print (Query)
cn.Execute Query
rs.Close
cn.Close
Set rs = Nothing
Set db = Nothing
This is the code I am using on different forms with different queries.
I was having the same issue, and was able to fix it by using CurrentProject.AccessConnection

Using Excel VBA to run SQL query

I am fairly new to SQL and VBA. I have written a SQL query that I would like to be able to call and run from a VBA sub in an excel workbook and then bring the query results into the workbook. I have found some subs online (stackoverflow and other places) that claim to do this but I am having trouble understanding them as they contain no explanation. For example, here is a sub that I found online:
Sub ConnectSqlServer()
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sConnString As String
' Create the connection string.
sConnString = "Provider=SQLOLEDB;Data Source=INSTANCE\SQLEXPRESS;" & _
"Initial Catalog=MyDatabaseName;" & _
"Integrated Security=SSPI;"
' Create the Connection and Recordset objects.
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
' Open the connection and execute.
conn.Open sConnString
Set rs = conn.Execute("SELECT * FROM Table1;")
' Check we have data.
If Not rs.EOF Then
' Transfer result.
Sheets(1).Range("A1").CopyFromRecordset rs
' Close the recordset
rs.Close
Else
MsgBox "Error: No records returned.", vbCritical
End If
' Clean up
If CBool(conn.State And adStateOpen) Then conn.Close
Set conn = Nothing
Set rs = Nothing
End Sub
First of all, would this work? Second, what do I need to replace in the sub (it looks like provider, data source, initial catalog, etc) and where do I find the info to replace them with?
I hope this question is not too confusing and I appreciate your help!
Below is code that I currently use to pull data from a MS SQL Server 2008 into VBA. You need to make sure you have the proper ADODB reference [VBA Editor->Tools->References] and make sure you have Microsoft ActiveX Data Objects 2.8 Library checked, which is the second from the bottom row that is checked (I'm using Excel 2010 on Windows 7; you might have a slightly different ActiveX version, but it will still begin with Microsoft ActiveX):
Sub Module for Connecting to MS SQL with Remote Host & Username/Password
Sub Download_Standard_BOM()
'Initializes variables
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim ConnectionString As String
Dim StrQuery As String
'Setup the connection string for accessing MS SQL database
'Make sure to change:
'1: PASSWORD
'2: USERNAME
'3: REMOTE_IP_ADDRESS
'4: DATABASE
ConnectionString = "Provider=SQLOLEDB.1;Password=PASSWORD;Persist Security Info=True;User ID=USERNAME;Data Source=REMOTE_IP_ADDRESS;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=DATABASE"
'Opens connection to the database
cnn.Open ConnectionString
'Timeout error in seconds for executing the entire query; this will run for 15 minutes before VBA timesout, but your database might timeout before this value
cnn.CommandTimeout = 900
'This is your actual MS SQL query that you need to run; you should check this query first using a more robust SQL editor (such as HeidiSQL) to ensure your query is valid
StrQuery = "SELECT TOP 10 * FROM tbl_table"
'Performs the actual query
rst.Open StrQuery, cnn
'Dumps all the results from the StrQuery into cell A2 of the first sheet in the active workbook
Sheets(1).Range("A2").CopyFromRecordset rst
End Sub