I'm trying to write a formula which does the following:
sum all rows above this one until row 3. (Row 1 and 2 are headers). This code has to go from columns E:AQ, What gets tricky for me is that the row with the last line varies monthly. This month it is row 133, next month it could be 145. Here is my code so far:
Sub Fsum()
Dim Rng1 As Range
Set ws1 = Worksheets("Actuals")
Set Rng1 = ws1.Range("A" & ws1.Rows.Count).End(x1Up)
.Range("Rng1:AQ").Formula = "=sum(???lines above???)"
End Sub
You can see where I get confused. Can someone help?
Here is one way to go about it:
Sub test()
Dim lr As Long
Dim ws As Worksheet
Set ws = Worksheets("Actuals")
With ws
lr = .Cells(1, 5).EntireColumn.Find(what:="*", _
After:=.Cells(1, 5).EntireColumn.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Range(.Cells(lr + 1, 5), .Cells(lr + 1, 43)).Formula = "=Sum(E3:E" & lr & ")"
End With
End Sub
This will find the last used cell in Column E (5 in the code) and set that as the overall last row. Then it will build a sum formula across to column AQ (43 in the code).
Each time you run the code, it will find the last row. So it should be fairly dymanic. If each column has a different last row, that can be done as well, just need to use a loop, but I got the impression that your last row will be different from report to report, not column to column.
Hope this helps!
EDIT*
Here is an alternate way of finding the last row in case the one above gives you problems:
Sub test()
Dim lr As Long
Dim ws As Worksheet
Set ws = Worksheets("Actuals")
With ws
lr = ws.Range("E" & .Rows.Count).End(xlUp).Row
Range(.Cells(lr + 1, 5), .Cells(lr + 1, 43)).Formula = "=Sum(E3:E" & lr & ")"
End With
End Sub
You will need to find the #REF! first and here is something for your reference to find the cell.
Option Explicit
Sub FindRef()
Dim Rng As Range
Dim RefRng As Range
Set Rng = Range("A1:F100") ' Use your own range
Set RefRng = Rng.Find(what:="#REF!", LookIn:=xlValues)
MsgBox "Found the #REF! " & RefRng.Column & RefRng.Row
End Sub
Related
I'm very new to VBA and there are so many ways to reference a cell and I'm kind of lost here.
My excel sheet comes with the columns swapped around and there is no guarantee that a column will be in the position it was last time but I do know that total number of columns and the column header names are consistent.
So I find my column number using this:
Dim target As Range
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
With ws
Set target = .Range("A1:M1").Find(What:="Target_Column", LookIn:= xlValues, LookAt: = xlWhole, _
MatchCase:=False, SeaarchFormat:=False)
targetCol = target.Column
This gives me the index number of my target column.
Now I want to apply the following function to column "N" in my worksheet (the below formula assumes target column is column "G":
"=RIGHT(G1,LEN(G1)-10)"
I want to use something similar (or easier) than the script below but don't know how to achieve this:
FinalRow = .Cells(.Rows.Count,1).End(xlUp).Row
.Range(.Cells(2,14), .Cells(FinalRow, 14)).FormulaR1C1 =
"=RIGHT(" & targetCol & "1, LEN(" & targetCol & "1)-10)"
I hope the question is clear enough and someone can point me in the right direction.
Thanks.
Based on your description, you may try something like this...
Remember that as per your description, the first formula will be in N2 and will be referencing G1, N2 will be referencing G2 and so on. Make sure that the formula is correct.
Range("N2:N" & FinalRow).Formula = "=RIGHT(" & Cells(1, TargetCol).Address(0, 0) & ",LEN(" & Cells(1, TargetCol).Address(0, 0) & ")-10)"
You may use
.Range(.Cells(2,14), .Cells(FinalRow, 14)).FormulaR1C1 ="=RIGHT(RC" & targetCol & ", LEN(RC" & targetCol & ")-10)"
Maybe something slightly more flexible like:
Option Explicit
Public Sub testing()
Dim wb As Workbook, ws As Worksheet, searchRange As Range, targetColumn As Long, lastRow As Long
Set wb = ThisWorkbook
Set ws = wb.ActiveSheet 'change as appropriate
Const header As String = "MyHeader" '<====Change to header name trying to find
Const startFormulaRow As Long = 2 '<=== change for column to start applying formula at. Assume not 1 as contains header
Const formulaColumn As Long = 14 '<==== change for column you want to apply formula in
Const charsToRemove As Long = 10 '<=== change to different number of characters to remove from len
With ws
Set searchRange = .Range("A1:M1") '<===Change to alternative search range
targetColumn = FindTargetColumn(header, searchRange)
If targetColumn > 0 Then
lastRow = GetLastRow(ws, targetColumn, startFormulaRow)
.Range(.Cells(startFormulaRow, formulaColumn), .Cells(lastRow, formulaColumn)).FormulaR1C1 = "=IFERROR(RIGHT(RC" & targetColumn & ",LEN(RC" & targetColumn & ")-" & charsToRemove & "),"""")"
End If
End With
End Sub
Public Function FindTargetColumn(ByVal header As String, ByVal searchRange As Range) As Long
Dim target As Range
Set target = searchRange.Find(What:=header, LookIn:=xlValues, LookAt:=xlWhole, _
MatchCase:=False, SearchOrder:=xlRows, SearchFormat:=False)
If Not target Is Nothing Then
FindTargetColumn = target.Column
Else
FindTargetColumn = -1
End If
End Function
Public Function GetLastRow(ByVal ws As Worksheet, ByVal targetColumn, ByVal startFormulaRow As Long) As Long
If Not Application.WorksheetFunction.Subtotal(103, ws.UsedRange) = 0 Then
GetLastRow = ws.Columns(targetColumn).SpecialCells(xlCellTypeLastCell).Row
Else
MsgBox "No data in " & ws.Name & " or last row is < than required formula start row of " & startFormulaRow
End
End If
End Function
I am having difficulty creating a macro that will copy a row of data from one worksheet to another, then instantly delete the copied data source and move up the rows underneath to clear the leftover blank/empty row. The context of this workbook is a request tracker, once a request has a completion date, after a certain period of time (30 days), the request will be copied over to a "historical requests" sheet. Then immediately after, the originally copied data on the active page will be deleted and everything else "moved up" to clear out the gap left behind. Here is what I have already developed, with some help of course... If someone could help, it would be greatly appreciated.
Public Sub DataBackup()
Dim RowDate
Dim CurrentDate
Dim Interval
Dim CurrentAddress
Dim ValueCellRange As Range
Dim ValueCell As Range
Dim ws As Worksheet
'Interval set to an appropriate number of days
Interval = 30
CurrentDate = Now()
For Each ws In Worksheets
Set ValueCellRange = ws.Range("U3:U130")
For Each ValueCell In ValueCellRange
If ValueCell.Value <> "" Then
If CurrentDate - ValueCell.Value >= Interval Then
Rows(ActiveCell.Row).Select
Sheets("Historical Requests").Select
ActiveSheet.Paste
ValueCell.EntireRow.ClearContents
End If
End If
Next ValueCell
Next ws
'Clear variable value for next initialization
Set ValueCell = Nothing
End Sub
You did put the work into it. As BruceWayne suggested your code is not bad but could use less selecting and less activating. You don't need to select or activate a worksheet or range to work with it. Here is code that is a little more efficient, and I think many others could make it even more efficient.
BTW, when deleting rows try to always work from the bottom-up. And make sure that column "H" is formatted as dates, or this my not work.
Sub copyCut()
Dim ws_DATA As Worksheet, ws_HISTORY As Worksheet
Dim lastRowHISTORY As Long
Set ws_DATA = Sheet3' Change this sheet to match your correct one
Set ws_HISTORY = Worksheets(4)' Change this sheet to match your correct one
For i = 130 To 3 Step -1
On Error Resume Next
lastRowHISTORY = ws_HISTORY.Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
If Err.Number = 91 Then lastRowHISTORY = 1
On Error GoTo 0
If Now - DateValue(ws_DATA.Range("U" & i).Value) > 29 Then
ws_DATA.Range("U" & i).EntireRow.Copy Destination:=ws_HISTORY.Range("A" & lastRowHISTORY)
ws_DATA.Range("U" & i).EntireRow.Delete
End If
Next i
Set ws_DATA = Nothing
Set ws_HISTORY = Nothing
End Sub
To loop through all four sheets just put a "for 1 = n to 4" loop in the script. The only problem I can foresee is if all four pages have different row counts. Easy fix if they are not all 130. Just let me know. It only takes code to find the last used row on each sheet.
Sub copyCut()
Dim ws_DATA As Worksheet, ws_HISTORY As Worksheet
Dim lastRowHISTORY As Long
Set ws_DATA = Sheet3' Change this sheet to match your correct one
Set ws_HISTORY = Worksheets(4)' Change this sheet to match your correct one
For n = 1 to 4
Select Case n
Case 1
Set ws_DATA = Worksheets("Sheet1")' change these to your sheet names
Case 2
Set ws_DATA = Worksheets("Sheet2")
Case 3
Set ws_DATA = Worksheets("Sheet3")
Case 4
Set ws_DATA = Worksheets("Sheet4")
End Select
For i = 130 To 3 Step -1
On Error Resume Next
lastRowHISTORY = ws_HISTORY.Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
If Err.Number = 91 Then lastRowHISTORY = 1
On Error GoTo 0
If Now - DateValue(ws_DATA.Range("U" & i).Value) > 29 Then
ws_DATA.Range("U" & i).EntireRow.Copy Destination:=ws_HISTORY.Range("A" & lastRowHISTORY)
ws_DATA.Range("U" & i).EntireRow.Delete
End If
Next i
Next n
Set ws_DATA = Nothing
Set ws_HISTORY = Nothing
End Sub
Excel VBA - Select a range using variables & COUNTA
Hi Staked VBA Kings & Queens, I'm trying to learn Excel VBA. A simple task I would like to do is select all the contagious cells in a report dump I get from sales. Simple i'm sure, but I am a total beginner at VBA.
Ok Report Info:
The report is a set number of columns (31). Although I would like to build a bit of variability into my code to accommodate a change in column numbers.
The report grows by number of rows each week, some times less, sometimes more. But Always starts at cell [A4].
I though of using COUNTA function to count used number of rows, then set that as a variable. Similar with rows.
This is what I came up with, although I get a "Run-time Error '1004': Method 'Range' of object'_Global failed... can anyone help me out".
For me the key is to learn VBA using task I need getting done. I understand the logic behind my code, but not exactly the write way to write it. If some proposes a totally different code I might get lost.
But I am open minded.
Sub ReportArea()
Dim numofrows As Integer
Dim numofcols As Integer
Dim mylastcell As String
Dim myrange As Range
Worksheets("Sheet1").Select
numofrows = WorksheetFunction.CountA(Range("AE:AE"))
numofcols = WorksheetFunction.CountA(Range("4:4"))
Set myrange = Range(Cells(4, 1), Cells(numofrows, numofcols))
Range(myrange).Select
End Sub
P.S I did try read slimier trends but only got confused as the solution where very involved.
Find last row and last column
Sub Sht1Rng()
Dim ws As Worksheet
Dim numofrows As Long
Dim numofcols As Long
Dim myrange As Range
Set ws = Sheets("Sheet1")
With ws
numofrows = .Cells(.Rows.Count, "AE").End(xlUp).Row
numofcols = .Cells(4, .Columns.Count).End(xlToLeft).Column
Set myrange = .Range(.Cells(4, 1), .Cells(numofrows, numofcols))
End With
MsgBox myrange.Address
End Sub
You can also use this code.
Sub SelectLastCellInInSheet()
Dim Rws As Long, Col As Integer, r As Range, fRng As Range
Set r = Range("A1")
Rws = Cells.Find(what:="*", after:=r, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Col = Cells.Find(what:="*", after:=r, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
Set fRng = Range(Cells(2, 1), Cells(Rws, Col)) ' range A2 to last cell on sheet
fRng.Select 'or whatever you want to do with the range
End Sub
Further to my above comment, is this what you are trying?
Sub ReportArea()
Dim ws As Worksheet
Dim Lrow As Long
Dim myrange As Range
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find Last row of COl AE. Change it to the relevant column
Lrow = .Range("AE" & .Rows.Count).End(xlUp).Row
Set myrange = .Range("A4:AE" & Lrow)
With myrange
'
'~~> Do whatever you want to do with the range
'
End With
End With
End Sub
Note: Also you don't need to select a range/worksheet. Work with objects. Interesting Read
alternative solutions to already posted:
1:
Dim LRow&, LColumn&
Lrow = Sheets("SheetName").Cells.SpecialCells(xlCellTypeLastCell).Row
LColumn = Sheets("SheetName").Cells.SpecialCells(xlCellTypeLastCell).Column
MsgBox "Last Row is: " & Lrow & ", Last Column is: " & LColumn
2:
Dim x As Range
Set x = Range(Split(Sheets("SheetName").UsedRange.Address(0, 0), ":")(1))
MsgBox "Last Row is: " & x.Row & ", Last Column is: " & x.Column
output result
I would appreciate any help on this matter. I am trying to create an Excel 2010 macro in VBA that will read strings in one spreadsheet row by row, and then search another spreadsheet to see if the value exists in a column of strings.
If/When it finds a matching string in column A, I would like to compare the string in column C of the original spreadsheet with the string in Column C of the spreadsheet being searched. If both strings are the same, I would like to move on back to the column A search and continue.
If the strings are different I would like to overwrite the string in Column C of the spreadsheet being searched. I would also like to highlight this change on the searched spreadsheet.
If no matching string is found in column A of the search spreadsheet, then I want to copy the row of the original spreadsheet into the searched spreadsheet and highlight it.
Here's what I have so far, but I can't seem to get it to work properly:
Sub SearchRows()
Dim bottomA1 As Integer
bottomA1 = Sheets("Original Spreadsheet").Range("A" & Rows.Count).End(xlUp).Row
Dim bottomA2 As Integer
bottomA2 = Sheets("Searched Spreadsheet").Range("A" & Rows.Count).End(xlUp).Row
Dim rng1 As Range
Dim rng2 As Range
Dim x As Long
Dim y As Long
Dim foundColumnA As Range
Dim foundColumnC As Range
For Each rng1 In Sheets("Original Spreadsheet").Range("A2:A" & bottomA1)
With Sheets("Searched Spreadsheet").Range("A2:A" & bottomA2)
Set foundColumnA = .Find(what:=rng1, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
For Each rng2 In Sheets("Original Spreadsheet").Range("E2:E" & bottomA1)
With Sheets("Searched Spreadsheet").Range("E2:E" & bottomA2)
Set foundSize = .Find(what:=rng2, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=True)
If foundColumnC Is Nothing Then
bottomE2 = Sheets("Column C Changes").Range("E" & Rows.Count).End(xlUp).Row
y = bottomA2 + 1
rng2.EntireRow.Copy Sheets("Column C Changes").Cells(y, "A")
Sheets("Column C Changes").Cells (y, "A").EntireRow.Interior.ColorIndex = 4
End If
End With
Next rng2
If foundTag Is Nothing Then
bottomA2 = Sheets("Column A Changes").Range("A" & Rows.Count).End(xlUp).Row
x = bottomA2 + 1
rng1.EntireRow.Copy Sheets("Column A Changes").Cells(x, "A")
Sheets("Column A Changes").Cells(x, "A").EntireRow.Interior.ColorIndex = 3
End If
End With
Next rng1
End Sub
You actually have too much code, but they're not set up cleanly. Qualify a lot of things as much as possible so it's cleaner, and try to be consistent with your style. This way you can identify the error as much as possible.
Anyway, on to the code. The basic logic you want is as follows, based on the details above:
Check if a string in Sheet1!A is in Sheet2!A.
If found, compare Column C values.
If Column C values are different, set value of Sheet2 to that in Sheet1 and highlight.
Else, exit.
If not found, copy whole row to Sheet2 and highlight.
Now that we have that written down, it's simpler! :)
Please check my screenshots for my set-up:
SCREENSHOTS:
Sheet1:
Sheet2:
Note that for Sheet2, I don't have BK207 onwards. ;) Now, onto the code.
CODE:
Sub LoopMatchReplace()
Dim ShSrc As Worksheet, ShTar As Worksheet
Dim SrcLRow As Long, TarLRow As Long, NextEmptyRow As Long
Dim RefList As Range, TarList As Range, RefCell As Range, RefColC
Dim TarCell As Range, TarColC As Range
Dim IsFound As Boolean
Dim ToFind As String
With ThisWorkbook
Set ShSrc = .Sheets("Sheet1")
Set ShTar = .Sheets("Sheet2")
End With
'Get the last rows for each sheet.
SrcLRow = ShSrc.Range("A" & Rows.Count).End(xlUp).Row
TarLRow = ShTar.Range("A" & Rows.Count).End(xlUp).Row
'Set the lists to compare.
Set RefList = ShSrc.Range("A2:A" & SrcLRow)
Set TarList = ShTar.Range("A2:A" & TarLRow)
'Initialize boolean, just for kicks.
IsFound = False
'Speed up the process.
Application.ScreenUpdating = False
'Create the loop.
For Each RefCell In RefList
ToFind = RefCell.Value
'Look for the value in our target column.
On Error Resume Next
Set TarCell = TarList.Find(ToFind)
If Not TarCell Is Nothing Then IsFound = True
On Error GoTo 0
'If value exists in target column...
If IsFound Then
'Compare the Column C of both sheets.
Set TarColC = TarCell.Offset(0, 2)
Set RefColC = RefCell.Offset(0, 2)
'If they are different, set the value to match and highlight.
If TarColC.Value <> RefColC.Value Then
TarColC.Value = RefColC.Value
TarColC.Interior.ColorIndex = 4
End If
Else 'If value does not exist...
'Get next empty row, copy the whole row from source sheet, and highlight.
NextEmptyRow = ShTar.Range("A" & Rows.Count).End(xlUp).Row + 1
RefCell.EntireRow.Copy ShTar.Rows(NextEmptyRow)
ShTar.Rows(NextEmptyRow).SpecialCells(xlCellTypeConstants).Interior.ColorIndex = 3
End If
'Set boolean check to False.
IsFound = False
Next RefCell
Application.ScreenUpdating = True
End Sub
Kindly read the comments for the codeblocks so you get an understanding of what I'm doing. Also, note the way that I have qualified everything and properly set them up in a very clean way. Clean code is 50% good code.
Check the following screenshot to see the results after running the code.
END RESULT:
Note the added rows at the end and the changed values in Column C. I did not have the whole row highlighted as I believe that's bad practice and messy, but it's up to you to change the respective lines and values to suit your taste for the end result.
Let us know if this helps.
I think you can use this code.
Values not found will be added to the end of destination sheet.
Differences are signed with a blue(change if you want) background color.
Sub copy_d()
Dim r1 As Long, rfound, vfound
Dim w1, w2, v, lastR As Long, lastC As Long
Set w1 = Sheets("sheet1") ' change the origin sheet at will
Set w2 = Sheets("sheet2") ' change the destination sheet at will
r1 = 1 ' assuming data start in row 1, change it if not
Do While Not IsEmpty(w1.Cells(r1, 1))
v = w1.Cells(r1, 1)
rfound = Application.Match(v, w2.Columns(1), 0) ' look for value
If Not IsError(rfound) Then ' found it?
vfound = w2.Cells(rfound, 3)
If w1.Cells(r1, 3) <> vfound Then ' value in column C is different?
w2.Cells(rfound, 3) = w1.Cells(r1, 3) ' update based on origin sheet
lastC = w2.Cells(rfound, 1).End(xlToRight).Column
w2.Range(w2.Cells(rfound, 1), w2.Cells(rfound, lastC)).Interior.ColorIndex = 5
End If
Else
lastR = w2.Cells(1, 1).End(xlDown).Row + 1
w1.Rows(r1).copy Destination:=w2.Rows(lastR) ' copy to last row of dest sheet
lastC = w2.Cells(lastR, 1).End(xlToRight).Column
w2.Range(w2.Cells(lastR, 1), w2.Cells(lastR, lastC)).Interior.ColorIndex = 5
End If
r1 = r1 + 1
Loop
End Sub
I have an Macro Based Excel file that generates a list of items received and their status (i.e. received, repaired, etc). This program runs daily, and right now I have it capture the previous day's list and place it in a spreadsheet called PreviousData before updating with the current day's list, which is placed in a spreadsheet called Data; this is used to compare what we believe we fixed/changed status on the previous day.
I'm basically self taught in VBA, so I'm not super efficient or experienced. What I want to do is the following:
On the Data Spreadsheet, grab the order number starting in J2
Switch to the PreviousData Spreadsheet, and search for the order number from step 1
Scenario A: If the order number is found on PreviousData, compare the status values next to the order number on both sheets; if they differ, run some code otherwise do nothing
Scenario B: If the order number is not found on PreviousData, do nothing
Repeat until 1st blank cell encountered in Data Spreadsheet
I did some searching around the interwebs and found something (it might have been from this forum, actually) that would go row by row and compare cell values, but if scenario B came up the function would fail with "out of range." Here is the code I tried and have modified to try to get to work:
Sub output()
Dim varSheetA As Variant
Dim varSheetB As Variant
Dim varSheetRMA As Variant
Dim strRangeToCheck As String
Dim strRangeRMA As String
Dim Variable As String
Dim iRow As Long
Dim iCol As Long
Dim Count As Integer
strRangeToCheck = "K2:L1000"
strRangeRMA = "J2:J1000"
' If you know the data will only be in a smaller range, reduce the size of the ranges above.
Debug.Print Now
varSheetA = Worksheets("PreviousData").Range(strRangeToCheck)
varSheetB = Worksheets("Data").Range(strRangeToCheck) ' or whatever your other sheet is.
varSheetRMA = Worksheets("Data").Range(strRangeRMA)
Debug.Print Now
Sheets("Data").Select
Range("J2").Select
Selection.Copy
Sheets("PreviousData").Select
Cells.Find(What:=Variable, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
For iRow = LBound(varSheetA, 1) To UBound(varSheetA, 1)
For iCol = LBound(varSheetA, 2) To UBound(varSheetA, 2)
If varSheetA(iRow, iCol) = varSheetB(iRow, iCol) Then
' Cells are identical.
' Do nothing.
Else
' Cells are different.
' Code goes here for whatever it is you want to do.
End If
Next iCol
Next iRow
End Sub
Please help :)
This code should be easier to understand + it does the job.
Option Explicit
Sub CompareStatuses()
Dim ws1 As Worksheet, ws2 As Worksheet, rng1 As Range, rng2 As Range
Dim lr1&, lr2&, i&, j&
Set ws1 = ThisWorkbook.Sheets("Data")
Set ws2 = ThisWorkbook.Sheets("PreviousData")
lr1 = ws1.Range("J" & Rows.Count).End(xlUp).Row
lr2 = ws2.Range("J" & Rows.Count).End(xlUp).Row
For i = 2 To lr1
For j = 2 To lr2
Set rng1 = ws1.Range("J" & i)
Set rng2 = ws2.Range("J" & j)
If StrComp(CStr(rng1.Value), CStr(rng2.Value), vbTextCompare) = 0 And _
StrComp(CStr(rng1.Offset(0, 1).Value), CStr(rng2.Offset(0, 1).Value) _
,vbTextCompare) <> 0 Then
' found a matching Order + both statuses are different
' this is where you wanted to run some code
End If
Set rng1 = Nothing
Set rng2 = Nothing
Next j
Next i
End Sub