Pull results into Excel from database - vba

I can't get this code to work. The first time I ran it, it prompted me for my password and the macro completes each time, but it is not pulling the result into sheet1. What can I do here?
Sub Update()
ThisWorkbook.Sheets("sheet1").Activate
ThisWorkbook.Sheets("sheet1").Range("A1").Select
Dim strStDt As String
Dim strEnDt As String
Dim strSQL As String
strStDt = ThisWorkbook.Worksheets("lookup").Range("B6").Value
strEnDt = ThisWorkbook.Worksheets("lookup").Range("B5").Value
strSQL = ""
strSQL = strSQL & "SELECT tkt.cntry_istto"
strSQL = strSQL & ",tkt.pod"
strSQL = strSQL & " FROM INTGY.GRUIP tkt"
strSQL = strSQL & " Where tky.year_month_nbr between " & strStDt & " and " & strEnDt
ThisWorkbook.Sheets("sheet1").Activate
ThisWorkbook.Sheets("sheet1").Range("A1").Select
With ActiveWorkbook.Connections(1).ODBCConnection
.BackgroundQuery = True
.Connection = "ODBC;DSN=#EDXX;UID=;;DATABASE=INTGY; AUTHENTICATION=;"
.CommandText = strSQL
.RefreshOnFileOpen = False
.SavePassword = False
.SourceConnectionFile = ""
.SourceDataFile = ""
.ServerCredentialsMethod = xlCredentialsMethodIntegrated
.AlwaysUseConnectionFile = False
.Refresh
End With
End Sub

Did you verify that strSQL is being entered correctly into your query? Put Msgbox strSQL before With ActiveWorkbook.Connections(1).ODBCConnection and make sure it appears as expected.
Also, all of this:
strSQL = ""
strSQL = strSQL & "SELECT tkt.cntry_istto"
strSQL = strSQL & ",tkt.pod"
strSQL = strSQL & " FROM INTGY.GRUIP tkt"
strSQL = strSQL & " Where tky.year_month_nbr between " & strStDt & " and " & strEnDt
Can be rewritten as:
strSQL = "SELECT tkt.cntry_istto,tkt.pod FROM INTGY.GRUIP tkt Where tky.year_month_nbr between " & strStDt & " and " & strEnDt

Use an ADO connection to retrieve a recordset and then use CopyFromRecordset to copy to worksheet range (specifying only the upper left cell).
Also, I am unaware of the database but pay attention to your dates which must be enclosed with either single quotes (for most databases) or if using MS Access enclose with # instead of quotes.
Dim conn As Object
Dim rst As Object
Dim strSQL As String, strStDt As String, strEnDt As String
Set conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
strStDt = ThisWorkbook.Worksheets("lookup").Range("B6")
strEnDt = ThisWorkbook.Worksheets("lookup").Range("B5")
strSQL = "SELECT tkt.cntry_istto, tkt.pod"
strSQL = strSQL & " FROM INTGY.GRUIP tkt"
strSQL = strSQL & " WHERE tkt.year_month_nbr"
strSQL = strSQL & " BETWEEN '" & strStDt & "' and '" & strEnDt & "'
conn.Open "DSN=#EDXX"
rst.Open strSQL, conn
ThisWorkbook.Sheets(1).Range("A1").CopyFromRecordest rst
rst.Close
Set rst = Nothing
Set conn = Nothing

Related

Data Type Mismatch error while using the SQL Update query

I am using SQL update query in VBA and I am getting the datatype mismatch error. I know that error is basically because of the column spare part. The spare part column contains numeric and alphanumeric values.
Public Function UpdateDistinctColumnFRNumberBasis()
StrInvoiceNumber = "109839-01"
FRSparepartNumber = "FT7119907459"
MergedInvoiceFile = "/test.xlsx"
Dim objConn As Object
Dim objRecordSet As Object
Set objConn = CreateObject("ADODB.Connection")
Set objRecCmd = CreateObject("ADODB.Command")
Set objRecCmd_Update = CreateObject("ADODB.Command")
objConn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & _
MergedInvoiceFile & ";Extended Properties=""Excel 8.0;""")
strSQL = " Update [Tabelle1$] SET [Status] = 'Include' Where " & _
"([RECHNR] ='" & StrInvoiceNumber & "' AND [Sparepart] = " & FRSparepartNumber & ")"
objConn.Execute strSQL
objConn.Close
End Function
As commented, the partnumber is text, thus it must be quoted in the SQL:
FRSparepartNumber = "FT7119907459"
' snip
strSQL = "Update [Tabelle1$] SET [Status] = 'Include' Where " & _
"([RECHNR] = '" & StrInvoiceNumber & "' AND " & _
"[Sparepart] = '" & FRSparepartNumber & "')"

