VBA - preventing Runtime Error 1004 - Method 'Union' error when using macro multiple times

时间:2015-07-28 16:02:58

标签: excel vba excel-vba

I have a large macro which is editing a number of excel spreadsheets in a folder. At one stage of the macro, I am deleting any unused rows on the spreadsheet, including those rows which have no content, but due to the formatting appear in

lastRow = ActiveSheet.UsedRange.Rows.Count

When I loop through the large macro for each spreadsheet, and reach the section of code, I encounter a Runtime Error 1004 - Method 'Union'. I have indicated the error below 'ISSUE HERE where I am having difficulties assigning an Excel.Range variable. It works the first time, but then crashes the second. I have tried initialising the variable as Null following the loop, but that doesn't work. I also considered the possibility of dynamically changing the name of the variable, but I'm not sure how to do that either.

Dim Tempwks As Excel.Worksheet
        Dim Temprng As Excel.Range
        Dim Temprow As Long
        Dim XlastRow As Long

    ''''''''''''''''

        Set Tempwks = Excel.ActiveSheet
        XlastRow = lastRow

        With Tempwks

            For Temprow = 1 To XlastRow
                If Application.WorksheetFunction.CountA(.Rows(Temprow)) = 0 Then

                    If Temprng Is Nothing Then
                        Set Temprng = .Rows(Temprow)
                    Else

                    ' ISSUE HERE
                        Set Temprng = Excel.Union(Temprng, .Rows(Temprow))

                    End If

                End If
            Next Temprow

        End With

        If Not Temprng Is Nothing Then
            Call Temprng.EntireRow.Delete
        End If

EDIT -- Just to confirm, there is nothing wrong with the functionality of this code, it does what is required, it's just that when I run it multiple times, it comes up with the Runtime Error 1004 on the following specific line.

   Set Temprng = Excel.Union(Temprng, .Rows(Temprow))

If this macro ran again and the variable name changed from Temprng to Temprng2, it would work. The issue seems to be that once the variable has been Set once, it cannot be overwritten.

2 个答案:

答案 0 :(得分:2)

I don't see it right off the bat, so this doesn't directly solve your problem, but you can try this instead:

For Temprow = XlastRow To 1 Step -1
    If Application.WorksheetFunction.CountA(.Rows(Temprow)) = 0 Then
        .Rows(TempRow).Delete
    End If
Next TempRow

By going backwards through the rows, you don't have to worry about getting your counter messed up as the rows change numbers. And since you don't have to worry about that, you don't have to use Union.

EDIT: If you're just trying to get the TRUE last row, you can avoid all of this by using Find, i.e.

lngLastRow = sht.Cells.Find(What:="*", After:=Cells(1, 1), LookIn:=xlFormulas, Lookat:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False).Row 

I prefer this method over any other, but you can find more here. The find method is the last one on that page. You can also mess with the LookIn argument and change that to xlValues if that suits your needs better.

答案 1 :(得分:0)

我不确定这是否是您的问题,但我遇到了与Union操作类似的问题并发现了答案here。我的问题是使用Union调用的正确上下文,即工作表中的范围所在的应用程序。所以在你的情况下:

Set Temprng = Tempwks.Parent.Application.Union(Temprng, .Rows(Temprow))

而不是:

Set Temprng = Excel.Union(Temprng, .Rows(Temprow))

从工作表中获取工作簿(Tempwks.Parent)和该工作簿中的应用程序(Tempwks.Parent.Application)。