Public Function GetPendingChangeOrders(strJ As String) As Double
strSQL = "SELECT DISTINCT Sum(jcdetail.cost) AS SumOfcost " &
"FROM jcchangeorder INNER JOIN jcdetail ON (jcchangeorder.ordernum = jcdetail.ponum) AND (jcchangeorder.jobnum =jcdetail.jobnum) " &
"GROUP BY jcdetail.jobnum, jcdetail.type, jcchangeorder.type, IIf(DLookUp(""type"",""jcchangeorderstep"",""jobnum = '"" & [jcchangeorder].[jobnum] & ""' and ordernum = '"" & [ordernum] & ""' and Type = 20"")=20,-1,0) " & _
"HAVING (((jcdetail.jobnum)='" & strJ & "') AND ((jcdetail.type)=19) AND ((jcchangeorder.type)<>2) AND ((IIf(DLookUp(""type"",""jcchangeorderstep"",""jobnum = '"" & [jcchangeorder].[jobnum] & ""' and ordernum = '"" & [ordernum] & ""' and Type = 20"")=20,-1,0))=0));"
Set rs = dbs.OpenRecordset(strSQL, dbOpenSnapshot, dbReadOnly, dbReadOnly)
If Not rs.EOF Then
dblResult = Nz(rs.Fields(0), 0)
rs.Close
Set rs = Nothing
GetPendingChangeOrders = dblResult
Else
GetPendingChangeOrders = 0
End If
End Function
So I got tossed into some MS-Access database with VBA/SQL statements all over. I am literally a beginner, but I have managed to figure some things out, and familiarize myself with our database that we use to print out job reports. Some of the call functions are setup wrong, and are pulling from the wrong tables, and I basically need some help figuring out which way I should be going to tackle this.
Currently if we run the report, and it calls " GetPendingChangeOrders " it does what it is supposed to do, but when we look at what is under pending. It shows a result even though it has a status of 21(DENIED) inside of "JCCHANGEORDERSTEP" table. I included images of it.
JCCHANGEORDER has the same as columns as JCCHANGEORDERSTEP(JOBNUM,ORDERNUM,TYPE) but the types in JCCHANGEORDER just has a type of 1 which I assume says hey I'm active.
JCCHANGEORDERSTEP contains 1 initiated (pending), 20 (approved), 21(denied). It filters out the 20's from results on report, but not 21. So I just need some help, and an explanation of why just adding 21 into the mix didn't work.
Thank you for your time.
EDIT-1 ADDED IMGS IMGUR ACCESS PICTURES
This part of the query in your HAVING and GROUP BY clauses is what's giving you problems:
IIf(DLookUp("type",
"jcchangeorderstep",
"jobnum = ' [jcchangeorder].[jobnum] ' and
ordernum = ' [ordernum] ' and
Type = 20")=20,-1,0))=0);
It's convoluted and very difficult to read. But it is saying, "If this job and order appears in JCCHANGEORDERSTEP with a type of 20, exclude it." So, that's what you need to fix.
The whole query should probably be fixed in a variety of ways. But I think this might get you where you need to go.
strSQL = "SELECT DISTINCT Sum(jcdetail.cost) AS SumOfcost " & _
"FROM jcchangeorder " & _
"INNER JOIN jcdetail " & _
"ON (jcchangeorder.ordernum = jcdetail.ponum) " & _
"AND (jcchangeorder.jobnum =jcdetail.jobnum) " & _
"GROUP BY jcdetail.jobnum, " & _
"jcdetail.type, " & _
"jcchangeorder.type, " & _
"DLookUp(""type"",""jcchangeorderstep"",""jobnum = '"" & [jcchangeorder].[jobnum] & ""' and ordernum = '"" & [ordernum] & ""' and Type = 1"") " & _
"HAVING (jcdetail.jobnum='" & strJ & "' AND " & _
"jcdetail.type=19 AND " & _
"jcchangeorder.type <> 2) AND " & _
"DLookUp(""type"",""jcchangeorderstep"",""jobnum = '"" & [jcchangeorder].[jobnum] & ""' and ordernum = '"" & [ordernum] & ""' and Type = 1"")=1;"
What I have done is changed to condition to say "If this job and order appears in JCCHANGEORDERSTEP with a type of 1, include it." Without actually seeing your data and testing the code myself, I can't promise this will work. There may be some typos, so I've explained what I'm trying to do, so you can fix them.
Also, take some time to go through the Stack Overflow tour. This community can be a great help if you work with it.
Try This:
After discussing the desired results with the OP, it appears that this would be a better solution. It gives the sum of all change orders that only have a change order step of PENDING
.
strSQL = _
"SELECT SUM(JCD.cost) AS sumofcost " & _
"FROM jcchangeorder JCCO " & _
"INNER JOIN jcdetail JCD " & _
"ON JCCO.ordernum = jcd.ponum " & _
"AND JCCO.jobnum = jcd.jobnum " & _
"INNER JOIN (SELECT JCCOS.ponum, " & _
"JCCOS.jobnum " & _
"FROM jcchangeorderstep JCCOS " & _
"GROUP BY JCCOS.ponum, " & _
"JCCOS.jobnum " & _
"HAVING Count(*) = 1 " & _
"AND First(JCCOS.type) = 1) JCSELECT " & _
"ON JCCO.ordernum = JCSELECT.ponum " & _
"AND JCCO.jobnum = JCSELECT.jobnum " & _
"GROUP BY JCD.jobnum, " & _
"JCD.type, " & _
"JCCO.type "
"HAVING JCD.jobnum='" & strJ & "' AND " & _
"JCD.type=19 AND " & _
"JCCO.type <> 2;"
JCCO, JCCOS, and JCD are SQL aliases. SQL understands them. JCSELECT is an aliased subquery. JCSELECT creates a set of all job/orders that only have a step of PENDING.
Having looked at your images and studied your existing SQL code, I think the following SQL query may be more suitable and altogether more readable:
select sum(d.cost) as sumofcost
from
(
jcchangeorder o inner join jcdetail d
on o.ordernum = d.ponum and o.jobnum = d.jobnum
) inner join
(
select distinct s.jobnum, s.ordernum
from jcchangeorderstep s
where s.type = 1
) q
on o.jobnum = q.jobnum and o.ordernum = q.ordernum
where
o.jobnum = ?job and d.type = 19 and o.type <> 2
Here, the inclusion of jcdetail
records for which the jcchangeorderstep.type = 1
is handled by the inner join
between the tables, rather than a separate dlookup
for every record.
You could implement this in your function in the following way:
Public Function GetPendingChangeOrders(strJ As String) As Double
Dim strS As String
strS = strS & "select sum(d.cost) "
strS = strS & "from "
strS = strS & " ( "
strS = strS & " jcchangeorder o inner join jcdetail d "
strS = strS & " on o.ordernum = d.ponum and o.jobnum = d.jobnum "
strS = strS & " ) inner join "
strS = strS & " ( "
strS = strS & " select distinct s.jobnum, s.ordernum "
strS = strS & " from jcchangeorderstep s "
strS = strS & " where s.type = 1 "
strS = strS & " ) q "
strS = strS & " on o.jobnum = q.jobnum and o.ordernum = q.ordernum "
strS = strS & "where "
strS = strS & " o.jobnum = ?job and d.type = 19 and o.type <> 2 "
Dim rst As DAO.Recordset
With CurrentDb.CreateQueryDef("", strS)
.Parameters(0) = strJ
Set rst = .OpenRecordset
If Not rst.EOF Then
rst.MoveFirst
GetPendingChangeOrders = Nz(rst.Fields(0), 0)
End If
rst.Close
End With
End Function
Following the subsequent comments, the following seems more aligned with your requirements:
select sum(d.cost)
from
jcchangeorder o inner join jcdetail d
on o.ordernum = d.ponum and o.jobnum = d.jobnum
where
o.jobnum = jobparam and
d.type = 19 and
o.type <> 2 and
not exists
(
select 1 from jcchangeorderstep s
where s.jobnum = o.jobnum and s.ordernum = o.ordernum and s.type <> 1
)
This may be implemented in your VBA function in the following way:
Public Function GetPendingChangeOrders(strJ As String) As Double
Dim strS As String
strS = strS & "select sum(d.cost) "
strS = strS & "from "
strS = strS & " jcchangeorder o inner join jcdetail d "
strS = strS & " on o.ordernum = d.ponum and o.jobnum = d.jobnum "
strS = strS & "where "
strS = strS & " o.jobnum = jobparam and "
strS = strS & " d.type = 19 and "
strS = strS & " o.type <> 2 and "
strS = strS & " not exists "
strS = strS & " ( "
strS = strS & " select 1 from jcchangeorderstep s "
strS = strS & " where s.jobnum = o.jobnum and s.ordernum = o.ordernum and s.type <> 1 "
strS = strS & " ) "
Dim rst As DAO.Recordset
With CurrentDb.CreateQueryDef("", strS)
.Parameters("jobparam") = strJ
Set rst = .OpenRecordset
If Not rst.EOF Then
rst.MoveFirst
GetPendingChangeOrders = Nz(rst.Fields(0), 0)
End If
rst.Close
End With
End Function
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.