Store Connection Names in Excel VBA - Add to connection text - vba

I have got a workbook containing several worksheets.
Parameters are entered on one sheet, and I am on the way to creating a macro which takes these parameters, adds them to the connection string and then updates each table on each sheet.
I have got it working for one connection, but I am struggling to find a way of storing each connection name and then and looping through each connection adding the variables.
Here is the code I have so far, some of it is commented out..which is how I managed to solve the problem for one connection. Any guidance would be very much appreciated.
Sub Update()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Parameters")
Dim startdate As Date
Dim enddate As Date
startdate = Range("week_start_date").Value
enddate = Range("week_end_date").Value
MsgBox "Values are " & startdate & " and " & enddate
Dim nm As ActiveWorkbook.Connections.name
Dim conn As WorkbookConnection
For Each conn In ActiveWorkbook.Connections
.CommandText = "exec dbo.'" & name & "', #start = '" & startdate & "', #end = '" & enddate & "' "
'With ActiveWorkbook.Connections("ps_STS_Op_Summary_Approvals").OLEDBConnection
'.CommandText = "exec dbo.ps_STS_Op_Summary_Approvals #start = '" & startdate & "', #end = '" & enddate & "'"
End With
'ActiveWorkbook.Connections("ps_STS_Op_Summary_Approvals").Refresh
For Each wSht In ThisWorkbook.Worksheets
For Each qt In wSht.QueryTables
qt.Refresh
Next
Next
End Sub

Find the number of connections stored in the workbook and then loop through them using the .item(x) property of ActiveWorkbook.Connections:
cnt = ActiveWorkbook.Connections.Count
For i = cnt To 1 Step -1
Set conn = ActiveWorkbook.Connections.Item(i)
'Do stuff to conn
Next i
Also refer to this question on stack overflow

Related

Is it possible to update MS Access database using Excel userform by using multiple conditions for WHERE SQL statement?

I am attempting to create an attendance monitoring system. One of its objective is to be able to update the attendance of a student upon taking attendance. In case the lecturer wants to change the attendance status.
Therefore, I have created a userform just to update attendance and it contains values for courseCode, subject, classDate, studentID, name, attendance status, and excuse. Is there a way to access my database (on access) through this userform to update the newest attendance status and excuse? I have tried using the method below but there is an error saying expected end of statement.
Private Sub CommandButton1_Click()
Dim cnt As ADODB.Connection
Dim db_path As String
Dim db_str As String
db_path = "filepath;"
Set cnt = New ADODB.Connection
db_str = "provider=Microsoft.ACE.OLEDB.12.0; data source=" & db_path
cnt.Open (db_str)
insert_str = "update Classdate set attendanceStatus = '" & cmbUpdateStatus.Value & "' and Excuse = '" & txtUpdateExcuse.Value & "' where classDate = '" & cmbUpdateDate.Value "' and courseCode = '" & cmbUpdateCourseCode.Value & "' and studentID = '" & cmbUpdateStudentID.Value & "'"
cnt.Execute (insert_str)
MsgBox "Updated sucessfully", vbInformation
Set cnt = Nothing

Loop through range and execute SQL statement when cell not empty

