Translating SQL query to VBA - sql

I have got SQL query running successfully in Oracle, the code is-
Select Sam.SAM_ID, sum( case when Aud.AUDIT_COMPLETION between (next_day(trunc(sysdate, 'iw'), 'Friday') - 14) and
(next_day(trunc(sysdate, 'iw'), 'Friday') - 7) then 1 else 0 end ) as "Major Defects - 1 week",
sum( case when Aud.AUDIT_COMPLETION between (next_day(trunc(sysdate, 'iw'), 'Friday') - 28) and (next_day(trunc(sysdate, 'iw'), 'Friday') - 7) then 1 else 0 end ) as "Major Defect - 4 week", count(Aud.AUDIT_COMPLETION)
From CMS.CMS_SAM_ALL_DATA Sam left join CMS.WATSON_AUDIT_INSPECTION_DT1_VW Aud ON Sam.SAM_ID = Aud.SAM_ID
Where Aud.DEFECT_SEVERITY = 'Major' AND
Aud.AUD_RESULT = 'Defect' And
NOT (Aud.AUDIT_OUTCOME = 'SPFR Withdrawn' and
Aud.AUDIT_OUTCOME = 'Defect/ Observation Cancelled' and
Aud.AUDIT_OUTCOME = 'Rejected by MIMA' and
Aud.AUD_RESULT = 'Fixed' and
Aud.AUDIT_OUTCOME = 'SPFR response accepted') and
Aud.AUDIT_COMPLETION IS NOT NULL
Group by Sam.SAM_ID;
Now I tried running the above code in macro(VBA) but not able to run macro successfully, Macro code -
StrSQL = StrSQL & "Select Sam.SAM_ID,"
StrSQL = StrSQL & "sum(case when Aud.AUDIT_COMPLETION between (next_day(trunc(sysdate, 'iw'), 'Friday') - 14) and (next_day(trunc(sysdate, 'iw'), 'Friday') - 7) then 1 else 0 end )as ""Major Defects - 1 week"","
StrSQL = StrSQL & "sum(case when Aud.AUDIT_COMPLETION between (next_day(trunc(sysdate, 'iw'), 'Friday') - 28) and (next_day(trunc(sysdate, 'iw'), 'Friday') - 7) then 1 else 0 end )as ""Major Defect - 4 week"","
StrSQL = StrSQL & "count(Aud.AUDIT_COMPLETION)as ""Total Open Defects""
StrSQL = StrSQL & "From CMS.CMS_SAM_ALL_DATA Sam left join CMS.WATSON_AUDIT_INSPECTION_DT1_VW Aud ON Sam.SAM_ID = Aud.SAM_ID"
StrSQL = StrSQL & "Where Aud.DEFECT_SEVERITY = 'Major' AND Aud.AUD_RESULT = 'Defect' And NOT (Aud.AUDIT_OUTCOME = 'SPFR Withdrawn' and Aud.AUDIT_OUTCOME = 'Defect/ Observation Cancelled' and Aud.AUDIT_OUTCOME = 'Rejected by MIMA' and Aud.AUD_RESULT = 'Fixed' and Aud.AUDIT_OUTCOME = 'SPFR response accepted') and Aud.AUDIT_COMPLETION IS NOT NULL, Aud.AUDIT_COMPLETION IS NOT NULL, "
StrSQL = StrSQL & "Group by Sam.SAM_ID;"
When I run above code I get an error as -
FROM Keyword not found where expected

Use line continuation (_) and double up your quotes to escape them:
strSQL = "select a, b as ""My Field"" from " & _
"tableZ where a = 'blah' and " & _
"b ='blah' "

You don't have space beetween from count(Aud.AUDIT_COMPLETION)From CMS.CMS_SAM_ALL_DATA Sam left
but take Tim Wiliams advice and split it to new lines. You can also do it like this:
Dim strSQL As String
strSQL = strSQL & "SELECT "
strSQL = strSQL & "1 "
strSQL = strSQL & "FROM dual "

Related

filter report based on date

