我怀疑移动 Next i 会解决任何问题。这段代码充满了恶意。
我的印象是您的代码旨在检查表中的三列(从第 6 行向下) - 这似乎是一致性检查。
命名。 z、x 和 b 的描述性不是很好。使用lengthCol2、lengthCol3 和hasPlaceHolderText 之类的名称将帮助您更紧密地遵循您的逻辑。
使用Option Explicit。总是。
您使用标准的MsgBox 调用,默认情况下只有一个按钮(“确定”)。 MsgBox 是一个阻塞代码元素,因此在用户单击“确定”之前宏不会进行。
vbOK 是一个枚举值(值 = 1)。所以If vbOK then 总是正确的。总是。您似乎正在寻求某种用户输入,但您不清楚该输入是什么。
解决这些简单的步骤给我们:
For i = 6 To ActiveDocument.Tables(2).Rows.Count
lengthCol2 = Len(ActiveDocument.Tables(2).Cell(i, 2).Range.Text) - 2
lengthCol3 = Len(ActiveDocument.Tables(2).Cell(i, 3).Range.Text) - 2
hasPlaceHolderText = ActiveDocument.Tables(2).Cell(i, 5).Range.ContentControls.Item(1).ShowingPlaceholderText
If (lengthCol2 = 0 And lengthCol3 = 0) Then
If hasPlaceHolderText = True Then
MsgBox "Please do error 1!"
Exit Sub
Else
MsgBox "Please do error 2!"
Exit Sub
End If
Else
If hasPlaceHolderText = True Then
MsgBox "Please do error 3!"
Exit Sub
Else
Confirm = MsgBox("Are you sure to submit?", vbYesNo, "Confirmation")
If Confirm = vbNo Then
Exit Sub
End If
End If
End If
Next i
你的逻辑是消极的——也就是说,打算找理由不做某事而不是做某事。正偏逻辑通常更容易理解和维护 - 编码人员的意图更清晰。
改写逻辑给我们:
For i = 6 To ActiveDocument.Tables(2).Rows.Count
lengthCol2 = Len(ActiveDocument.Tables(2).Cell(i, 2).Range.Text) - 2
lengthCol3 = Len(ActiveDocument.Tables(2).Cell(i, 3).Range.Text) - 2
hasPlaceHolderText = ActiveDocument.Tables(2).Cell(i, 5).Range.ContentControls.Item(1).ShowingPlaceholderText
If (lengthCol2 > 0 OR lengthCol3 > 0) AND hasPlaceHolderText Then
Confirm = MsgBox("Are you sure to submit?", vbYesNo, "Confirmation")
If Confirm = vbYes Then
'Do submission code here - or call the submission procedure
End If ' Just do nothing if they say "No" - this is what your current code does.
Else
' The next line could be used instead of the nested IF-the-else statements following.
'MsgBox " Table contents are not valid, please ensure columns 2,3 and 5 are completed"
If hasPlaceHolderText then
If (lengthCol2 = 0 And lengthCol3 = 0) Then
MsgBox "Please do error 1!"
Else
MsgBox "Please do error 2!"
EndIF
Else
MsgBox "Please do error 3!"
End If
End If
Next i
请注意,在您的逻辑中,第 2 列或第 3 列可以为空,并且(只要未显示占位符文本)您的文档已准备好提交。也许你的意思是AND 而不是OR(即所有列都应该填满)。
还有一个问题。你的循环。如当前所写,您循环逻辑,因此您要求用户检查错误或根据每行中的错误检查次数提交文档 x 次。但是,仅移动 Next i 并不能解决问题,因为唯一保留的结果是最后一行中的结果。换句话说,之前的所有行都可能是错误的/无效的,但您仍然可以提交。
我们可以通过创建累积逻辑来修复最后一点。换句话说,我们在一个短循环中跟踪错误,然后进入主逻辑。这似乎有点复杂,但它确实是相对简单的。但是,我们确实需要更多 Booleans 才能使其正常工作。
Dim rowsOK as Boolean
'explicit initialisation - I am working on a positive bias here.
rowsOK = True
For i = 6 To ActiveDocument.Tables(2).Rows.Count
Dim lengthCol2OK as Boolean ' Use these just to make the logic clearer and the code cleaner
Dim lengthCol3OK as Boolean
Dim hasPlaceHolderTextOK as Boolean
lengthCol2OK = Len(ActiveDocument.Tables(2).Cell(i, 2).Range.Text) > 2
lengthCol3OK = Len(ActiveDocument.Tables(2).Cell(i, 3).Range.Text) > 2
hasPlaceHolderTextOK = ActiveDocument.Tables(2).Cell(i, 5).Range.ContentControls.Item(1).ShowingPlaceholderText
rowsOK = rowsOK And ((lengthCol2OK Or lengthCol3OK) And hasPlaceHolderTextOK) ' Note: Using "Or" here as per original code logic
' Extra logic could go here to message the user if any of the above are false.
Next i
If rowsOK Then
Confirm = MsgBox("Are you sure to submit?", vbYesNo, "Confirmation")
If Confirm = vbYes Then
'Do submission code here - or call the submission procedure
End If ' Just do nothing if they say "No" - this is what your current code does.
Else
MsgBox " Table contents are not valid, please ensure columns 2,3 and 5 are completed"
End If
但是,此逻辑适用于所有行,因此无法在主循环中识别单个行错误。您可以在 For-Next 循环中使用额外的逻辑来向用户发送错误消息。
现在代码是可维护的,更有可能做你想做的事。
关键点:
- 使用
Option Explicit。这样可以防止拼写错误,并确保您以您想要的方式使用变量。
- 使用有意义的变量名。使您更容易遵循您想做的事情。
- 不要将枚举值与函数返回值混淆。不要将常量与变量混淆。
- 花一些时间检查您的逻辑链,以确保它们做您想做的事情,而不是不做您不想做的事情。后者更有可能错过无效路径。