Update case when sql query to vba - sql-server

I've been trying to convert the below code from SQL Server to run directly from Excel VBA. But unable to do so.
Update Legal
Set Category = Case
when datediff(month, GETDATE(), [End date]) > 9
then 'Blue'
when datediff(month, GETDATE(), [End date]) < 9
and datediff(month, GETDATE(), [end date]) > 1
then 'Orange'
when datediff(month, GETDATE(), [End date]) < 2
then 'Red'
End
where classification = 'A'
Select
classification,
datediff(month, GETDATE(), [End date]),
Category
from
Legal
Into VBA like below
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 SQLSelect As String
Dim rs As ADODB.Recordset
Dim sqlcmd as string
cbb = Environ("computername")
With Sheet3.Range("A4:Z" & Rows.Count)
.ClearContents
'.ClearFormats
End With
sqlcmd = "Update Legal Set Category = Case" & _
" when datediff(month,GETDATE(),[End date])>9 then 'Blue'" & _
" when datediff(month,GETDATE(),[End date])<9 and datediff(month,GETDATE(),[end date])>1 then 'Orange'" & _
" when datediff(month,GETDATE(),[End date])<2 then 'Red'" & _
" End " & _
" where classification = 'A'"
Debug.Print sqlcmd
With Sheet3.ListObjects.Add(SourceType:=0, Source:=Array( _
"OLEDB;Provider=SQLOLEDB.1;Persist Security Info=True;User ID=Login_ID;Password=Password;Data Source=Server_Name;Use Procedure f" _
, _
"or Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=" & cbb & ";Use Encryption for Data=False;Tag with column collatio" _
, "n when possible=False;Initial Catalog=DB_Name"), Destination:=Sheet3.Range( _
"$A$4")).QueryTable
.CommandType = xlCmdSql
.CommandText = sqlcmd
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.SourceConnectionFile = _
"C:\Users\xxxxx\Documents\My Data Sources\xxxxx.odc"
.ListObject.DisplayName = _
"AP_123"
.Refresh BackgroundQuery:=False
End With
This query works absolutely in SQL Server. But I get the following error in VBA:
The query did not run, or the database table could not be opened.
Check the database server or contact your database administrator. Make sure the external database is available and hasn't been moved or reorganized, then try the operation again.
Kindly help me guys!! Been trying this for weeks!
P.S. Do not require a Power Query as it will ask for credentials to the other users whom do not have access to the server

As mentioned, simply separate the two queries by first actually running the action UPDATE statement and then connect your QueryTable to SELECT statement. You can even shorten connection string in Source argument:
Dim Cn As ADODB.Connection, rs As ADODB.Recordset
Dim Server_Name As String, Database_Name As String
Dim User_ID As String, Password As String
Dim conn_str As String, SQLSelect As String, sqlcmd as string
cbb = Environ("computername")
With Sheet3.Range("A4:Z" & Rows.Count)
.ClearContents
'.ClearFormats
End With
conn_str = "Provider=SQLOLEDB.1;Persist Security Info=True;User ID=Login_ID;Password=Password;" & _
"Data Source=Server_Name;Use Procedure for Prepare=1;Auto Translate=True;" & _
"Packet Size=4096;Workstation ID=" & cbb & ";Use Encryption for Data=False;" & _
"Tag with column collation when possible=False;Initial Catalog=DB_Name"
Cn.Open conn_str
' EXECUTE ACTION QUERY
sqlcmd = "UPDATE Legal SET Category = Case" & _
" when datediff(month,GETDATE(),[End date])>9 then 'Blue'" & _
" when datediff(month,GETDATE(),[End date])<9 and " & _
" datediff(month,GETDATE(),[end date])>1 then 'Orange'" & _
" when datediff(month,GETDATE(),[End date])<2 then 'Red'" & _
" End " & _
" where classification = 'A'"
Cn.Execute sqlcmd
' CONNECT TO SELECT QUERY
sqlcmd = "SELECT classification, datediff(month, GETDATE(), [End date]), Category " & _
" FROM Legal;"
With Sheet3.ListObjects.Add(SourceType:=0, Source:=Array( _
"OLEDB;" & conn_str), Destination:=Sheet3.Range( _
"$A$4")).QueryTable
.CommandType = xlCmdSql
.CommandText = sqlcmd
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.SourceConnectionFile = _
"C:\Users\xxxxx\Documents\My Data Sources\xxxxx.odc"
.ListObject.DisplayName = _
"AP_123"
.Refresh BackgroundQuery:=False
End With
Cn.Close
Set Cn = Nothing

