当我认为NoMatch应该是假的时,访问VBA NoMatch = True,我哪里出错了?

问题描述 投票:0回答:1

通过各种善良的灵魂@jericho johnson和其他人。我有VBA代码似乎正在工作。除了一部分。最后的'Else'条件,“Do While Not StrSQL1.NoMatch”。它总是等于真。即使在第一个Else语句中引用的值“StrSQL1.FindFirst([PrimaryKey] = qs.Fields(”external_nmad_id“))”

当我将鼠标悬停在'external_nmad_id'上时,它会显示一个字符串值。当我将鼠标悬停在[PrimaryKey]上时,它显示'[PrimaryKey] =“”'。空引用集是引用值的记录集 - 还是表示没有引用任何内容(因此NoMatch始终为True)。或者我在其他地方遗漏了什么?

Public Sub EditFinalOutput2()

'set variables
Dim i As Long
Dim intCount As Long
Dim qs As DAO.Recordset
Dim ss As DAO.Recordset
Dim StrSQL1 As DAO.Recordset
Dim IRSfileFormatKey As String
Dim external_nmad_id As String
Dim nmad_address_1 As String
Dim nmad_address_2 As String
Dim nmad_address_3 As String
Dim mytestwrite As String
Dim PrimaryKey As String
Dim box13c_Address As String

'open reference set
Set db = CurrentDb
Set qs = db.OpenRecordset("SunstarAccountsInWebir_SarahTest")

'turn popup messages off
'DoCmd.SetWarnings False

With qs.Fields

intCount = qs.RecordCount - 1
For i = 0 To intCount
'===
'=== Condition 1 Test - validate address
'===
If (IsNull(!nmad_address_1) Or (!nmad_address_1 = !nmad_city) Or 
(!nmad_address_1 = !Webir_Country) And IsNull(!nmad_address_2) Or 
(!nmad_address_2 = !nmad_city) Or (!nmad_address_2 = !Webir_Country) And 
IsNull(!nmad_address_3) Or (!nmad_address_3 = !nmad_city) Or 
(!nmad_address_3 = !Webir_Country)) Then
'=== Address Not Valid, insert into Review table
DoCmd.RunSQL "INSERT INTO Addresses_ToBeReviewed SELECT 
SunstarAccountsInWebir_SarahTest.* FROM SunstarAccountsInWebir_SarahTest 
WHERE (((SunstarAccountsInWebir_SarahTest.external_nmad_id)='" & 
qs!external_nmad_id & "'));"

Else
Set StrSQL1 = db.OpenRecordset("SELECT RIGHT(IRSfileFormatKey, 10) As PrimaryKey, box13c_Address FROM 1042s_FinalOutput_7 WHERE 'PrimaryKey' = 'external_nmad_id';", dbOpenDynaset)
StrSQL1.FindFirst ([PrimaryKey] = qs.Fields("external_nmad_id"))
'===
'=== Condition 2 Test
'===
If StrSQL1.NoMatch Then
    '=== ID Not Found, insert into NotUsed table
    DoCmd.RunSQL "INSERT INTO Addresses_NotUsed SELECT SunstarAccountsInWebir_SarahTest.* FROM SunstarAccountsInWebir_SarahTest WHERE (((SunstarAccountsInWebir_SarahTest.external_nmad_id)='" & qs!external_nmad_id & "'));"

Else
    '=== Address Found, update record
    Do While Not StrSQL1.NoMatch
        StrSQL1.Edit
        StrSQL1.Fields("box13c_Address") = (qs.Fields("nmad_address_1") & qs.Fields("nmad_address_2") & qs.Fields("nmad_address_3"))
        StrSQL1.Update
    Loop
End If
....[more code below]
access-vba findfirst no-match
1个回答
2
投票

有几个问题,这可能是主要问题:

StrSQL1.FindFirst ([PrimaryKey] = qs.Fields("external_nmad_id"))

FindFirst以字符串作为参数。你所拥有的是一个表达式,它可能总是计算为False或Null,因为[PrimaryKey]是一个未定义的变量,因为它在字符串之外。

它应该是

StrSQL1.FindFirst "[PrimaryKey] = " & CSql(qs.Fields("external_nmad_id").Value)

来自这里的CSql()https://stackoverflow.com/a/36494189/3820271 它适用于external_nmad_id是数字或字符串。

要捕获这样的错误,请将Option Explicit放在每个模块的顶部。它强制执行变量声明,并在编译时报告未声明或拼写错误的变量/常量。 要在新模块中自动执行此操作,请在VBA编辑器中设置Require Variable Declaration选项。这对于VBA开发来说确实是必须的。

其他问题:

1)命名记录集变量StrSQL1是相当混乱的。

2)

Do While Not StrSQL1.NoMatch

只有你在循环中做一个.FindNext才有意义。通常你总是需要If.NoMatch

3)

intCount = qs.RecordCount - 1
For i = 0 To intCount
    ' ...
    qs.MoveNext
Next i

不是一个做记录集循环的好方法 - .RecordCount只能在.MoveLast之后可靠地设置。请改用:

Do While Not qs.EOF
    ' ...
    qs.MoveNext
Loop

它更简单可靠。

© www.soinside.com 2019 - 2024. All rights reserved.