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
因此,我迷上了一些带有VBA / SQL语句的MS-Access数据库。 我实际上是一个初学者,但是我设法弄清楚了一些事情,并使自己熟悉了我们用于打印作业报告的数据库。 某些调用函数设置有误,并且是从错误的表中提取的,基本上,我需要一些帮助,以确定应该采取哪种方法。
当前,如果我们运行报表,并调用“ GetPendingChangeOrders ”,它将执行应做的工作,但是当我们查看待处理的内容时。 即使“ JCCHANGEORDERSTEP”表中的状态为21(DENIED),它也会显示结果。我包括了它的图像。
JCCHANGEORDER与JCCHANGEORDERSTEP(JOBNUM,ORDERNUM,TYPE)的列相同,但JCCHANGEORDER中的类型只有1,我认为这很活跃。
JCCHANGEORDERSTEP包含1个已发起(待定),20个(已批准),21个(已拒绝)。它从报告的结果中筛选出20而不是21。因此,我只需要一些帮助,并解释了为什么仅将21加到混合中是行不通的。
谢谢您的时间。
EDIT-1添加了IMGS IMGUR ACCESS PICTURES
答案 0 :(得分:0)
您在HAVING和GROUP BY子句中查询的这一部分是给您带来问题的原因:
IIf(DLookUp("type",
"jcchangeorderstep",
"jobnum = ' [jcchangeorder].[jobnum] ' and
ordernum = ' [ordernum] ' and
Type = 20")=20,-1,0))=0);
令人费解,很难阅读。但是,这是说:“如果此工作和订单出现在 JCCHANGEORDERSTEP 中,类型为20,则将其排除。”因此,这就是您需要解决的问题。
整个查询可能应该以多种方式固定。但是我认为这可能使您到达需要的地方。
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;"
我所做的更改为条件为“如果此工作和订单出现在 JCCHANGEORDERSTEP 中,且类型为1,则将其包括在内”。如果没有实际看到您的数据并亲自测试代码,我不能保证这会起作用。可能会有一些错别字,所以我已经解释了我要做什么,以便您可以解决它们。
另外,花一些时间来完成堆栈溢出之旅。如果您与之合作,那么这个社区将是一个很大的帮助。
尝试一下:
在与OP讨论了预期的结果之后,看来这将是一个更好的解决方案。它给出了只有 变更订单步骤为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和JCD是SQL别名。 SQL理解它们。 JCSELECT是一个别名子查询。 JCSELECT创建的一组所有作业/订单只有一个待处理步骤。
答案 1 :(得分:0)
查看了图像并研究了现有的SQL代码之后,我认为以下SQL查询可能更合适并且更易读:
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
在这里,包含jcdetail
条记录,其中jcchangeorderstep.type = 1
由表之间的inner join
处理,而不是为每条记录单独的dlookup
。
您可以通过以下方式在您的函数中实现此目标:
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
在后续评论之后,以下内容似乎更符合您的要求:
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
)
这可以通过以下方式在您的VBA功能中实现:
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