I have a table with date column a query for the same table and a report, on my form I have a button which loads the report using vba code which is below, I have two text fields to filter date on the report, my issue is with the date it is not being filtered. my code is below
Public Function makeMWO_RPT(Optional excelMode As Boolean = False)
Dim ctlArr(3) As String
ctlArr(0) = "Combo79"
ctlArr(1) = "Combo82"
ctlArr(2) = "WOPRCO"
ctlArr(3) = "Combo165"
Dim fldArr(3) As String
fldArr(0) = "[Group]"
fldArr(1) = "[User status]"
fldArr(2) = "[Priority]"
fldArr(3) = "iif([orders].[User status] In (""Closed"",""Open""),""YES"",""NO"")"
'for date -- for date -- for date -- for date -- for date
Dim qDef, sqlStr, frm As Form
Set frm = Forms("Statusfrm")
Set qDef = CurrentDb.QueryDefs("OrderNewQry")
sqlStr = "SELECT orders.[Group], orders.Order, orders.Description,orders.Post_Form, orders.Attachment, orders.Video_link, orders.[Estimated costs], orders.[Total], orders.Location, orders.[System status], orders.Priority, orders.date, orders.[User status], " & _
"orders.Equipment, orders.Diff, orders.Remarks,[orders].[User status] In (""Closed *"",""Open *"") AS Completed
"FROM orders"
Dim filtrStr As String
If Not IsNull(frm("Text489")) Then
filtrStr = "[date] >= #" & frm("Text489") & "#"
End If
If Not IsNull(frm("Text491")) Then
filtrStr = filtrStr & " AND [date] <= #" & frm("Text491") & "#"
End If
If filtrStr <> "" Then
sqlStr = sqlStr & " WHERE " & filtrStr
End If
qDef.SQL = sqlStr
'for date -- for date -- for date -- for date -- for date
Dim baseSQL, qName, rName
baseSQL = "SELECT orders.[Group], orders.Order, orders.Description,orders.Post_Form, orders.Attachment, orders.Video_link, orders.[Estimated costs], orders.[Total], orders.Location, orders.[System status], orders.Priority, orders.date, orders.[User status], " & _
"orders.Equipment, orders.Diff, orders.Remarks,[orders].[User status] In (""Closed *"",""Open *"") AS Completed
"FROM orders"
qName = "OrderNewQry"
rName = "FUllOpenOrdersRpt"
makeGenericRPT ctlArr, fldArr, baseSQL, qName, rName, excelMode
End Function

CSQL code in vb6 for displaying data between two dates?

Set COUNTER_RS = New Recordset
COUNTER_RS.Open "Select * from TT_COUNTER where Trans_dt >'" + Format(mskFdate.Text, "mm-dd-yyyy") + "' and Trans_dt <='" + Format(mskTdate.Text, "mm-dd-yyyy") + "' and Receipt_No like 'A%' and Head_Details='MED' order by Receipt_No", db, adOpenStatic, adLockOptimistic
MEDI = 0
If COUNTER_RS.RecordCount > 0 Then
While COUNTER_RS.EOF = False
MEDI = Val(COUNTER_RS!Rate)
COUNTER_RS.MoveNext
Wend
End If
Cant find the correct amount between two dates, please help with the code?

SQL Syntax error, expression of non-boolean type

