2016-11-07 87 views
0

我正在使用通过尝试命名并重定向错误直到找到有效名称来创建唯一表名的子文件夹。错误处理完成后出现奇怪的错误行为

子的作品,但在离开子,并试图在OLEOBJECT复选框来测试值后,它给了我,我以前被重定向错误 - 那就是除非我执行一些其他呼叫如ws.Activateapplication.screenupdating = false 。我曾尝试在代码中的各个位置放置Err.Clear,但没有成功。

我很新的VBA(不到一个月的使用它),所以原谅我的明显错误。

我用Excel 2013年

运行此首先创建在Sheet1中的复选框,并与一个指定名称的新表:

Private Sub runfirst() 

    Dim cb1 As OLEObject 
    Dim ws As Worksheet 

    Sheet1.OLEObjects.Delete 
    Set cb1 = Sheet1.OLEObjects.Add(ClassType:="Forms.CheckBox.1") 
    cb1.Name = "CheckBox1" 
    cb1.Object.Caption = "Checkbox1" 

    Set ws = ThisWorkbook.Sheets.Add 
    ws.Name = "mysheet" 

End Sub 

主要代码:

Private Sub test1() 
    'This throws an error 
    Dim ws As Worksheet 

    Set ws = ThisWorkbook.Sheets.Add 
    NameWS rootname:="mysheet", ws:=ws 
    'ws.Activate 
    If Sheet1.CheckBox1.Value = True Then MsgBox "true" Else MsgBox "false" 

End Sub 

Private Sub test2() 
    ' This works fine 
    Dim ws As Worksheet 

    Set ws = ThisWorkbook.Sheets.Add 
    NameWS rootname:="mysheet", ws:=ws 
    ws.Activate 
    If Sheet1.CheckBox1.Value = True Then MsgBox "true" Else MsgBox "false" 

End Sub 


Private Sub NameWS(rootname As String, ws As Worksheet) 
    ' This sub tries to name the WS as rootname, if it fails, it increments a counter in the name. 

    Dim ctr As Long 
    ctr = 0 

    On Error GoTo Err1: 
    ws.Name = rootname 
    Exit Sub 

BaseNameTaken: 
    ctr = ctr + 1 
    On Error GoTo Err1: 
    ws.Name = rootname & " (" & ctr & ")" 
    ' If execution makes it to here it means that a valid name has been found 

    On Error GoTo 0 
    Exit Sub 

Err1: 
    If ctr > 99 Then Resume Fail ' Just to ensure we haven't created an infinite loop 
    Resume BaseNameTaken 

Fail: 
    ' Leave sub. Inability to name WS is not a critical error. 
    MsgBox "Failed to name worksheet after " & ctr & " tries. Excel default name used." 

End Sub 
+2

它给你什么错误?我刚测试过。如果我先运行第一个程序,然后运行Test1,只要NameWS在同一模块中,它就可以正常运行。 – Niclas

+0

我得到运行时错误1004:“该名称已被占用,请尝试使用其他名称。”这是我在NameWS函数中重定向的错误。我只是在家用电脑上试过它(在我工作之前),并且出现同样的错误,因此对我来说是可重现的。 –

回答

0

它的设置Application.DisplayAlerts

的问题,你可能想要使用此功能

Private Sub NameWS(rootname As String, ws As Worksheet) 
    Dim ctr As Long 
    Application.DisplayAlerts = False 
    Do 
     On Error Resume Next 
     ws.name = rootname & IIf(ctr = 0, "", " (" & ctr & ")") 
     ctr = ctr + 1 
    Loop While Err > 0 
    Application.DisplayAlerts = True 
End Sub 

此外,该行:

If Sheet1.CheckBox1.Value = True Then MsgBox "true" Else MsgBox "false" 

可以简化为:

MsgBox Sheet1.CheckBox1.Value 
+0