How do I limit my sql to an end date in my Access report?

I created an Access database to track work orders and create/print schedules.
On the report I have two different print buttons. One prints the weeks schedule I'm currently viewing to my printer and the other button prints the current week and all future weeks to a PDF. My code for the 2nd button changes the SQL data source and works perfect.
That code looks like this (see pic):
Working SQL code
-----Set default printer to PDF-----
-working code-
-----Set the datasource to show everything from this week and future weeks excluding unscheduled (NULL)-----
Dim strSQL As String
Dim vbDblQuote As String
'set variable to = "
vbDblQuote = Chr(34)
'SQL for the data source
strSQL = "SELECT tblSchedule.ScheduleID, tblSchedule.Scheduled, tblSchedule.Attending, "
strSQL = strSQL & "tblSchedule.Time, tblSchedule.Account, tblSchedule.Address , "
strSQL = strSQL & "tblSchedule.Comments, tblSchedule.Contact, tblSchedule.WONumber "
strSQL = strSQL & "FROM tblSchedule "
strSQL = strSQL & "WHERE (((DatePart(" & vbDblQuote & "ww" & vbDblQuote & ",[Scheduled])) "
strSQL = strSQL & ">=DatePart(" & vbDblQuote & "ww" & vbDblQuote & ",Date()))"
strSQL = strSQL & "AND ((Year([Scheduled]))>=Year(Date())))"
strSQL = strSQL & "ORDER BY tblSchedule.Scheduled, tblSchedule.Attending, tblSchedule.Time;"
'set data source for the report
Reports![rptSchedule].Report.RecordSource = strSQL
-----Print and restore default printer-----
-working code-
Now I want to enable the user to select an end date for the report. I changed the code every which way I could but can't get it to work now. Can anyone help me with the new SQL? It contains a variable to accept the users date.
The new code looks like this (see pic): New Code
-----Set default printer to PDF-----
-working code-
-----Get the end date from user-----
Dim endDate
endDate = InputBox("Select an End Date m/d/yy")
-----Set the datasource to show everything from this week and future weeks excluding unscheduled (NULL)-----
Dim strSQL As String
Dim vbDblQuote As String
'set variable to = "
vbDblQuote = Chr(34)
Dim mySQLVariable
'set variable to user’s end date
mySQLVariable = endDate
'SQL for the data source
strSQL = "SELECT tblSchedule.ScheduleID, tblSchedule.Scheduled, tblSchedule.Attending, "
strSQL = strSQL & "tblSchedule.Time, tblSchedule.Account, tblSchedule.Address , "
strSQL = strSQL & "tblSchedule.Comments, tblSchedule.Contact, tblSchedule.WONumber "
strSQL = strSQL & "FROM tblSchedule "
strSQL = strSQL & "WHERE (((DatePart(" & vbDblQuote & "ww" & vbDblQuote & ",[Scheduled])) "
strSQL = strSQL & ">=DatePart(" & vbDblQuote & "ww" & vbDblQuote & ",Date()))"
strSQL = strSQL & "AND ((Year([Scheduled]))>=Year(Date())))"
strSQL = strSQL & "OR (((DatePart(" & vbDblQuote & "ww" & vbDblQuote & ", [Scheduled])) "
strSQL = strSQL & "<= DatePart(" & vbDblQuote & "ww" & vbDblQuote & ", Date() + '" & (mySQLVariable) & "')) "
strSQL = strSQL & "And ((Year([Scheduled])) = Year(Date() + '" & (mySQLVariable) & "'))) "
strSQL = strSQL & "ORDER BY tblSchedule.Scheduled, tblSchedule.Attending, tblSchedule.Time;"
'set data source for the report
Reports![Reset_Schedule].Report.RecordSource = strSQL
-----Print and restore default printer-----
-working code-
I hope this is clear enough to understand my problem.

Global Temporary table drops after another recordset is opened

