Доступ к VBA NoMatch = True, если я считаю, что NoMatch должен иметь значение False. Куда я иду? - PullRequest
0 голосов
/ 14 сентября 2018

Через различные добрые души @jericho Джонсон и другие.У меня есть код VBA, который, кажется, работает.За исключением одной части.Окончательное условие Else: «Пока не 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]

1 Ответ

0 голосов
/ 14 сентября 2018

Существует несколько проблем, вероятно, это основная проблема:

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.Это действительно необходимо для разработки 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

Это проще и надежнее.

...