我正在编写使用Application.GetOpenFileName 的代码。我试图确保如果有人在选择文件时点击取消,该代码不会中断。我有一个 if 语句,声明 if file = "false" 然后显示 msgbox 并退出 sub。当没有选择文件时,这工作正常,但是当我运行所选文件的宏时,我收到类型不匹配错误。我尝试了很多不同的方法,但没有任何效果。我在这里看过其他类似的问题,但没有任何效果对我有用。
Dim nom As String
Dim wb1, wb2, wb3, wb4, wb5 As Excel.Workbook
Dim i, j, k, file As Variant
nom = ActiveWorkbook.Name
If CurDir() <> CurDir("J:") Then
ChDrive "J:"
ChDir "J:FEA Material Data"
End If
For i = 1 To 5
Application.ScreenUpdating = False
MsgBox ("Select Compound" & vbNewLine & vbNewLine & "If Data From Criterion, Select Loading Only" & vbNewLine & vbNewLine & "If Data From Alliance, Select All")
file = Application.GetOpenFilename( _
FileFilter:="Text Files (*.csv), *.csv", _
MultiSelect:=True)
If file = "False" Then
MsgBox "No File Selected"
Exit Sub
Else
counter = 1
While counter <= UBound(file)
Workbooks.Open file(counter)
counter = counter + 1
Wend
End If
more code
当它有文件时,它返回一个带有数组的变体。
Debug.Print VarType(file)
返回 8204。因此您需要检查数组中的文件名。如果用户选择取消,则 Variant 将是布尔值。
If VarType(file) = 11 Then
MsgBox "No File Selected"
Exit Sub
或者更具可读性(感谢 Dirk Reichel):
If Not IsArray(file) Then
MsgBox "No File Selected"
Exit Sub
单个文件选择模式
如果您正在做
MultiSelect:=False
,您有:
If file = "False" Then
应该是:
If file = False Then
,则变体返回布尔值,而不是作为字符串值的 False
。一旦更正为不使用引号,它将在
Cancel上退出。
值,则它会落入
Else
条件,因为它不会是 False
,就像我们想要的那样。
....
多文件选择模式既然你正在做
MultiSelect:=True
——即使你更正它以使用
If file = False Then
它不会像上面那样工作,如果它确实有某些东西,它会给你一个不匹配错误,因为它会将你在条件语句中提供的布尔值与返回的数组进行比较。
If Not IsArray(file) Then
@D_Bester 和 @Dirk Reichel 在这种情况下给你的是最好的。
我写这篇文章不仅仅是为了获得他们的答案,因为我想更深入地解释一切,因为这不仅仅是说“使用那个”,它还有多个方面,它可能会让人感到困惑,而且它也让我有点生气,所以我觉得我们应该用更完整的答案阐明原因:
这是有效的,因为如果选择了
False
值(就像在单文件选择模式中一样),并且将测试布尔值是否为数组对象,发现显然不是数组,并将退出。 (这很有用,因为我们需要一个文件名数组才能继续:没有数组?退出。)
您不能一直测试False
False
与文件路径数组的类型不匹配比较。同样,您也不能总是测试文件路径数组(例如If UBound(file) = 0 Then
Cancel按钮时,它将返回布尔值而不是数组。单击并在尝试获取布尔对象的长度时给您类型不匹配的信息,因为布尔值中没有底层插槽。