Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 跳过错误';变量未定义';在未设置带有显式选项的对象上_Excel_Vba - Fatal编程技术网

Excel 跳过错误';变量未定义';在未设置带有显式选项的对象上

Excel 跳过错误';变量未定义';在未设置带有显式选项的对象上,excel,vba,Excel,Vba,我编写了一个Excel应用程序,我们称之为MasterWb,其中包含一些表单,例如(代码名):wsFirst、wsSecond、wsThird 1。我想要实现的目标 我想要第二份工作簿——MasterWb的副本,但没有第三张工作表。我们称之为ClientWb 2。我现在如何实现我的目标 只是我的应用程序有一个宏prepareClientsWb,它: -使用SaveCopyAs方法创建MasterWb的副本(ClientWb) -打开ClientWb并删除第三张工作表,然后使用“保存”将其关闭 3


我编写了一个Excel应用程序,我们称之为MasterWb,其中包含一些表单,例如(代码名):wsFirst、wsSecond、wsThird

1。我想要实现的目标

我想要第二份工作簿——MasterWb的副本,但没有第三张工作表。我们称之为ClientWb

2。我现在如何实现我的目标

只是我的应用程序有一个宏prepareClientsWb,它:
-使用SaveCopyAs方法创建MasterWb的副本(ClientWb)
-打开ClientWb并删除第三张工作表,然后使用“保存”将其关闭

3。问题是什么

我在我的应用程序中使用工作簿_Open事件来准备打开时工作表的可见性

 Private Sub Workbook_Open()

     ' xlSheetVisible
        wsFirst.Visible = xlSheetVisible

     ' xlSheetHidden
        wsSecond.Visible = xlSheetHidden

     ' xlSheetVeryHidden
        wsThird.Visible = xlSheetVeryHidden

 End Sub
问题是我不能同时使用Option Explicit和工作表代码名:当然,运行生成的clientWb时未定义错误发生变量(“wsThird”无法识别)。目前我不使用OptionExplicit,而是使用On ErrorResume Next语句。有什么更优雅的解决方案来处理我的问题?我想这可能真的很容易,但我不知道这方面的最佳做法是什么

我不能使用名称或索引来代替代码名,因为它可能会发生很多变化。 我不会使用模板,因为该应用程序仍在开发中,在两个工作簿中进行更改对我来说是一个很大的问题。 我不会将部分代码存储在另一个模块中,并在创建clientWb时删除此模块-这对我来说似乎非常困难,可能需要对VBA项目对象模型的信任访问,如果可能的话,我会避免这种访问。或者

4。可能使用条件编译?

…但它不是用大锤敲开坚果吗:-)

例如,使用A1范围内的布尔值(0 masterWb,1 clientWb)创建额外的工作表wsConditionalConst,或者检查wsThird是否存在,或者用另一种方法确定我们是否在masterWb或clientWb中,并将此信息存储在ISMASTER布尔变量中。我不知道我们是否可以用条件变量代替常量——这只是一个想法

 Private Sub Workbook_Open()

     ' xlSheetVisible
        wsFirst.Visible = xlSheetVisible

     ' xlSheetHidden
        wsSecond.Visible = xlSheetHidden

     ' xlSheetVeryHidden
      #If isMasterWorkbook = True Then
            wsThird.Visible = xlSheetVeryHidden
      #End If

 End Sub
也许有一种简单的方法可以通过VBA代码更改/添加条件编译参数,而不是在项目属性中手动更改它?我不知道这是否可能,我从未尝试过

在我的实际情况中,我的应用程序相当复杂(登录时有大约2k行代码,大量的工作表准备工作,如关闭网格线、标题等。为了确保应用程序尽可能可读),MasterWb中的工作表比上述示例中的工作表多得多(大约15张),我在创建ClientWb时删除了一些工作表


我为标题感到抱歉-我不知道如何用英语简单明了地解释它。

你可以这样做。使用函数使用工作表的代码名查找工作表,如果未找到,则返回
Nothing
。然后使用该功能获取工作表(如果存在)并设置其可见性