Here's the stored procedure method. In SSMS, run this one time
CREATE PROCEDURE dbo.UpdateAndGetLegal
AS
UPDATE Legal
SET Category = CASE WHEN DATEDIFF(MONTH, GETDATE(), [End date]) > 9 THEN 'Blue'
WHEN DATEDIFF(MONTH, GETDATE(), [End date]) < 9
AND DATEDIFF(MONTH, GETDATE(), [end date]) > 1 THEN 'Orange'
WHEN DATEDIFF(MONTH, GETDATE(), [End date]) < 2 THEN 'Red'
END
WHERE classification = 'A'
SELECT classification
, DATEDIFF(MONTH, GETDATE(), [End date])
, Category
FROM Legal
That will create a stored procedure that runs the update and returns the SELECT results.
In Excel, I almost never have to .Add a ListObject. Sometimes I have to change the SQL statement of an existing ListObject, but once a table is created, you don't really need to create it again. So I'm not entirely sure what you're doing, but here's how it would look in one of my projects.
I create an Excel file (or template if it's something I'm generating on the fly). In that file, I create an external data ListObject with a commandtext of
EXEC UpdateAndGetLegal
Then if the user simply refreshes the table, I'm done. If I need my code to refresh the table, it's
Sheet3.ListObjects(1).QueryTable.Refresh
If you're passing Windows credentials through to SQL Server, all of the users will need EXECUTE rights for the stored procedures.

I'm taking a bit of a guess here, but it's based on something that feels off.
Every time you run your SELECT to get some data
Select
classification,
datediff(month, GETDATE(), [End date]),
Category
from
Legal
You first run an UPDATE...
Update Legal
Set Category = Case
when datediff(month, GETDATE(), [End date]) > 9
then 'Blue'
when datediff(month, GETDATE(), [End date]) < 9
and datediff(month, GETDATE(), [end date]) > 1
then 'Orange'
when datediff(month, GETDATE(), [End date]) < 2
then 'Red'
End
where classification = 'A'
That's strange and I can't think of a usecase where this would be appropriate in any database. Instead you could just have a SELECT all by itself:
Select
classification,
datediff(month, GETDATE(), [End date]),
Case WHEN classification = 'A'
THEN
CASE
when datediff(month, GETDATE(), [End date]) > 9
then 'Blue'
when datediff(month, GETDATE(), [End date]) < 9
and datediff(month, GETDATE(), [end date]) > 1
then 'Orange'
when datediff(month, GETDATE(), [End date]) < 2
then 'Red'
End
ELSE Category
END
from
Legal
That does the same thing, but without touching the underlying data in Legal. This SELECT is the one that you want to shoehorn in to your VBA/QueryTable.

Related

VBA: object is closed error in sql query when using a join table

