I want to remove all the rows except the last one for a matching userId "james.oconnor", i have a huge excel file and there are multiple rows of same "userId" with different "account" name. i want to keep only the last row having all the "account" name for a given userId - how can i do that?
How can i turn my Excel file from to
Many Thanks, Deepak
I would add a helper column that counts the number of accounts you have in that line, e.g. =COUNTA(F2:AA:2) in cell E2 then sort the sheet by this new column in descending order (highest numbers on the top).
After that you can either go through Remove Duplicates (only filtering by the userId column) or a VLOOKUP to only keep the top ones.
Does that work for you?
You could try:
Option Explicit
Sub test()
Dim Counter As Long, i As Long, LastRow As Long
Dim LookUpValue As String
LookUpValue = "james.oconnor"
With ThisWorkbook.Worksheets("Sheet1")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Counter = 0
For i = LastRow To 2 Step -1
If .Range("A" & i).Value = LookUpValue Then
Counter = Counter + 1
If Counter > 1 Then
.Rows(i).EntireRow.Delete
End If
End If
Next i
End With
End Sub
Related
I am trying to find the last row the same way I found the last column:
Sheets("Sheet2").Cells(1,Sheets("Sheet2").Columns.Count).End(xlToLeft).Column
I know this way but it is not as helpful as the prior would be:
u = Sheets("Sheet1").Range("A65536").End(xlUp).Row
I tried:
Sheets("Sheet2").Cells(Sheets("Sheet2",1).Rowa.Count).End(xlToUP).Column
Synopsis: I would like the below way for last row.
Sheets("Sheet2").Cells(1,Sheets("Sheet2").Columns.Count).End(xlToLeft).Column
You should use a with statement to qualify both your Rows and Columns counts. This will prevent any errors while working with older pre 2007 and newer 2007 Excel Workbooks.
Last Column
With Sheets("Sheet2")
.Cells(1, .Columns.Count).End(xlToLeft).Column
End With
Last Row
With Sheets("Sheet2")
.Range("A" & .Rows.Count).End(xlUp).Row
End With
Or
With Sheets("Sheet2")
.Cells(.Rows.Count, 1).End(xlUp).Row
End With
How is this?
dim rownum as integer
dim colnum as integer
dim lstrow as integer
dim lstcol as integer
dim r as range
'finds the last row
lastrow = ActiveSheet.UsedRange.Rows.Count
'finds the last column
lastcol = ActiveSheet.UsedRange.Columns.Count
'sets the range
set r = range(cells(rownum,colnum), cells(lstrow,lstcol))
This function should do the trick if you want to specify a particular sheet. I took the solution from user6432984 and modified it to not throw any errors. I am using Excel 2016 so it may not work for older versions:
Function findLastRow(ByVal inputSheet As Worksheet) As Integer
findLastRow = inputSheet.cellS(inputSheet.Rows.Count, 1).End(xlUp).Row
End Function
This is the code to run if you are already working in the sheet you want to find the last row of:
Dim lastRow as Integer
lastRow = cellS(Rows.Count, 1).End(xlUp).Row
I use this routine to find the count of data rows. There is a minimum of overhead required, but by counting using a decreasing scale, even a very large result requires few iterations. For example, a result of 28,395 would only require 2 + 8 + 3 + 9 + 5, or 27 times through the loop, instead of a time-expensive 28,395 times.
Even were we to multiply that by 10 (283,950), the iteration count is the same 27 times.
Dim lWorksheetRecordCountScaler as Long
Dim lWorksheetRecordCount as Long
Const sDataColumn = "A" '<----Set to column that has data in all rows (Code, ID, etc.)
'Count the data records
lWorksheetRecordCountScaler = 100000 'Begin by counting in 100,000-record bites
lWorksheetRecordCount = lWorksheetRecordCountScaler
While lWorksheetRecordCountScaler >= 1
While Sheets("Sheet2").Range(sDataColumn & lWorksheetRecordCount + 2).Formula > " "
lWorksheetRecordCount = lWorksheetRecordCount + lWorksheetRecordCountScaler
Wend
'To the beginning of the previous bite, count 1/10th of the scale from there
lWorksheetRecordCount = lWorksheetRecordCount - lWorksheetRecordCountScaler
lWorksheetRecordCountScaler = lWorksheetRecordCountScaler / 10
Wend
lWorksheetRecordCount = lWorksheetRecordCount + 1 'Final answer
This gives you the last used row in a specified column.
Optionally you can specify the worksheet, otherwise it will take the active sheet.
Function getLastRow(col As Integer, Optional ws As Worksheet) As Long
If ws Is Nothing Then Set ws = ActiveSheet
If ws.Cells(ws.Rows.Count, col).Value <> "" Then
getLastRow = ws.Cells(ws.Rows.Count, col).Row
Exit Function
End If
getLastRow = ws.Cells(Rows.Count, col).End(xlUp).Row
If shtRowCount = 1 Then
If ws.Cells(1, col) = "" Then
getLastRow = 0
Else
getLastRow = 1
End If
End If
End Function
Sub test()
Dim lgLastRow As Long
lgLastRow = getLastRow(2) 'Column B
End Sub
This is the best way I've seen to find the last cell.
MsgBox ActiveSheet.UsedRage.SpecialCells(xlCellTypeLastCell).Row
One of the disadvantages to using this is that it's not always accurate. If you use it then delete the last few rows and use it again, it does not always update. Saving your workbook before using this seems to force it to update though.
Using the next bit of code after updating the table (or refreshing the query that feeds the table) forces everything to update before finding the last row. But, it's been reported that it makes excel crash. Either way, calling this before trying to find the last row will ensure the table has finished updating first.
Application.CalculateUntilAsyncQueriesDone
Another way to get the last row for any given column, if you don't mind the overhead.
Function GetLastRow(col, row)
' col and row are where we will start.
' We will find the last row for the given column.
Do Until ActiveSheet.Cells(row, col) = ""
row = row + 1
Loop
GetLastRow = row
End Function
Problems with normal methods
Account for Blank Rows / Columns -
If you have blank rows or columns at the beginning of your data then methods like UsedRange.Rows.Count and UsedRange.Columns.Count will skip over these blank rows (although they do account for any blank rows / columns that might break up the data), so if you refer to ThisWorkbook.Sheets(1).UsedRange.Rows.Count you will skip lines in cases where there are blank rows at the top of your sheet, for example on this sheet:
This will skip the top row from the count and return 11:
ThisWorkbook.Sheets(1).UsedRange.Rows.Count
This code will include the blank row and return 12 instead:
ThisWorkbook.Sheets(1).UsedRange.Cells(ThisWorkbook.Sheets(1).UsedRange.Rows.Count, 1).Row
The same issue applies to columns.
Full Sheets -
Identifying the last row or column can be difficult if your sheet is full (this only matters if either your data contains over a million lines or might have values in the final rows or columns of your data). For example, if you use xlEndUp or similar and the cell you're referring to is populated then the code will skip over data, in extreme cases your entire data set can be skipped if for example the data continues from the last row of the sheet (where you start your xlEndUp) solidly up to the first row (in this case the result would be 1).
'This code works, but...
'Will not function as intended if there is data in the cell you start with (Cell A:1048576).
Dim Sht1 as Range: Set Sht1 = ThisWorkbook.Sheets(1)
Sht1.Cells(Sht1.Rows.Count, 1).End(xlUp).Row
Columns with blank rows -
The above code also assumes that your data extends the entire way down column 1, if you have blank entries in column 1 you may lose rows as the code will find the first filled row from the bottom only for column 1.
Unnecessary Looping -
Self explanatory, best to avoid looping where possible as if you're dealing with a lot of data and repeating the looping process often it can slow down your code.
Solution
Note that this is targeted at finding the last "Used" Row or Column on an entire sheet, this doesn't work if you just want the last cell in a specific range.
I've setup some Functions here
Private Function GetLastRow(Sheet As Worksheet)
'Gets last used row # on sheet.
GetLastRow = Sheet.UsedRange.Cells(Sheet.UsedRange.Rows.Count, 1).Row
End Function
Private Function GetLastCol(Sheet As Worksheet)
'Gets last used column # on sheet.
GetLastCol = Sheet.UsedRange.Cells(1, Sheet.UsedRange.Columns.Count).Column
End Function
Examples of calling these Functions:
Sub CallFunctions()
'Define the Target Worksheet we're interested in:
Dim Sht1 As Worksheet: Set Sht1 = ThisWorkbook.Sheets(1)
'Print the last row and column numbers:
Debug.Print "Last Row = "; GetLastRow(Sht1)
Debug.Print "Last Col = "; GetLastCol(Sht1)
End Sub
I preferred search last blank cell:
Il you want last empty cell of column you can do that
Dim sh as Worksheet, r as range
set sh = ActiveWorksheet 'if you want an other it's possible
'find a value
'Columns("A:D") 'to check on multiple columns
Set r = sh.Columns("A").Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
'no value return first row
If r Is Nothing Then Set r = sh.Cells(1, "A") Else Set r = sh1.Cells(r.Row + 1, "A")
If this is to insert new row, find on multiple columns is a good choice because first column can contains less rows than next columns
I use the following function extensively. As pointed out above, using other methods can sometimes give inaccurate results due to used range updates, gaps in the data, or different columns having different row counts.
Example of use:
lastRow=FindRange("Sheet1","A1:A1000")
would return the last occupied row number of the entire range. You can specify any range you want from single columns to random rows, eg FindRange("Sheet1","A100:A150")
Public Function FindRange(inSheet As String, inRange As String) As Long
Set fr = ThisWorkbook.Sheets(inSheet).Range(inRange).find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
If Not fr Is Nothing Then FindRange = fr.row Else FindRange = 0
End Function
I want to know the VBA script for the Loop: Add sequence number (start number 1000 and 1001,1002,1003 so on) to the specific column and delete the another specific columns from multiple excel files into one folder. The purpose is to have the exact excel format to process the data in the special software.
I am beginner with VBA code.
Thank you for your time.
A possible solution:
Option Explicit
Sub test()
Dim LastRowC As Long, i As Long
With ThisWorkbook.Worksheets("Sheet1")
'Let us assume that values appear in Column C. Find last row of column C
LastRowC = .Cells(.Rows.Count, "C").End(xlUp).Row
'Add Values in Column B
For i = 1 To LastRowC
.Range("B" & i).Value = i + 1000
Next i
'Clear Column A
.Columns("A:A").Clear
End With
End Sub
dim i as integer
i = 1000
dim max as integer
max = 1000000
while i < max
begin
set i = i + 1
' do funky column editing , deleting, whatever
end
So first my disclaimer. While I have some programming background, im not proficient in VB scripting so I may need some hand holding on this but I am mighty grateful for any help you wonderful people can render.
Im creating a print button that will print a worksheet based on criteria that the user will type in. Well basically I need the script to check certain cells in a row and if there is data in those cells, move to the next line. Rinse and repeat until you get to a row with no data in those certain cells and then automatically print the correct number of pages based on the data. I hope that makes sense. I hope that makes sense.
I tried writing a piece of code to check certain columns and return the value when all of those columns are blank. Hope that helps you
Sub Printing()
Dim CheckCol1 As Integer, CheckCol2 As Integer
Dim rowCount As Integer, rowCount1 As Integer, rowCount2 As Integer, currentRow As Integer
Dim currentRowValue1 As String, currentRowValue2 As String
Dim found As String
found = "No"
CheckCol1 = 1 'column A has a value of 1
CheckCol2 = 2 'column B has a value of 2
rowCount1 = Cells(Rows.Count, CheckCol1).End(xlUp).Row
rowCount2 = Cells(Rows.Count, CheckCol2).End(xlUp).Row
rowCount = Application.Max(rowCount1, rowCount2)
' find the first blank cell on both the columns
For currentRow = 1 To rowCount
currentRowValue1 = Cells(currentRow, CheckCol1).Value
currentRowValue2 = Cells(currentRow, CheckCol2).Value
If (IsEmpty(currentRowValue1) Or currentRowValue1 = "") And (IsEmpty(currentRowValue2) Or currentRowValue2 = "") Then
MsgBox ("No data on Column A and B in row" & currentRow)
found = "Yes"
End If
Next
If found = "No" Then ' This will return rowcount+1 when the columns have values throughout the range
MsgBox ("No data on Column A and B in row" & rowCount + 1)
End If
End Sub
Note:- You can increase the number of columns to be checked by adding few variables. You can try Adding third column by adding Checkcol3, rowcount3, currentrowvalue3 and adding one more condition to the if clause
I am trying to find the last row the same way I found the last column:
Sheets("Sheet2").Cells(1,Sheets("Sheet2").Columns.Count).End(xlToLeft).Column
I know this way but it is not as helpful as the prior would be:
u = Sheets("Sheet1").Range("A65536").End(xlUp).Row
I tried:
Sheets("Sheet2").Cells(Sheets("Sheet2",1).Rowa.Count).End(xlToUP).Column
Synopsis: I would like the below way for last row.
Sheets("Sheet2").Cells(1,Sheets("Sheet2").Columns.Count).End(xlToLeft).Column
You should use a with statement to qualify both your Rows and Columns counts. This will prevent any errors while working with older pre 2007 and newer 2007 Excel Workbooks.
Last Column
With Sheets("Sheet2")
.Cells(1, .Columns.Count).End(xlToLeft).Column
End With
Last Row
With Sheets("Sheet2")
.Range("A" & .Rows.Count).End(xlUp).Row
End With
Or
With Sheets("Sheet2")
.Cells(.Rows.Count, 1).End(xlUp).Row
End With
How is this?
dim rownum as integer
dim colnum as integer
dim lstrow as integer
dim lstcol as integer
dim r as range
'finds the last row
lastrow = ActiveSheet.UsedRange.Rows.Count
'finds the last column
lastcol = ActiveSheet.UsedRange.Columns.Count
'sets the range
set r = range(cells(rownum,colnum), cells(lstrow,lstcol))
This function should do the trick if you want to specify a particular sheet. I took the solution from user6432984 and modified it to not throw any errors. I am using Excel 2016 so it may not work for older versions:
Function findLastRow(ByVal inputSheet As Worksheet) As Integer
findLastRow = inputSheet.cellS(inputSheet.Rows.Count, 1).End(xlUp).Row
End Function
This is the code to run if you are already working in the sheet you want to find the last row of:
Dim lastRow as Integer
lastRow = cellS(Rows.Count, 1).End(xlUp).Row
I use this routine to find the count of data rows. There is a minimum of overhead required, but by counting using a decreasing scale, even a very large result requires few iterations. For example, a result of 28,395 would only require 2 + 8 + 3 + 9 + 5, or 27 times through the loop, instead of a time-expensive 28,395 times.
Even were we to multiply that by 10 (283,950), the iteration count is the same 27 times.
Dim lWorksheetRecordCountScaler as Long
Dim lWorksheetRecordCount as Long
Const sDataColumn = "A" '<----Set to column that has data in all rows (Code, ID, etc.)
'Count the data records
lWorksheetRecordCountScaler = 100000 'Begin by counting in 100,000-record bites
lWorksheetRecordCount = lWorksheetRecordCountScaler
While lWorksheetRecordCountScaler >= 1
While Sheets("Sheet2").Range(sDataColumn & lWorksheetRecordCount + 2).Formula > " "
lWorksheetRecordCount = lWorksheetRecordCount + lWorksheetRecordCountScaler
Wend
'To the beginning of the previous bite, count 1/10th of the scale from there
lWorksheetRecordCount = lWorksheetRecordCount - lWorksheetRecordCountScaler
lWorksheetRecordCountScaler = lWorksheetRecordCountScaler / 10
Wend
lWorksheetRecordCount = lWorksheetRecordCount + 1 'Final answer
This gives you the last used row in a specified column.
Optionally you can specify the worksheet, otherwise it will take the active sheet.
Function getLastRow(col As Integer, Optional ws As Worksheet) As Long
If ws Is Nothing Then Set ws = ActiveSheet
If ws.Cells(ws.Rows.Count, col).Value <> "" Then
getLastRow = ws.Cells(ws.Rows.Count, col).Row
Exit Function
End If
getLastRow = ws.Cells(Rows.Count, col).End(xlUp).Row
If shtRowCount = 1 Then
If ws.Cells(1, col) = "" Then
getLastRow = 0
Else
getLastRow = 1
End If
End If
End Function
Sub test()
Dim lgLastRow As Long
lgLastRow = getLastRow(2) 'Column B
End Sub
This is the best way I've seen to find the last cell.
MsgBox ActiveSheet.UsedRage.SpecialCells(xlCellTypeLastCell).Row
One of the disadvantages to using this is that it's not always accurate. If you use it then delete the last few rows and use it again, it does not always update. Saving your workbook before using this seems to force it to update though.
Using the next bit of code after updating the table (or refreshing the query that feeds the table) forces everything to update before finding the last row. But, it's been reported that it makes excel crash. Either way, calling this before trying to find the last row will ensure the table has finished updating first.
Application.CalculateUntilAsyncQueriesDone
Another way to get the last row for any given column, if you don't mind the overhead.
Function GetLastRow(col, row)
' col and row are where we will start.
' We will find the last row for the given column.
Do Until ActiveSheet.Cells(row, col) = ""
row = row + 1
Loop
GetLastRow = row
End Function
Problems with normal methods
Account for Blank Rows / Columns -
If you have blank rows or columns at the beginning of your data then methods like UsedRange.Rows.Count and UsedRange.Columns.Count will skip over these blank rows (although they do account for any blank rows / columns that might break up the data), so if you refer to ThisWorkbook.Sheets(1).UsedRange.Rows.Count you will skip lines in cases where there are blank rows at the top of your sheet, for example on this sheet:
This will skip the top row from the count and return 11:
ThisWorkbook.Sheets(1).UsedRange.Rows.Count
This code will include the blank row and return 12 instead:
ThisWorkbook.Sheets(1).UsedRange.Cells(ThisWorkbook.Sheets(1).UsedRange.Rows.Count, 1).Row
The same issue applies to columns.
Full Sheets -
Identifying the last row or column can be difficult if your sheet is full (this only matters if either your data contains over a million lines or might have values in the final rows or columns of your data). For example, if you use xlEndUp or similar and the cell you're referring to is populated then the code will skip over data, in extreme cases your entire data set can be skipped if for example the data continues from the last row of the sheet (where you start your xlEndUp) solidly up to the first row (in this case the result would be 1).
'This code works, but...
'Will not function as intended if there is data in the cell you start with (Cell A:1048576).
Dim Sht1 as Range: Set Sht1 = ThisWorkbook.Sheets(1)
Sht1.Cells(Sht1.Rows.Count, 1).End(xlUp).Row
Columns with blank rows -
The above code also assumes that your data extends the entire way down column 1, if you have blank entries in column 1 you may lose rows as the code will find the first filled row from the bottom only for column 1.
Unnecessary Looping -
Self explanatory, best to avoid looping where possible as if you're dealing with a lot of data and repeating the looping process often it can slow down your code.
Solution
Note that this is targeted at finding the last "Used" Row or Column on an entire sheet, this doesn't work if you just want the last cell in a specific range.
I've setup some Functions here
Private Function GetLastRow(Sheet As Worksheet)
'Gets last used row # on sheet.
GetLastRow = Sheet.UsedRange.Cells(Sheet.UsedRange.Rows.Count, 1).Row
End Function
Private Function GetLastCol(Sheet As Worksheet)
'Gets last used column # on sheet.
GetLastCol = Sheet.UsedRange.Cells(1, Sheet.UsedRange.Columns.Count).Column
End Function
Examples of calling these Functions:
Sub CallFunctions()
'Define the Target Worksheet we're interested in:
Dim Sht1 As Worksheet: Set Sht1 = ThisWorkbook.Sheets(1)
'Print the last row and column numbers:
Debug.Print "Last Row = "; GetLastRow(Sht1)
Debug.Print "Last Col = "; GetLastCol(Sht1)
End Sub
I preferred search last blank cell:
Il you want last empty cell of column you can do that
Dim sh as Worksheet, r as range
set sh = ActiveWorksheet 'if you want an other it's possible
'find a value
'Columns("A:D") 'to check on multiple columns
Set r = sh.Columns("A").Find(What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
'no value return first row
If r Is Nothing Then Set r = sh.Cells(1, "A") Else Set r = sh1.Cells(r.Row + 1, "A")
If this is to insert new row, find on multiple columns is a good choice because first column can contains less rows than next columns
I use the following function extensively. As pointed out above, using other methods can sometimes give inaccurate results due to used range updates, gaps in the data, or different columns having different row counts.
Example of use:
lastRow=FindRange("Sheet1","A1:A1000")
would return the last occupied row number of the entire range. You can specify any range you want from single columns to random rows, eg FindRange("Sheet1","A100:A150")
Public Function FindRange(inSheet As String, inRange As String) As Long
Set fr = ThisWorkbook.Sheets(inSheet).Range(inRange).find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
If Not fr Is Nothing Then FindRange = fr.row Else FindRange = 0
End Function
Excel 2010. I am trying to write a macro that could copy a set of data multiple times based on criteria on another sheet, but I've been stuck for a long time. I very much appreciate any help that could be offered to help me solve this problem.
Step 1: In the "Criteria" worksheet, there are three columns in which each row contains a specific combination of data. The first set of combination is "USD, Car".
Criteria worksheet
Step 2: Then the macro will move to the Output worksheet (please refer to the below link for screenshots), and then filter column A and B with the first set of criteria "USD" and "Car" in the "Criteria" worksheet.
Step 3: Afterwards, the macro will copy the filtered data into the last blank row. But the tricky part here is that, the filtered data has to be copied two times (as the "Number of set" column in the "Criteria" tab is 3 in this combination, and it doesn't have to copy the data three times since the filtered data would be treated as the first set of data)
Step4: After the filtered data have been copied, the "Set" column D will need to fill in the corresponding number of set that the rows are in. Therefore, in this 1st example, cell D2 and D8 will have "1" value, cell D14-15 will have "2" value, and cell D16-17 will have "3" value.
Step5: The macro will then move back to the "Criteria" worksheet and continue to based on the 2nd set of combination "USD, Plane" to filter the data in the "Output" worksheet. Again, it will copy the filtered data based on the "Number of set" in the "Criteria" worksheet. This process will continue until all the different combinations in the "Criteria" worksheet have been processed.
Output worksheet
Ok sorry for delay, here is a working version
you just have to add a sheet called "BF" because the autofilter count wasn't working properly so I had to use another sheet
Sub testfct()
Dim ShC As Worksheet
Set ShC = ThisWorkbook.Sheets("Criteria")
Dim EndRow As Integer
EndRow = ShC.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To EndRow
Get_Filtered ShC.Cells(i, 1), ShC.Cells(i, 2), ShC.Cells(i, 3)
Next i
End Sub
Sub Get_Filtered(ByVal FilterF1 As String, ByVal FilterF2 As String, ByVal NumberSetsDisered As Integer)
Dim NbSet As Integer
NbSet = 0
Dim ShF As Worksheet
Set ShF = ThisWorkbook.Sheets("Output")
Dim ColCr1 As Integer
Dim ColCr2 As Integer
Dim ColRef As Integer
ColCr1 = 1
ColCr2 = 2
ColRef = 4
If ShF.AutoFilterMode = True Then ShF.AutoFilterMode = False
Dim RgTotal As String
RgTotal = "$A$1:$" & ColLet(ShF.Cells(1, Columns.Count).End(xlToLeft).Column) & "$" & ShF.Cells(Rows.Count, 1).End(xlUp).Row
ShF.Range(RgTotal).AutoFilter field:=ColCr1, Criteria1:=FilterF1
ShF.Range(RgTotal).AutoFilter field:=ColCr2, Criteria1:=FilterF2
'Erase Header value, fix? or correct at the end?
ShF.AutoFilter.Range.Columns(ColRef).Value = 1
Sheets("BF").Cells.ClearContents
ShF.AutoFilter.Range.Copy Destination:=Sheets("BF").Cells(1, 1)
Dim RgFilt As String
RgFilt = "$A$2:$B" & Sheets("BF").Cells(Rows.Count, 1).End(xlUp).Row '+ 1
Dim VR As Integer
'Here was the main issue, the value I got with autofilter was not correct and I couldn't figure out why....
'ShF.AutoFilter.Range.SpecialCells(xlCellTypeVisible).Rows.Count
'Changed it to a buffer sheet to have correct value
VR = Sheets("BF").Cells(Rows.Count, 1).End(xlUp).Row - 1
Dim RgDest As String
ShF.AutoFilterMode = False
'Now we need to define Set's number and paste N times
For k = 1 To NumberSetsDisered - 1
'define number set
For j = 1 To VR
ShF.Cells(Rows.Count, 1).End(xlUp).Offset(j, 3) = k + 1
Next j
RgDest = "$A$" & ShF.Cells(Rows.Count, 1).End(xlUp).Row + 1 & ":$B$" & (ShF.Cells(Rows.Count, 1).End(xlUp).Row + VR)
Sheets("BF").Range(RgFilt).Copy Destination:=ShF.Range(RgDest)
Next k
ShF.Cells(1, 4) = "Set"
Sheets("BF").Cells.ClearContents
'ShF.AutoFilterMode = False
End Sub
And the function to get column letter using an integer input :
Function ColLet(x As Integer) As String
With ActiveSheet.Columns(x)
ColLet = Left(.Address(False, False), InStr(.Address(False, False), ":") - 1)
End With
End Function