Public Function GetWorksheet(codeName As String) As Worksheet
    Dim ws As Worksheet

    For Each ws In ThisWorkbook
        If ws.codeName = codeName Then
            Set GetWorksheet = ws
            Exit Function
        End If

        '//If you get here, we didn't find it
        Set GetWorksheet = Nothing
    Next
End Function 
现在您的工作簿\u打开事件如下所示:

Private Sub Workbook_Open()
    Dim ws As Worksheet
     ' xlSheetVisible
    Set ws = GetWorksheet("wsFirst")
    If Not ws Is Nothing Then ws.Visible = xlSheetVisible

     ' xlSheetHidden
    Set ws = GetWorksheet("wsSecond")
    If Not ws Is Nothing Then ws.Visible = xlSheetHidden

     ' xlSheetVeryHidden
    Set ws = GetWorksheet("wsThird")
    If Not ws Is Nothing Then ws.Visible = xlSheetVeryHidden

 End Sub

你可以这样做。使用函数使用工作表的代码名查找工作表,如果未找到,则返回
Nothing
。然后使用该功能获取工作表(如果存在)并设置其可见性

Public Function GetWorksheet(codeName As String) As Worksheet
    Dim ws As Worksheet

    For Each ws In ThisWorkbook
        If ws.codeName = codeName Then
            Set GetWorksheet = ws
            Exit Function
        End If

        '//If you get here, we didn't find it
        Set GetWorksheet = Nothing
    Next
End Function 
现在您的工作簿\u打开事件如下所示:

Private Sub Workbook_Open()
    Dim ws As Worksheet
     ' xlSheetVisible
    Set ws = GetWorksheet("wsFirst")
    If Not ws Is Nothing Then ws.Visible = xlSheetVisible

     ' xlSheetHidden
    Set ws = GetWorksheet("wsSecond")
    If Not ws Is Nothing Then ws.Visible = xlSheetHidden

     ' xlSheetVeryHidden
    Set ws = GetWorksheet("wsThird")
    If Not ws Is Nothing Then ws.Visible = xlSheetVeryHidden

 End Sub

我将更改工作簿的打开代码:

Option Explicit
Private Sub Workbook_Open()
    Dim ws As Worksheet

For Each ws In Worksheets
    Select Case ws.CodeName
        Case "wsFirst"
            ws.Visible = xlSheetVisible
        Case "wsSecond"
            ws.Visible = xlSheetHidden
        Case "wsThird"
            ws.Visible = xlSheetVeryHidden
    End Select
Next ws

End Sub



我将更改工作簿的打开代码:

Option Explicit
Private Sub Workbook_Open()
    Dim ws As Worksheet

For Each ws In Worksheets
    Select Case ws.CodeName
        Case "wsFirst"
            ws.Visible = xlSheetVisible
        Case "wsSecond"
            ws.Visible = xlSheetHidden
        Case "wsThird"
            ws.Visible = xlSheetVeryHidden
    End Select
Next ws

End Sub



wsFirst
不是代码名。如果你想让它代表一个代码名,你需要声明它,然后设置它。@RonRosenfeld-我知道它是一个代码名,但问题发生在主工作簿副本中删除该工作表之后。@RonRosenfeld-我猜就这个问题而言,OP simplified,但听起来好像主工作簿中的代码名已更改为
wsFirst
wsSecond
wsThird
等等。。。但这些似乎只是示例名称。我在属性窗口中设置了代码名,因此,例如Debug.Print wsFirst.CodeName返回wsFirst:)如果使用
选项Explicit
wsFirst
不是代码名,所有这些仍然会导致编译器错误。如果你想让它代表一个代码名,你需要声明它,然后设置它。@RonRosenfeld-我知道它是一个代码名,但问题发生在主工作簿副本中删除该工作表之后。@RonRosenfeld-我猜就这个问题而言,OP simplified,但听起来好像主工作簿中的代码名已更改为
wsFirst
wsSecond
wsThird
等等。。。但这些似乎只是示例名称。我在“属性”窗口中设置了代码名,因此,例如Debug.Print wsFirst.CodeName返回wsFirst:)使用
选项Explicit