I currently open and fill a global table with the name ##GlobalTableMain via a macro at the moment. The table gets created the following way:
Public Sub ExecuteSQLQuery(sQuery As String)
Dim cn As New ADODB.Connection
cn.Open strConnection
cn.Execute "SET NOCOUNT ON;" & sQuery
cn.Close
End Sub
The Query roughly looks like this:
CREATE TABLE ##GlobalTableMain (Columns here);
INSERT INTO ##GlobalTableMain (Columns) VALUES
BUNCH OF ROWS
All of this worked just fine until I tried to add another macro that became necessary due to another factor.
The query in question:
Sub AggregateSQLTempTable(sTempTable As String, sAggClm As String)
Dim cn As New ADODB.Connection, rs As New ADODB.Recordset, sQuery As String
Dim selectClms As String, groupClms As String
cn.Open strConnection
sQuery = "SET NOCOUNT ON; SELECT tempdb.sys.columns.name FROM tempdb.sys.columns WHERE tempdb.sys.columns.object_id = Object_Id('tempdb.." & sTempTable & "')"
rs.Open sQuery, cn
sQuery = vbNullString
selectClms = vbNullString
groupClms = vbNullString
If Not (rs.EOF Or rs.BOF) Then
rs.MoveFirst
Do While Not (rs.EOF Or rs.BOF)
selectClms = selectClms & IIf(Len(selectClms) > 0, ", ", "") & IIf(rs!Name = sAggClm, "SUM(" & rs!Name & ") " & rs!Name, rs!Name)
groupClms = groupClms & IIf(rs!Name = sAggClm, "", IIf(Len(groupClms) > 0, ", ", "") & rs!Name)
rs.MoveNext
Loop
sQuery = vbNullString
sQuery = "SELECT * INTO #aggTempTable FROM (SELECT " & selectClms & " FROM " & sTempTable & " GROUP BY " & groupClms & ") a;"
sQuery = sQuery & Chr(10) & "TRUNCATE TABLE " & sTempTable & ";"
sQuery = sQuery & Chr(10) & "INSERT INTO " & sTempTable & " SELECT * FROM #aggTempTable;"
sQuery = sQuery & Chr(10) & "DROP TABLE #aggTempTable;"
cn.Execute sQuery
End If
rs.Close
cn.Close
End Sub
Supposedly SET NOCOUNT ON should prevent this but it doesn't work for me unfortunately.
I've found a solution that helps me do this.
I went ahead and made the Connection a public variable and added the following two macros. Here are all the new macros:
Public cn As New ADODB.Connection
Public Sub OpenSQLConnection()
If Not cn.State = adStateOpen Then cn.Open strConnection
End Sub
Public Sub CloseSQLConnection()
If Not cn.State = adStateClosed Then cn.Close
End Sub
Public Sub ExecuteSQLQuery(sQuery As String)
OpenSQLConnection
cn.Execute "SET NOCOUNT ON;" & sQuery
End Sub
Sub AggregateSQLTempTable(sTempTable As String, sAggClm As String)
Dim rs As New ADODB.Recordset, sQuery As String
Dim selectClms As String, groupClms As String
OpenSQLConnection
sQuery = "SET NOCOUNT ON; SELECT tempdb.sys.columns.name FROM tempdb.sys.columns WHERE tempdb.sys.columns.object_id = Object_Id('tempdb.." & sTempTable & "')"
rs.Open sQuery, cn
sQuery = vbNullString
selectClms = vbNullString
groupClms = vbNullString
If Not (rs.EOF Or rs.BOF) Then
rs.MoveFirst
Do While Not (rs.EOF Or rs.BOF)
selectClms = selectClms & IIf(Len(selectClms) > 0, ", ", "") & IIf(rs!Name = sAggClm, "SUM(" & rs!Name & ") " & rs!Name, rs!Name)
groupClms = groupClms & IIf(rs!Name = sAggClm, "", IIf(Len(groupClms) > 0, ", ", "") & rs!Name)
rs.MoveNext
Loop
sQuery = vbNullString
sQuery = "SELECT * INTO #aggTempTable FROM (SELECT " & selectClms & " FROM " & sTempTable & " GROUP BY " & groupClms & ") a;"
sQuery = sQuery & Chr(10) & "TRUNCATE TABLE " & sTempTable & ";"
sQuery = sQuery & Chr(10) & "INSERT INTO " & sTempTable & " SELECT * FROM #aggTempTable;"
sQuery = sQuery & Chr(10) & "DROP TABLE #aggTempTable;"
cn.Execute sQuery
End If
rs.Close
End Sub

Append queried Recordset to Table in Access