非常简洁。这一个完美的作品。我唯一的问题是为什么。我想了解为什么设置Application.DisplayAlerts = False使它消失。为什么,当我点击错误调试时,它会带我到if语句。 –

+0

我的意思是,你的循环只有在没有错误时才退出,那为什么它会在后面的一行中提出错误(如果我注释掉'Application.DisplayAlerts'行)? –

+0

后者是_alert_而不是_error_,即[something](https://msdn.microsoft.com/en-us/library/office/ff839782.aspx),您通常会意识到并响应,但是你可以通过抑制警报而忽略它。还有一些有用的地方(按照上面的链接获取其中的一些)。最后,您可能希望通过点击答案旁边的复选标记来接受此答案,以将其从灰色变为填充。谢谢! – user3598756

0

我不喜欢On Error Goto Label。我发现代码跳跃难以理解,难以正确理解。

下面的宏是我如何将代码,如例程。

首先,几点可能会有所帮助。

我有一个名为Resources的子文件夹“VBA”,“VBA Excel”和“VBA Outlook”。如果我使用VBA Word或VBA Access,我也会为它们设置子文件夹。每当我完成一个开发时,我会查看我的代码,以查找可能会再次使用的例程。如果例程是通用VBA,则将其作为文本文件保存在“VBA”中。按照你的日常工作,我将它保存为“NameWS .txt”文件夹“VBA Excel”中。

宏开始时会解释它的功能。如果这个宏很复杂,它也会概述它是如何实现它的目标的。当我在六个月或十二个月或五年的时间里观察宏观时,这可以帮助我。我有几年前写的宏,快速查看它是否对今天的问题有帮助。

最后,宏的历史的第一行。每次我更新宏时,我都会添加一个或两个说什么和为什么。

Private Sub NameWS(rootname As String, ws As Worksheet) 

    ' Attempt to rename worksheet ws as rootname. If successful, exit. 
    ' If unsuccessful, rename worksheet as rootname (N) where 
    ' N is the first number in the sequence 1, 2, 3 and so on such 
    ' that rootname (N) did not previously exist. 

    ' 7Nov16 Coded. 

    Dim ctr As Long 
    Dim NameCrnt As String 

    ' Try rootname first 
    On Error Resume Next 
    ws.Name = rootname 
    On Error GoTo 0 
    If ws.Name = rootname Then 
    ' Rename successful 
    Exit Sub 
    End If 

    ' rootnamne is use. Try rootname (1), rootname(2), etc, until 
    ' get successful rename. 
    ctr = 1 
    Do While True 
    NameCrnt = rootname & " (" & ctr & ")" 
    On Error Resume Next 
    ws.Name = NameCrnt 
    On Error GoTo 0 
    If ws.Name = NameCrnt Then 
     ' Rename successful 
     Exit Sub 
    End If 
    ctr = ctr + 1 
    Loop 

End Sub 
+0

当我从我的子test1运行时,我仍然从这个错误中得到相同的错误。你能重现错误吗? –

+0

@BenP。我没有仔细阅读你的问题。我看到了子程序NameWS的问题并解决了这个问题。我不明白真正的问题是'Sheet1.CheckBox1.Value'后面的错误。暂时抑制Excel标准错误处理有时是处理可能失败的语句的唯一技术。有可能编写一个不会产生错误的NameWS版本;它可能会很慢,但它会起作用。但是还有其他一些声明,对于这些声明,临时压缩Excel标准错误处理是唯一的选择。 –

+0

我从来没有见过这样的错误。我不明白为什么使用'DisplayAlerts'有帮助,因为这不是一个警报。 'Err.Clear'和'Err.Number = 0'没有帮助。有关旧错误的信息会被保留。它可以通过WS.Activate或者使用DisplayAlerts来清除。我无法找到能够清除此错误的“普通”语句。这个问题是OLEObject唯一的吗?我不知道。也许我们不应该太担心,因为这个问题会在日常测试中被发现并且有一个解决方法。 –