In my workbook I frequently need to activate some sheets by using their CodeName then search for some texts within that sheet and use the row or column number of the cell that contains the text I'm looking for.
In that situations, I am using below kind of codes:
Sheet16.Select '(Using codename)
Cells.Find(What:="FIRST TEXT I'M LOOKING FOR", After:= _
ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
FirstRow= ActiveCell.Row
Cells.Find(What:="SECOND TEXT I'M LOOKING FOR", After:= _
ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
SecondRow = ActiveCell.Row
Rows(FirstRow & ":" & SecondRow + 1).EntireRow.Hidden = False
Eveything works well, but nowadays I am trying to improve my codes and I'd like to run my codes faster.
Now,
1- How can I reference my WorkSheets' CodeName easily?
(I'm looking for answer like ThisWorkbook.Worksheets("Sheet1") - not a function
Dim wb as Workbook, ws as Worksheet
set wb = ThisWorkbook
set ws = wb.CodeName(Sheet16) or wb.Sheet16 or sheet16
'then
ws.Cells.Find(What .......... rest of the code ...... )
none of them working for CodeName property.
Fully reference a worksheet by codename or Referencing sheets in another workbook by codename using VBA didn't answer my question.
2- How can I avoid using .Activate to use the result cell of Cells.Find() formula.
Again in that example I firstly search for specific text, which is :="FIRST TEXT I'M LOOKING FOR" in the first part of my code, and then I need to use that cell to get it's row number or use offset or anything , and because of that I feel myself obligated to use .Activate because,
FirstRow = Cells.Find(What:="FIRST TEXT I'M LOOKING FOR", After:= _
ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Row
kind of codes do not work as well. How to avoid using Select in Excel VBA macros here in that answer there are couple of suggestions but none of them helps me in this case. I tried to get an answer from the owner of this answer to avoid any duplicate question but he suggested me to ask a new question. (And as long as both of my questions belong to my example code and I'll connect them, I asked them together in one question.)
While setting a sheet variable to the codename, the limitation is you can use the codename in ThisWorkbook only i.e. the workbook which contains the code.
Consider this code...
Dim ws As Worksheet
Set ws = wsData 'where wsData is the CodeName of a sheet.
Now in your code you can manipulate or perform actions on ws sheet without activating or selecting it.
Actually in case of CodeNames, you don't need to declare a sheet variable, you can directly refer to the sheet by using it's codename irrespective of which sheet is currently active.
like...
wsData.Cells.Clear
Set Rng = wsData.Range("A1").CurrentRegion
e.g. with your another example code
Dim ws As Worksheet
Set ws = wsData 'where wsData is the CodeName of a sheet.
FirstRow = ws.Cells.Find(What:="FIRST TEXT I'M LOOKING FOR", After:= _
ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Row
'Or just (without declaring the ws sheet variable where wsData is the sheet code name)
FirstRow = wsData.Cells.Find(What:="FIRST TEXT I'M LOOKING FOR", After:= _
ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Row
Related
I am using Find method to bring the cell value from another workbook.
The code below brings the value. But I wanted to erase Activate methods, so just using Block Statements with Find method to bring values from another workbook.
'Windows(wb_name).Activate
'Sheets("SheetA").Select
'Set rg =Worksheets("SheetA").Range("C:C")
'With rg
'value1 = Cells.Find(What:="11693", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False,
SearchFormat:=False).Value
'End With
For clarifying, what exactly I want; in values1 = Cells.Find ...I changed Cells to rg but it doesnt work. I want to know why? Also I see it unnecessary to use activate . I want to write a code where I will get rid of Activate another workbook. So, just by giving source wb and ws names and range to look for the value
Try the next way, please:
Sub FindInOtherSheet()
Dim Value1 As String, rg As Range
Set rg = Workbooks("W1.xlsx").Worksheets("SheetA").Range("C:C")
With rg
Value1 = .cells.Find(What:="11693", After:=.cells(1, 1), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, _
SearchFormat:=False).value
End With
End Sub
It starts searching after the first cell of the range. ActiveCell does not have sense in a not activated sheet...
Edited:
As an example to clarify your question about the Find "problem" of not returning any error in case of no any match, I would state that this should be considered an advantage.
You can simple check if the function returned a range in this simple way (I will use the above code to exemplify):
Sub FindInOtherSheet()
Dim Value1 As String, rg As Range, fndCell as Range
Set rg = Workbooks("W1.xlsx").Worksheets("SheetA").Range("C:C")
With rg
set fndCell = .cells.Find(What:="11693", After:=.cells(1, 1), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, _
SearchFormat:=False)
'check if Find returned a range:
If not fndCell is Nothing Then 'if a match has been found
Value1 = fndCell.value
Else
MsgBox "No match has been found...": Exit Sub
End If
End With
End Sub
VBA noob. Script to search input data, match criteria, go into existing spreadsheet, copy to latest row, and then go back to original input workbook to repeat.
I can get everything working with absolute paths (ie "Book1.csv") but I will have to replace these every time I run the macro with a new input data workbook. Pretty sure I have the dim/set part figured out but every time I call the Windows().Activate I always get subscript out of range. Code:
Dim wb1 As Workbook
Set wb1 = ThisWorkbook
' Search Title column (B) for match
Cells.Find(What:="A154L-T031-#1590", After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
' Select date and copy
ActiveCell.Offset(0, 1).Range("A1:Q1").Copy
' Activate and select correct sheet in NCRP spreadsheet and then select row after latest data
Windows("Approach_North.xlsx").Activate
Worksheets("T031").Activate
Range("T1048576").End(xlUp).Select
' Select row below it and paste
ActiveCell.Offset(1, 0).Range("A1").Select
ActiveSheet.Paste
' To repeat have to go back to the original data sheet
Windows(wb1).Activate
ActiveCell.Select
Selection.Font.Bold = True
The debugger lands on Windows(wb1).Activate.
Any help what doing wrong?
No need for select/activate:
Dim f As Range
Set f = Cells.Find(What:="A154L-T031-#1590", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not f Is Nothing Then
f.Copy Workbooks("Approach_North.xlsx").Worksheets("T031").Cells(Rows.Count, "T").End(xlUp).Offset(1, 0)
f.Bold = True
End If
I am not experienced in VBA coding.
My VBA code:
Search = InStr(ActiveCell.NumberFormat, Chr(128))
Selection.Find(What:=Search, After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
It searches and activates the cells which include the € symbol. It works only if I manually define my selection range.
When I try inserting ActiveSheet.Range("H:H").Select to make column H my selection (which is my goal), the code stops working.
The problem is in the ActiveCell, which is changing depending on what you are selecting. Try like this, you should get lucky:
Option Explicit
Sub TestMe()
Dim Search As String
ActiveSheet.Range("H:H").Select
Search = CStr(Chr(128))
Selection.Find(What:=Search, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Select 'or .Activate
End Sub
Once you feel a bit better with recording macros, you may try to avoid ActiveSheet, Selection and ActiveCell:
How to avoid using Select in Excel VBA
This code found the cell with the Greek Euro format in the range A1:A6 on Sheet1 in the workbook containing the code (ThisWorkbook).
The cell must hold a value (to find blanks change "*" to "").
Sub Test()
Dim rRangeToSearch As Range
Dim rFoundRange As Range
Set rRangeToSearch = ThisWorkbook.Worksheets("Sheet1").Range("A1:A6")
Application.FindFormat.Clear
Application.FindFormat.NumberFormat = "#,##0.00 [$€-408]"
Set rFoundRange = rRangeToSearch.Find(What:="*", SearchFormat:=True)
If Not rFoundRange Is Nothing Then
MsgBox "Greek Euro format found in cell " & rFoundRange.Address
End If
End Sub
No idea why [$€-408] denotes Greek.
Im trying to make excel search for a text string in a specific column in a specific worksheet that is not the active worksheet. VBA gives me an error that says i cannot use this method of selection. so my question is, do you have a suggestion to do it in another way?
Worksheets("Parts for renovation").Columns("Q:Q").Select
Set cell = Selection.Find(What:="Total transfer price", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If cell Is Nothing Then
Exit Sub
Else
Worksheets("Internal").Cells(29, 4) = Worksheets("Parts for Renovation").ActiveCell.Offset(0, 4)
End If
There is no need to select anything there:
With Worksheets("Parts for renovation").Columns("Q:Q")
Set cell = .Find(What:="Total transfer price", After:=.Cells(1), LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If cell Is Nothing Then
Exit Sub
Else
Worksheets("Internal").Cells(29, 4) = Cell.Offset(0, 4)
End If
End With
Your error comes, because you select a range on a non-active worksheet. This is one of the reasons, why you should be avoiding select in general.
However, if you want to make your code working (which is strongly not advisable), you may consider selecting the worksheet before selecting the range:
Worksheets("Parts for renovation").Select
Columns("Q:Q").Select
For the advisable part, try to avoid the usage of "Select" -
How to avoid using Select in Excel VBA
How do I modify this line in VBA to only select the columns that have values?
Set rng = Range("A1", Range("A65536").End(xlUp)).SpecialCells(xlCellTypeVisible)
I don't think I'm doing something right since the CountLarge property is several billion cells
Here is a sample of my data
#SiddharthRout Yes I only need the rows that have data. I think I have it working now with End(xlToLeft) from #JMax ... Now that I'm iterating over the cells, I can just quit the For each loop once the last row is reached. I might have this working now. – makerofthings7 14 mins ago
For this neither you need .SpecialCells nor do you need to loop through the rows :)
Here is a sample code. This will copy all the rows which have data to Sheet2 (TRIED AND TESTED)
Sub Sample()
Dim ws As Worksheet
Dim rng As Range
Dim LastRow As Long, LastCol As Long
Set ws = Sheets("Sheet1")
With ws
LastRow = .Cells.Find(What:="*", After:=.Range("A1"), Lookat:=xlPart, _
LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False).Row
LastCol = .Cells.Find(What:="*", After:=.Range("A1"), Lookat:=xlPart, _
LookIn:=xlFormulas, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, _
MatchCase:=False).Column
With .Range("A1:" & Split(Cells(, LastCol).Address, "$")(1) & LastRow)
.AutoFilter Field:=1, Criteria1:="<>"
Set rng = ws.AutoFilter.Range
rng.Offset(1, 0).Resize(rng.Rows.Count - 1).Copy _
Destination:=Sheets("Sheet2").Range("A1")
End With
End With
End Sub
SNAPSHOT
I am assuming that all cells in a particular row will have data and there won't be a case like this
#makerofthings7: I think I know what exactly you are trying to do :) you don't need to use loops to achieve what you want. Just a quick question. Is it possible that say Cell C10 might have a value but B10 might not? – Siddharth Rout 12 mins ago
If there is then we will have to set the autofilter criteria accordingly.
Edit:
WAY 2
The other way would be to sort your data, pushing the blanks way down and then copying the resulting range :)
HTH