I am getting the error for the ws.Cells(2, 2).CopyFromRecordset adoDbRs line:
operation is not allowed when the object is closed
If I remove the JOIN to the temp table #reporttable, it works fine, I feel like the recordset is empty because I'm sending it to a temp table and then trying to JOIN and pull out of that, but I'm not sure how to take the output from the final select query properly, it works fine when reformatted and typed directly into the SQL Server.
Secondary question:
Since I have been struggling with this, but can always get it working on the server, is there a way to setup a custom call to the SQL Server which is like command(var1,var2,var3) which runs a stored brick of working code on the SQL Server and returns what it returns, instead of my current process which is get it to work on the SQL Server and then struggle to adapt it into VBA?
Private Sub Run_Summary_Click()
Dim adoDbConn As New ADODB.Connection
Dim adoDbRs As New ADODB.Recordset
Dim selectCmd As New ADODB.Command
Dim Machvar As Integer
Machvar = Worksheets("SumImport").Range("A1").Value
Dim DateYMD As String
Dim DateStart As Date
Dim DateEnd As Date
Dim SQL As String
DateYMD = Format(Worksheets("SumImport").Range("A2").Value, "YYYY-MM-DD")
' Open connection to the SQL Server database
adoDbConn.Open "Provider=SQLOLEDB; Data Source=********; Initial Catalog=SMP; User Id=Query;"
' Execute the select query
selectCmd.ActiveConnection = adoDbConn
selectCmd.CommandText = "IF OBJECT_ID('tempdb.#reporttable2') IS NOT NULL DROP TABLE #reporttable2 " & _
" SELECT " & _
" DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101') as Date_Time " & _
" ,max(Part_Count)-min(Part_Count) as PartsMade " & _
" ,max(convert(char(5), DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101'), 108)) as times " & _
" ,max(Alarm_Light) as AlarmLight " & _
" ,max(PV_Alarm) as AlarmCode " & _
" INTO #reporttable2 " & _
" FROM [33_TestImport]" & _
" Where [DateTime]>= DateAdd(Hour, DateDiff(Hour, 0, '" & DateYMD & "')-0, 0) AND [DateTime]<= DateAdd(Hour, DateDiff(Hour, 0, '" & DateYMD & "')+24, 0) " & _
" AND Machine_Number = " & Machvar & " " & _
" Group BY DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101') " & _
" select * " & _
" from #reporttable2 p " & _
" right join SMP.dbo.Timerange c " & _
" ON c.mins = p.times " & _
" order by mins "
Set adoDbRs = selectCmd.Execute(, , adCmdText)
' Clear the contents in cells where we're going to display the result
Dim cellRange As Range
Dim ws As Worksheet
Set ws = Worksheets("SumImport")
ws.Activate
Set cellRange = Worksheets("SumImport").Range("B1:M1800")
cellRange.ClearContents
' Activate the Worksheet
Set ws = Worksheets("SumImport")
ws.Activate
' Put the query results starting from cell B2
ws.Cells(2, 2).CopyFromRecordset adoDbRs
' Set the column header
ws.Cells(1, 2) = "DateTime"
ws.Cells(1, 3) = "Part Total"
ws.Cells(1, 4) = "TimeSync"
ws.Cells(1, 5) = "Alarm Light"
ws.Cells(1, 6) = "Alarm Code"
' Close the connection and free the memory
Set adoDbRs = Nothing
Set selectCmd = Nothing
adoDbConn.Close
Set adoDbConn = Nothing
Set ws = Worksheets("Summary")
ws.Activate
End Sub
And the code that works in SQL directly
drop table #reporttable2
declare #dateget as date
set #Dateget = '2020-03-19'
SELECT
DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101') as Date_Time
,max(Part_Count)-min(Part_Count) as PartsMade
,max(convert(char(5), DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101'), 108)) as times
into #reporttable2
FROM
[SMP].[dbo].[33_TestImport]
where [DateTime]>= DateAdd(Hour, DateDiff(Hour, 0, #Dateget)-1, 0)
and [DateTime]<= DateAdd(Hour, DateDiff(Hour, 0, #Dateget)+24, 0)
GROUP BY
DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101')
select *
from #reporttable2 p
right join SMP.dbo.Timerange c
ON c.mins = p.times
order by mins
In VBA, ADO connections do not support multiple line SQL commands. Therefore, the recordset is possibly being created based on the very first line of SQL or the DROP statement and may not return anything.
However, looking closer at your situation, consider a Common Table Expression (CTE) and avoid the need of a temp table and then integrate a parameterized query for your date variable. Doing so, your original 5 statements convert to a single statement:
SQL
WITH reporttable2 AS (
SELECT
DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5) * 5, '20000101') AS Date_Time
, MAX(Part_Count) - MIN(Part_Count) AS PartsMade
, MAX(CONVERT(CHAR(5), DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101'), 108)) AS times
FROM
[SMP].[dbo].[33_TestImport]
WHERE [DateTime] >= DATEADD(Hour, DATEDIFF(Hour, 0, #Dateget) - 1, 0)
AND [DateTime] <= DATEADD(Hour, DATEDIFF(Hour, 0, #Dateget) + 24, 0)
GROUP BY
DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5) * 5, '20000101')
)
SELECT *
FROM reporttable2 p
RIGHT JOIN SMP.dbo.Timerange c
ON c.mins = p.times
ORDER BY mins
VBA
' ASSIGN DATE (NOT STRING) VARIABLE FOR PARAMETER
myDate = Worksheets("SumImport").Range("A2").Value
' PREPARED STATEMENT WITH QMARKS ?
sql = "WITH reporttable2 AS ( " _
& " SELECT " _
& " DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5) * 5, '20000101') AS Date_Time " _
& " , MAX(Part_Count) - MIN(Part_Count) AS PartsMade " _
& " , MAX(CONVERT(CHAR(5), DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5)*5, '20000101'), 108)) AS times " _
& " FROM " _
& " [SMP].[dbo].[33_TestImport] " _
& " WHERE [DateTime] >= DATEADD(Hour, DATEDIFF(Hour, 0, ?) - 1, 0) " _
& " AND [DateTime] <= DATEADD(Hour, DATEDIFF(Hour, 0, ?) + 24, 0) " _
& " GROUP BY " _
& " DATEADD(MINUTE, (DATEDIFF(MINUTE, '20000101', DateTime) / 5) * 5, '20000101') " _
& ")" _
& " " _
& " SELECT * " _
& " FROM reporttable2 p " _
& " RIGHT JOIN SMP.dbo.Timerange c " _
& " ON c.mins = p.times " _
& " ORDER BY mins"
With selectCmd
.ActiveConnection = adoDbConn
.CommandText = sql
.CommandType = adCmdText
' BIND TWO PARAM VALUES
.Parameters.Append .CreateParameter("param1", adDate, adParamInput, , myDate)
.Parameters.Append .CreateParameter("param2", adDate, adParamInput, , myDate)
' ASSIGN RECORDSET TO RESULT
Set adoDbRs = .Execute
End With

I am gettin a null error in the code below for one user

The function below is trying to get the earliest date from a table with 3 dates, one for each type of user, care, sales and manager. This is to build up the diary system by first finding the first date in the diary dates. It's working for some users, but in one case the values do not return at and it gives null.
Private Function GetEarliestDate() As Date
Dim strSQL As String
Dim cmd As New SqlCommand
Dim dDate As Date
Try
strSQL = "Select dT.RecordID, MIN(dT.inDate) As [EarliestDate]
FROM (
Select RecordID, SentDate As [inDate]
From tblOrderDetails Where Flagged = 0 AND SalesID = '" & gUserID & "'
UNION ALL
Select RecordID, DiaryDate AS [inDate]
From tblOrderDetails
Where Flagged=0 And ManID ='" & gUserID & "'
UNION ALL
Select RecordID, CareDate As [inDate]
From tblOrderDetails
Where Flagged = 0 And CareID ='" & gUserID & "'
) As dT Group By RecordID"
cmd.CommandText = strSQL
cmd.Connection = CnMaster
cmd.CommandType = CommandType.Text
Dim RecordCount As Integer
RecordCount = 0
dDate = DateTime.MaxValue
Using reader As SqlDataReader = cmd.ExecuteReader()
While (reader.Read())
RecordCount += 1
Dim dt As DateTime = reader.GetDateTime(1)
If dt < dDate Then
dDate = dt
End If
End While
If dDate = DateTime.MaxValue Then
dDate = DateTime.MinValue
End If
End Using
cmd.Dispose()
Return dDate
Catch ex As Exception
Error_Handler(ex, "GetEarliestDate", "Unable to Get The Earliest Date!")
End Try
Put in all 3 queries additional where:
where SentDate is not null ...
where DiaryDate is not null ...
where CareDate is not null ...

Connecting to Excel ODBC

I have the below query and I was wondering how to setup an ODBC connection to get this to an excel spreadsheet.
declare #StartDate DATE
declare #EndDate DATE
SELECT Sum(case when status = 6 then 1 else 0 end) as Failed,
Sum(case when status = 9 then 1 else 0 end) as Successful,
UniqueID
Into #tempsheet1
FROM Documents
WHERE ownerID = 467
and status in (6,9)
and CreationTime between #StartDate and #EndDate
Group By UniqueID
Select D.UniqueID, FromName, ToName, CreationTime,
cast(CreationTime as date) as CreationDate, cast(CreationTime as date) as CreationTime,
ErrorCode, ElapsedSendTime, RemoteID
From #tempsheet1 ts1
Inner Join Documents D On
D.UniqueID = ts1.UniqueID
and [Status] = 9
ORDER BY D.CreationTime desc
I'm still researching stuff online, but if anyone can point me in the right direction or give me some tips that would be awesome.
In excel go to Data tab > Get external data > From other sources > From Microsoft Query. From there depends on what type of database you are connecting to but the wizard should guide you through.
Once you have your connection set you can right click in the resulting data set and select table > edit query, choose command type = SQL and then edit your query as required.
Depending on what you are doing an ADO db connection may be better and will allow you to set dynamic date filters and the like... but that is another topic
Edit: ADO approach below
Add a reference to Microsoft ActiveX Data objects library
Figure out your connection string: https://www.connectionstrings.com/
Implement something like the below
.
Sub adoConExample()
Dim startDate As String
Dim endDate As String
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sql As String
Set con = New ADODB.Connection
Set rs = New ADODB.Recordset
startDate = format("Your date range reference".value, "yyyy-mm-dd")
endDate = format("Your date range reference".value, "yyyy-mm-dd")
With con
.ConnectionString = "Your connection string"
.CursorLocation = adUseClient
.Open
End With
sql = "Your sql string"
sql = Replace(sql, "DATE1", startDate)
sql = Replace(sql, "DATE2", endDate)
rs.CursorLocation = adUseClient
rs.Open sql, con, adOpenStatic, adLockReadOnly, adCmdText
"Your paste target range".CopyFromRecordset rs
con.Close
rs = Nothing
con = Nothing
End Sub

Access 2010 report constrained between dates

I am trying to get a form setup to launch various reports based on different criteria and I am having problems getting one of the reports that is a GroupBy/Count/Sum based SQL Data source to work between 2 unbound textboxes serving as a FromDate and a ToDate.
VBA script - calling report from form (frmRptFeedback):
Private Sub cmdPrint_Click()
If Not chkPrintPreview Then
Set Application.Printer = Application.Printers.Item(cboPrinter.Value)
End If
Dim strCondition As String
Dim strFromDate As String
Dim strToDate As String
strFromDate = txtFromDate.Value
strToDate = txtToDate.Value
Select Case opgOptions
Case 1 ' Feedback By Employee
If IsNull(cboEmployee.Value) Then
strCondition = "DateSubmitted BETWEEN '" & strFromDate & "' AND '" & strToDate & "'"
Else
strCondition = "RespEmp = '" & cboEmployee.Value & "' AND DateSubmitted BETWEEN '" & _
strFromDate & "' AND '" & strToDate & "'"
End If
Call OpenReport("rptFeedbackByEmp", IIf(chkPrintPreview, acViewPreview, acViewNormal), strCondition)
Case 2 ' Feedback By Team
If IsNull(cboTeam.Value) Then
strCondition = "DateSubmitted BETWEEN '" & strFromDate & "' AND '" & strToDate & "'"
Else
strCondition = "EmpType = '" & cboTeam.Value & "' AND DateSubmitted BETWEEN '" & _
strFromDate & "' AND '" & strToDate & "'"
End If
Call OpenReport("rptFeedbackByTeam", IIf(chkPrintPreview, acViewPreview, acViewNormal), strCondition)
Case 3 ' Feedback By Project #
If IsNull(txtProjectID) Then
strCondition = "DateSubmitted BETWEEN '" & strFromDate & "' AND '" & strToDate & "'"
Else
strCondition = "ProjectID = " & txtProjectID & "AND DateSubmitted BETWEEN '" & _
strFromDate & "' AND '" & strToDate & "'"
End If
Call OpenReport("rptFeedbackByProject", IIf(chkPrintPreview, acViewPreview, acViewNormal), strCondition)
End Select
If Not chkPreview Then
Set Application.Printer = Nothing
End If
End Sub
SQL query - initially pulling data into main SQL View (vueRptFeedback):
SELECT f.FeedbackID, f.BFID, bf.ProjectID, p.ProjectName, e2.Name AS PM, e1.Name AS RespEmp,
et.Description AS EmpType, f.SubByInits, f.DateSubmitted, f.QtyIssues,
f.EstHoursImpact, f.PlusDelta, f.Notes, f.HowResolved
FROM dbo.tblEmployee e2
INNER JOIN dbo.tblProject p
INNER JOIN dbo.tblBookingForm bf
ON p.ProjectID = bf.ProjectID
ON e2.EmployeeID = p.Scope_PM_EmployeeID
RIGHT OUTER JOIN dbo.tblEmployeeType et
INNER JOIN dbo.tblEmployee e1
ON et.EmployeeTypeID = e1.EmployeeTypeID
INNER JOIN dbo.tblFeedback f
ON e1.EmployeeID = f.ResponsibleEmpID
ON bf.BookingFormID = f.BFID
SQL query - current recordsource for report by Project ID (vueRptFeedbackByProject):
SELECT ProjectID, ProjectName, RespEmp, COUNT(FeedbackID) AS CountReports,
SUM(QtyIssues) AS SumIssues, SUM(EstHoursImpact) AS SumHours
FROM vueRptFeedback
WHERE (DateSubmitted
BETWEEN CONVERT(DATETIME, [Forms]![frmRptFeedback]![txtFromDate], 102)
AND CONVERT(DATETIME, [Forms]![frmRptFeedback]![txtToDate], 102))
GROUP BY ProjectID, RespEmp, ProjectName, DateSubmitted
ORDER BY ProjectID, RespEmp
I know my problem is in the WHERE clause as when I take it out, the report pulls fine but with all records, not the ones between those two dates. Once I can get the report to pull between the txtFromDate and txtToDate, I will probably need to change the OpenReport() to pass the txtFromDate and txtToDate as parameters instead of a Between X and Y, but I keep getting tripped up by syntax on the Recordsource of the report.
Fundamentally, you are conflating two SQL dialects - SQL Server SQL and MS Access SQL. There is no CONVERT() function in Access SQL syntax which appears to be the engine running the recordsource of the report and not the pass-through query, vueRptFeedback, run by MSSQL.
Consider using FORMAT() to align dates to ANSI datetime format: YYYY-MM-DD:
SELECT ProjectID, ProjectName, RespEmp, COUNT(FeedbackID) AS CountReports,
SUM(QtyIssues) AS SumIssues, SUM(EstHoursImpact) AS SumHours
FROM vueRptFeedback
WHERE (DateSubmitted
BETWEEN FORMAT([Forms]![frmRptFeedback]![txtFromDate], "YYYY-MM-DD")
AND FORMAT([Forms]![frmRptFeedback]![txtToDate], "YYYY-MM-DD"))
GROUP BY ProjectID, RespEmp, ProjectName, DateSubmitted
ORDER BY ProjectID, RespEmp
On the VBA side, you can still use Format() as many of Access's SQL functions derived from VBA functions (possibly, this is the reason Access SQL differs from its other RDMS counterparts who adhere to ANSI more due to the need to stay compatible in MS Office VBA context):
Dim strFromDate As String
Dim strToDate As String
strFromDate = Format(txtFromDate.Value, "YYYY-MM-DD")
strToDate = Format(txtToDate.Value, "YYYY-MM-DD")
...

SQL Server stored procedure does not return data to the class but works fine in SQL Server Management Studio

I'm trying to retrieve data from this SQL Server stored procedure from a vb class and on the class:
Dim GetDailySalesAmateurRptOrderItems_DataArray(,) As String =
oDAL.GetDailySalesAmateurRptOrderItems("2014-04-17", "2014-04-20")
Even though there is enough data in the database it returns nothing to the array... any idea what is causing this problem?
USE [QUICKFIX_COLOR_LAB_POS]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[GetDailySalesAmateurRptOrderItems]
#FromDate Datetime, #ToDate Datetime
as
SELECT
ITEMS.ItemID, ITEMS.ItemName, ORDER_ITEMSET.Qty,
ORDER_ITEMSET.SoldPrice, ORDERS.OrderTimestamp
FROM
ORDERS
INNER JOIN
ORDER_ITEMSET ON ORDERS.OrderID = ORDER_ITEMSET.OrderID
INNER JOIN
CUSTOMER_ACCOUNTS ON ORDERS.CustomerID = CUSTOMER_ACCOUNTS.CUSTOMER_ID
CROSS JOIN
ITEMS
WHERE
(CUSTOMER_ACCOUNTS.CUSTOMER_CATEGORY = 'Amateur')
AND (ORDERS.OrderTimestamp BETWEEN CONVERT(DATETIME, #FromDate, 102) AND CONVERT(DATETIME, #ToDate, 102))
ORDER BY
ITEMS.ItemID
VB function
Function GetDailySalesAmateurRptOrderItems(DateFrom As String, ByVal DateTo As String)
Try
Dim DateFrom_Date As DateTime = DateFrom
Dim DateTo_Date As DateTime = DateTo
Dim output(,) As String
Dim counter As Integer
Dim cmd As New SqlCommand("GetDailySalesAmateurRptOrderItems", DBconn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#FromDate", DateFrom_Date)
cmd.Parameters.AddWithValue("#ToDate", DateTo_Date)
Dim reader As SqlDataReader
DBconn.Open()
reader = cmd.ExecuteReader
While reader.Read()
counter = counter + 1
End While
ReDim output(counter - 1, 0 To 4)
counter = 0
reader.Close()
reader = cmd.ExecuteReader
While reader.Read()
output(counter, 0) = reader(0)
output(counter, 1) = reader(1)
output(counter, 2) = reader(2)
output(counter, 3) = reader(3)
output(counter, 4) = reader(4)
counter = counter + 1
End While
DBconn.Close()
Return output
Catch ex As Exception
Return ex.Message
End Try
End Function

Resources