I've tried to figure out the last used column in my excel spreadsheet using VBA to start writing something right after that column. In the image below I've tried to show what I meant and where I wanna start writing from. The desired field is already selected there which is "F2".
However, the problem is the data already available there did not maintain uniformity. How can I figure out the last used column using VBA?
This is my try:
Sub FindLastColumn()
Dim lCol&
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
MsgBox lCol
End Sub
It produces 8 as result which is not correct as the right one should be 5.
The data-ridden sheet looks like below:
If you want to find the last column in your range excluding the header, you could achieve that as below, amend the Sheet name from Sheet1 to the Sheet you are actually using:
Sub foo()
LastRow = Sheet1.UsedRange.Rows.Count
'get the last row with data in your used range
MaxCol = 1
For i = 2 To LastRow 'loop from row 2 to last
If Sheet1.Cells(i, Sheet1.Columns.Count).End(xlToLeft).Column > MaxCol Then
MaxCol = Sheet1.Cells(i, Sheet1.Columns.Count).End(xlToLeft).Column
'get the highest value for the column into variable
End If
Next i
MsgBox MaxCol
End Sub
It appears that you want to find the right-hand most used column in rows 2 to the end of your data. To do that, you'll need to loop through all the rows of data keeping track of which column is Max(LastUsedColumn). Unfortunately, there is no such built in function, but you could write one something like this:
Public Function MaxUsedColumnInRow(ByVal SheetToCheck As Worksheet, ByVal RowToCheck As Long) As Long
MaxUsedColumnInRow = SheetToCheck.Cells(RowToCheck, Columns.count).End(xlToLeft).Column
End Function
Now that you have a nifty function to determine which is the maximum used column in a row, you can call it in a loop, like this:
Public Function MaxUsedColumnInRange(ByVal SheetToCheck As Worksheet, ByVal StartRow As Long, ByVal EndRow As Long) As Long
Dim curRow As Long
For curRow = StartRow To EndRow
Dim CurCol As Long
CurCol = MaxUsedColumnInRow(SheetToCheck, curRow)
Dim maxCol As Long
If CurCol > maxCol Then
maxCol = CurCol
End If
Next
End Function
And, finally, give it a quick test replacing "Sheet1" with the name of the worksheet you're specifically checking:
Public Sub TestIt()
MsgBox "Max Used column on sheet1 = " & CStr(MaxUsedColumnInRange("Sheet1", 2, 50))
End Sub
Of course, you'll want to determine the max used row on your sheet and pass that into the the MaxUsedColumnInRange function - unless you happen to have exactly 50 rows of data, the example test Sub probably won't get you your actual desired result.
As a side benefit, you now have a handy function you can call in the future to determine the max column in a row so you don't have to remember the proper way of doing it. (I usually forget so I have to look it up, or use a nifty helper function to "remember" for me.)
Use a variation of the Find method of finding it, but limit it to ignore row 1:
Sub Test()
Dim rng As Range
Set rng = LastCell(Sheet1)
MsgBox "Last cell containing data is " & rng.Address & vbCr & _
"Selected cell is in example is " & Sheet1.Cells(2, rng.Column + 1).Address
End Sub
Public Function LastCell(wrkSht As Worksheet) As Range
Dim lLastCol As Long, lLastRow As Long
On Error Resume Next
With wrkSht.Rows("2:1048576")
lLastCol = .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
lLastRow = .Cells.Find("*", , , , xlByRows, xlPrevious).Row
If lLastCol = 0 Then lLastCol = 1
If lLastRow = 0 Then lLastRow = 1
Set LastCell = wrkSht.Cells(lLastRow, lLastCol)
End With
On Error GoTo 0
End Function
Easy route would be to use Find like below:
Dim rgLastColumnCell As Range
Set rgLastColumnCell = ActiveSheet.Cells.Find("*", , , , xlByColumns, xlPrevious)
MsgBox "Last Used Column is : " & rgLastColumnCell.Column
Adjust ActiveSheet.Cells portion to suit your need like: Activesheet.Range("B2:XFD1048576") if you want to skip first row from the check.
You cannot get the result you require by using built-in functions, either you can get the column H because it is the last used column or the column B, because it is the last filled column, To get E you have to write your own code, and by the look of it, it seems that you want the end of the colored range. You can check the last column where color is not present in a loop
Sub checkLastColumn()
col_num = 1
Do While Cells(2, col_num).Interior.Pattern <> xlNone
col_num = col_num + 1
Loop
MsgBox col_num
End Sub
It will return column F
EDIT....
As I said earlier you cannot get the cell you require by any built-in function, you have to write some code, and in order to do that you must have a definite logic that should be known and decided between you and the users of the sheet.
For example:
you can color the range as you have already done
You can name the column header, as in your example, it is status.
You can fix the number of data columns and status columns, and there will be no need to use any code
For finding the status column or any other if you decide you can use a loop as below
Sub getStatusColumn()
col_num = 1
Do While Cells(1, col_num) <> "status"
col_num = col_num + 1
Loop
MsgBox col_num
End Sub
OR
Sub getLastItemColumn()
col_num = 1
Do While Left(Cells(1, col_num), 4) = "Item"
col_num = col_num + 1
Loop
MsgBox col_num
End Sub
Related
I have a table with numbers from 1 to 10. (Starting from D2 to M2)
Suppose in A1 there is 03/09/2019
AND in B1 there is 06/09/2019
AND in C1 there is Hello
In COLUMN A I have a multiple series of words starting from A3 to A10
Here is an Example of the Excel Table
What I would like to do is: Search for the word Student in Column A, when I find it, get the numbers from A1 --> 3
and A2 --> 6 and write the word Hello that is in C1 in the cells that go to 3 to 6 in the row of the finded word Student
So my output would be like:
This is my code so far:
Dim Cell As Range
Columns("A:A").Select
Set Cell = Selection.Find(What:="Student", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Cell Is Nothing Then
MsgBox "Word not found"
Else
MsgBox "Word found"
End If
Basically I can find the word Student but don't know how to write the word Hello in the cells between 3 to 6
A few notes regarding the code below (not tested!).
1) Always try use worksheet qualifiers when working with VBA. This will allow for cleaner code with less room for unnecessary errors
2) When using .Find method I use LookAt:=xlWhole because if you do not explicitly define this your code will use the last known method that you would have used in Excel. Again, explicit definition leaves less room for error.
3) Try include error handling when you code. This provides “break points” for easier debugging in the future.
4) You can make the below much more dynamic that it currently is. But I'll leave that up to you to learn how to do!
Option Explicit
Sub SearchAndBuild()
Dim rSearch As Range
Dim lDayOne As Long, lDayTwo As Long
Dim lColOne As Long, lColTwo As Long
Dim sHello As String
Dim wsS1 As Worksheet
Dim i As Long
'set the worksheet object
Set wsS1 = ThisWorkbook.Sheets("Sheet1")
'store variables
lDayOne = Day(wsS1.Range("A1").Value)
lDayTwo = Day(wsS1.Range("B1").Value)
sHello = wsS1.Range("C1").Value
'find the student first
Set rSearch = wsS1.Range("A:A").Find(What:="Student", LookAt:=xlWhole)
'error handling
If rSearch Is Nothing Then
MsgBox "Error, could not find Student."
Exit Sub
End If
'now loop forwards to find first date and second date - store column naumbers
'adjust these limits where necessary - can make dynamic
For i = 4 To 13
If wsS1.Cells(2, i).Value = lDayOne Then
lColOne = i
End If
If wsS1.Cells(2, i).Value = lDayTwo Then
lColTwo = i
Exit For
End If
Next i
'now merge the range
wsS1.Range(wsS1.Cells(rSearch.Row, lColOne), wsS1.Cells(rSearch.Row, lColTwo)).Merge
'set the vvalue
wsS1.Cells(rSearch.Row, lColOne).Value = sHello
End Sub
This is just one way to approach the problem. Hopefully this helps your understanding!
No need for a loop here - just find your value and parse the dates. Assuming your value to be found exists in Column A and your table starts in Column D, there is clear relationship between the columns which is Day(date) + 3.
Sub Test()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim lr As Long, Found As Range
Dim date_a As Long, date_b As Long
lr = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
Set Found = ws.Range("A2:A" & lr).Find("Student", LookIn:=xlValues)
If Not Found Is Nothing Then
date_a = Day(Range("A1")) + 3
date_b = Day(Range("B1")) + 3
With ws.Range(ws.Cells(Found.Row, date_a), ws.Cells(Found.Row, date_b))
.Merge
.Value = ws.Range("C1")
End With
Else
MsgBox "Value 'Student' Not Found"
End If
End Sub
I've tried this:
Dim ThisRow As Long
Dim FindWhat As String
FindWhat = "Student"
Dim MyStart As Byte
Dim MyEnd As Byte
MyStart = Day(Range("A1").Value) + 3 'we add +3 because starting 1 is in the fourth column
MyEnd = Day(Range("B1").Value) + 3 'we add +3 because starting 1 is in the fourth column
Dim SearchRange As Range
Set SearchRange = Range("A3:A10") 'range of values
With Application.WorksheetFunction
'we first if the value exists with a count.
If .CountIf(SearchRange, FindWhat) > 0 Then 'it means findwhat exists
ThisRow = .Match(FindWhat, Range("A:A"), 0) 'we find row number of value
Range(Cells(ThisRow, MyStart), Cells(ThisRow, MyEnd)).Value = Range("C1").Value
Application.DisplayAlerts = False
Range(Cells(ThisRow, MyStart), Cells(ThisRow, MyEnd)).Merge
Application.DisplayAlerts = True
Else
MsgBox "Value 'Student' Not Found"
End If
End With
Note I've used worksheets function COUNTIF and MATCH. MATCH will find the position of an element in a range, so if you check the whole column, it will tell you the row number. But if it finds nothing, it will rise an error. Easy way to avoid that is, first, counting if the value exists in that range with COUNTIF, and if it does, then you can use MATCH safely
Also, note that because we are using MATCH, this function only finds first coincidence, so if your list of values in column A got duplicates, this method won't work for you!.
My input form contains 2 texts which corresponds to a specific row & column header of my worksheet. I want to use the 2 selected texts in the form to locate the cell, and edit the respective cell's value.
1 of the value is part of an array in a Listbox (e.g. located in ListBox2.Column(0,1))
The other value is from a combo box (e.g. cmbName).
How can I use these 2 values to locate the cell? I thought maybe index/match will work, but it seems all too complicated.. any help will be appreciated - thanks!
I tried doing a double for loop to locate the column, but I can't figured out how to locate the right row.
For m=27 To finalcol
For n = 0 to ListBox2.ListCount - 1
If ListBox2.Column(0,n) = Trim(ThisWorkBook.Worksheets("Masterlist").Cells(1,m).Text) Then
MsgBox ("Matched!")
End If
Next n
Next m
I get the "Matched!" output, but I'm not sure how to achieve the next step. Is this approach fundamentally limited?
First you can find the row corresponding to cmbName, and then the column as you already did:
' Find the row corresponding to cmbName
For r=2 To ThisWorkBook.Worksheets("Masterlist").UsedRange.Rows.Count
If cmbName = Trim(ThisWorkBook.Worksheets("Masterlist").Cells(r,1).Text)
therow=r
End if
Next r
' Find the column corresponding to ListBox2 column 0:
For m=27 To finalcol
For n = 0 to ListBox2.ListCount - 1
If ListBox2.Column(0,n) = Trim(ThisWorkBook.Worksheets("Masterlist").Cells(1,m).Text) Then
If ListBox2.Selected(n)
ThisWorkBook.Worksheets("Masterlist").Cells(therow,m).Text = ListBox2.Column(1,n)
End If
End If
Next n
Next m
If you want to use the double for loop it would be something like:
Public Sub Test
'Loops through all items in Listbox2'
For n = 0 to ListBox2.ListCount - 1
FindCell ListBox2.List(n)
Next
End Sub
Private Sub FindCell (lstValue As String)
'Sets the ws As a variable we can use'
Dim ws as Worksheet
Set ws = ThisWorkBook.Worksheets("Masterlist")
Dim ColumnLetter as String
'Find the last non-blank cell in row 1
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
'Loops through each cell in Row 1'
For Each cell In ws.Range("A1:A" & lCol)
If cell.Value = lstValue Then 'Checks if the cell value is equal to the item we passed in from the ListBox'
ColumnLetter = Split(Cells(1, cell.Column).Address, "$")(1) 'To use Worksheet.Range below, we need to find the column letter'
'Find the last non-blank cell in column A(1)
lRow = Cells(Rows.Count, cell.Column).End(xlUp).Row 'Goes from the bottom of the file up to the first cell that contains a value and stores the row # as a variable'
For Each cellCol in ws.Range(ColumnLetter & "2:" ColumnLetter & lRow) 'Now we need to check each cell in the row for the value in the combo box'
If cellCol.Value = cmbName.Value Then
Messagebox ("Matched")
End If
Next
End If
Next
End Sub
Let me know how this goes :)
You can try this.
I dummied up a worksheet that looks like this ...
... I then added a named range to that matrix called rngDataSet.
Then, using this code, it demonstrates logic that will ultimately find and select the relevant cell based on the row and column headings you provide. You should be able to adapt this code to your own logic.
Public Sub FindCell(ByVal rngDataSet As Range, ByVal strRowHeader As String, ByVal strColHeader As String, ByVal varNewValue As Variant)
Dim objCell As Range, objColCell As Range, objRowCell As Range
' Find the column header
For Each objCell In rngDataSet.Rows(1).Cells
If UCase(Trim(objCell.Text)) = UCase(Trim(strColHeader)) Then
Set objColCell = objCell
Exit For
End If
Next
' Find the row header
For Each objCell In rngDataSet.Columns(1).Cells
If UCase(Trim(objCell.Text)) = UCase(Trim(strRowHeader)) Then
Set objRowCell = objCell
Exit For
End If
Next
If objColCell Is Nothing Or objRowCell Is Nothing Then
MsgBox "Either 1 or both of the supplied headers were not found.", vbCritical, "Error"
Else
rngDataSet.Worksheet.Cells(objRowCell.Row, objColCell.Column) = varNewValue
End If
End Sub
Public Sub DoFindCell()
Dim strRowHeader As String, strColHeader As String
strRowHeader = InputBox("Row Header ...", "Row Header", "Row Header ")
strColHeader = InputBox("Column Header ...", "Column Header", "Col Header ")
FindCell Sheet1.Range("rngDataSet"), strRowHeader, strColHeader, “New Value”
End Sub
I hope that helps.
"DoFindCell" only exists to invoke the logic, that should be replaced by your own list/combo box values.
I have a vb.net application from which I open an excel spreadsheet that contains data. I copy all the data and insert it into sql server. I'm coming across a small issue with finding the last row. Here's how I've been doing it right now...
Dim lastRow As Long = 0
lastRow = xlws.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing).Row
This finds the last row for me but often times, the spreadsheet might contain data that is not relevant to what I'm trying to insert into my table - in this case it's a confidentiality statement at the last row of the spreadsheet. So what i'm trying to do is set the last row to whatever the last row of ACTUAL data is. This is what it looks like...
So in this case - i want the last row to be recognized to be row 11 rather than row 13. The thing is - the formatting of the report might be slightly different (for the confidentiality statement) so often times it might start in column A or B and be merged (possibly) or they might write it elsewhere.
Another thing is that Column A and B of data (ending at row 11) might sometimes not have a value. How should I go about something like this?
EDIT:
This is what I'm coming up with - Hate GoTo's but....
LastRowCheck:
If CStr(excel.Cells(lastRow, 4).Value) = "" And CStr(excel.Cells(lastRow, 5).value) = "" And CStr(excel.Cells(lastRow, 6).value) = "" Then
lastRow += -1
goto LastRowCheck
End If
How about:
Sub TheTrueLastRow()
Dim i As Long
For i = 1 To Rows.Count
If Cells(i, "B").Value = "" Or Cells(i, "E").Value = "" Then
lastRow = i - 1
Exit For
End If
Next i
MsgBox lastRow
End Sub
Maybe something like this:
Sub Test()
MsgBox LastRow(ThisWorkbook.Worksheets(2))
End Sub
Public Function LastRow(wrkSht As Worksheet) As Long
Dim rLastCell As Range
Dim lLastCol As Long, lLastRow As Long
Dim rCol As Range
On Error Resume Next
With wrkSht
lLastCol = .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
lLastRow = .Cells.Find("*", , , , xlByRows, xlPrevious).Row
If lLastCol = 0 Then lLastCol = 1
If lLastRow = 0 Then lLastRow = 1
Set rLastCell = .Cells(lLastRow, lLastCol)
'Look at each column, if the last cell is merged then look up from there,
'otherwise leave the last row as it is.
For Each rCol In .Range(.Cells(rLastCell.Row, 1), rLastCell).Columns
If rCol.MergeCells Then
LastRow = rCol.End(xlUp).Row
Exit For
Else
LastRow = rLastCell.Row
End If
Next rCol
End With
On Error GoTo 0
End Function
Edit: Just noticed, it will fail at this point (well, if the last column is shorter rather than the first two).
Another thing is that Column A and B of data (ending at row 11) might
sometimes not have a value. How should I go about something like this?
If you have a column that has data in each row of the table and the there is an empty cell between that on wanted data
xlws.Range("B1").End(Excel.XlDirection.xlDown).Row
Alternately, you can take the bottom up approach if the only there is no unwanted data at the end of a column.
xlws.Range("B" & xlws.Rows.Count).End(Excel.XlDirection.xlUp).Row
need a function that returns the first completely empty row (no values, no formulas, no blanks) from a sheet with sparely populated cells. No one single column is required to be filled.
I tried this, but i can even get it to compile:
Public Donations As Worksheet
Set Donations = Sheets("Sheet2")
Function getEmptyRow() As Long
Dim lastCol As Long, lastRow As Long, maxRow As Long
Dim col As Long
Dim r As Variant
lastCol = Donations.Cells(1, Columns.Count).End(xlToLeft).Column
For col = 1 To lastCol Step 1
lastRow = Donations.Cells(Rows.Count, col).End(xlUp).row
maxRow = Application.WorksheetFunction.max(maxRow, lastRow)
Next col
getEmptyRow = maxRow + 1
End Function
Using EntireRow (which is so useful let me tell you) and counting row by row starting in A1 is one very basic way of doing this.
This will tell you in the immediate window:
Sub findemptyrow() '''Psuedo Code
Application.ScreenUpdating = False 'turns off annoying blinky
Range("a1").Activate 'start at beginning
While a <> 1 'keep going
If Application.CountA(ActiveCell.EntireRow) = 0 Then 'is it blank?
Debug.Print "Row " & (ActiveCell.Row) & " is blank." 'it is
a = 1 'stop going
End If
ActiveCell.Offset(1).Activate 'next cell
Wend 'do it all over again
Application.ScreenUpdating = True 'back to normal settings
End Sub
Making ScreenUpdating False will make this faster, even with 10k's of rows.
The Range.Find method is likely the most expedient method. Look for a wildcard (What:=Chr(42)), start in A1 (After:=.Cells(1, 1), search backwards (SearchDirection:=xlPrevious), search row-by-row (SearchOrder:=xlByRows).Row), look at the formulas (LookIn:=xlFormulas) since that will find the first value or formula; looking at xlValues may not be correct if a formula is returning an empty string ("").
Option Explicit
Public Donations As Worksheet
Sub test()
Set Donations = Worksheets("Sheet2")
Debug.Print getNextEmptyRow(Donations)
End Sub
Function getNextEmptyRow(ws As Worksheet)
With ws.Cells
getNextEmptyRow = .Find(What:=Chr(42), After:=.Cells(1, 1), LookIn:=xlFormulas, _
SearchDirection:=xlPrevious, SearchOrder:=xlByRows).Row + 1
End With
End Function
You cannot set Donations in the declarations area of a module code sheet. Declare the public variable in the declarations area (top) of the code sheet but Set the variable in a sub or function.
Don't forget to add 1 to the row returned if you want the 'next empty row'.
Just another alternative using the SpecialCells method of a `Range:
Option Explicit
Sub Test()
Debug.Print "Last row on Sheet1 is: " & FirstCompletelyEmptyRow(Sheet1)
End Sub
Function FirstCompletelyEmptyRow(ByRef wsTarget As Worksheet) As Long
FirstCompletelyEmptyRow = wsTarget.Range("A1").SpecialCells(xlCellTypeLastCell).Row + 1
End Function
Preamble: I'm a self taught hand at anything VB script. Most of my stuff is hodgepodged-together scripts I've found.
I need to sort rows into different sheets based on a set of cell values.
In some instances its a set of numbers which would apply, in others it's a very direct value.
See:
A cell value of 1-99 goes to a sheet titled "1-99"
A cell value of 100 goes to a sheet titled "100"
There are several ranges like that. The working iteration I have only works for the direct value.
Basically, how to I get the script to understand less than or greater than or both--for instances in which it's between sets (see: 101-199)?
Set Sorter = Sheets("Raw Data").Range("M2:M100000")
For Each cell In Sorter
If cell.Value = "100" Then
cell.EntireRow.Copy
Sheets("100").Range("C" & Rows.Count).End(xlUp).Offset(1, -2).PasteSpecial
If cell.Value = "200" Then
cell.EntireRow.Copy
Sheets("200").Range("C" & Rows.Count).End(xlUp).Offset(1, -2).PasteSpecial
End If
Next
Application.CutCopyMode = False
Thank you for any and all help.
EDIT:
Below are the ranges:
1-99
100
101-199
200
201-299
300
I've got a solution for you that should show you some good concepts in VBA.
PREP FROM YOU:
Create sheets named "1-99", "100", "101-199", "200", "201-299", "300"
Include the header rows, the code I wrote works from row 2, so if your headers take up more than that, you will simply have to modify the initialization part.
Copy this code into a module and run it.
PROCESS:
Initialize the row numbers and names of all the sheets
Loop through "Raw Data" and get the tempValue to evaluate.
Using SELECT CASE statements, decide which rows go to which sheets.
Pass some arguments into a sub that will move the data accordingly, saving space and sanity.
NOTE: I'm unsure of your column that has the value to check, It looked like "M" so that's what I'm using. If it's "A" you can change it, and let me know, I will modify the answer.
TESTED:
Sub SortValuesToSheets()
Dim lastRow As Long
Dim lastCol As Long
Dim tempValue As Double 'Using Double not knowing what kind of numbers you are evaluating
Dim lRow As Long
Dim sh1 As String, sh2 As String, sh3 As String
Dim sh4 As String, sh5 As String, sh6 As String
Dim raw As String
Dim sh1Row As Long, sh2Row As Long, sh3Row As Long
Dim sh4Row As Long, sh5Row As Long, sh6Row As Long
'INITIALIZE TARGET SHEETS
'Name the target sheets
raw = "Raw Data"
sh1 = "1-99"
sh2 = "100"
sh3 = "101-199"
sh4 = "200"
sh5 = "201-299"
sh6 = "300"
'Set the row number for each target sheet to 2, to account for headers
sh1Row = 2
sh2Row = 2
sh3Row = 2
sh4Row = 2
sh5Row = 2
sh6Row = 2
lastRow = Sheets(raw).Cells(Rows.Count, "A").End(xlUp).row 'Get the last Row
lastCol = Sheets(raw).Cells(2, Columns.Count).End(xlToLeft).Column 'and column
'BEGIN LOOP THROUGH RAW DATA
For lRow = 2 To lastRow
tempValue = CDbl(Sheets(raw).Cells(lRow, "M").Value) 'set TempValue to SEARCH COLUMN
Select Case tempValue
Case Is < 1
MsgBox ("Out of Range, Under 1")
Case 1 To 99
Call CopyTempRow(lRow, sh1, sh1Row, lastCol)
sh1Row = sh1Row + 1
Case 100
Call CopyTempRow(lRow, sh2, sh2Row, lastCol)
sh2Row = sh2Row + 1
Case 101 - 199
Call CopyTempRow(lRow, sh3, sh3Row, lastCol)
sh3Row = sh3Row + 1
Case 200
Call CopyTempRow(lRow, sh4, sh4Row, lastCol)
sh4Row = sh4Row + 1
Case 201 - 299
Call CopyTempRow(lRow, sh5, sh5Row, lastCol)
sh5Row = sh5Row + 1
Case 300
Call CopyTempRow(lRow, sh6, sh6Row, lastCol)
sh6Row = sh6Row + 1
Case Is > 300
MsgBox ("Out of Range, Over 300")
End Select
Next lRow
End Sub
This is the subroutine that will copy the entire row. The reason for separating it is so that we don't have to re-write for each case with the slight variations. You wouldn't want to see this loop 6 times with only one number being changed each time. If you have to change it, you change it here, once, and call it whenever you need.
Sub CopyTempRow(row As Long, target As String, tRow As Long, lastCol As Long)
For lCol = 1 To lastCol
Sheets(target).Cells(tRow, lCol) = Sheets("Raw Data").Cells(row, lCol)
Next lCol
End Sub
Untested:
Dim v, s
Set Sorter = Sheets("Raw Data").Range("M2:M100000")
For Each cell In Sorter
v = cell.Value
if Len(v) > 0 And Isnumeric(v) Then
If v>1 and v<=99 Then
s = "1-99"
Elseif v = 100 Then
s = "100"
Else
s = ""
End If
If s<>"" Then
Sheets(s).Range("C" & Rows.Count).End(xlUp).Offset(1,0).Entirerow.Value = _
c.entirerow.Value
End if
End if
Next