【问题标题】:While Loop in VBA AccessVBA访问中的while循环
【发布时间】:2018-10-29 12:51:59
【问题描述】:

我有根据用户输入构建 Table1 的删除和附加函数。因此,Table1 为每个用户附加了不同数量的记录。

我的 SQL 代码用于查找日期,但它只执行一次,我需要循环 SQL 代码以获得表的长度。我不擅长编码,我尝试了一个 while 语句,不确定我是否可以在标准中使用变量 Z,但我希望它运行直到填充了具有最小 ID 值的记录中的到期日期。

这是我尝试过的:

Private Sub Command7_Click()
Y = DMax("ID", "Table1", BuildCriteria("Due_date", dbDate, "Null"))
A = DMin("ID", "Table1", BuildCriteria("Due_date", dbDate, "Not Null"))
X = DMin("ID", "Table1")
Z = DLookup("Due_date", "Table1", BuildCriteria("ID", dbLong, CStr(X)))

B = DLookup("Duration", "Table1", BuildCriteria("ID", dbLong, CStr(Y)))
C = DLookup("Due_date", "Table1", BuildCriteria("ID", dbLong, CStr(A)))
E = DateAdd("d", -B, C)

Dim SQL As String

SQL = "UPDATE Table1 " & _
    "SET " & BuildCriteria("Due_date", dbDate, CStr(E)) & " " & _
    "WHERE " & BuildCriteria("ID", dbLong, CStr(Y))


While Z Is Null
DoCmd.RunSQL SQL

End While

End Sub

举例说明:

  • 运行 SQL 之前

  • 运行一次 SQL 后

  • 点击几次后

目标是单击一次,整个表格就会填满

【问题讨论】:

  • 请显示当前数据的样本和期望的结果。另外,我们需要查看BuildCriteria。总之,这有助于设置minimal reproducible example
  • 我不太明白 BuildCriteria 是做什么的,但这是我在上面粘贴的整个代码,没有其他可真正显示的内容。
  • 我的 Table1 的行数是可变的,这就是为什么有变量来识别最后一行,它之前的行,然后它从最后一行中减去上一行的持续时间并粘贴它在前一行。但是,单击一个按钮只执行一次,我需要它为表中的每条记录执行此操作,而无需单击按钮 20 次以上来完成它。
  • edit您的帖子并显示原始数据(几行)和您想要的输出(几行)。很难用文字看出你的意思。有趣的是,在我这些年来,我从未听说过或使用过 MS Access 的BuildCriteria() 方法。每天学习新东西!
  • 已编辑 - 谢谢!

标签: sql vba ms-access


【解决方案1】:

您的变量Z 包含DLookup 函数返回的结果,当评估为您的子Command7_Click 定义的第四行时;除非重新定义变量,否则该变量的值不会改变。

使用BuildCriteria 函数有点模糊了代码的意图,因此很难建议编写代码的最佳方式...

编辑BuildCriteria 对我来说是新的 - 感谢@Andre 指出这一点。

由于您的 SQL 语句的内容是静态的,因此不需要循环,因为循环内没有任何变化 - SQL 语句将更新所有符合您的条件的记录,并且不会对每次后续迭代执行任何操作 (除非,也就是说,您将记录更新到的值也满足选择标准)。


编辑

根据您的其他解释和屏幕截图,您可以通过遍历按您的ID 字段排序的记录集并为每条记录连续计算适当的Due_date 来完成任务 - 类似于:

Private Sub Command7_Click()
    Dim dbs As DAO.Database
    Dim rst As DAO.Recordset
    Dim dat As Date
    Set dbs = CurrentDb
    Set rst = dbs.OpenRecordset("select * from Table1 order by ID desc")
    With rst
        If Not .EOF Then
            .MoveFirst
            Do Until .EOF
                If Not IsNull(!Due_date) Then
                    dat = !Due_date
                Else
                    dat = DateAdd("d", -!Duration, dat)
                    .Edit
                    !Due_date = dat
                    .Update
                End If
                .MoveNext
            Loop
        End If
        .Close
    End With
    Set rst = Nothing
    Set dbs = Nothing
End Sub

尽管根据您的屏幕截图,您似乎正在尝试像 Excel 电子表格一样使用 Access。

【讨论】:

  • SQL 语句只更新倒数第二个记录。该表具有 ID 字段、任务字段、持续时间字段和到期日期字段。首次创建时,到期日期附加在底部,该字段中的其余记录为 Null。然后 SQL 获取截止日期,从它上面的记录中减去持续时间(以天为单位),并将其作为该记录的截止日期。问题是它只执行一次,而且我的表的长度取决于用户输入。
  • 如果我多次单击 cmd_7,它会填充相同数量的记录。
  • 我必须同意——在不知道 buildCriteria 做什么的情况下,我们只能为您做这么多。然而,所有 D 函数中所有浪费的处理能力似乎都是不必要的。即使不知道 BuildCriteria 做了什么,我也很确定您可以使用一个 SQL 命令处理整个过程
  • 有没有办法让它点击现有记录数的按钮?运行一次SQL命令只填一条记录,我需要填满整个表。
【解决方案2】:

考虑实际上没有For 循环,没有BuildCriteria,甚至没有VBA SQL。将更新查询另存为在单击按钮时运行的 MS Access 操作查询对象。

具体来说,您需要几个域函数 --DLookUpDSumDMax-- 在其中计算持续天数的运行总和(即相关聚合计算),然后是 DateAdd结果到相应最大值IDDueDate,没有丢失DueDate

SQL

UPDATE myTable d
SET d.DueDate =  DateAdd("d", -1 * DSum("Duration", "DueDateDuration", "ID >= " & d.ID),  
                                         DLookUp("DueDate", "DueDateDuration", "ID = " &  
                                                 DMax("ID", "DueDateDuration", "DueDate IS NOT NULL") 
                                       )
                        )
WHERE d.DueDate IS NULL;

VBA

Private Sub Command7_Click()
    DoCmd.OpenQuery "mySavedUpdateQuery"     ' WITH WARNINGS

    CurrentDb.Execute "mySavedUpdateQuery"   ' WITHOUT WARNINGS
End Sub

在样本数据上进行演示:

更新前 (mytable)

ID      Item       Duration     DueDate
2674    Issue             1   2/18/2019
2675    Shipping          1   2/19/2019
2678    Completed         0   2/20/2019
2679    Issue             1 
2680    Shipping         10 
2681    Other             6 
2682    Buy Off           6 
2683    Punch List        3 
2684    Completed         0   3/29/2019

更新后 (mytable)

ID      Item       Duration     DueDate
2674    Issue             1   2/18/2019
2675    Shipping          1   2/19/2019
2678    Completed         0   2/20/2019
2679    Issue             1    3/3/2019
2680    Shipping         10    3/4/2019
2681    Other             6   3/14/2019
2682    Buy Off           6   3/20/2019
2683    Punch List        3   3/26/2019
2684    Completed         0   3/29/2019

【讨论】:

  • 大家好。我们有机会让我的原始代码工作吗?我将不得不添加更多变量并使其更复杂,因此能够使用我的变量编写 sql 将是一个巨大的帮助。
猜你喜欢
  • 2011-09-21
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-08
  • 1970-01-01
相关资源
最近更新 更多