I think I need help with this one:
I look for a way to send a number of line items within a transaction to a database with as little coding as possible
A transaction can consist of 1 or several lineitems for a defined set of products (CategoryIDs). Each combination of CategoryIDs and LineItems is stored in a seperate row. Rows with 0 lineItems are to be ignored.
The products are listed in Worksheet-Column B, and the number of products purchased (the lineitem number) is stored in Column C
In addition, I have a CustomerID and a TransactionID, but these two values are "outside" of the loop because they are the same for the complete transaction, so they are not part of my question.
What I would like to accomplish is:
let the code loop through each row
ignore all rows with 0 line items
at a row with >0 line items, run an SQL insert containing the categoryID and the lineitems of that row
go to next row
I am not sure if this is at all possible in the way I try to do this:
Private Sub AbsendenNeu_Click()
Dim Cell As Range
'Variables for the connection to the SQL server
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Dim conStr As String
Dim strSQL As String
'variables "outside the loop" that I am not too concerned with in this question
Dim CustomerUniqueName As String
Dim TransactionID As String
CustomerUniqueName = Worksheets("Eingabe").CustomerSelect.Value
TransactionID = "1-" & CustomerUniqueName & Now()
'These are the two variables "in the loop"
Dim CatID As Range
Dim LineItems As Range
'Open the database connection
Set con = New ADODB.Connection
con.Open "Driver={ODBC Driver 17 for SQL Server};Server=tcp:my-servername,1433;Database=my-database;Uid=my-User;Pwd=My-Password;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;"
'this is the loop I try to get to work
With Worksheets("EmissionenNeu") 'This is the worksheet that contains the CategoryIDs and LineItems
Set CatID = Range("B" & Cell.Row)
Set LineItems = Range("C" & Cell.Row)
For Each Cell In Range("C2:C39")
If Cell.Value > 0 Then
strSQL = "INSERT INTO tblTransactions(ShopID,TransactionID,CategoryID,CustomerUniqueName,LineItems) VALUES(1,'" & TransactionID & "','" & CatID & "', '" & CustomerUniqueName & "','" & LineItems & "');"
con.Execute strSQL
End If
Next Cell
con.Close
Set con = Nothing
' End With
End Sub
I read this example in a different context so I am not sure if I can adapt this to my case. I get an error at " Set CatID = Range("B" & Cell.Row) " that says "Object Variable or With-Block Variable not defined" (in German), which sounds pretty basic, and I have the feeling more problems might wait ahead. Is the route I am trying at all possible?
Thanks in advance.
Try something like this:
Private Sub AbsendenNeu_Click()
Dim Cell As Range, rw As Range
Dim con As ADODB.Connection
Dim strSQL As String
Dim CatID, LineItems
Dim CustomerUniqueName As String
Dim TransactionID As String
CustomerUniqueName = Worksheets("Eingabe").CustomerSelect.Value
TransactionID = "1-" & CustomerUniqueName & Now()
'Open the database connection
Set con = New ADODB.Connection
con.Open "Driver={ODBC Driver 17 for SQL Server};Server=tcp:my-servername,1433;" & _
"Database=my-database;Uid=my-User;Pwd=My-Password;Encrypt=yes;" & _
"TrustServerCertificate=no;Connection Timeout=30;"
'loop each row in the input range
For Each rw In Worksheets("EmissionenNeu").Range("B2:C39").Rows
CatID = rw.Cells(1).Value
LineItems = rw.Cells(2).Value
If Len(LineItems) > 0 Then
strSQL = "INSERT INTO tblTransactions(ShopID,TransactionID,CategoryID," & _
"CustomerUniqueName,LineItems) VALUES" & _
"(1,'" & TransactionID & "','" & CatID & "', '" & _
CustomerUniqueName & "','" & LineItems & "')"
con.Execute strSQL
End If
Next rw
con.Close
Set con = Nothing
End Sub

Query MS Access using Excel VBA, SQL BETWEEN dates query

