Você tem um erro na sua cadeia de condições:
cond1 And cond2 Or cond3 Or cond4
será sempre avaliado como True
se um (ou ambos) de cond3
ou cond4
for True
. Isso ocorre porque And
será avaliado antes de Or
. Consulte a documentação para obter mais informações.
Você pode usar parênteses para ajustar a ordem de avaliação:
cond1 And (cond2 Or cond3 Or cond4)
Esta expressão só avaliará True
se cond1
e qualquer cond2, cond3, cond4
forem True
.
No seu caso, eu recomendaria as seguintes melhorias no seu código:
- Primeiramente, leia sobre loops no VBA.
For ... Next
eDo ... Loop
são os dois tipos que você precisa conhecer. - Então, para fazer as coisas pouco mais claro (isto é, deixe suas intenções visíveis no código), coloque esse código validação em sua própria sub-rotina / função.
- E finalmente, para tornar ainda mais óbvio o que está acontecendo, você pode dividir estas longas cadeias de condições.
Se nós olharmos agora para o procedimento Workbook_BeforeSave
, não é imediatamente óbvio o que ele está fazendo lá (pode ser para você, porque você acabou de colocar o código lá e está fresco em sua mente - mas volte a este folha em 3/6/12 meses e primeiro você precisa entender o que está fazendo). Vamos remediar isso:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Cancel = IsUserInputMissing
End Sub
Private Function IsUserInputMissing() as Boolean
' Validation code goes in here
End Function
Agora, todos que estão vendo o código podem ver rapidamente o que acontecerá quando a pasta de trabalho for salva.
Esta linha
If Sheets("Sheet1").Range("A7").Value <> "" And Sheets("Sheet1").Range("B7").Value = "" Or Range("C7").Value = "" Or Range("D7").Value = "" Or Range("E7").Value = "" Or Range("F7").Value = "" Or Range("G7").Value = "" Or Range("H7").Value = "" Or Range("I7").Value = "" Or Range("J7").Value = "" Or Range("K7").Value = "" Or Range("L7").Value = "" Or Range("M7").Value = "" Or Range("N7").Value = "" Or Range("O7").Value = "" Then
não é muito amigável aos olhos. Verbatim diz If FirstCellIsNotEmpty And AnyFollowingCellIsEmpty Then
. Vamos codificar dessa maneira.
Dim FirstCellIsEmpty as Boolean
FirstCellIsEmpty = Sheets("Sheet1").Range("A7").Value = ""
Dim AnyFollowingCellIsEmpty as Boolean
AnyFollowingCellIsEmpty = WorksheetFunction.CountBlank(Sheets("Sheet1").Range("B7:O7")) > 0
If Not FirstCellIsEmpty And AnyFollowingCellIsEmpty Then
MsgBox "I don't know any Swedish. But please fill out the necessary cells."
End If
Observe o uso de WorksheetFunction.CountBlank
para evitar a necessidade de digitar todas as células a serem verificadas.
No final, darei um exemplo de como sua função IsUserInputMissing
poderia se parecer. (Ainda há muito espaço para melhorias, no entanto.)
Private Function IsUserInputMissing() As Boolean
' Easy way to set the beginning of the range
Const FirstRowToBeChecked As Long = 7
' Set a reference to the sheet that needs checking
Dim Ws As Worksheet
Set Ws = ThisWorkbook.Worksheets("Sheet1")
Dim iRow As Long
iRow = FirstRowToBeChecked
Do
Dim FirstCellIsEmpty As Boolean
FirstCellIsEmpty = Ws.Cells(iRow, 1).Value = vbNullString ' vbNullString is a clearer way of saying ""
' Exit loop at the first empty row
If FirstCellIsEmpty Then Exit Do
Dim AnyFollowingCellIsEmpty As Boolean
AnyFollowingCellIsEmpty = WorksheetFunction.CountBlank(Ws.Range(Ws.Cells(iRow, 2), Ws.Cells(iRow, 15))) > 0
If AnyFollowingCellIsEmpty Then
' Any time the requirements are not met, notify user and abort checking and saving
' This is not as elegant as checking the whole range and collecting info about all missing inputs
' But it's way easier to code :)
MsgBox "I don't know any Swedish. But please fill out the necessary cells. Tack!"
IsUserInputMissing = True
Exit Function
End If
' Don't forget to increment the counter, otherwise you've got yourself an endless loop
iRow = iRow + 1
Loop
' If execution reaches this line, all rows fulfil the requirement
' IsUserInputMissing will have its Default value: False
End Function
Tome seu tempo e trabalhe com isso. Eu tentei deixar as coisas o mais claras possível. Mas se algo não está claro. Não hesite em perguntar. :)