I am very new with programming and I am trying to finish a small Project for my Company. I am trying to write a code that loops through a range and for every cell.value greater than 0 it will find corresponding excel sheet and execute the specific code. Thank you!
Sub test()
Dim rng As Range, cell As Range
Set rng = Range("B3:B53")
For Each cell In rng
If cell > 0 Then
SheetName = ThisWorkbook.Sheets(cell.Value)
ThisWorkbook.Sheets(SheetName).Select
ActiveWindow.SelectedSheets.PrintOut Copies:=1
Range("E4:P50").Select
Selection.ClearContest
End If
Next cell
End Sub
Try
If cell > 0 Then
dim ws as worksheet
set ws = ThisWorkbook.Sheets(cell.Value)
ws.PrintOut Copies:=1
ws.Range("E4:P50").ClearContest
End If
Try:
Sub test()
Dim rng As Range, Cell As Range
Dim ws As Worksheet
Set rng = Sheets(1).Range("B3:B53")
On Error Resume Next
For Each Cell In rng
If Cell.Value > 0 Then
Set ws = Sheets(Cell.Value)
If Not ws Is Nothing Then
With ws
.PrintOut Copies:=1
.Range("E4:P50").ClearContents
End With
End If
End If
Next Cell
End Sub
Hopefully this is what you are looking for..
A simple code
Dim cell As Range
Dim cell2 As Range
Dim cell3 As Range
Set cell = Cells.Find(What:="Your Value", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Set cell2 = Cells.Find(What:="Your Value", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Set cell3 = Cells.Find(What:="Your Value", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If cell Is Nothing Then
'Your code
Else
'Your code
End If
If cell2 Is Nothing Then
'Your code
Else
'Your code
End If
If cell3 Is Nothing Then
'Your code
Else
'Your code
End If
You can add more cell values by setting its variables.
Please let us know if you have any query..
Related
I am using userforms to input data, at a certain point part of the data is copied to one of the sheets in the workbook.
My code then needs to use one of the values in the sheet to check if this value apears on another sheet, if it does it copies values linked to that value to the original sheet and then populates the userform so that further info can be captured.
If I activate on error resume next everything works except the tab function stops working on the userform, if I run it without on error resume next, I get run-time error:
'91' Object variable or with block variable not set.
How do i fix this?
Sub Find_7_day()
Dim vfind
Dim rng As Range
Sheets("Test Data").Select
Sheets("Test Data").Range("$E$3").Select
vfind = ActiveCell
'On Error Resume Next
Call Sheet
Set rng = Cells.Find(What:=vfind, After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False).Activate
If ActiveCell = vfind Then
Call Old_7_day
Call Form_7_day_fill
Else
Sheets("Test Data").Select
End If
End Sub
You can't declare and .Activate a variable range at the same time:
Dim rng As Range
Set rng = Cells.Find(What:=vfind, After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False).Activate
suggestion, avoid using .Select and Activate, explanation here How to Avoid the Select Method in VBA & Why
Code:
Sub Find_7_day()
Dim vfind As String
Dim rng As Range
vfind = Sheets("Test Data").Range("$E$3").Value
Call Sheet
Set rng = Cells.Find(What:=vfind, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=True, _
SearchFormat:=False)
If rng Is Nothing Then
MsgBox vfind & " " & "dont exist"
Exit Sub
End If
If rng.Value = vfind Then
Call Old_7_day
Call Form_7_day_fill
Else
Sheets("Test Data").Select
End If
Exit Sub
End Sub
I am trying to create a macro in excel VBA, that searches the Range (B1:B30) of the value of the ActiveCell in Column “B” by a loop. Along with the search of Column, I also want to check if the date’s cell is colored with a particular color. If the date's cell equals the set color "Good", then I want it to change the color of the cell in Column H of the same row as selected to red.
When I run the code, I get an error message of “Run-time error ‘424’: Object required.” When I go to debug the problem, it highlights the .Find function I have and points to the last line of the search which is “SearchFormat:=False).Activate” What should I do to fix this problem?
Any improvement with my overall code will be very much appreciated.
Sub Find()
Dim FirstAddress As String
Dim MySearch As Variant
Dim Rng As Range
Dim I As Long
MySearch = Array(ActiveCell)
With Sheets("Sheet1").Range("B1:B30")
For I = LBound(MySearch) To UBound(MySearch)
Set Rng = .Find(What:=MySearch(I), _
After:=ActiveCell, _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
SearchFormat:=False).Activate
If Not Rng Is Nothing Then
FirstAddress = Rng.Address
Do
If ActiveCell.Style.Name = "Good" Then
Rng("H" & ActiveCell.Row).Select
Rng.Interior.ColorIndex = xlColorIndexRed
End If
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
Next I
End With
End Sub
Showing the Debug mode of the run-time error.
Screenshot of the Spreadsheet for reference
Code Review:
You have several problems here.
MySearch = Array(ActiveCell) will always be a single value. So why bother looping through it
You cannot set a range to equal range.activate. Searching Sheets("Sheet1").Range("B1:B30") implies that you are searching a worksheet other that the ActiveSheet. If this is the case than .Find(After:=Activecell) suggests that you are looking for a value after the ActiveCell of another worksheet.
Set Rng = .Find(What:=MySearch(I), _
After:=ActiveCell, _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
SearchFormat:=False).Activate
Rng("H" & ActiveCell.Row) Rng is a Range object. It doesn't work like Range. You cannot pass it a cell address. You can do this Rng(1,"H") which is really shorthand for Rng.cells(1,"H") bit that is misleading because Rng is in column 2 Rng(1,"H") will reference the value in column I.
Sub Find()
Dim FirstAddress As String
Dim MySearch As Variant
Dim Rng As Range
Dim I As Long
MySearch = ActiveCell 'This is the ActiveCell of the ActiveSheet not necessarily Sheets("Sheet1")
With Sheets("Sheet1").Range("B1:B30")
Set Rng = .Find(What:=MySearch, _
After:=.Range("B1"), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
SearchFormat:=False)
If Not Rng Is Nothing Then
FirstAddress = Rng.Address
Do
If Rng.Style.Name = "Good" Then
.Range("H" & Rng.Row).Interior.ColorIndex = xlColorIndexRed
End If
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
End With
End Sub
UPDATE:
Here is the actual answer to your question:
Sub FindMatchingValue()
Const AllUsedCellsColumnB = False
Dim rFound As Range, SearchRange As Range
If AllUsedCellsColumnB Then
Set SearchRange = Range("B1", Range("B" & Rows.count).End(xlUp))
Else
Set SearchRange = Range("B1:B30")
End If
If Intersect(SearchRange, ActiveCell) Is Nothing Then
SearchRange.Select
MsgBox "You must select a cell in the highlighted area before continuing", vbInformation, "Action Cancelled"
Exit Sub
End If
Set rFound = SearchRange.Find(What:=ActiveCell.Value, _
After:=ActiveCell, _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
SearchFormat:=False)
If Not rFound Is Nothing Then
Do
If rFound.Style.Name = "Good" Then
Range("H" & rFound.Row).Interior.Color = vbRed
End If
Set rFound = SearchRange.FindNext(rFound)
Loop While Not rFound Is Nothing And rFound.Address <> ActiveCell.Address
End If
End Sub
You can't put Activate at the end of the findthe way you are trying to do.
Try this as you find statement.
Set Rng = .Find(What:=MySearch(I), _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False)
Rng.Activate
Then if you want to Activate the range, do that. But, it is best to stay away from Select, Activate etc in VBA code. I strongly suggest not using that last line of code and adjust you code to not rely on Select and Activate.
you may want to consider an Autofilter approach so as to loop only through relevant cells, as follows:
Option Explicit
Sub Find()
Dim cell As Range
With Sheets("Sheet1").Range("B1:B30")
.Rows(1).Insert '<--| insert a dummy header cell to exploit Autofilter. it'll be removed by the end
With .Offset(-1).Resize(.Rows.Count + 1) '<--| consider the range expanded up to the dummy header cell
.Rows(1) = "header" '<--| give the dummy header cell a dummy name
.AutoFilter field:=1, Criteria1:=ActiveCell '<--| filter range on the wanted criteria
If Application.WorksheetFunction.Subtotal(103, .Cells) > 1 Then '<--| if any cell other than "header" one has been filtered...
For Each cell In .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible) '<--| ... loop through filtered cells only
If cell.Style.Name = "Good" Then cell.Offset(, 6).Interior.ColorIndex = 3 '<--| ... and color only properly styled cells
Next cell
End If
.AutoFilter '<--| .. show all rows back...
End With
.Offset(-1).Resize(1).Delete '<--|delete dummy header cell
End With
End Sub
I would like to ask if you can help with the code below. On every sheet in my workbook there is the same kind of a table, however on each sheet the table has different location and values. I need to go through all sheets, search for table values on every sheet and then do some other operations with the values. I use Find function to determine header of the table and subsequently table range. The Find function does not work properly though as it keeps found address of "Header" cell from the first sheet for every other sheet. Is there any way to reset the found header address value before looping to another sheet? Thank you in advance.
Sub FindInDynamicRanges()
Dim wb1 As Workbook
Dim ws As Worksheet
Dim FoundCell, FoundTab, TabEntries As Excel.Range
Dim FirstAddr As String
Dim FirstRow, LastRow As Long
Set wb1 = ThisWorkbook
'Find all occurences of any table value on all sheets in dynamic ranges
For Each ws In wb1.Worksheets
Set ws = ActiveSheet
'Find "Header" cell
Set FoundCell = ws.Columns(2).Find(What:="Header", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
MsgBox FoundCell.Address
'Set number of first entry row and last entry row
FirstRow = FoundCell.Row + 1
LastRow = ws.Cells.Find(What:="*", After:=Range("A1"), LookAt:=xlPart, LookIn:=xlValues, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, MatchCase:=False).Row
ws.Range("B" & FirstRow & ":B" & LastRow).Name = "TabEntries"
MsgBox Range("TabEntries").Address
With ws.Range("TabEntries")
Set LastCell = .Cells(.Cells.Count)
End With
Set FoundTab = ws.Range("TabEntries").Find(What:="*", After:=LastCell, LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Not FoundTab Is Nothing Then
FirstAddr = FoundTab.Address
End If
Do Until FoundTab Is Nothing
'do some staff with found values
Set FoundTab = ws.Range("TabEntries").FindNext(After:=FoundTab)
If FoundTab.Address = FirstAddr Then
Exit Do
End If
Loop
Next ws
End Sub
as it keeps found address of "Header" cell from the first sheet for every other sheet.
That is because you are telling it to...
For Each ws In wb1.Worksheets
Set ws = ActiveSheet
You don't need that Set ws = ActiveSheet
When you say For Each ws, the ws is automatically initialized. So just remove the second line.
Sheets("DATA").Rows(2).Find(What:="Apple", LookIn:=xlValues, _
LookAt:=xlWhole).Offset(1, 0).Value = "=A3-B3"
Selection.FillDown
I want to find a column "Apple" in Row 2 and filldown with formula "A3-B3"
Would something like .value="=A3-B3".filldown work?
Thanks!
Further to my comments above, try this. I have commented the code. Do let me know if you find anything confusing...
Sub Sample()
Dim ws As Worksheet
Dim LRow As Long
Dim aCell As Range
'~~> Set this to the relevant sheet
Set ws = ThisWorkbook.Sheets("Data")
With ws
'~~> Find Last Row
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Find the cell which has "Apple"
Set aCell = .Rows(2).Find(What:="Apple", LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'~~> if found, then enter the formula till the last row IN ONE GO
If Not aCell Is Nothing Then
.Range(.Cells(3, aCell.Column), .Cells(LRow, aCell.Column)).Formula = "=A3-B3"
End If
End With
End Sub
I found a code online and want to make edits to it. The code is in VBA and I want the macro code to delete multiple rows rather than one. Here is the code:
Sub findDelete()
Dim c As String
Dim Rng As Range
c = InputBox("FIND WHAT?")
Set Rng = Nothing
Set Rng = Range("A:A").Find(what:=c, _
After:=Range("A1"), _
LookIn:=xlFormulas, _
lookat:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
Rng.EntireRow.Delete shift:=xlUp
End Sub
Instead of using find, use Autofilter and delete the VisibleCells
Sub findDelete()
Dim c As String, Rng As Range, wks as Worksheet
c = InputBox("FIND WHAT?")
Set wks = Sheets(1) '-> change to suit your needs
Set Rng = wks.Range("A:A").Find(c, After:=Range("A1"), LookIn:=xlFormulas, _
lookat:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
With wks
.Range(.Range("A1"), .Range("A" & .Rows.Count).End(xlUp)).AutoFilter 1, c
Set Rng = Intersect(.UsedRange, .UsedRange.Offset(1), .Range("A:A")).SpecialCells(xlCellTypeVisible)
Rng.Offset(1).EntireRow.Delete
End With
End If
End Sub
EDIT
To replace the InputBox with Multiple Values to Find / Delete Do This:
Option Explicit
Sub FindAndDeleteValues()
Dim strValues() as String
strValues() = Split("these,are,my,values",",")
Dim i as Integer
For i = LBound(strValues()) to UBound(strValues())
Dim c As String, Rng As Range, wks as Worksheet
c = strValues(i)
'.... then continue with code as above ...
Next
End Sub
Just wrap it up in a While loop.
Sub findDelete()
Dim c As String
Dim Rng As Range
c = InputBox("FIND WHAT?")
Set Rng = Nothing
Do While Not Range("A:A").Find(what:=c) Is Nothing
Set Rng = Range("A:A").Find(what:=c, _
After:=Range("A1"), _
LookIn:=xlFormulas, _
lookat:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
Rng.EntireRow.Delete shift:=xlUp
Loop
End Sub
You already have the code to delete rows in Rng.EntireRow.Delete shift:=xlUp, what you need is the code to set the range to the rows which you want to delete. As usual in VBA, this can be done in a lot of ways:
'***** By using the Rng object
Set Rng = Rows("3:5")
Rng.EntireRow.Delete shift:=xlUp
Set Rng = Nothing
'***** Directly
Rows("3:5").EntireRow.Delete shift:=xlUp
Your Find statement only finds the first occurrence of c, that's why it's not deleting more that one row.