MS word 2016中我的VBA for循环不工作
我在MS word VBA中遇到以下代码问题MS word 2016中我的VBA for循环不工作,vba,for-loop,ms-word,Vba,For Loop,Ms Word,我在MS word VBA中遇到以下代码问题 For i = 6 To ActiveDocument.Tables(2).Rows.Count z = Len(ActiveDocument.Tables(2).Cell(i, 2).Range.Text) - 2 x = Len(ActiveDocument.Tables(2).Cell(i, 3).Range.Text) - 2 b = ActiveDocument.Tables(2).Cell(i, 5).Range.
For i = 6 To ActiveDocument.Tables(2).Rows.Count
z = Len(ActiveDocument.Tables(2).Cell(i, 2).Range.Text) - 2
x = Len(ActiveDocument.Tables(2).Cell(i, 3).Range.Text) - 2
b = ActiveDocument.Tables(2).Cell(i, 5).Range.ContentControls.Item(1).ShowingPlaceholderText
If (z = 0 And x = 0) Then
If b = True Then
MsgBox "Please do error 1!"
If vbOK Then
Exit Sub
End If
Else
MsgBox "Please do error 2!"
If vbOK Then
Exit Sub
End If
End If
Else
If b = True Then
MsgBox "Please do error 3!"
If vbOK Then
Exit Sub
End If
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循环不会进入第二行检查z或x是否有值我怀疑移动
下一个I
会解决任何问题。这段代码充满了恶意
我的印象是,您的代码旨在检查表中的三列(从第6行向下)-这似乎是一个一致性检查
命名z
、x
和b
都不是很好的描述。使用像lengthCol2
、lengthCol3
和haspocholdertext
这样的名称将帮助您更紧密地遵循逻辑
使用显式选项
。总是
您使用标准的MsgBox
调用,默认情况下只有一个按钮(“OK”)。MsgBox
是一个阻塞代码元素,因此在用户单击“确定”之前,宏将不会进行
vbOK
是一个枚举值(值=1)。所以如果vbOK那么
总是为真。总是。您似乎在寻找某种用户输入,但不清楚该输入是什么
解决这些简单步骤为我们提供了:
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
你的逻辑是消极偏见的——也就是说,你想找到不做某事的理由,而不是去做某事。积极偏见逻辑通常更容易理解和维护——编码者的意图更清晰
改写逻辑给我们提供了:
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列可以为空,并且(只要未显示占位符文本),您的文档已准备好提交。也许您的意思是和
,而不是或
(即所有列都应填写)
还有一个问题。你的循环。正如目前所写的那样,您在逻辑上循环,因此您要求用户检查错误或根据每行中的错误检查提交文档x次。但是,仅仅移动下一个i
并不能解决问题,因为只保留最后一行中的结果。换句话说,前面的所有行都可能是坏的/无效的,但您仍然可以提交
我们可以通过创建累积逻辑来修复最后一点。换句话说,我们在一个短循环中跟踪错误,然后进入主逻辑。这看起来有点复杂,但实际上是相对直接的。但是,我们确实需要更多的Boolean
s来使它工作
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
但是,此逻辑适用于所有行,因此在主循环中不可能识别单个行错误。您可以在下一个循环的中使用额外的逻辑向用户发送错误消息
现在代码是可维护的,并且更可能实现您想要的功能
要点:
- 使用显式
选项
。这可以防止输入错误,并确保您以您想要的方式使用变量
- 使用有意义的变量名。让你更容易跟随你想做的事情李>
- 不要将枚举值与函数返回值混淆。不要混淆常量和变量
- 花些时间检查你的逻辑链,确保它们做你想做的事,而不是不做你不想做的事。后者丢失无效路径的可能性更大
解决了这个问题。下一个i应该放在If语句之前,以便进行循环。