Clear different range of data in multiple worksheets - excel

I have a workbook that is used as a template to fill in data. The data is cleared and the workbook is reused.
The workbook has multiple worksheets and the range that needs to be cleared is different in every worksheet.
Let's say I want to clear the data in the range A10:Y50, I put value "Start" in the cell Z10, as a starting point to clear data. "Start" is located in different cell in every worksheet.
The code is clearing data based on the "Start" located in the first worksheet and not independently for each worksheet.
Sub TestReset()
Dim sht As Worksheet
For Each sht In ActiveWorkbook.Sheets
If sht.Name <> "Sheet1" And sht.Name <> "Sheet2" Then '
Dim iRow As Long, iMax As Long
iRow = Cells.Find(What:="start", LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Row
iMax = Cells(iRow, "A").End(xlDown).Row
sht.Range("A" & iRow & ":AY" & iMax).ClearContents
End If
Next sht
End Sub

As #Tony Dallimore mentioned in his comment you need to specify in what sheet you are looking for specific cells (if you dont specify it it assumes you are looking in ActiveSheet). So it is always best to specify with what sheet you work. It is good to use With statement for that. When you use With then it is enough to use only dot "."
Sub TestReset()
Dim sht As Worksheet
For Each sht In ActiveWorkbook.Sheets
With sht
If .Name <> "Sheet1" And .Name <> "Sheet2" Then '
Dim iRow As Long, iMax As Long
iRow = .Cells.Find(What:="start", LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Row
iMax = .Cells(iRow, "A").End(xlDown).Row
.Range("A" & iRow & ":AY" & iMax).ClearContents
End If
End with
Next sht
End Sub

Also use Dim iRow as Long before for each loop... But here is added example of how you can manage sheets to skip (Create sheet "Setup" and in cell A1 add name to skip, for example Sheet1, in cell A2 add Sheet2 and it should do the trick.
Sub WorkInUnSpecifiedSheets()
Dim xRng As Range
'sheet "Setup" must exist and Range A1 contains name of sheet to skip, current region might not work on some PCs. But it is simple
Set xRng = ThisWorkbook.Sheets("Setup").Range("A1").CurrentRegion
'you can also use another method to specify range... Named ranges for example or using last row and last column...
Dim sht As Worksheet
For Each sht In ActiveWorkbook.Sheets 'i would recommend using ThisWorkbook or Workbook variable instead of Active
If xRng.Find(What:=sht.Name, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False) Is Nothing Then
'your code to work in unspecified sheets
End If
Next sht
End Sub

Related

Replace the Cell Value throughout the Entire Workbook

I am using FndRplce() that code which replaces fnd = "Ilya Malikzada" with rplc = "Arham" throughout the entire workbook.
But how to create such a code which works like: When i change any name from the below attached picture that effect should apply on entire workbook.
For example "Ilya Malikzada" A2 has this first name so when i write on cell A2 Arham then wherever is "Ilya Malikzada" on entire workbook should replace with Arham.
your help will be much appreciated. Thanks
Sub FndRplce()
Dim sht As Worksheet
Dim fnd As Variant
Dim rplc As Variant
Dim ReplaceCount As Long
fnd = "Ilya Malikzada"
rplc = "Arham"
For Each sht In ActiveWorkbook.Worksheets
ReplaceCount = ReplaceCount + Application.WorksheetFunction.CountIf(sht.Cells, "*" & fnd & "*")
sht.Cells.Replace what:=fnd, Replacement:=rplc, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
Next sht
End Sub
If you want the name input to be a variable you can reference the cell specifically to do so. Just make it obvious so the user knows that's the input. I use Cell A1, but you can adjust this and the sheet name accordingly. This reference can be a excel-named reference as well as long as you keep it within it's quotes
The adjustment I made was to your rplc line like so
ActiveWorkbook.Sheets("YourSheetName").Range("A1").Value
Sub FndRplce()
Dim sht As Worksheet
Dim fnd As Variant
Dim rplc As Variant
Dim ReplaceCount As Long
fnd = "Ilya Malikzada"
rplc = ActiveWorkbook.Sheets("YourSheetName").Range("A1").Value
For Each sht In ActiveWorkbook.Worksheets
ReplaceCount = ReplaceCount + Application.WorksheetFunction.CountIf(sht.Cells, "*" & fnd & "*")
sht.Cells.Replace what:=fnd, Replacement:=rplc, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
Next sht
End Sub

Selecting a range until the last used row

I am trying to select a range until the last used row in the sheet. I currently have the following:
Sub Select_Active_Down()
Dim lr As Long
lr = ActiveSheet.UsedRange.Rows.Count
If Cells(ActiveCell.Row, ActiveCell.Column) = Cells(lr, ActiveCell.Column) Then
MsgBox "There isn't any data to select."
Else
Range(Cells(ActiveCell.Row, ActiveCell.Column), Cells(lr, ActiveCell.Column)).Select
Cells(lr, ActiveCell.Column).Activate
End If
End Sub
The issue is that I need to select multiple columns, and this will only select the first column of the active range. How can I modify this to select multiple columns rather than just the first?
What about selection the entire region? This can be done as follows in VBA:
Selection.CurrentRegion.Select
There also is the possibility to select the entire array. For that, just press Ctrl+G, choose Special and see over there.
I would do this slightly different. I would use .Find to find the last row and the last column (using the same logic shown in the link) to construct my range rather than using Selection | Select | ActiveCell | UsedRange | ActiveSheet.
Is this what you are trying?
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim rng As Range
'~~> Change it to the relevant sheet
Set ws = Sheet1
With ws
'~~> Check if there is data
If Application.WorksheetFunction.CountA(.Cells) = 0 Then
MsgBox "No Data Found"
Exit Sub
End If
'~~> Find last row
LastRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
'~~> Find last column
LastColumn = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
'~~> Construct your range
Set rng = .Range(.Cells(1, 1), .Cells(LastRow, LastColumn))
'~~> Work with the range
With rng
MsgBox .Address
'
'~~> Do what you want with the range here
'
End With
End With
End Sub

Find function in Excel VBA only refers to newly created sheet

I have been racking my brain on a bug whereby VBA seems to be using the wrong sheet within a Find function. For purposes such as printing the name of the sheet and values within cells, VBA refers to the sheet I expect. But for the Find function, it reverts to the most recently created sheet and I cannot force a reference to any other sheet. Below is an example that illustrates the problem. The lastRow variable gets assigned based on the Find function from the newly created sheet (three row) whereas the sht variable refers to the five row sheet.
Option Explicit
Dim wb As Workbook
Sub start()
Set wb = ThisWorkbook
Call make5RowSheet
Call make3RowSheet
Call CountRows5RowSheet
End Sub
Sub CountRows5RowSheet()
Dim thing As Variant
Dim sht As Worksheet
Dim lastRow As Long
For Each thing In wb.Worksheets
If LCase(thing.Name) = LCase("five rows") Then Set sht = thing
Next thing
With sht
lastRow = Cells.Find(What:="*", _
After:=.Range("A1"), _ '!!! .range here should refer to five row sheet, but lastRow gets set to 3
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
End With
Debug.Print "sheet name: " & sht.Name 'prints "five rows" as expected
Debug.Print "Cell(3,3) value: " & sht.Cells(3, 1).Value 'blank, as expected
Debug.Print "cell(5,5) value: " & sht.Cells(5, 1).Value 'prints "foo", as expected
Debug.Print "last Row: " & lastRow 'prints 3, which is puzzling
End Sub
Sub make5RowSheet()
Dim sht As Worksheet
Set sht = wb.Worksheets.Add
sht.Name = "five rows"
sht.Cells(5, 1) = "foo"
End Sub
Sub make3RowSheet()
Dim sht As Worksheet
Set sht = wb.Worksheets.Add
sht.Name = "three rows"
sht.Cells(3, 1).Value = "foo"
End Sub
Here
With sht
lastRow = Cells.Find(What:="*", _
Cells is not tied to sht so it refers to the ActiveSheet
With sht
lastRow = .Cells.Find(What:="*", _
should fix things
Your Cells.Find will be executed on whatever sheet is active.
In your case, the last sheet that was created is three rows.
So to avoid this hassle, make sure you Activate the right sheet right before you Find.
sht.Activate ' move from (three rows) to (five rows)
With sht
lastRow = Cells.Find(What:="*", _
After:=.Range("A1"), _ '!!! .range here should refer to five row sheet, but lastRow gets set to 3
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
End With

Copy multiple sheets to one single sheet based on the sheet's content in VBA

I have an Excel workbook which contains more than 50 sheets. I need to copy every sheet that contains "Seasoned Passthrough OAS" and paste it to the sheet whose name is "BC-Summary". How can I achieve this by VBA?
This should get you started, not sure what all you'd want to copy to the summary so I just used a2-z100.
Sub test()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "BC-Summary" Then
Set cFind = ws.Cells.Find(What:="Seasoned Passthrough OAS", After:=ws.Range("A1"), LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
If Not cFind Is Nothing Then
ws.Range("A2:Z100").Copy
Sheets("BC-Summary").Range("A" & Sheets("BC-Summary").Range("A" & Rows.Count).End(xlUp).Row + 1).PasteSpecial xlPasteValues
End If
End If
Next ws
End Sub

VBA find and replace skipping some cells

I have a bit of code that finds blanks in a given column and replaces them with "BLANK", this has worked fine in the past and works for all of the sheets I am looking at bar one.
In the 'meter' sheet the whole column is blank, yet the find and replace fills all bar 6 of the blanks with no apparent pattern as below. I expect this could be another of my Monday morning 'user malfunction' errors but would appreciate any insight.
I am aware this would be better in a loop, which I will write once I've fixed the problem of it missing some blanks.
Cheers
Public Function FILL_blanks() '''' this searches for blanks
'in the columns in the raw data we are interested in and replaces
'them with BLANK there is a value assigned to BLANK in the flag matrix.
Dim LastRow_g As Long '''' HYDRANT, NODE ---->CHANGES LENGTH FOR EACH ASSET
Dim LastRow_j As Long ''''
Dim LastRow_bp As Long ''''
Dim WS_Count As Integer
Dim i As Integer
WS_Count = ActiveWorkbook.Worksheets.Count
For i = 1 To WS_Count
If ActiveWorkbook.Worksheets(i).Name = "hydrant" Then
Worksheets(i).Select
Range("g4").Select ' this will change j/g/bp only
LastRow_g = Range("g" & Rows.Count).End(xlUp).Row 'define the last row as all of the rows in DMA flag column
Range("r4:r" & LastRow_g).Select
'find and replace below
Selection.Replace What:="", Replacement:="BLANK", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
ElseIf ActiveWorkbook.Worksheets(i).Name = "meter" Then
Worksheets(i).Select
Range("j4").Select
LastRow_j = Range("j" & Rows.Count).End(xlUp).Row 'define the last row
Range("y4:y" & LastRow_j).Select
'find and replace below
Selection.Replace What:="", Replacement:="BLANK", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
I would use Sub here rather than Function because there doesn't seem to be a return. This code replaces blank cells in the columns specified above:
Option Explicit
Sub FillBlanks2() '''' this searches for blanks
Dim LastRow As Long '''' HYDRANT, NODE ---->CHANGES LENGTH FOR EACH ASSET
Dim Sheet As Worksheet
Dim TargetRange As Range
'loop through worksheets in this workbook
For Each Sheet In ThisWorkbook.Worksheets
If Sheet.Name = "hydrant" Then '<~ concerned with col G on hydrant sheet
With Sheet
LastRow = .Range("G" & .Rows.Count).End(xlUp).Row
Set TargetRange = .Range(.Cells(4, 7), .Cells(LastRow, 7))
End With
'apply replacement to the target range
TargetRange.Replace What:="", Replacement:="BLANK", LookAt:=xlWhole, SearchOrder:=xlByRows
ElseIf Sheet.Name = "meter" Then '<~ concerned with col J on hydrant sheet
With Sheet
LastRow = .Range("J" & .Rows.Count).End(xlUp).Row
Set TargetRange = .Range(.Cells(4, 10), .Cells(LastRow, 10))
End With
'apply replacement to the target range
TargetRange.Replace What:="", Replacement:="BLANK", LookAt:=xlWhole, SearchOrder:=xlByRows
End If
Next Sheet
End Sub
I adapted the code from Dan Wagner to account for cells that appear blank but actually have spaces in them. if the cells are only likely to contain a blank or one space then it is possible to use "" and " ".
However, I am sure there is a more elegant solution that accounts for all blank spaces. SpecialCells(xlCellTypeBlanks) is a possibility but it appears to be limited to a certain number of rows.
Sub FILL_blanks() '''' this searches for blanks
Dim LastRow As Long '''' HYDRANT, NODE ---->CHANGES LENGTH FOR EACH ASSET
Dim Sheet As Worksheet
Dim TargetRange As Range
Sheets("Sheet1").Select
LastRow = Range("a" & Rows.Count).End(xlUp).Row
Set TargetRange = Range("b4:b" & LastRow)
'apply replacement to the target range
'"" accounts for true blank cells (no spaces)
' "*" is a wildcard and accounts for one or more spaces
TargetRange.Replace What:="", replacement:="BLANK", LookAt:=xlWhole, SearchOrder:=xlByRows
TargetRange.Replace What:=" ", replacement:="BLANK", LookAt:=xlWhole, SearchOrder:=xlByRows
End Sub
Thanks again for your assistance

Resources