all--
I'm attempting to use an SQL query to pull records from an Access db into an Excel VBA userform listbox using the following code:
Sub FillLBBillIDs()
'build bill ID list box with bill IDs available in database, based on client and/or date range
'<---------------------------------------------------Dimension all variables
Dim con As Object, cmd As Object, rst As Object
Dim Path As String, CName As String
Dim FromDate As Date, ToDate As Date
Dim X As Long, Y As Long
'<---------------------------------------------------Define Default Variables
X = 0
CName = AuditParametersFRM.CBOCxName.Value
FromDate = AuditParametersFRM.DTPFrom.Value
ToDate = AuditParametersFRM.DTPTo.Value
'<---------------------------------------------------Define Access connection
Set con = CreateObject("ADODB.Connection"): Set cmd = CreateObject("ADODB.Command"): Set rst = CreateObject("ADODB.RecordSet"):
Path = Sheets("AuditTool").Range("B2").Value
'<---------------------------------------------------Open Access connection
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Path & ";Persist Security Info=False;"
con.ConnectionTimeout = 0: con.CommandTimeout = 0: con.Open: cmd.CommandTimeout = 0: Set cmd.ActiveConnection = con
'<---------------------------------------------------Find all bill IDs in the database which match the selected client and
'<---------------------------------------------------are within the consolidated date range
rst.Open "SELECT DISTINCT AdHocReport.[BillID] FROM AdHocReport WHERE AdHocReport.[CxName] = '" & CName & "' AND AdHocReport.[ConsolidationDate] BETWEEN #" & FromDate & "# AND #" & ToDate & "#", con, 1, 3
On Error Resume Next
rst.MoveLast
rst.MoveFirst
Y = 0
Y = rst.RecordCount
AuditToolFRM.LBBillIDs.Clear
If Not Y = 0 Then
Do Until rst.EOF
'<---------------------------------------------------Build the listbox with the acquired information
With AuditToolFRM.LBBillIDs
.AddItem
.List(X, 0) = rst![BillID]
X = X + 1
End With
rst.MoveNext
Loop
End If
rst.Close
On Error GoTo 0
con.Close
End Sub
This code works just fine if I use a greater than argument, thusly:
rst.Open "SELECT DISTINCT AdHocReport.[BillID] FROM AdHocReport WHERE AdHocReport.[CxName] = '" & CName & "' AND AdHocReport.ConsolidationDate > #" & FromDate & "#", con 1, 3
I've gone through all the pertinent questions on this site and can't find anything that works. Any ideas?
Thanks in advance!
12/08/2017 12:54
I've done more testing and it appears that the greater than query isn't working either; it's pulling all records that meet the first criteria whilst ignoring the second, even when using parentheses to enclose the second. This tells me that the issue is definitely in the date portion of the query somehow. Any help is appreciated greatly!
In Access
DATE_FIELD BETWEEN #2/2/2012# AND #2/4/2012#
is the same as
DATE_FIELD >=#2/2/2012# AND <=#2/4/2012#
When you have another AND put parathesis around the date range syntax.
rst.Open "SELECT DISTINCT AdHocReport.[BillID] FROM AdHocReport WHERE AdHocReport.[CxName] = '" & CName & "' AND (AdHocReport.[ConsolidationDate] BETWEEN #" & FromDate & "# AND #" & ToDate & "#)", con, 1, 3
In ADO you must use the ISO sequence in string expressions for date values:
... "' AND AdHocReport.[ConsolidationDate] BETWEEN #" & Format(FromDate, "yyyy\/mm\/dd") & "# AND #" & Format(ToDate, "yyyy\/mm\/dd") & "#" ...

Using inputs from Excel worksheet to run Access SQL query from vba

I have tables that are created each month to reflect that month's records. I have created vba code that runs a query in excel on multiple months to show changes, new adds, etc. However, I would like the user to be able to choose the two months they would like to compare from an excel drop down box. I am struggling to create dynamic SQL that can do this. Below is my attempted code
`Private Sub ADO_New()
Dim DBFullName As String
Dim Cnct As String, Src As String
Dim Connection As ADODB.Connection
Dim Recordset As ADODB.Recordset
Dim Col As Integer
Dim vCurrentMonth As Variant
Dim vPriorMonth As Variant
Dim wSummary As Worksheet
Set wSummary = Worksheets("Summary")
vCurrentMonth = wSummary.Range("Current_Month").Value
vPriorMonth = wSummary.Range("Prior_Month").Value
Worksheets("New").Cells.ClearContents
DBFullName = ThisWorkbook.Path & "\Guardian_CensusDB.accdb"
Set Connection = New ADODB.Connection
Cnct = "Provider=Microsoft.ACE.OLEDB.12.0;"
Cnct = Cnct & "Data Source=" & DBFullName & ";"
Connection.Open ConnectionString:=Cnct
Set Recordset = New ADODB.Recordset
With Recordset
Src = "SELECT * FROM [vCurrentMonth] LEFT JOIN [vPriorMonth] ON
[vCurrentMonth].[Plan Number] = [vPriorMonth].[Plan Number]" & _
"WHERE ((([vPriorMonth].[Plan Number]) Is Null))"
.Open Source:=Src, ActiveConnection:=Connection
For Col = 0 To Recordset.Fields.Count - 1
Sheets("New").Range("A1").Offset(0, Col).Value = _
Recordset.Fields(Col).Name
Next
Sheets("New").Range("A1").Offset(1, 0).CopyFromRecordset Recordset
End With
Set Recordset = Nothing
Connection.Close
Set Connection = Nothing
End Sub`
You need to concatenate the variables into your string:
Src = "SELECT * FROM [" & vCurrentMonth & "] LEFT JOIN [" & vPriorMonth & "] ON
[" & vCurrentMonth & "].[Plan Number] = [" & vPriorMonth & "].[Plan Number]" & _
"WHERE ((([" & vPriorMonth & "].[Plan Number]) Is Null))"

