嵌套嵌套的Access VBA仅在第一条记录中起作用

时间:2018-12-21 16:32:13

标签: for-loop ms-access access-vba do-while

我有一个Access 2010数据库,其中的一个表包含受益人和中介人的列表。对于质量控制,我需要计算所有受益者的所有权,并省略充当最低受益者和最高中介机构之间链接的实体的所有权。因此,我有一个包含4列中介的表格。我希望执行以下步骤:

  1. 从“ IMY_Up1”列开始,选择第一个中介ID
  2. 浏览第二个“ IMY_Up2”列,以查看该ID是否存在。
  3. 如果是-将“链接的IMY”列编辑为“是”,如果该列中不存在,则将“链接的IMY”列编辑为“否”。

我面临的问题:当前代码-准确循环(“本地”窗口按预期显示“ i”和“ j”步进)。但是只有第一行的“ Linked_IMy”值更新为“否”。

尝试的修正:放入“ Do While”循环。但这会导致循环继续运行,并且在“本地”窗口中没有达到“ i”或“ j”值。

我的最终问题:如何更改代码,使其逐步执行并按需工作?我需要重新设计整个事情吗?如果是这样,我应该如何开始?

snippet of table structure (fake data for proprietary reasons)

这是VBA代码:

Option Compare Database
Option Explicit

Public Sub modFieldlengthRegulate()

Dim i As Integer            'set "i" as integer for IMY_Up1 loop
Dim j As Integer            'set "j" as integer for IMY_Up2 loop
Dim db As DAO.Database          'imy database
Dim rs As DAO.Recordset         'QC_LoopTestTable as recordset


Set db = CurrentDb                              'imy database
Set rs = db.OpenRecordset("QC_LoopTestTable")   'QC_LoopTestTable as recordset

For i = 0 To rs.RecordCount - 1                 'set up for IMY_Up1 loop

rs.MoveFirst                                    'always start at first row

'Do While Not rs.EOF

    'Set rs.Fields("IMY_Up1").Value = refSelect             'wanted to see what value it was assigning, but causes errors, so comment out

    For j = 0 To rs.RecordCount - 1         'set up for IMY_Up2 loop
    rs.MoveFirst
        'Do While Not rs.EOF
        'Set rs.Fields("IMY_Up2").Value = compareSelect     'wanted to see what value it was assigning, but causes errors, so comment out
            If (rs.Fields("IMY_Up2").Value = rs.Fields("IMY_Up1").Value) Then
                rs.Edit
                rs.Fields("Linked_IMY") = "Yes"
                rs.Update

            Else:
                rs.Edit
                rs.Fields("Linked_IMY") = "No"
                rs.Update
            End If
        'Loop
    Next j

'Loop
Next i


rs.Close                    'close the recordset as part of the last step
Set rs = Nothing            'close the recordset as part of the last step
db.Close                    'close the database as part of the last step

End Sub

1 个答案:

答案 0 :(得分:1)

使用SQL的力量

一个简单的

SELECT QC_LoopTestTable.ID
    ,QC_LoopTestTable.IMY_Up1
    ,QC_LoopTestTable.IMY_Up2
    ,IIf(IsNull([QC_LoopTestTable_1].[id]), "No", "Yes") AS Linked_IMY
FROM QC_LoopTestTable
LEFT JOIN QC_LoopTestTable AS QC_LoopTestTable_1 
ON QC_LoopTestTable.IMY_Up2 = QC_LoopTestTable_1.IMY_Up1;

做得更干净,更快(如果对IMY_Up1和IMY_Up2进行了索引)。

这会抓取QC_LoopTestTable并与其自身(QC_LoopTestTable AS QC_LoopTestTable_1)连接,其中Up2 = Up1。 如果不匹配,则复制表(QC_LoopTestTable_1)的结果为NULL,可以测试哪些内容(Iif-Statement),并且使用的对应值为(Yes / No)。

如果您要存储Linked_IMY的结果,则可以使用类似的UPDATE查询,但是不建议这样做(通常不存储计算值),因为如果您编辑记录,需要再次更新。

如果IMY_Up2匹配多个IMY_Up1,则这些值将加倍,但可以在必要时进行过滤

代码为何失败

  • 您的代码仅更新第一行,因为您不告诉记录集移至下一条记录。

  • 然后,您将需要两个独立的记录集才能在另一个中进行循环(使用rs.MoveFirst的内循环也会将外循环rs也设置为第一行(相同的变量rs))

    < / li>
  • 找到匹配项后,内部循环需要退出(Exit Do)或下一行将导致还原,因为它将在Else部分写入{{1}中结束}。

避免变量Linked_IMY在2 ^ 15-1以上失败,请使用Integer

使用Long遍历记录集。

代码可能像(仅供演示,请勿使用):

Do Until rs.eof ... Loop