Ms access 所有复选框切换Access 2010时的填充字段

Ms access 所有复选框切换Access 2010时的填充字段,ms-access,checkbox,vba,ms-access-2010,Ms Access,Checkbox,Vba,Ms Access 2010,我在Access 2010中有一个支出子表单,其中列出了每年与项目相关的预测成本。大多数项目只有一年的时间,但有些项目有一年以上的时间。每个成本旁边都有一个最后的复选框,在确认金额时(即每年年底)应选中该复选框 它基本上是这样的: Year | Cost | Final --------+-----------+-------------------- 2017 | $100 | [checked box] 2018 | $200 |

我在Access 2010中有一个支出子表单,其中列出了每年与项目相关的预测成本。大多数项目只有一年的时间,但有些项目有一年以上的时间。每个成本旁边都有一个最后的复选框,在确认金额时(即每年年底)应选中该复选框

它基本上是这样的:

Year    |   Cost    |   Final
--------+-----------+--------------------
2017    |   $100    |   [checked box]
2018    |   $200    |   [unchecked box]
        |          |   [unchecked box]
我在表外还有一个字段FinalCost,它将成本字段中的所有内容相加。现在,它将填写任何一年的金额,该金额有一个勾选的最终框。只有在选中所有最终框时,才应填写此字段

现在,即使2017年的决赛被选中,它也不会显示任何内容。当2018年被选中时,它应该显示300美元。相反,它显示100美元,尽管仍然有一个空复选框

这是此表单的代码

Private Sub Form_AfterUpdate()
Dim rs1, rs2 As Recordset
Dim sql, sql2 As String

sql = "SELECT Sum(Amount) as Final From Expenditures " & _
"Where ProjNo = '" + Me.ProjNo + "' And Final = True Group by ProjNo"

sql2 = "SELECT FinalExpenditure From ActivityCash " & _
"Where ProjNo = '" + Me.ProjNo + "'"

Set rs1 = CurrentDb.OpenRecordset(sql, dbOpenDynaset, dpinconsistent)
Set rs2 = CurrentDb.OpenRecordset(sql2, dbOpenDynaset, dpinconsistent)

If rs1.RecordCount > 0 Then
If rs2.RecordCount > 0 Then
Do While Not rs2.EOF
    rs2.Edit
    rs2!FinalExpenditure = rs1!Final
    rs2.Update
    rs2.MoveNext
Loop
End If
End If

rs2.Close
rs1.Close
Set rs1 = Nothing
Set rs2 = Nothing

End Sub
这样做的最佳方式是什么


编辑:选中最后一个复选框时,将自动添加一个新行,其中包含一个未更改的复选框,但没有任何信息。

因此,在
sql
之前,我将验证所有记录在
Final
字段中是否都有
True

要做到这一点,我们只需返回具有
Final=False
的(任何)记录的
COUNT()
,然后我们就可以决定执行我们想要的操作

所以呢,

Dim Test as Integer

test = DCount("*", "YourTableName", "Final = False AND ProjNo = " & Me.ProjNo &"")

If test > 0 Then
    'Don't fill the box
Else
    'Fill the box, everything is True
    'Read through your recordsets or whatever else you need to do
End If
要使用查询,我们基本上需要复制
Dcount()
功能。 为此,我们需要另一个
Recordset
变量,并且需要检查查询中
Count()
字段的值

创建一个模拟以下内容的查询:

SELECT COUNT(*) As CountTest
FROM YourTable 
HAVING Final = False 
   AND ProjNo = whateverprojectnumberyou'reusing
保存它,并记住该查询的名称

DCount()
非常相似,我们需要通过此“检查”来确定代码的路径

Dim rst As DAO.Recordset

Set rst = CurrentDb.OpenRecordset("YourQuery'sNameHere")

If rst!CountTest > 0 Then
    'They are not all Checked (aka True)
    Else
    'Supply the value to the FinalCost
End If
Set rst = Nothing
更改此项:

sql = "SELECT Sum(Amount) as Final From Expenditures " & _
"Where ProjNo = '" + Me.ProjNo + "' And Final = True Group by ProjNo"
为此:

"SELECT SUM(Amount) - SUM(IIF(Final,1,0)*Amount) as YetToConfirm, SUM(Amount) as Confirmed From Expenditures " & _
"Where ProjNo = '" + Me.ProjNo + "' Group by ProjNo"
rs1将返回两个值,如果在
rs1中确认了所有成本,则返回总值!已确认
,以及
rs1中尚未确认的值!YetToConfirm