Sql query taking values from the column in the excelsheet using VBA(macro)

I need to use sql query using VBA. My input values for the query is from the Column in the excel sheet.I need to take all the values present in the column and it should be passed as input to the query to sqlserver. But i could'nt get the answer. I am getting type mismatch as error. could any one help me out. Thanks in advance
for example in J column contains J1=25, j2=26, ....so on
stSQL = "SELECT * FROM prod..status where state in"
stSQL = stSQL & wsSheet.Range("J:J").Value
My full code is below
Sub Add_Results_Of_ADO_Recordset()
'This was set up using Microsoft ActiveX Data Components version 2.8
Dim cnt As ADODB.Connection
Dim rst As ADODB.Recordset
Dim stSQL As Variant
Dim wbBook As Workbook
Dim wsSheet As Worksheet
Dim rnStart As Range
Const stADO As String = "Provider=SQLOLEDB.1;Integrated Security=SSPI;" & _
"Persist Security Info=False;" & _
"Initial Catalog=prod;" & _
"Data Source=777777777V009D\YTR_MAIN4_T"
'where BI is SQL Database & AURDWDEV01 is SQL Server
Set wbBook = ActiveWorkbook
Set wsSheet = wbBook.Worksheets("sheet1")
With wsSheet
Set rnStart = .Range("A2")
End With
' My SQL Query
stSQL = "SELECT * FROM prod..status where state in"
stSQL = stSQL + wsSheet.Range("J:J").Value
Set cnt = New ADODB.Connection
With cnt
.CursorLocation = adUseClient
.Open stADO
.CommandTimeout = 0
Set rst = .Execute(stSQL)
End With
'Here we add the Recordset to the sheet from A1
rnStart.CopyFromRecordset rst
'Cleaning up.
rst.Close
cnt.Close
Set rst = Nothing
Set cnt = Nothing
End Sub
change to
stSQL = stSQL + " ('" + Replace(wsSheet.range("J:J").Value, "'", "") + ")"
but sql IN statement is usually used like this
state IN (25,26,28)
But if you are only using one integer value you might want to go this way.
stSQL = "SELECT * FROM prod..status where state = "
stSQL = Val(wsSheet.range("J:J").Value)
There is though one thing that is dangerous in using a in statement.
If your In part of the statement is very long, it will become slow and then with even larger in statements crash altogeather.
The solution for that kind of situation is creating a temp table with the in values and do where in (temp table) or a inner join based on the temp table
There is no space after your "in" in your stSQL variable. So if your cell contains the value "TEST", stSQL will be
SELECT * FROM prod..status where state inTEST
I used for loop and mid command to convert the values in the column to a single variable. Below is the code i used to perform the function which i required
' Getting the last row
With wsSheet
lastrow1 = .Range("J" & .Rows.Count).End(xlUp).Row
End With
' Appending the values to a single variable
For i = 1 To lastrow
s1 = s1 & "'" & Val(wsSheet.Cells(i, 10)) & "'" & ","
Next
' Variable which could be used in IN command
If lastrow > 0 Then
s1 = Mid(s1, 1, Len(s1) - 1)
s1 = "(" & s1 & ")"
Else
Exit Sub
End If