I am trying to create some code that looks through a range of cells and will copy and paste the cells that meet a specific parameter to a different location in the workbook.
I would like to copy anything with the letter L from "sheet5" and copy a specific range to "sheet1"
I must have something wrong with the loop part of the code because only the top of the cell range is being copied. I would like the pasting to start at row 5 and continue moving downward. Does this mean I correctly put the IRow = IRow + 1 below the paste function?
Sub Paste_Value_Test()
Dim c As Range
Dim IRow As Long
Dim rDestination As Excel.Range
Application.ScreenUpdating = False
Sheets("sheet5").Activate
For Each c In Sheets("sheet5").Range("b2", Range("N65536").End(xlUp))
If c.Value = "L" Then
Sheets("sheet5").Cells(c.Row, 2).Copy
Set rDestination = Worksheets("sheet5").Cells(5 + IRow, 12)
rDestination.Select
Selection.PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, _
SkipBlanks:=False, _
Transpose:=False
IRow = IRow + 1
End If
Next c
End Sub
I really appreciate any help on this. I'm relatively new to VBA and am going to start seriously digging in.
Is this what you are trying by any chance? I have commented the code so you shouldn't have any problem understanding it.
Sub Paste_Value_Test()
Dim c As Range
Dim IRow As Long, lastrow As Long
Dim rSource As Range
Dim wsI As Worksheet, wsO As Worksheet
On Error GoTo Whoa
'~~> Sheet Where "L" needs to be checked
Set wsI = ThisWorkbook.Sheets("Sheet5")
'~~> Output sheet
Set wsO = ThisWorkbook.Sheets("Sheet1")
Application.ScreenUpdating = False
With wsI
'~~> Find Last Row which has data in Col B to N
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastrow = .Columns("B:N").Find(What:="*", _
After:=.Range("B1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lastrow = 1
End If
'~~> Set you input range
Set rSource = .Range("B2:N" & lastrow)
'~~> Search for the cell which has "L" and then copy it across to sheet1
For Each c In rSource
If c.Value = "L" Then
.Cells(c.Row, 2).Copy
wsO.Cells(5 + IRow, 12).PasteSpecial Paste:=xlPasteValues
IRow = IRow + 1
End If
Next
End With
LetsContinue:
Application.ScreenUpdating = True
Application.CutCopyMode = False
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
Related
I have this Macro which essentially uses two sheets - sheet2 updates sheet1 and then kills the second worksheet.
I noticed that when it comes to one part of the macro (delete row which has "Delete" in column A in worksheet 1) it doesn't appear to work if I run the Macro from worksheet 2. If I run it from Sheet 1 is works without a problem.
This is the full code, just in case you need to look at it - I'll highlight the part that I'm having trouble with next.:
Public Sub Cable_Load_full()
'~~> Copy New Accounts from worksheet2
Dim ws1 As Worksheet, ws2 As Worksheet
Dim bottomL As Integer
Dim x As Integer
Dim c As Range
Dim i As Long, J As Long, LastCol As Long
Dim ws1LR As Long, ws2LR As Long
Dim ws1Rng As Range, aCell As Range
Dim SearchString
Set ws1 = Sheets("CableSocials")
Set ws2 = Sheets("CableRevised")
bottomL = ws2.Range("A" & Rows.Count).End(xlUp).Row: x = 1
x = ws1.Range("A" & Rows.Count).End(xlUp).Row
x = x + 1
For Each c In ws2.Range("A1:A" & bottomL)
If c.Value = "New" Then
c.EntireRow.Copy ws1.Range("A" & x)
x = x + 1
End If
Next c
'~~> Assuming that ID is in Col B
'~~> Get last row in Col B in Sheet1
ws1LR = ws1.Range("B" & Rows.Count).End(xlUp).Row
'~~> Set the Search Range
Set ws1Rng = ws1.Range("B1:B" & ws1LR)
'~~> Adding Revise Column to worksheet 1
ws1.Columns("A:A").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("A1").Value = "Revise"
Set ws2 = Sheets("CableRevised")
'~~> Turn off Filter
ws2.AutoFilterMode = False
'~~> Get last row in Col A in Sheet2
ws2LR = ws2.Range("B" & Rows.Count).End(xlUp).Row
'~~> Loop through the range in Sheet 2 to match it with the range in Sheet1
For i = 1 To ws2LR
SearchString = ws2.Range("B" & i).Value
'~~> Search for the ID
Set aCell = ws1Rng.Find(What:=SearchString, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'~~> If found
If Not aCell Is Nothing Then
'~~> Append values
ws1.Cells(aCell.Row, 1).Value = ws2.Cells(i, 1).Value
ws1.Cells(aCell.Row, 3).Value = ws2.Cells(i, 2).Value
ws1.Cells(aCell.Row, 19).Value = ws2.Cells(i, 18).Value
ws1.Cells(aCell.Row, 20).Value = ws2.Cells(i, 19).Value
End If
Next i
'~~> Delete the accounts that need to be deleted
ws1.AutoFilterMode = False
With Range("A1", Range("A" & Rows.Count).End(xlUp))
.AutoFilter 1, "Delete"
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
End With
ws1.AutoFilterMode = False
'~~> Removing New from Column B
ws1.Columns("B").Replace What:="New", _
Replacement:="", _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
MatchCase:=False, _
SearchFormat:=False, _
ReplaceFormat:=False
ws1.Columns("A").EntireColumn.Delete
Call SheetKiller
End Sub
Sub SheetKiller()
Dim s As Worksheet, t As String
Dim i As Long, K As Long
K = Sheets.Count
For i = K To 1 Step -1
t = Sheets(i).Name
If t = "CableRevised" Then
Application.DisplayAlerts = False
Sheets(i).Delete
Application.DisplayAlerts = True
End If
Next i
End Sub
So the part that only works when I run the Macro from Sheet1 is:
'~~> Delete the accounts that need to be deleted
ws1.AutoFilterMode = False
With Range("A1", Range("A" & Rows.Count).End(xlUp))
.AutoFilter 1, "Delete"
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
End With
ws1.AutoFilterMode = False
I'm not sure why - is it acting as if it will only delete the rows from the ActiveSheet (which I guess would be the Sheet I run the Macro from?) ? Is it possible to make it work even if I run the Macro from Sheet2?
Thanks for any help you provide!
You need to explicitly refer to ranges on ws1. As written, your code is looking for ranges on the active sheet.
Try this:
'~~> Delete the accounts that need to be deleted
ws1.AutoFilterMode = False
With ws1.Range("A1", ws1.Range("A" & ws1.Rows.Count).End(xlUp))
.AutoFilter 1, "Delete"
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
End With
ws1.AutoFilterMode = False
I have multiple sheets, each with data only in the first two columns:
Column A - ID
Column B - Name
I am trying to consolidate all these sheets into a master sheet. The format of the master sheet should be:
Column A - Sheet Name (From where the data was copied)
Column B - ID
Column C - Name
I have found a site that has code that does more or less this, however, after messing around with it for what feels like an eternity I just cannot get it to work.
The code works, in the sense that it copies the correct range and inputs the sheet name into column A, however, it doesn't stop by the "last row" of the range in the master sheet, it continues to populate the ENTIRE column A and the IF Statement that counts the rows is triggered and I get the msgbox pop up (see below in code). At this point, the code just ends and it does not get a chance to execute for the remaining sheets.
Link to site: https://www.rondebruin.nl/win/s3/win002.htm
Below is the code from the original site, with some minor adjustments for the range I will be using:
Sub CopySheetNameToColumn()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim CopyRng As Range
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the sheet "RDBMergeSheet" if it exist
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("RDBMergeSheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a worksheet with the name "RDBMergeSheet"
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "RDBMergeSheet"
'loop through all worksheets and copy the data to the DestSh
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> DestSh.Name Then
'Find the last row with data on the DestSh
Last = LastRow(DestSh)
'Fill in the range that you want to copy
Set CopyRng = sh.Range("A:B")
'Test if there enough rows in the DestSh to copy all the data
If Last + CopyRng.Rows.count > DestSh.Rows.count Then
MsgBox "There are not enough rows in the Destsh"
GoTo ExitTheSub
End If
'This example copies values/formats, if you only want to copy the
'values or want to copy everything look at the example below this macro
CopyRng.Copy
With DestSh.Cells(Last + 1, "B")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
'Optional: This will copy the sheet name in the H column
DestSh.Cells(Last + 1, "A").Resize(CopyRng.Rows.count).Value = sh.Name
End If
Next
ExitTheSub:
Application.Goto DestSh.Cells(1)
'AutoFit the column width in the DestSh sheet
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Functions:
Function LastRow(sh As Worksheet)
On Error Resume Next
LastRow = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
End Function
Function LastCol(sh As Worksheet)
On Error Resume Next
LastCol = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
End Function
Instead of
Set CopyRng = sh.Range("A:B")
try
Set CopyRng = sh.Range("A1", sh.Range("B" & Rows.Count).End(xlUp))
as the former covers every row of the worksheet, hence the message box and the name running down the whole sheet.
Something like:
Option Explicit
Sub CopySheetNameToColumn()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim CopyRng As Range
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("RDBMergeSheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "RDBMergeSheet"
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> DestSh.Name Then
Last = GetLastRow(DestSh, 1)
With sh
Set CopyRng = sh.Range("A1:B" & GetLastRow(sh, 1))
End With
If Last + CopyRng.Rows.Count > DestSh.Rows.Count Then
MsgBox "There are not enough rows in the Destsh"
GoTo ExitTheSub
Else
CopyRng.Copy IIf(Last = 1, DestSh.Cells(1, "B"), DestSh.Cells(Last + 1, "B"))
End If
If Last = 1 Then
DestSh.Cells(Last, "A").Resize(CopyRng.Rows.Count).Value = sh.Name
Else
DestSh.Cells(Last + 1, "A").Resize(CopyRng.Rows.Count).Value = sh.Name
End If
End If
Next
ExitTheSub:
Application.Goto DestSh.Cells(1)
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Public Function GetLastRow(ByVal ws As Worksheet, Optional ByVal columnNumber As Long = 1) As Long
With ws
GetLastRow = .Cells(.Rows.Count, columnNumber).End(xlUp).Row
End With
End Function
You can shorten this significantly... there are lots of posts about getting items on a master sheet, 4 from yesterday alone.
Take a look at this:
Dim lrSrc As Long, lrDst As Long, i As Long
For i = 1 To Sheets.Count
If Not Sheets(i).Name = "Destination" Then
lrSrc = Sheets(i).Cells(Sheets(i).Rows.Count, "A").End(xlUp).Row
lrDst = Sheets("Destination").Cells(Sheets("Destination").Rows.Count, "A").End(xlUp).Row
With Sheets(i)
.Range(.Cells(2, "A"), .Cells(lrSrc, "B")).Copy Sheets("Destination").Range(Sheets("Destination").Cells(lrDst + 1, "B"), Sheets("Destination").Cells(lrDst + 1 + lrSrc, "C")) 'Assumes headers in first row aren't being copied
Sheets("Destination").Range(Sheets("Destination").Cells(lrDst + 1, "A"), Sheets("Destination").Cells(lrDst + 1 + lrSrc, "A")).Value = Sheets(i).Name
End With
End If
Next i
Code now tested
I am trying to come up with a macro that checks if any numeral value exists in a cell. If a numeral value exists, copy a portion of that row and paste it into another worksheet within the same spreadsheet.
Sheet1 is the sheet that has all my data in it. I am trying to look in column R if there is any values in it. If it does, copy that cell and the four adjacent cells to the left of it and paste it into Sheet2.
This is what I have come up with so far based on mish-mashing other people's code though it only does a part of what I want. It just copies part of a row then pastes it into another worksheet but it does not check column R for a value first. It just copies and pastes regardless and does not move onto the next row once it has done that. I need it to continue onto the next row to continue looking:
Sub Paste_Value_Test()
Dim c As Range
Dim IRow As Long, lastrow As Long
Dim rSource As Range
Dim wsI As Worksheet, wsO As Worksheet
On Error GoTo Whoa
'~~> Sheet Where values needs to be checked
Set wsI = ThisWorkbook.Sheets("Sheet1")
'~~> Output sheet
Set wsO = ThisWorkbook.Sheets("Sheet2")
Application.ScreenUpdating = False
With wsI
'~~> Find Last Row which has data in Col O to R
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastrow = .Columns("O:R").Find(What:="*", _
After:=.Range("O3"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lastrow = 1
End If
'~~> Set you input range
Set rSource = .Range("R" & lastrow)
'~~> Search for the cell which has "L" and then copy it across to sheet1
For Each c In rSource
Debug.Print cValue
If c.Value > "0" Then
.Range("O" & c.Row & ":R" & c.Row).Copy
wsO.Cells(5 + IRow, 12).PasteSpecial Paste:=xlPasteValues
IRow = IRow + 1
End If
Next
End With
LetsContinue:
Application.ScreenUpdating = True
Application.CutCopyMode = False
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
Below is some code which hopefully achieves what I think you are trying to do. I have included comments throughout stating what I changed:
Sub Paste_Value_Test()
Dim c As Range
Dim IRow As Long, lastrow As Long
Dim rSource As Range
Dim wsI As Worksheet, wsO As Worksheet
On Error GoTo Whoa
'~~> Sheet Where values needs to be checked
Set wsI = ThisWorkbook.Sheets("Sheet1")
'~~> Output sheet
Set wsO = ThisWorkbook.Sheets("Sheet2")
Application.ScreenUpdating = False
With wsI
'~~> Find Last Row which has data in Col O to R
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
'You specified "After" to be cell O3. This means a match will
' occur on row 2 if cell R2 (or O2 or P2) has something in it
' because cell R2 is the cell "after" O3 when
' "SearchDirection:=xlPrevious"
' After:=.Range("O3"), _
lastrow = .Columns("O:R").Find(What:="*", _
After:=.Range("O1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lastrow = 1
End If
'This was only referring to the single cell in column R on the
' last row (in columns O:R)
'Set rSource = .Range("R" & lastrow)
'Create a range referring to everything in column R, from row 1
' down to the "last row"
Set rSource = .Range("R1:R" & lastrow)
'This comment doesn't seem to reflect what the code was doing, or what the
'question said
'~~> Search for the cell which has "L" and then copy it across to sheet1
For Each c In rSource
'This is printing the variable "cValue", which has never been set
'Debug.Print cValue
'It was probably meant to be
Debug.Print c.Value
'This was testing whether the value in the cell was
' greater than the string "0"
'So the following values would be > "0"
' ABC
' 54
' ;asd
'And the following values would not be > "0"
' (ABC)
' $523 (assuming that was as text, and not just 523 formatted as currency)
'If c.Value > "0" Then
'I suspect you are trying to test whether the cell is numeric
' and greater than 0
If IsNumeric(c.Value) Then
If c.Value > 0 Then
'This is only copying the cell and the *three* cells
' to the left of it
'.Range("O" & c.Row & ":R" & c.Row).Copy
'This will copy the cell and the *four* cells
' to the left of it
'.Range("N" & c.Row & ":R" & c.Row).Copy
'wsO.Cells(5 + IRow, 12).PasteSpecial Paste:=xlPasteValues
'But this would avoid the use of copy/paste
wsO.Cells(5 + IRow, 12).Resize(1, 5).Value = _
.Range("N" & c.Row & ":R" & c.Row).Value
IRow = IRow + 1
End If
End If
Next
End With
LetsContinue:
Application.ScreenUpdating = True
Application.CutCopyMode = False
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
I am trying to copy all worksheets, one at a time, and pasting into a new worksheet. These files come from multiple third parties so the worksheets can vary. I'm running into a problem below when trying to determine last row Lrow and last column Lcol because an error appears saying Object doesn't support this property or method. I do plan on submitting this to my work so any help with error proofing or general macro tips are appreciated.
Sub ws_copy()
Dim Lrow As Long
Dim Lcol As Long
Dim Pasterow As Long
Dim WSCount As Integer
Dim i As Integer
'On Error Resume Next
'Application.DisplayAlerts = False
i = Application.InputBox(prompt:="Enter the place order of first tab to be copied.", Title:="Worksheet Consolidation", Type:=1)
If IsEmpty(i) = True Then
Exit Sub
Else
If IsNumeric(i) = False Then
MsgBox "Enter a numeric value."
Else
If IsNumeric(i) = True Then
Worksheets.Add(before:=Sheets(1)).Name = "Upload"
WSCount = Worksheets.Count
For i = i + 1 To WSCount
Lrow = Worksheets(i).Find("*", After:=Cells(1, 1), _
LookIn:=xlFormulas, _
Lookat:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Lcol = Worksheets(i).Find("*", After:=Cells(1, 1), _
LookIn:=xlFormulas, _
Lookat:=xlPart, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Pasterow = Lrow + 1
Workbook.Worksheets(i).Range(Cells(1, 1), Cells(Lrow, Lcol)).Copy
Workbook.Worksheets("Upload").Cells(Pasterow, 1).Paste
Next i
Else
Exit Sub
End If
End If
End If
'On Error GoTo 0
'Application.DisplayAlerts = False
End Sub
A common way to find the last row/column is:
With Worksheets(i)
Lrow = .Cells(.Rows.Count, 1).End(xlUp).Row
Lcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
hth
Based on the comment that:
I can't assume any one column or row has the last piece of data because of the variety of the files received.
You should look at using the UsedRange property of the Worksheet (MSDN). UsedRange expands as more data is entered onto the worksheet.
Some people will avoid using UsedRange because if some data has been entered, and then deleted then UsedRange will include these 'empty' cells. The UsedRange will update itself when the workbook is saved. However, in your case, it doesn't sound like this is a relevant issue.
An example would be:
Sub Test()
Dim wsSource As Worksheet
Dim wsTarget As Worksheet
Dim rngSource As Range
Dim rngTarget As Range
Set wsSource = ThisWorkbook.Worksheets("Sheet1")
Set wsTarget = ThisWorkbook.Worksheets("Sheet2")
Set rngSource = wsSource.UsedRange
rngSource.Copy Destination:=wsTarget.Cells
End Sub
Here is a method of finding the last used row and last used column in a worksheet. It avoids the issues with UsedRange and also your issues of not knowing which row might have the last column (and which column might have the last row). Adapt to your purposes:
Option Explicit
Sub LastRowCol()
Dim LastRow As Long, LastCol As Long
With Worksheets("sheet1") 'or any sheet
If Application.WorksheetFunction.CountA(.Cells) > 0 Then
LastRow = .Cells.Find(what:="*", after:=[A1], _
LookIn:=xlFormulas, _
searchorder:=xlByRows, _
searchdirection:=xlPrevious).Row
LastCol = .Cells.Find(what:="*", after:=[A1], _
LookIn:=xlFormulas, _
searchorder:=xlByColumns, _
searchdirection:=xlPrevious).Column
Else
LastRow = 1
LastCol = 1
End If
End With
Debug.Print LastRow, LastCol
End Sub
Although the basic technique has been long used, Siddarth Rout, some time ago, posted a version adding COUNTA to account for the case where the worksheet might be empty -- a useful addition.
If you want to merge data on each sheet into one MasterSheet, run the script below.
Sub CopyRangeFromMultiWorksheets()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim CopyRng As Range
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the sheet "RDBMergeSheet" if it exist
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("RDBMergeSheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a worksheet with the name "RDBMergeSheet"
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "RDBMergeSheet"
'loop through all worksheets and copy the data to the DestSh
For Each sh In ActiveWorkbook.Worksheets
If sh.Name <> DestSh.Name Then
'Find the last row with data on the DestSh
Last = LastRow(DestSh)
'Fill in the range that you want to copy
Set CopyRng = sh.Range("A1:G1")
'Test if there enough rows in the DestSh to copy all the data
If Last + CopyRng.Rows.Count > DestSh.Rows.Count Then
MsgBox "There are not enough rows in the Destsh"
GoTo ExitTheSub
End If
'This example copies values/formats, if you only want to copy the
'values or want to copy everything look at the example below this macro
CopyRng.Copy
With DestSh.Cells(Last + 1, "A")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
'Optional: This will copy the sheet name in the H column
DestSh.Cells(Last + 1, "H").Resize(CopyRng.Rows.Count).Value = sh.Name
End If
Next
ExitTheSub:
Application.Goto DestSh.Cells(1)
'AutoFit the column width in the DestSh sheet
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Function LastRow(sh As Worksheet)
On Error Resume Next
LastRow = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
End Function
Function LastCol(sh As Worksheet)
On Error Resume Next
LastCol = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
End Function
Also, see the link below for some other options to do this slightly differently.
http://www.rondebruin.nl/win/s3/win002.htm
My query is if I insert row using a button, it should also add serial numbers to the rows like 1,2,3 etc...
I have the below code here in Sheet1 of the worksheet for adding the serial numbers when I add rows
Private Sub Worksheet_Change1(ByVal Target As Range)
Dim StartNum As Integer
Dim FirstCell As Integer
Dim LastCell As Integer
StartNum = 2
FirstCell = 3
LastCell = 17
Application.EnableEvents = False
Do While FirstCell <= LastCell
Range("B" & FirstCell).Value = StartNum
FirstCell = FirstCell + 1
StartNum = StartNum + 1
Loop
Range("B" & LastCell + 1).Value = ""
Application.EnableEvents = True
End Sub
The below code is written in module1 to insert rows with formula of A1 copied to new rows
Sub Macro2()
Rows("2:2").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Range("B1:D1").Select
Selection.AutoFill Destination:=Range("B1:D2"), Type:=xlFillDefault
Range("B1:D2").Select
End Sub
Now my Question is how to call the private sub from the Module Macro2 code while inserting rows
Any suggestions, waiting for your replies at the earliest.
Like I mentioned you do not need the Worksheet_Change code for this. Paste the below code in a module and try it..
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long
'~~> Set this to the relevant sheet
Set ws = Sheets("Sheet1")
With ws
'~~> Insert at row 2
.Rows(2).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
'~~> Autofill B1:D1 to C1:D2
.Range("B1:D1").AutoFill Destination:=.Range("B1:D2"), Type:=xlFillDefault
'~~> Find the last row
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
'~~> Renumber the cells in Col B
For i = 1 To lRow
.Range("B" & i).Value = i
Next i
End With
End Sub
FOLLOWUP
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long, j As Double
'~~> Set this to the relevant sheet
Set ws = Sheets("Sheet1")
With ws
'~~> Insert at row 2
.Rows(2).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
'~~> Autofill B1:D1 to C1:D2
.Range("B1:D1").AutoFill Destination:=.Range("B1:D2"), Type:=xlFillDefault
'~~> Find the last row
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
'~~> Renumber the cells in Col B 1,1.1,1.2,1.3 etc
j = 1
For i = 1 To lRow
.Range("B" & i).Value = j
j = j + 0.1
Next i
End With
End Sub