Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.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
Vba 访问另一个打开的工作簿中的工作表时,下标超出范围_Vba_Excel - Fatal编程技术网

Vba 访问另一个打开的工作簿中的工作表时,下标超出范围

Vba 访问另一个打开的工作簿中的工作表时,下标超出范围,vba,excel,Vba,Excel,我想引用第一个打开的工作簿。打开了两个工作簿:一个是调用宏执行的工作簿,另一个是包含宏的工作簿。不知何故,代码通常运行平稳。但有时,在访问第一个打开的工作簿中的数据时会发生引用错误:下标超出范围 在这一行中,会出现以下错误: Set mastersheet = Workbooks(1).Sheets("Setting") 所以藏书中应该有两本工作手册。我在监督什么?请记住,第一个打开的工作簿没有固定名称,因此打开的工作簿的名称会更改。第二个工作簿(包含要执行的宏的工作簿)不会更改其名称 我建议

我想引用第一个打开的工作簿。打开了两个工作簿:一个是调用宏执行的工作簿,另一个是包含宏的工作簿。不知何故,代码通常运行平稳。但有时,在访问第一个打开的工作簿中的数据时会发生引用错误:下标超出范围

在这一行中,会出现以下错误:

Set mastersheet = Workbooks(1).Sheets("Setting")

所以藏书中应该有两本工作手册。我在监督什么?请记住,第一个打开的工作簿没有固定名称,因此打开的工作簿的名称会更改。第二个工作簿(包含要执行的宏的工作簿)不会更改其名称

我建议以下内容来查找
设置
工作表:

Option Explicit

Public Sub FindSettingWorksheet()
    Dim MasterSheet As Worksheet

    Dim wb As Workbook
    For Each wb In Workbooks 'loop through all open workbooks
        On Error Resume Next 'stop error reporting
        Set MasterSheet = wb.Worksheets("Setting") 'if this throws an error it's the wrong workbook
        On Error GoTo 0 're-enable error reporting
        If Not MasterSheet Is Nothing Then Exit For 'if we found the setting worksheet we can exit/stop
    Next wb


    If Not MasterSheet Is Nothing Then 'test if we found it
        Debug.Print MasterSheet.Name
    Else
        Debug.Print "Settings not found"
    End If
End Sub

不幸的是,您没有提供更多的代码,也没有提供有关宏所在的代码“容器”类型的任何信息。以下解决方案假定宏位于工作表或工作簿代码容器中(例如,VBA编辑器中的
Sheet1
ThisWorkbook

可以从代码容器中获取工作簿。如果代码位于工作表代码容器中,则使用
Me.Parent
。如果它在
本工作簿中
请使用
Me
。这些容器实际上是表示工作表/工作簿对象的类。所以
Me
指的是那个对象。工作表的父级是其工作簿

因此,将
工作簿
对象设置为其容器工作簿。然后将打开的工作簿循环成一个
For…Each
,并测试工作簿是否与代码容器工作簿相同,或者是否是另一个工作簿。如果是另一个,则退出循环
Debug.Print
显示结果(两个不同的名称),并演示如何继续使用单独的工作簿对象

Sub GetOtherWorkbook()
    Dim wbWithMacro As Workbook
    Dim wbOther As Workbook, wb As Workbook

    Set wbWithMacro = Me.Parent 'Assumes macro is in a "Sheet" code container
    'Set wbWithMacro = Me   'Assumes macro is in "ThisWorkbook" code container
    For Each wb In Workbooks
        If Not wb Is Me Then
            Set wbOther = wb
            Exit For
        End If
    Next
    Debug.Print wbWithMacro.Name, wbOther.Name
End Sub

我会将
Debug.print工作簿(1).Name
放在那一行之前,等待您重现错误,然后查看即时窗口显示的内容。还请记住,如果您有任何个人宏设置,
工作簿(1)
将始终是
personal.xlsb
,这将摆脱您的索引…可能更好的办法是按名称而不是按编号识别工作簿:
工作簿(“MyWorkbookName”).Sheets(“设置”)
@Pᴇʜ他说他的工作簿没有固定的名称,所以他不能使用那个解决方案(我想?)@d讽刺的是,但我认为依赖工作簿编号更糟糕。因此,他需要一个变通方法来正确识别他的工作簿,可以通过名称或引用,如
Set Wb=Workbooks.Open(filename)
@rwatermelon这些工作簿是如何打开的?通过VBA还是手动?CommonMacro驻留在一个模块中,称为Module1。我想我不能使用你提供的代码?因此,我需要使用ThisWorkbook或ActiveWorkbook在它们之间进行引用,但我希望避免使用这种方法。谢谢你的提示!!为什么不直接使用此工作簿?这总是指代码所在的工作簿(实际上我以前应该想到这一点)。你不需要ActiveWorkbook,因为它可以是任何东西。因为我认为这个工作簿引用的是错误的。此工作簿是执行代码的工作簿,但我想访问名为“设置”的工作表,因此我需要检查工作簿是否包含名为“设置”的工作表,以便正确引用。我还试图避免.Select和.Activate.CommonMacro驻留在模块1-Container@RWatermelon如您所说,如果只有两个工作簿处于打开状态,那么其中一个将成为代码容器,而另一个则不会。从您的问题描述中不清楚工作簿“设置”是哪一个,但它要么在
此工作簿中
中,要么在另一个工作簿中-这可以使用我答案中的逻辑(循环)确定。或者用佩赫的逻辑。但这两种方法都会奏效…看起来不错,我会试试看。我希望引用工作,然后它不会把我的下标超出范围了。我会通知你的。非常感谢。小细节:当找到正确的WB时,for循环在不重置错误处理程序的情况下退出。@chris neilsen:如果我分配一个包含正确工作簿的变量。Name而不是Exit for?@RWatermelon更好的方法是
对于工作簿集合母版纸中的每个wb=无错误恢复下一集合母版纸=wb.工作表(“设置”)在错误转到0时,如果不是母版纸,则退出下一个wb
您能告诉我如何为变量分配正确的文件名吗?当我赋值并用MessageBox抛出它时,我没有收到任何值。我还想从宏中的其他子程序和函数调用此文件名,以便正确地赋值