Excel VBA错误处理仅在第一次通过时有效
我的代码是:Excel VBA错误处理仅在第一次通过时有效,excel,vba,Excel,Vba,我的代码是: Sub zaa() 'code to find another open file that has the defined name "data" ' - useful where the name changes each month or week For Each wb In Workbooks On Error GoTo abcd x = wb.Name Workbooks(x).Activate If Range("Data").Address
Sub zaa()
'code to find another open file that has the defined name "data"
' - useful where the name changes each month or week
For Each wb In Workbooks
On Error GoTo abcd
x = wb.Name
Workbooks(x).Activate
If Range("Data").Address <> "" Then y = wb.Name
Exit Sub
abcd:
Next wb
End Sub
Sub-zaa()
'查找另一个具有定义名称“data”的打开文件的代码'
'-在名称每月或每周更改时非常有用
对于工作簿中的每个wb
关于错误转到abcd
x=wb.Name
工作簿(x)。激活
如果范围(“数据”).Address”,则y=wb.Name
出口接头
abcd:
下一个wb
端接头
基本目标是,当我知道某个Excel文件存在但不知道文件名时,查找具有特定命名范围的Excel文件,因为该文件每周或每月都会更改。目标是找到文件并在该点退出子文件(或者在该文件上执行其他代码并退出,而不是转到其他文件)
我发现如果我只打开了两个文件就可以了,但如果有更多的文件就不行了(除非目标文件是第二行的)。虽然我可以用我所拥有的东西来运行,但我认为其他人可能会从我所拥有的东西中受益,我可以有一个更强大的解决方案
更新:
感谢所有回复的人&感谢米奇将原始帖子以可读的格式发布!(从那以后,我学会了如何纠正这个问题,并能够直接复制代码——我在下面的一些评论中指出了我遇到的问题。)
我取得了不同程度的成功——PaulStock和Reafidy的代码最初都为我工作,但PaulStock代码已经停止为我工作。Jean-François Corbett和Chris Neilsen的回复和代码对我很有帮助,但目前当我运行代码(按原样)时,它似乎什么都没做——ie没有离开我运行代码的工作表(范围名称数据也没有出现)。我最初是在Excel 2007的工作表中使用其他宏运行代码的,但为了尝试获得不同的结果,我将它们移动到一个独立的工作表中,而没有打开其他宏文件。还尝试从保存为'97-'03格式的文件中运行它们。两者都没有产生不同的结果。其他比我更有经验的人(见我在与Reafidy的评论讨论中所犯的错误,请记住,我最初发布的代码是通过谷歌找到的材料的结果,并由我针对特定任务和应用程序进行了修改,这意味着我没有足够的悟性来独立完成)可能会找到其他更适合他们的解决方案,但目前:
我非常高兴Reafidy的代码对我有用
由于我没有注册(我尝试过,但没有成功),而且没有足够的声望点数,我不能投票,但我在Reafidy的解决方案旁边打了一个复选标记
进一步更新:
我现在发现PaulStock&Jean François Corbett的代码对我来说不起作用,因为我有一个很小的差异——代码包含“数据”,而我命名的范围是“数据”。在他们的代码中进行此更改(考虑到区分大小写)意味着他们的两个解决方案现在都适用于我,因此我尝试在他们的解决方案中添加一个勾号!不幸的是,我发现只有一个解决方案有问题
我还了解到,我把克里斯的密码看得太过字面。为了“按原样”测试每个代码,我就是这么做的。在他有“do stuff”的部分中添加了一个简单的“wb.activate”,使代码可以执行我想要的操作
再次感谢您的四点贡献。您不能这样使用错误处理。将错误处理移出循环或在每次发生时重置错误处理程序,因此使用如下错误处理: 一个更受欢迎的选择是:
Sub Test()
For Each wb In Workbooks
x = wb.Name
Workbooks(x).Activate
If RangeExists("Data") Then
y = wb.Name
Exit Sub
End If
Next wb
End Sub
Function RangeExists(s As String) As Boolean
On Error Resume Next
RangeExists = Range(s).Count > 0
End Function
编辑:
Sub Test()
For Each wb In Workbooks
x = wb.Name
Workbooks(x).Activate
If RangeExists("Data") Then
y = wb.Name
Exit Sub
End If
Next wb
End Sub
Function RangeExists(s As String) As Boolean
On Error Resume Next
RangeExists = Range(s).Count > 0
End Function
@让·弗朗索瓦·科贝特,我得说,你可以很快按下投票按钮。我发布的第一个解决方案是因为我假设OP没有发布他的全部代码,因此我没有像通常那样尝试简化或“清理”。我同意我没有很好地表达我的答案,但是关于第一个解决方案,我试图证明他需要重置错误处理程序。不幸的是,我应该说“更喜欢的选择是”
@德里克,很抱歉我没能及时回答你进一步的问题。显然,你可以自由选择任何你喜欢的方法。在我看来,其他人提供的挖掘工作簿名称集合的多循环解决方案是不必要的,也是冗长的。现在更重要的是,名称集合可以包含引用常量、公式或范围的名称。我假设您只想检查定义的名称是否是一个特定的命名范围,这意味着其他人提供的循环方法需要调整以使其可靠
我同意其他人的意见,即应该避免错误处理,但excel中不必要的循环可能与使用错误处理一样有害,我个人像瘟疫一样避免它
上面的函数可以放在它自己的模块中,并且可以任意重用。它快速、可靠,避免了不必要的循环,专门检查工作簿中的命名范围,是检查excel vba社区中是否存在命名范围的最广泛接受/使用的方法(我的意思是使用函数和错误处理通过名称集合进行循环)。如果你不相信我,在谷歌上搜索“检查命名范围是否存在”。如果您需要其他excel vba专家的意见,请访问www.ozgrid.com/forum
现在我知道您已经发布了全部代码,并且不打算激活每个工作簿,您可以使用此代码激活第一个命名范围为“data”的工作簿:
我完全理解积极批评的必要性,如果正确使用否决票制度,我相信否决票制度。然而,我认为这是一个合理的解决方案,我投了两张反对票,再加上我在ops格式问题上的帮助——不幸的是,我忍不住觉得我想与这个论坛保持距离。这里有一个替代方法,我不想对错误处理程序产生幻想
Sub zaa()
Dim wb As Workbook
Dim CheckForNamedRange As Boolean
Dim nm As Name
On Error GoTo EH
For Each wb In Workbooks
CheckForNamedRange = True
Set nm = wb.Names("data")
If CheckForNamedRange Then
' Name found
' do stuff
Exit For
End If
Next
Exit Sub
EH:
If CheckForNamedRange Then
' Name not found
Err.Clear
CheckForNamedRange = False
Resume Next
Else
' Some other error occured, so handle it
'...
End If
End Sub
试试这个代码。不必担心出错
Sub zaa()
For Each wb In Workbooks
x = wb.Name
Workbooks(x).Activate
For Each n In Workbooks(x).Names
If n.Name = "Data" Then
y = wb.Name
Exit Sub
End If
Next
Next wb
End Sub
x = wb.Name
Workbooks(x).Activate
Sub zaa2()
Dim wb As Workbook
Dim nm As Name
For Each wb In Workbooks
For Each nm In wb.Names
If nm.Name = "Data" Then
wb.Activate
Exit Sub
End If
Next
Next wb
End Sub
' A workbook containing a range named "Data" is now activated
' (if one is found amongst the open workbooks).
' Note that there may be more than one, but only the first found is activated...
If StrComp(nm.Name, "data", vbTextCompare) = 0 Then
If LCase(nm.Name) = "data" Then