那么这里:

Do While Not rs2.EOF
rs2.编辑
rs2!最终支出=rs1!最终的
rs2.更新
rs2.MoveNext
循环

将其更改为:

Do While Not rs2.EOF
rs2.编辑
rs2!最终支出=Iif(rs1!YetToConfirm=0,rs1!Confirm,0)
rs2.更新
rs2.MoveNext

循环

将以
sql=…
开头的语句替换为以下内容:

sql = "SELECT SUM(e1.Amount) AS Final " & _
    " FROM Expenditures AS e1 " & _
    " WHERE NOT EXISTS (SELECT 'x' FROM Expenditures e2 WHERE e2.Final=0 AND e1.ProjNo = e2.ProjNo) " & _
    " AND e1.ProjNo = '" & Me.ProjNo & "'"

只有当项目的所有费用都标记为最终费用时,此查询才会返回数据。当您检查
rs1.RecordCount>0时,如果此查询未返回任何记录,则不会进行更新。

处理此问题的一种方法是使用子查询检查每个项目中去年(使用dmax函数验证)是否已在最后一列中检查,如果这是真的,则获取检查金额的总和,否则不要计算总数。
我已经修改了您的sql字符串,将其包括在内,并针对给定的示例对其进行了测试,以确认其显示的金额为300美元或零

SQL = ""
SQL = SQL & " SELECT Sum(Amount) as Final From Expenditures "
SQL = SQL & " Where ProjNo = '" & Me.ProjNo & "' And Final = True "
SQL = SQL & " And (SELECT Expenditures.Final FROM Expenditures where year = ( "
SQL = SQL & " DMax('Year','Expenditures','ProjNo= " & Chr(34) & Me.ProjNo & Chr(34) & "'))) = true "
SQL = SQL & " Group by ProjNo "

如果
计数(*),其中Final=False>0
,则不要填充。您说过“只有在选中所有最终框时才应填充它”。。因此,如果
Final
的一个或多个记录值为
False
,则不提供值。我应该将其放在哪里?上面的
sql=
?首先,这听起来像解决了您的问题吗?如果是这样的话,我会把它放在一个答案里。看起来它确实可以满足我的要求。好吧,你说你只想在
test<1
时填写它,也就是说如果没有
Final=False
的记录。因此,我会将所有代码放在
Else和End If
之间(我在评论中指出了这一点)。否则,我会将您字段的值设置为
或您想对其执行的任何操作。它仍然会给我相同的结果。我将第一部分写成
如果Test>0,那么FinalExpenditure=“”
。也许这是错的?我不是一个真正的VBA程序员。我想我应该提一下。有一个支出表,其中包含所有项目的所有信息。每个项目的表单都有一个支出子表单,其中只列出了一个项目的支出。如果这有意义的话。也许我需要指定我引用的是子窗体中的表?确切地说。我们的DCount可以工作,但我们需要进一步缩小它的范围,以确保我们没有检查我们不关心的事情,因此如果它是
ProjNo
或其他一些字段,我们也需要添加它。您认为这能解决您的问题吗?好的,创建一个模拟
DCount
的查询并运行它。类似于,
SELECT COUNT(*)从您的表中选择Final=False和ProjNo=whateverprojectnumberyou'reusing
当我尝试运行这个时,它告诉我“运行时错误2085:Set rs1=
处表达式中未定义的函数'IFF'。。。我的错,函数是IIF不是IFF。。。我已经更新了相应的答案。嗯。。。这会使
FinalExpenditures
字段留空,即使所有框都已切换。您要做什么
rs1!是的,确认
rs1!已确认
返回可不可以单步执行(F8)到此步骤
rs2!FinalExpenditure=Iif(rs1!YetToConfirm=0,rs1!Confirm,0)
它不允许我这么做。我设置了一个断点,但当我运行它时它不会停止。当我尝试运行它时,它在set rs1=CurrentDb.OpenRecordset(sql,dbOpenDynaset,dpinconsistent)处给我一个错误:“运行时错误3061:参数太少。应为1。”这是一个肯定的迹象,sql中有一个引用不存在的表字段的文本。请仔细检查您的“支出”表中是否存在“金额”、“最终”和“ProjNo”字段。我不知道,我只是在我已有的基础上重新编写了这段代码,它起了作用。