This code is supposed to create a graph of revenue from money made through sales tickets at an event.
The code only executes up to da.Fill(ds) when it returns the error, which can be seen at the end of the code.
Does anybody know why
Private Sub frmRevenue_Load(sender As Object, e As EventArgs) Handles Me.Load
frmMDI.addFormToCMS()
Dim dt As DataTable
dt = New DataTable
dt.Columns.Add("Fee")
Dim sales As Integer = 0
Dim gridtable As New DataTable
gridtable.Columns.Add("Month")
gridtable.Columns.Add("Total")
gridtable.Columns.Add("#")
For i = 1 To 12
sql = "SELECT Fee FROM tblTickets WHERE MONTH(DatePurchased) = " & i & " AND (YEAR(DatePurchased) = " & Today.Year & " OR " & Year(Today.AddYears(1)) & ") AND (Status = 'SOLD' OR RESERVED" _
& " = 'AWAITING CONFIRMATION' OR Status = 'AVAILABLE' OR Status = 'AWAITING PAYMENT');"
da = New OleDb.OleDbDataAdapter(sql, con)
ds = New DataSet
da.Fill(ds)
Dim dr As DataRow
For Each dr In ds.Tables(0).Rows
monthly(i) = monthly(i) + 1
contracts = sales + 1
total(i) = total(i) + dr.Item("Fee")
yearlytotal = yearlytotal + dr.Item("Fee")
Next
Next
For i = 1 To 12
Dim month As String
Select Case i
Case 1
month = "Jan"
Case 2
month = "Feb"
Case 3
month = "Mar"
Case 4
month = "Apr"
Case 5
month = "May"
Case 6
month = "Jun"
Case 7
month = "Jul"
Case 8
month = "Aug"
Case 9
month = "Sep"
Case 10
month = "Oct"
Case 11
month = "Nov"
Case 12
month = "Dec"
Case Else
month = "ERR"
End Select
gridtable.Rows.Add(month, FormatCurrency(total(i)), monthly(i))
Next
ugTickets.DataSource = gridtable
ugTickets.DisplayLayout.Bands(0).Columns("Month").Width = 35
ugTickets.DisplayLayout.Bands(0).Columns("#").Width = 20
ugTickets.DisplayLayout.Override.AllowUpdate = DefaultableBoolean.False
txtAnnual.ReadOnly = True
txtAnnual.BackColor = Color.White
txtAnnualContracts.ReadOnly = True
txtAnnualContracts.BackColor = Color.White
chRevenue.Titles("chTitle").Text = "Predicted revenue for " & Today.Year & " - " & Year(Today.AddYears(1))
txtAnnual.Text = FormatCurrency(yearlytotal, 2)
txtAnnualContracts.Text = contracts
chRevenue.Series("Series1").Name = "Revenue"
For i = 1 To 12
chRevenue.Series("Revenue").Points.AddY(total(i))
Next
Try
chRevenue.BackColor = Color.Transparent
chRevenue.Legends("Revenue").BackColor = Color.Transparent
chRevenue.Series("Revenue").ChartArea = "ChartArea1"
chRevenue.Series("Revenue").Color = Color.SkyBlue
chRevenue.Series("Revenue").ToolTip = FormatCurrency("#VALY", 2)
Catch
End Try
End Sub
An expression of non-boolean type specified in a context where a condition is expected, near ')'.
The problem is with this bit of the SQL:
(YEAR(DatePurchased) = " & Today.Year & " OR " & Year(Today.AddYears(1)) & ")
It should probably be
(YEAR(DatePurchased) = " & Today.Year & " OR YEAR(DatePurchased) = " & Year(Today.AddYears(1)) & ")
The OR in SQL (and in most other languages) needs to have two independently valid conditions on each side. The left hand side currently looks like this:
YEAR(DatePurchased) = 2016
...which is fine. But the right looks like this:
2017
...which isn't a valid boolean.
When you get an error like this on the da.Fill() line (ie. the line that's actually running the SQL in the database), the easiest way to debug it is to print out the value of the "sql" variable.
Often, you can just look at the SQL it's generated and the problem will be obvious. Other times you have to copy it and run it directly against your database to see what the problem is.
Might be your SQL, try:
"SELECT Fee FROM tblTickets WHERE MONTH(DatePurchased) = '" & i &
"' AND (YEAR(DatePurchased) = '" & Today.Year &
"' OR '" & Year(Today.AddYears(1)) & "') " &
"AND (Status = 'SOLD' OR RESERVED = 'AWAITING CONFIRMATION' " &
"OR Status = 'AVAILABLE' " &
"OR Status = 'AWAITING PAYMENT');"

How to calculate difference between 2 dates when it goes to past? VBA, EXCEL

I have a problem with calculating difference between 2 dates where first is older than second.
For example: I want to find difference between
5.5.2015 and 1.11.2014
I used function
=IF((A(DATEDIF(B12,$W$3,"M")<=12,RANK(Q12,Q:Q)<=11)),Q12;0)
but the function is limited only to situations where the second date is higher than the first one.
I want to know whether B12 is within last 12 months from given date. If it is, then I want to calculate with it.
Is there any way to calculate backwards in excel or VBA?
Thank you.
I know this is an old post already but for anyone who needs this...
Function FindDateDiff(myDate1 As Date, myDate2 As Date) As String
Dim myYears As Long, myMonths As Long, myDays As Long
Dim yearString As String, monthString As String, dayString As String, FinalString As String
If myDate1 > myDate2 Then
myYears = Year(myDate1) - Year(myDate2)
myMonths = Month(myDate1) - Month(myDate2)
myDays = Day(myDate1) - Day(myDate2)
If myDays < 0 Then
myMonths = myMonths - 1
myDays = Day(WorksheetFunction.EoMonth(myDate1, 0)) - Abs(myDays) - 1
End If
Else
myYears = Year(myDate2) - Year(myDate1)
myMonths = Month(myDate2) - Month(myDate1)
myDays = Day(myDate2) - Day(myDate1)
If myDays < 0 Then
myMonths = myMonths - 1
myDays = Day(WorksheetFunction.EoMonth(myDate2, 0)) - Abs(myDays) - 1
End If
End If
If myMonths < 0 Then
myYears = myYears - 1
myMonths = 12 - Abs(myMonths)
End If
If myYears = 0 Then
yearString = ""
ElseIf myYears = 1 Then
yearString = myYears & " year, "
ElseIf myYears > 1 Then
yearString = myYears & " years, "
End If
If myMonths = 0 Then
monthString = ""
ElseIf myMonths = 1 Then
monthString = myMonths & " month, "
ElseIf myMonths > 1 Then
monthString = myMonths & " months, "
End If
If myDays = 0 Then
dayString = ""
ElseIf myDays = 1 Then
dayString = myDays & " day"
ElseIf myDays > 1 Then
dayString = myDays & " days"
End If
FinalString = yearString & monthString & dayString
If Right(FinalString, 2) = ", " Then FinalString = Left(FinalString, Len(FinalString) - 2)
FindDateDiff= FinalString
End Function
Just paste this function in a new module in the workbook and you can start calling this function. '=FindDateDiff(A1,B1)'
This function only require 2 dates as arguments and the order doesn't matter.
I've tested this function with both UK and US format, both works exactly the same.
I used DateDiff before, but the calculation for days and months returns an incorrect value and could be very confuse sometimes.
In VBA use the same function.
NoOfDays = DateDiff("D", DATE1, DATE2)
NoOfDays returns either positive or negative value depending on the dates
I have it solved by using ISERROR
=IF(ISERROR(DATEDIF(RC[-16],R3C23,""M"")<=12),0,RC[-1])

Incredibly slow performance with this query

I am getting incredibly slow performance when executing this query,
i cannot see anything obvious,can any one suggest me the best way to get through it
CREATE TABLE #tmp_NominalPurchase (
NomCode varchar(16),
NomDesc varchar(61),
GoodsSold money
)
declare #Pos Int
select #Pos = 1
while #Pos <= (select max(dbo.fn_DCount(NValues,'~')) from pledger)
begin
INSERT INTO #tmp_NominalPurchase (NomCode, NomDesc, GoodsSold) (
select
a.keyCode NomCode,
a.descr NomDesc,
sum(convert(money, dbo.fn_Field(pl.NValues,'~', #Pos) )) GoodsSold
from pledger pl
inner join accts a
On dbo.fn_Field(pl.NCodes,'~', #Pos) = a.keycode
and (acctType='N' and pb='P' and category='cs')
where convert(datetime, pl.batch) >='2014-01-01'
and convert(datetime, pl.batch) <'2014-06-25'
group by a.keyCode, a.descr)
select #Pos = #Pos + 1
end
select o.* FROM
(
select t.NomCode,
t.NomDesc,
0 GoodsCost,
0 GoodsDisc,
sum(t.GoodsSold) GoodsSold,
'24/06/2014 05:01:14 PM' as LocalDateAndTime
from #tmp_NominalPurchase t
group by
t.NomCode,
t.NomDesc
) o
Order By o.NomCode Asc
DROP TABLE #tmp_NominalPurchase
One obvious thing I see is you are converting pl.batch to a string before you do the comparison in the where clause. That would defeat any indices that might prevent a table scan.
You are also doing a join on a user defined function fn_field. Not knowing the purpose of that function, I'm wondering if that is creating an issue. When I see things like that, I suspect it's there because the data schema isn't well thought out.
No rewritten query and performance has increased majorly, this has reduced the query runtime from 12 seconds to < 1 second
added a function to get the count
SQL rewritten to use the count
The Improved SQL
SELECT dbo.fn_Field(pl.NValues,'~',1) AS [nVals1], dbo.fn_Field(pl.Ncodes,'~',1) as [nCodes1], dbo.fn_Field(pl.NValues,'~',2) as [nVals2], dbo.fn_Field(pl.Ncodes,'~',2) as [nCodes2],
'x' AS x INTO #tmp_NominalPurchase
FROM pledger pl
WHERE convert(datetime, pl.batch) >='2014-06-01'
AND convert(datetime, pl.batch) <'2014-06-28'
SELECT a.keycode AS NomCode,
a.descr AS NomDesc,
max(0) AS goodsCost,
max(0) AS GoodsDisc,
sum(CAST (NValue AS money)) AS GoodsSold ,
'06/27/2014 11:44:47 AM' AS LocalDateAndTime
FROM
(SELECT [nVals1] AS NValue,[nCodes1] AS NCode
FROM dbo.#tmp_NominalPurchase tnp
UNION ALL SELECT [nVals2]AS NValue,[nCodes2] AS NCode
FROM dbo.#tmp_NominalPurchase tnp) x
INNER JOIN dbo.Accts a ON x.Ncode = a.keycode
AND acctType='N'
AND category='cs'
AND pb='P'
GROUP BY a.keycode,
a.descr
ORDER BY NomCode
DROP TABLE #tmp_NominalPurchase
Function to get count
Public Function getNCodeCount(ByVal sWhere) As Integer '00528591
Dim Ds As DataSet
Dim sqlSb As StringBuilder = New StringBuilder
Dim nCodesCount As Integer = 0
sqlSb.Append("SELECT isnull(max(dbo.fn_DCount(NValues,'~')),0) FROM PLEDGER PL with (nolock)" & sWhere)
Ds = SqlConnect.SqlNet.OpenSQLdataset(sqlSb.ToString)
If Ds Is Nothing Then GoTo report_failed
If Ds.Tables.Count < 1 Then
GoTo report_failed
End If
With Ds.Tables(0)
For Each r In .Rows
nCodesCount = r(0)
Next
End With
Return nCodesCount
Exit Function
report_failed:
Return 0
'00528591 END
End Function
Function to build the SQL string and output the report
Public Function LedgerNominalListingReportPurchase(ByVal DateFrom As String, ByVal DateTo As String, ByVal SortType As String, Optional ByVal DetailReport As Boolean = False, Optional ByVal NominalCode As String = "") As DataView 'L754303 (163.47)
Dim sql As String = ""
Dim gs As New GeneralSQL
Dim aWhere As New ArrayList
Dim sWhere As String = ""
If IsDate(DateFrom) Then aWhere.Add("convert(datetime, pl.batch) >=" & gs.SqlDate(CDate(DateFrom)))
If IsDate(DateTo) Then aWhere.Add("convert(datetime, pl.batch) <" & gs.SqlDate(CDate(DateTo).AddDays(1)))
For Each s As String In aWhere
If sWhere = "" Then
sWhere &= " where "
Else
sWhere &= " and "
End If
sWhere &= s
Next
If Not DetailReport Then 'L754303 (163.47)
'NEW SQL (FASTER) 00528591
sql &= "SELECT max(dbo.fn_DCount(NValues,'~')) FROM PLEDGER"
Dim nCodeCount As Integer = (getNCodeCount(sWhere))
If nCodeCount = Nothing Or 0 Then
sql = "CREATE TABLE #tmp_NominalPurchase (NomCode varchar(16), NomDesc varchar(61), GoodsCost money, GoodsDisc money, GoodsSold money) SELECT * FROM #tmp_NominalPurchase DROP TABLE #tmp_NominalPurchase"
Else
Dim qCount As Integer = 1
sql = "SELECT "
While qCount <= nCodeCount
sql &= "dbo.fn_Field(pl.NValues,'~'," + qCount.ToString
sql &= ") "
sql &= " as [nVals" + qCount.ToString
sql &= "], "
sql &= "dbo.fn_Field(pl.Ncodes,'~'," + qCount.ToString
sql &= ") "
sql &= " as [nCodes" + qCount.ToString
sql &= "], "
qCount += 1
End While
sql &= " 'x' as x "
sql &= "INTO #tmp_NominalPurchase FROM pledger pl " & sWhere
sql &= "SELECT a.keycode as NomCode, a.descr as NomDesc,max(0) AS goodsCost,max(0) AS GoodsDisc, sum(cast (NValue AS money) ) AS GoodsSold "
sql &= String.Format(", '{0}' as LocalDateAndTime", Format(General.UserNow, vars.Ses.FmtDate & " " & "hh:mm:ss tt")) 'V759658 (163.31) - format the date column based on the CountryMode setting
sql &= " FROM ("
sql &= "SELECT [nVals1] AS NValue,[nCodes1] AS NCode FROM dbo.#tmp_NominalPurchase tnp "
qCount = 2
While qCount <= nCodeCount
sql &= " UNION all "
sql &= "SELECT [nVals" + qCount.ToString
sql &= "]AS NValue,[nCodes" + qCount.ToString
sql &= "] AS NCode FROM dbo.#tmp_NominalPurchase tnp"
qCount += 1
End While
sql &= ") x inner join dbo.Accts a on x.Ncode = a.keycode and acctType='N' AND category='cs' AND pb='P' group by a.keycode,a.descr "
sql &= "ORDER BY " & SortType
sql &= " DROP TABLE #tmp_NominalPurchase"
End If
End If
Return SqlConnect.SqlNet.OpenSQLdataset(sql).Tables(0).DefaultView '00529265
End Function