I am querying Active Directory to list Users and other fields in Access. Is there a way to append my queried results into an existing table? Currently I am trying to use INSERT INTO but having issues with my Object variable not being set or block variable.
Private Sub Command0_Click()
Dim objRecordSet As Object
Dim objCommand As Object
Dim objConnection As Object
Dim dbs As Database
Const ADS_SCOPE_SUBTREE = 2
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.Properties("Sort On") = "whenCreated"
objCommand.CommandText = _
"SELECT Name,Title,PhysicalDeliveryOfficeName,WhenCreated,Mail FROM 'LDAP://OU=Standard Users,OU=Active Users,OU=All Users,DC=contoso,dc=local' WHERE objectCategory='user'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
dbs.Execute " INSERT INTO ADUsers" & "(Name,Title,Site,Created,Email) VALUES " & "(objRecordSet.Fields('Name').Value,objRecordSet.Fields('Title').Value,objRecordSet.Fields('physicalDeliveryOfficeName').Value,objRecordSet.Fields('whenCreated').Value,objRecordSet.Fields('Mail').Value);"
dbs.Close
Debug.Print objRecordSet.Fields("Name").Value; "," & objRecordSet.Fields("Title").Value; "," & objRecordSet.Fields("physicalDeliveryOfficeName").Value; "," & objRecordSet.Fields("whenCreated").Value; "," & objRecordSet.Fields("Mail").Value
objRecordSet.MoveNext
Loop
End Sub
Everything inside doublequotes " is interpreted as string not as code and strings (the values of objRecordSet.Fields("myFieldName").Value) have to be quoted in insert statement.
dim strSQLInsert as String
strSQLInsert = "INSERT INTO ADUsers(Name,Title,Site,Created,Email) VALUES ('" & _
objRecordSet.Fields("Name").Value & "','" & _
objRecordSet.Fields("Title").Value & "','" &
objRecordSet.Fields("physicalDeliveryOfficeName").Value & "','" & _
objRecordSet.Fields("whenCreated").Value & "','" & _
objRecordSet.Fields("Mail").Value & "');"
Debug.Print strSQLInsert
dbs.Execute strSQLInsert
Store your sql statements in a string, then you can check it with Debug.Print.
Consider a parameterized query using querydefs to avoid the need of quotes. Also be sure to initialize the database object which may be your main issue: set dbs = CurrentDb.
...
Dim strSQL As String
Set dbs = CurrentDb
strSQL = "PARAMETERS NameParm TEXT(255), TitleParam TEXT(255), SiteParam TEXT(255)," _
& " CreatedParm Date, EmailParam TEXT(255);" _
& " INSERT INTO ADUsers (Name, Title, Site, Created, Email)" _
& " VALUES ([NameParm], [TitleParam], [SiteParam], [Created], [Email]);"
Do Until objRecordSet.EOF
Set qdef = dbs.CreateQueryDef("", strSQL)
qdef!NameParam = objRecordSet![Name]
qdef!TitleParam = objRecordSet![Title]
qdef!SiteParam = objRecordSet![PhysicalDeliveryOfficeName]
qdef!CreatedParam = objRecordSet![WhenCreated]
qdef!EmailParam = objRecordSet![Mail]
qdef.Execute (dbfailOnError)
Set qdef = Nothing
objRecordSet.MoveNext
Loop

form not found error. MS Access SQL

I'm getting an error saying that Access cannot find the referenced form CFRRR but there is definitely a form there. Not sure if I'm just not writing the code correctly.
Public Function AssignNullProjects() As Long
Dim db As dao.Database
Dim rs As dao.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT CFRRRID, [program], [language] FROM CFRRR WHERE assignedto Is Null"
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
If Not rs.BOF And Not rs.EOF Then
While Not rs.EOF
strSQL = "UPDATE CFRRR SET assignedto = " & GetNextAssignee & ", assignedby = " & [Forms]![CFRRR]![assignedby] & ", Dateassigned = #" & Now & "#, actiondate = #" & Now & "#, Workername = " & _ [Forms]![CFRRR]![assignedto] & ", WorkerID = " & [Forms]![CFRRR]![assignedto] & " WHERE CFRRRID = " & rs!CFRRRID
db.Execute strSQL, dbFailOnError
rs.MoveNext
Wend
End If
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
End Function
Public Function GetNextAssignee(program As String, Language As String) As Long
' Returns UserID as a Long Integer with the lowest [TS] value,
' and updates same [TS] by incremented with 1.
Dim db As dao.Database
Dim rs As dao.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT TOP 1 WorkerID FROM attendance WHERE [Programs] LIKE '*" & program & "*' AND [Language] = '" & Language & "' AND [Status] = '" & Available & "' ORDER BY TS ASC"
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
If Not rs.BOF And Not rs.EOF Then
'Found next assignee, update date/time stamp
'strSQL = "UPDATE tblUser SET TS = " & DMax("[TS]", tblUser) + 1 & " WHERE [WorkerID]= " & rs!workerid
strSQL = "UPDATE attendance SET TS = " & DMax("[TS]", "attendance") + 1 & " WHERE [WorkerID]= " & rs!workerid
db.Execute strSQL, dbFailOnError
GetNextAssignee = rs!workerid
Else
'Field TS has NO VALUE FOR ALL RECORDS!
'Code calling this function should check for a return of 0 indicating an error.
GetNextAssignee = 0
End If
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
End Function