Ms access VBA函数中的SQL SUM语句
我的数据库有三个表:Holder、Product(即帐户)和Transaction。我已经从Holder表中设置了一个表单,该表单包含产品表中的子表单,而产品子表单将事务表作为子表单。在表单的持有者部分,我放置了一个未结清的未绑定文本字段,该字段应显示交易表中尚未支付的交易的总金额和税务字段(由交易表上的复选框指示)。我已经将未绑定文本框的控制源设置为=calcOutstanding(),并为表单编写了以下函数 公共功能calcOutstanding() 端函数Ms access VBA函数中的SQL SUM语句,ms-access,Ms Access,我的数据库有三个表:Holder、Product(即帐户)和Transaction。我已经从Holder表中设置了一个表单,该表单包含产品表中的子表单,而产品子表单将事务表作为子表单。在表单的持有者部分,我放置了一个未结清的未绑定文本字段,该字段应显示交易表中尚未支付的交易的总金额和税务字段(由交易表上的复选框指示)。我已经将未绑定文本框的控制源设置为=calcOutstanding(),并为表单编写了以下函数 公共功能calcOutstanding() 端函数 该字段现在只显示#Error。我
该字段现在只显示#Error。我做错了什么?我怀疑您是否需要外部函数来执行此操作。MS Access允许您仅通过我引用子窗体中的字段。子窗体!字段名。值 这意味着,您可以简单地访问与当前记录相关的子表单字段。甚至在该字段上执行IIF(条件、真值、假值) 在此处阅读有关访问表单和子表单的详细信息: 编辑: 在第三个子表单(tbl_事务)中,创建一个名为(txt_未决)的新未绑定文本框,并分配此表达式
=IIF([txPaid]=false, sum(txAMount +TxTax),0)
现在,您可以在父窗体中访问此字段,类似于以下内容:
me.txt_someTextbox.value = nz(me.tbltransactionsubform!txt_outstanding.value,"")
我马上就看到你发布的代码中有一个问题:
strSQL = "SELECT SUM(tblTransaction.TxAmount + tblTransaction.TxTax) As Outstanding" _
& "FROM tblTransaction" _
& "INNER JOIN tblProduct ON tblTransaction.fkProductID = tblProduct.ProductID" _
& "INNER JOIN tblHolder ON tblProduct.fkHolderID = tblHolder.HolderID" _
& "WHERE tblTransaction.TxPaid = False" _
& "AND tlbHolder.HolderID = Me.HolderID;"
在每行
未完成的“\uu
末尾或TBLTTransaction中的”开头都应该有一个空格,否则您的字符串在解析时将读取未完成的TBLTTransaction
,这将给您一个错误。您的方法有很多错误:
RunSQL仅用于操作查询(插入、更新、删除)
您不能像尝试将DoCmd.RunSQL中的值放入变量中一样从DoCmd.RunSQL返回值
where子句的连接不正确
正如HansUp提到的,Access在SQL中对连接中的括号非常挑剔
假设SQL是正确的,这段代码存在于父窗体上,并且您无法在查询中返回多行,可能类似这样的操作会起作用:
Public Function calcOutstanding() As Currency
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT SUM(tblTransaction.TxAmount + tblTransaction.TxTax) As Outstanding " _
& "FROM (tblTransaction " _
& "INNER JOIN tblProduct ON tblTransaction.fkProductID = tblProduct.ProductID) " _
& "INNER JOIN tblHolder ON tblProduct.fkHolderID = tblHolder.HolderID " _
& "WHERE tblTransaction.TxPaid = False " _
& "AND tlbHolder.HolderID = " & Me.HolderID
Set rst = db.OpenRecordset(strSQL, dbForwardOnly)
calcOutstanding = rst![Outstanding]
Set rst = Nothing
set db = Nothing
End Function
注意WHERE子句中的连接以从表单的数据源获取值(否则SQL无法在SQL本身的范围内协调Me.HolderID)。此外,我们将返回的数据集推送到记录集中并从中读取。我认为,沿着这条思路应该行得通。(现在不在Access前面,如果有任何非编译语句,请抱歉。)
编辑:为了明确起见,将函数返回类型添加为整数。
编辑2:为了明确起见,将函数返回类型添加为currency。Doh.在DoCmd.RunSQL
之前的行中包含Debug.Print strSQL
。。。然后看看你给访问权限的状态。首先请注意,未完成查询和起始查询之间没有空格。请使用Access查询设计器创建和测试查询。它将在适当的位置添加所需的括号,以便查询FROM
包含多个联接。DoCmd.RunSQL
用于“操作”查询。为您的选择查询使用其他内容。根据您希望对查询返回的结果执行的操作进行选择。结果仅用于表单的文本字段中。哪些命令是特定于选择查询的?我在所有SQL语句行的末尾添加了空格,但仍然有一个错误。@Sphere还有另一个问题,现在我更详细地了解了这个问题:DoCmd.RunSQL仅适用于操作查询。这是MSDN页面:在您的情况下,您可能希望使用CurrentDb.Execute而不是CurrentDb.Execute实际上,CurrentDb.Execute也仅限于操作查询。您需要使用DAO访问数据并返回记录集。更多信息,请访问我将在今天晚些时候编辑我的答案以解决此问题。我是否需要一个嵌套的IIF语句来搜索交易表中的特定持有人交易,然后仅搜索未标记为已支付的交易?@sphere由于您拥有主表,您的tbl_交易来源的子表将始终具有记录[仅]与父表相关。这意味着您只需要执行一次检查。无论是否缴纳税款,然后合计金额谢谢你的帮助。我更正了SQL WHERE子句中的连接错误,但不幸的是,持有人可能拥有的未完成事务中可能涉及多个事务。好的,那么您是想在SQL中处理这个问题,还是想通过遍历上面返回的记录集中的多行中的每一行来执行基于游标的解决方案?无论如何,这个解决方案的总体框架仍然是坚实的,我更愿意用SQL来处理它。根据我收集的信息,上面的SQL语句将遍历整个事务表,并对所有未标记为paid的记录的TXAmount和TxTax字段求和,并与表单上当前的holderID匹配。对吗?从我的角度看,是的,对。然后返回一行,结果是al THITH。哦,如果它返回一行,它将不能作为文本框的控制源。我只需要在文本框中显示未完成变量的值,我假设它是sum函数的值。
Public Function calcOutstanding() As Currency
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb
strSQL = "SELECT SUM(tblTransaction.TxAmount + tblTransaction.TxTax) As Outstanding " _
& "FROM (tblTransaction " _
& "INNER JOIN tblProduct ON tblTransaction.fkProductID = tblProduct.ProductID) " _
& "INNER JOIN tblHolder ON tblProduct.fkHolderID = tblHolder.HolderID " _
& "WHERE tblTransaction.TxPaid = False " _
& "AND tlbHolder.HolderID = " & Me.HolderID
Set rst = db.OpenRecordset(strSQL, dbForwardOnly)
calcOutstanding = rst![Outstanding]
Set rst = Nothing
set db = Nothing
End Function