Доступ к VBA NoMatch = True, если я считаю, что NoMatch должен иметь значение False. Куда я иду не так?
Через различные добрые души @jericho Johnson и других. У меня есть код 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 ответ
Есть несколько проблем, это, вероятно, главная:
StrSQL1.FindFirst ([PrimaryKey] = qs.Fields("external_nmad_id"))
FindFirst
принимает строку в качестве аргумента. То, что у вас есть, это выражение, которое, вероятно, всегда оценивается как False или Null, так как [PrimaryKey]
является неопределенной переменной, потому что она находится за пределами строки.
Так должно быть
StrSQL1.FindFirst "[PrimaryKey] = " & CSql(qs.Fields("external_nmad_id").Value)
с CSql()
отсюда: /questions/42928643/popyitka-ispolzovat-peremennyie-v-kachestve-znachenij-vba-dlya-sql/42928654#42928654
Это работает для 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
Это проще и надежнее.