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.
答案 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)。