打开工作簿时,宏引用了不正确的工作簿

时间:2018-07-26 21:14:32

标签: excel vba excel-vba

Sub ShipReportPopulate(TicketDataCollection, TicketArray)

Dim Shipwb As Workbook
Dim ShipWS As Worksheet
Dim NamedRng As String
Dim FN As String
FN = ThisWorkbook.Path & "\Shipping Report.xlsx"

Set Shipwb = Workbooks.Open(FileName:=FN)
Set ShipWS = Shipwb.Sheets("Sheet1")

PopRow = ShipWS.UsedRange.Rows.Count + 1


For i = 1 To UBound(TicketDataCollection)
    NamedRng = TicketDataCollection(i, 6)
    With ShipWS
        .Cells(PopRow, ShipWS.Range("Date").Column) = TicketArray(1)
        'Application.Goto ShipWS.Range("Customer")
        .Cells(PopRow, ShipWS.Range("Customer").Column) = TicketArray(2)
        .Cells(PopRow, ShipWS.Range("TicketNum").Column) = TicketArray(3)
        .Cells(PopRow, ShipWS.Range("Key").Column) = TicketDataCollection(i, 1)
        .Cells(PopRow, ShipWS.Range("Product").Column) = TicketDataCollection(i, 4)
        .Cells(PopRow, ShipWS.Range("Weight").Column) = TicketDataCollection(i, 8)
        .Cells(PopRow, ShipWS.Range("Footage").Column) = TicketDataCollection(i, 7)
        .Cells(PopRow, ShipWS.Range("Type").Column) = TicketDataCollection(i, 9)
        'If primary category is footage then populate footage, else weight
        If TicketDataCollection(i, 5) = "F" Then
            .Cells(PopRow, ShipWS.Range(NamedRng).Column) = TicketDataCollection(i, 7)
        Else
            .Cells(PopRow, ShipWS.Range(NamedRng).Column) = TicketDataCollection(i, 8)
        End If
    End With
    PopRow = PopRow + 1
Next i

'Shipwb.Close

End Sub

此行出现错误

Set ShipWS = Shipwb.Sheets("Sheet1")

仅当'Shipwb'工作簿已打开时出现错误,并且当我取消注释'Shipwb.Close'函数时,一切正常-但我希望保持工作簿为打开状态并能够多次运行此功能。我尝试删除并重命名命名范围,但没有成功。

我没有主意,可能是什么原因导致此问题?预先感谢您的帮助。

更新:

我认为真正的问题是,当打开工作簿并再次运行代码时,宏将引用“ RoyalWS”而不是“ ShipWS”。我的潜艇如下:

Sub Main()
'Some stuff here
Call ShipReportPopulate(TicketDataCollection, TicketArray)
Call RoyaltyReportPopulate(TicketDataCollection, TicketArray)
End Sub

哪里

Sub RoyaltyReportPopulate(TicketDataCollection As Variant, TicketArray As Variant)

Dim Royalwb As Workbook
Dim RoyalWS As Worksheet
Dim NamedRng As String
Dim FN2 As String
FN2 = ThisWorkbook.Path & "\Royalty Report.xlsx"

Set Royalwb = Workbooks.Open(FileName:=FN2)
Set RoyalWS = Royalwb.Sheets("Sheet2")

PopRow = RoyalWS.UsedRange.Rows.Count + 2

For i = 1 To UBound(TicketDataCollection)
    NamedRng = TicketDataCollection(i, 3)
    Sum = 0
    For j = 1 To UBound(TicketDataCollection)
        If TicketDataCollection(i, 3) = TicketDataCollection(j, 3) Then
            Sum = Sum + TicketDataCollection(j, 8)
        End If
    Next j
    RoyalWS.Cells(PopRow, RoyalWS.Range(NamedRng).Column).Value = Sum
Next i

With RoyalWS
    .Cells(PopRow, RoyalWS.Range("Date").Column).Value = TicketArray(1)
    .Cells(PopRow, RoyalWS.Range("TicketNum").Column).Value = TicketArray(3)
End With

'Royalwb.Close

End Sub

如何确保宏引用正确的工作簿?

更新2:

好的,所以最初我在各自的工作簿上都使用了“ ShipWS”和“ RoyalWS”来引用“ Sheet1”。我已经按照上面的代码对其进行了修改,现在在这里出现“运行时错误9:下标超出范围”

Set ShipWS = Shipwb.Sheets("Sheet1")

说“ ShipWS”一无所获

2 个答案:

答案 0 :(得分:0)

尝试一下:

Set Shipwb = Excel.Application.ThisWorkbook

这只会存储对您工作簿的引用,而不是打开它,因此您不需要

Shipwb.Close

更新:

尝试检测工作簿是否打开。我从this线程的可接受答案中窃取了一些代码。

Function IsOpen(strWkbNm As String) As Boolean
    Dim wb As Workbook
    On Error Resume Next
    Set wb = Workbooks(strWkbNm)
    IsOpen = Err.Number = 0
    On Error GoTo 0
End Function

这是我将其实现到您的函数中的方法:

Function ShipReportPopulate(TicketDataCollection, TicketArray)
    Dim open As Boolean
    Dim Shipwb As Workbook
    Dim ShipWS As Worksheet
    Dim NamedRng As String
    Dim FN As String
    FN = ThisWorkbook.Path & "\Shipping Report.xlsx"

    open = IsOpen(FN)
    If open Then
        'closes the workbook
        Excel.Application.Workbooks(FN).Close (SaveChanges:=True)
        Set Shipwb = Workbooks.Open(FileName:=FN)
        Set ShipWS = Shipwb.Sheets("Sheet1")

        'do the thing here
    ElseIf Not open Then
        Set Shipwb = Workbooks.Open(FileName:=FN)
        Set ShipWS = Shipwb.Sheets("Sheet1")

        'do the thing here
    End If
End Function

因为这会检测到您要打开的工作簿是否已打开,所以您可以将Shipwb.Close放在最后。你的电话。

答案 1 :(得分:0)

我不喜欢这种调用命名范围的方法。您可以采用更直接的方式处理对象,如下所示:

var user = context.Users.Create();
var test = context.Tests.Create();
var fudge = context.Fudges.Create();

先获取范围,然后

wb.names("NameHere").RefersToRange

获取值

无需处理(可能会更改)工作表名称