Excel代码中的应用程序定义或对象定义的错误

时间:2018-09-09 11:18:25

标签: excel vba excel-vba

我下面的代码用于打开订单报告文件和关键字列表文件,然后使用自动过滤功能过滤订单报告中的必需数据>通过关键字列表归档,然后复制到另一个工作表。

我的问题是,当此代码运行时:

OrderCount = wsOrder.Range("A2", wsOrder.Range("A" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible).Cells.Count

...发生错误应用程序定义或对象定义的错误,但仅在某些订单报告文件上。我有2个确切的布局,仅标准工作簿中的数据是不同的,但是一个文件可以运行,而另一个文件则不能。

它在一个工作簿(如下)上运行正常,但在另一个工作簿上却运行不正常。 img

img

Public Sub btn1_Click()
    Dim i As Double, N As Double, strKeyWord As String, myCount As Integer
    Dim OrderCount As Integer, SubTotal As Range, Country As Range
    Dim DisCount As Range, Quantity As Range, ItemName As Range
    Dim OrderName As Range, RequiredData As Range, wsOrder As Worksheet
    Dim wsResult As Worksheet, wsCondition As Worksheet, wbOrder As Workbook
    Dim wbCondition As Workbook, OrderFile As String, ConditionFile As String

    OrderFile = Application.GetOpenFilename() 'Open Order wb
    Set wbOrder = Workbooks.Open(OrderFile)
    Set wsOrder = wbOrder.Worksheets(1)
    ConditionFile = Application.GetOpenFilename() 'Open Condition wb
    Set wbCondition = Workbooks.Open(ConditionFile)
    Set wsResult = wbCondition.Worksheets(1)
    Set wsCondition = wbCondition.Worksheets(2)
    myCount = Application.CountA(wsCondition.Range("A:A")) 'use CountA (all non-blanks)
    For i = 2 To myCount Step 1
        strKeyWord = wsCondition.Range("A" & i)
        wsOrder.Range("R:R").AutoFilter Field:=1, Criteria1:="=*" & strKeyWord & "*"
        If wsOrder.Cells(Rows.Count, 1).End(xlUp).Row > 1 Then
            Set SubTotal = wsOrder.Range("I2", wsOrder.Range("I" & Rows.Count).End(xlUp))
            Set Country = wsOrder.Range("AG2", wsOrder.Range("AG" & Rows.Count).End(xlUp))
            Set DisCount = wsOrder.Range("N2", wsOrder.Range("N" & Rows.Count).End(xlUp))
            Set Quantity = wsOrder.Range("Q2", wsOrder.Range("Q" & Rows.Count).End(xlUp))
            Set OrderName = wsOrder.Range("A2", wsOrder.Range("A" & Rows.Count).End(xlUp))
            Set ItemName = wsOrder.Range("R2", wsOrder.Range("R" & Rows.Count).End(xlUp))
            Set RequiredData = Union(SubTotal, Country, _
                        DisCount, Quantity, OrderName, ItemName)
            RequiredData.SpecialCells(xlCellTypeVisible).Copy
            OrderCount = wsOrder.Range("A2", wsOrder.Range("A" & Rows.Count) _
                        .End(xlUp)).SpecialCells(xlCellTypeVisible).Cells.Count
            With wsResult
                If OrderCount >= 2 Then
                    For N = 1 To OrderCount Step 1
                        .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Value = strKeyWord
                        .Cells(.Rows.Count, "B").End(xlUp).Offset(1).Value = "Available"
                    Next N
                Else
                    .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Value = strKeyWord
                    .Cells(.Rows.Count, "B").End(xlUp).Offset(1).Value = "Available"
                End If
                .Cells(.Rows.Count, "C").End(xlUp).Offset(1).PasteSpecial
            End With
        Else
            With wsResult
                .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Value = strKeyWord
                .Cells(.Rows.Count, "B").End(xlUp).Offset(1).Value = "No Order"
                .Cells(.Rows.Count, "C").End(xlUp).Offset(1).Value = "N/A"
                .Cells(.Rows.Count, "D").End(xlUp).Offset(1).Value = "N/A"
                .Cells(.Rows.Count, "E").End(xlUp).Offset(1).Value = "N/A"
            End With
        End If
        OrderCount = 0
    Next i
    wbCondition.Sheets("Result").Activate
    wsOrder.AutoFilterMode = False
End Sub

1 个答案:

答案 0 :(得分:1)

必须 是因为您的“条件”文件是 post 2003 excel工作簿,而您的不起作用“订单”文件是< em>直到2003 excel工作簿。

因此,您的“条件”工作簿工作表每个都有大约一百万行,而您的“订单”工作簿工作表每个都有大约65k行

在:

OrderCount = wsOrder.Range("A2", wsOrder.Range("A" & Rows.Count) _
                    .End(xlUp)).SpecialCells(xlCellTypeVisible).Cells.Count

不合格的Rows.Count隐含地假设活动工作表是计算

行的工作表

最后打开的工作簿是“条件”工作簿,因此wsOrder.Range("A" & Rows.Count)试图访问第100万行的“订单”工作簿工作表,而该工作簿最多有65 k ...

一种解决方案是简单地交换工作簿的打开顺序:

ConditionFile = Application.GetOpenFilename() 'Open Condition wb first
Set wbCondition = Workbooks.Open(ConditionFile)
Set wsResult = wbCondition.Worksheets(1)
Set wsCondition = wbCondition.Worksheets(2)

OrderFile = Application.GetOpenFilename() 'Open Order wb as the last one
Set wbOrder = Workbooks.Open(OrderFile)
Set wsOrder = wbOrder.Worksheets(1)

因此将“订单”工作簿作为活动一个

但最佳做法是避免依赖Active / Selection编码模式,而改用完全限定范围的引用:

OrderCount = wsOrder.Range("A2", wsOrder.Range("A" & wsOrder.Rows.Count) _
                    .End(xlUp)).SpecialCells(xlCellTypeVisible).Cells.Count

所以我建议您后者修复