У меня есть база данных доступа, которая отслеживает наши внутренние проверки качества для персонала. У них есть 8 элементов, по которым мы их отслеживаем, и каждый из этих элементов имеет 4 возможных значения:
Пройти (1)
Без прохода (2)
К вашему сведению (3)
NP&FYI (4).
Вы можете увидеть эти 4 набора слева в столбце, над которым стоит «CPT». [1]. Я хотел бы, чтобы произошло, если ЛЮБОЕ из этих 8 полей FYI (ID 3), он устанавливает флажок FYI в true. Если ЛЮБОЙ не проходит (ID 2), он устанавливает флажки прохождения на false. Если ЛЮБОЕ из полей имеет значение NP&FYI (ID 4), я хочу, чтобы для двух флажков были установлены значения non-pass и FYI. Код, который я пытаюсь:
Private Sub Form_AfterUpdate()
If (Me.Diagnosis And Me.CPT And Me.DOS And Me.UpDownCode And
Me.ChargeCorrections And Me.ChurnEsc And Me.Protocol And Me.BillServProv)
= 1 Then
Me.FYI = 0
Me.QAFail = -1
End If
If (Me.Diagnosis Or Me.CPT Or Me.DOS Or Me.UpDownCode Or
Me.ChargeCorrections Or Me.ChurnEsc Or Me.Protocol Or Me.BillServProv) = 2
Then
Me.QAFail = 0
End If
If (Me.Diagnosis Or Me.CPT Or Me.DOS Or Me.UpDownCode Or
Me.ChargeCorrections Or Me.ChurnEsc Or Me.Protocol Or Me.BillServProv) = 3
Then
Me.FYI = -1
End If
If (Me.Diagnosis Or Me.CPT Or Me.DOS Or Me.UpDownCode Or
Me.ChargeCorrections Or Me.ChurnEsc Or Me.Protocol Or Me.BillServProv) = 4
Then
Me.FYI = -1
Me.QAFail = 0
End If
End Sub
К сожалению, я получаю противоречивые результаты. Если я устанавливаю поле, такое как CPT, как непроходное, то галочки флажка FYI и поле QAFail не очищаются. Если я устанавливаю для других полей другие значения, я получаю самые разные результаты. Я предполагаю это из-за путаницы между возможными значениями полей, интерпретируемых последовательными операторами If. Я думал об использовании CASE, но не мог понять, как установить значение case на основе 8 разных полей. Я новичок в VBA, может ли кто-нибудь указать мне правильное направление?
Альтернативный код 7 июня (работает)
Dim strCodes As String
With Me
strCodes = Nz(.Diagnosis & .CPT & .DOS & .UpDownCode & _
.ChargeCorrections & .ChurnEsc & .Protocol & .BillServProv, "")
End With
If InStr(strCodes, 2) > 0 Then
Me.QAFail = 0
ElseIf InStr(strCodes, 3) > 0 Then
Me.txtFYI = -1
ElseIf InStr(strCodes, 4) > 0 Then
Me.txtFYI = -1
Me.QAFail = 0
ElseIf strCodes <> "" Then
Me.txtFYI = 0
Me.QAFail = -1
End If
End Sub
Условие If
возвращает либо True, либо False (-1 или 0), а не 1, 2, 3, 4, которые вы тестируете. Каждый блок If
выполняется, поэтому последний, отвечающий критериям, возвращает результат. Используйте ElseIf
, тогда только один End If
. Используйте блок With Me
и не нужно повторять квалификатор Me
. Почему опубликованный код не показывает символ продолжения строки? Код предполагает, что каждое поле имеет значение. Если какое-либо поле имеет значение Null или пустую строку, тест для ID 1 всегда будет возвращать False, даже если в других 7 полях есть 1.
With Me
If (.Diagnosis = 1 And .CPT = 1 And .DOS = 1 And .UpDownCode = 1 And _
.ChargeCorrections = 1 And .ChurnEsc = 1 And .Protocol = 1 And .BillServProv = 1) Then
...
ElseIf (...) Then
...
ElseIf (...) Then
...
ElseIf (...) Then
...
End If
End With
Используйте тот же синтаксис для выражений ElseIf
с помощью оператора Or
.
Убедитесь, что тестовые значения расположены в порядке приоритета. Если ID 3 должен иметь приоритет над 2 и 4, сначала проверьте 3. Я бы подумал, что 2 имеет приоритет, но ваш рассказ противоречит.
Рассмотрим альтернативный код:
Dim strCodes As String
With Me
strCodes = Nz(.Diagnosis & .CPT & .DOS & .UpDownCode & _
.ChargeCorrections & .ChurnEsc & .Protocol & .BillServProv, "")
End With
If InStr(strCodes, 2) > 0 Then
...
ElseIf InStr(strCodes, 3) > 0 Then
...
ElseIf InStr(strCodes, 4) > 0 Then
...
ElseIf strCodes <> "" Then
...
End If
8 полей не являются полями да/нет, они являются полями поиска на основе таблицы, в которой хранятся 4 значения. Числа, которые я перечислил, являются значениями идентификаторов для этих записей. Я не знал об операторе with/end with - попробую.
Я знаю, что это не поля да/нет. Я никогда не говорил, что они есть. Условие If
возвращает True/False в зависимости от того, являются ли выражения критериев истинными или ложными. С And
все 8 выражений должны быть истинными, чтобы условие было истинным. С Or
только любое из 8 выражений должно быть истинным, чтобы условие было истинным.
Я попробовал ваш альтернативный код, и он работает, но я не уверен, что понимаю последний оператор elseif. Access не примет его без оператора then после него, и я поместил его туда. Должен ли я указывать то, что я хочу, если все 8 полей = 1? Я поставил код, который пробовал выше.
Извините, исправил недостающую Then
опечатку. Условие для всех 8 полей = 1 на самом деле не нужно. Любая ситуация, которая не соответствует первым трем условиям, будет проверена последним условием, и если переменная не является пустой строкой, будет выполнен код в этом ElseIf. После проверки первых трех условий в каждом поле должно быть только значение 1 (при условии, что пользователям запрещено вводить какие-либо другие значения, кроме этих четырех). Однако ни один код не гарантирует наличие данных в КАЖДОМ поле. Разрешено ли пользователям оставлять поле пустым?
Нет, по умолчанию для полей установлено значение «1». Я хотел, чтобы там был код «все равно 1», на случай, если кто-то установит значение непроходного, а затем вернет его обратно. Я хотел, чтобы автоматическое обновление произошло. Код работает отлично! Я очень ценю это! Ответ отмечен.
Ну а последний ElseIf
позаботится о «все равно 1». Может быть даже просто Else
, без проверки на пустую строку.
Поле может быть установлено по умолчанию равным 1, но разрешено ли пользователям удалять значение и оставлять поле пустым (Null)? Если у вас нет проверки, чтобы предотвратить это, это, безусловно, может произойти, даже случайно.
Они не могут, это поле со списком, ограниченное списком, поэтому оно всегда имеет значение. По другому вопросу у меня есть к вам вопрос по предложенному вами коду. У меня есть это в свойстве After Update формы. он работает на форме ввода данных. Однако, когда я пытаюсь добавить новую запись с помощью макроса доступа или методов DoCmd.GoToRecord , , acNewRec, мне не удается добавить новую запись. Есть предположения? У меня есть это в неправильном свойстве?
Поле со списком с ограничением на список по-прежнему допускает Null. Пользователь просто должен удалить ввод с помощью клавиши ESC, DELETE или BACKSPACE. Следует использовать AfterUpdate каждого элемента управления. Поместите код в подпрограмму за формой, затем вызовите подпрограмму из каждого из 8 элементов управления.
Спасибо, 7 июня, все работает отлично. Спасибо за помощь и урок!
Изображение не вставилось.