3

我有一个函数可以添加一个工作表并重命名它,但首先检查该名称的工作表是否已经存在。为此,我在这里使用了相当广泛的功能 -

Function WorksheetExists(ByVal WorksheetName As String) As Boolean

    On Error Resume Next ' Set to Resume Next as don't want to end macro if this fails
    WorksheetExists = (Sheets(WorksheetName).Name <> "")
    On Error GoTo 0

End Function

我的问题是我已经On Error GoTo error_exit在调用此函数的父子中进行了设置,因此On Error GoTo 0在检查工作表是否存在后会取消该调用。

我已经尝试On Error GoTo error_exit过此功能,但出现以下错误 -

编译错误:未定义标签

有人知道我该如何解决这个问题吗?

4

2 回答 2

5

当您退出 Function 时,WorksheetExists您的错误范围会自动恢复到以前的情况。您无需执行任何操作即可On Error Goto error_exit在调用子/函数中恢复。

有趣的是,如果您从此函数中删除错误处理并且具有传递名称的工作表不存在,您的代码将在调用错误处理标签上恢复执行(即在调用代码中的 error_exit: 标签处) )

于 2013-02-15T11:58:37.010 回答
0

我想你的意思是不使用大多数程序员不喜欢的 On Error Resume Next,这也意味着在调试期间你不能使用“Break On All Errors”来让代码停止死(Tools->Options->General->Error Trapping->Break on All Errors)。

对我来说,一种解决方案是将任何 On Error Resume Next 埋入已编译的 DLL 中,在过去,这将是 VB6。今天你可以使用 VB.NET,但我选择使用 C#。

如果您可以使用 Visual Studio,那么这里有一些来源。该模式类似于 C# 的 TryParse,它返回表示成功的布尔值,但也在返回参数(或 C# 用语中的 out 参数)中返回结果

这是 C# 源代码,启动一个名为 BuryVBAErrorsCS 的类库,设置 ComVisible(true) 添加对 COM 库“Microsoft Excel n”的引用,单击 Register for Interop。

using Microsoft.Office.Interop.Excel;
using System;
using System.Runtime.InteropServices;

namespace BuryVBAErrorsCS
{
    // Requires adding a reference to COM library Microsoft Excel 
    // In AssemblyInfo.cs set ComVisible(true);
    // In Build tab check 'Register for Interop'
    public interface ICollectionItemTry
    {
        bool SheetsItemTry(Sheets worksheetsCol, object vItem, out Worksheet result);
        bool WorkbooksItemTry(Workbooks workbooksCol, object vItem, out Workbook result);
    }

    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(ICollectionItemTry))]
    public class CCollectionItemTry : ICollectionItemTry
    {
        public bool SheetsItemTry(Sheets worksheetsCol, object vItem, out Worksheet result)
        {
            result = null;
            try
            {
                result = worksheetsCol.Item[vItem];
                return true;
            }
            catch (Exception)
            { }
            return false;
        }

        public bool WorkbooksItemTry(Workbooks workbooksCol, object vItem, out Workbook result)
        {
            result = null;
            try
            {
                result = workbooksCol.Item[vItem];
                return true;
            }
            catch (Exception)
            { }
            return false;
        }
    }
}

对于 Excel 客户端 VBA 代码,这里有一些源代码

Sub TestCCollectionItemTry()
    Dim o As BuryVBAErrorsCS.CCollectionItemTry
    Set o = New BuryVBAErrorsCS.CCollectionItemTry

    Dim ws As Excel.Worksheet
    Debug.Assert Not o.SheetsItemTry(ThisWorkbook.Sheets, "Sheet3366", ws)
    Debug.Assert ws Is Nothing

    '* sanity check
    Set ws = ThisWorkbook.Worksheets.Item("Sheet1")
    Debug.Assert Not ws Is Nothing

    '* assuming Sheet1 exists
    Set ws = Nothing
    Debug.Assert o.SheetsItemTry(ThisWorkbook.Sheets, "Sheet1", ws)
    Debug.Assert Not ws Is Nothing

    Set ws = Nothing
    Debug.Assert o.SheetsItemTry(ThisWorkbook.Sheets, 1, ws)
    Debug.Assert Not ws Is Nothing

    '* workbooks
    Dim wb As Excel.Workbook
    Debug.Assert o.WorkbooksItemTry(Application.Workbooks, 1, wb)
    Debug.Assert Not wb Is Nothing

    Set wb = Nothing
    Debug.Assert o.WorkbooksItemTry(Application.Workbooks, ThisWorkbook.Name, wb)
    Debug.Assert Not wb Is Nothing

    Set wb = Nothing
    Debug.Assert Not o.WorkbooksItemTry(Application.Workbooks, "BonzoDogDoodah.xls", wb)
    Debug.Assert wb Is Nothing


End Sub

注意 WELL 传入Sheets 集合而不是 Worksheets 集合。

于 2016-08-04T17:13:18.417 回答