Loop Through First Nonempty Cell to Last Nonempty Cell - excel

I am trying to loop through the first occurrence of a cell up to some unknown last nonempty cell. For example.
I know how to find the last and first nonempty cell but how can I put
them in a loop?
With Worksheets("AssignedTickets").Columns("F")
Set test = .Find(what:="*", after:=.Cells(1, 1), LookIn:=xlValues)
End With

Here is a couple of techniques:
Sub LoopThroughCells()
Dim c As Range, Target As Range, rFirst As Range, rLast As Range
Dim x As Long, y As Long
With Worksheets("Sheet1").Cells
Set rLast = .Find(What:="*", _
After:=.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False)
Set rFirst = .Find(What:="*", _
After:=rLast, _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
With .Range(rFirst, rLast)
Debug.Print "For Each c In .Cells"
For Each c In .Cells
If x <> c.Row Then Debug.Print
x = c.Row
Debug.Print c.Value,
Next
Stop
Debug.Print
Debug.Print "For x = 1 To .Rows.Count"
For x = 1 To .Rows.Count
Debug.Print
For y = 1 To .Columns.Count
Debug.Print .Cells(x, y),
Next
Next
End With
End With
End Sub
Note: A For Each Loop to iterates over a range row by row (e.g. All cells in Rows(1) then all the cells in Rows(2) ..etc.).
UPDATE:
Selecting the range starting from the first used cell and last used cell; without using find.
With Worksheets("Sheet1")
With .Range(.Range("C1").End(xlDown), .Range("C" & Rows.Count).End(xlUp))
For Each c In .Cells
If x <> c.Row Then Debug.Print
x = c.Row
Debug.Print c.Value,
Next
End With
End With

Related

VBA loop selection.find

I want to loop or find multiple value in another sheets. My code doesn't work even after I do..loop the code.
For i = 1 To lastrowBAU
Worksheets(fname).Range("A1:A" & lastrowsheet).Select
Do Until Cell Is Nothing
Set Cell = Selection.find(What:=ThisWorkbook.Worksheets("BAU").Range("A" & i).Value, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
MatchCase:=False)
If Not Cell Is Nothing Then
Cell.Activate
ActiveCell.Copy
ActiveCell.Insert Shift:=xlShiftDown
ActiveCell.Offset(1, 0).Select
Selection.Replace What:=ThisWorkbook.Worksheets("BAU").Range("A" & i).Value, _
replacement:=ThisWorkbook.Worksheets("BAU").Range("B" & i).Value, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False
Set Cell = Worksheets(fname).Range("A1:A" & lastrowsheet).FindNext(Cell)
End If
Loop
Next i
You need to set the cell before entering the loop
Set cell = rngSrc.Find(sA, LookIn:=xlFormulas, LookAt:=xlPart, _
After:=rngSrc.Cells(rngSrc.Cells.Count), SearchOrder:=xlByRows, MatchCase:=False)
If Not cell Is Nothing Then
however you also need to avoid an endless loop by checking if the search has returned to the first one found.
Option Explicit
Sub macro1()
Dim ws As Worksheet, wsBAU As Worksheet
Dim cell As Range, rngSrc As Range
Dim fname As String, lastrow As Long, lastrowBAU As Long
Dim i As Long, n As Long, first As String
Dim sA As String, sB As String
fname = "Sheet1"
With ThisWorkbook
Set ws = .Sheets(fname)
Set wsBAU = .Sheets("BAU")
End With
With ws
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rngSrc = .Range("A1:A" & lastrow)
End With
With wsBAU
lastrowBAU = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
With ws
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rngSrc = .Range("A1:A" & lastrow)
End With
' search and replace
Application.ScreenUpdating = False
For i = 1 To lastrowBAU
sA = wsBAU.Cells(i, "A")
sB = wsBAU.Cells(i, "B")
Set cell = rngSrc.Find(sA, LookIn:=xlFormulas, LookAt:=xlPart, _
After:=rngSrc.Cells(rngSrc.Cells.Count), SearchOrder:=xlByRows, MatchCase:=False)
If Not cell Is Nothing Then
first = cell.Address
Do
' insert cell above
cell.Insert xlDown
cell.Offset(-1).Value2 = cell.Value2
cell.Value2 = Replace(cell.Value2, sA, sB)
' expand search range
n = n + 1
Set rngSrc = ws.Range("A1:A" & lastrow + n)
' find next
Set cell = rngSrc.FindNext(cell)
Loop While cell.Address <> first
End If
Next
Application.ScreenUpdating = True
MsgBox n & " replacements", vbInformation
End Sub

Insert new row based on the cell text in column C

I am trying to add a blank row if the cell values under column C is "Confirm". Is this possible?
I want the macro to add blank rows below until the last active row of the sheet if it finds "Confirm" under column C.
regards,
Arjun T A
Option Explicit
Sub blankAfterConfirm()
Dim rng As Range, fnd As Range, addr As String
With Worksheets("sheet3").Range("C:C")
Set rng = .Find(what:="confirm", After:=.Cells(1), MatchCase:=False, _
LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, SearchFormat:=False)
If Not rng Is Nothing Then
addr = rng.Address(0, 0)
Set fnd = rng
Do
Set fnd = Union(fnd, rng)
Set rng = .FindNext(After:=rng)
Loop Until addr = rng.Address(0, 0)
fnd.Offset(1, 0).EntireRow.Insert
End If
End With
End Sub
Edited.
Dim x As Long, lRow As Long
lRow = Sheet1.Cells(Rows.Count, 3).End(xlUp).Row
For x = lRow To 2 Step -1
If Cells(x, 3).Value = "Confirm" Then
With Cells(x, 3).Offset(1).EntireRow
.Insert Shift:=xlDown
.ClearFormats
End With
End If
Next x

Using Excel's find and searching by 2 strings

I need your help,
Is it possible to search an Excel spreadsheet based on 2 given values, as opposed to just 1? similar to that of an "AND" operator?
Here's what I have so far, but I guess if your looking for a needle in a hay stack:
Str = "apples" AND "oranges"
With Sheets(xSheet)
Set foundCell = .Cells.Find(What:=Str, After:=.Cells(1, 1), _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
End With
The code below returns the wanted result:
Sub TestMe()
Dim str As String: str = "apples*oranges"
Dim foundCell As Range
Dim options As Variant
options = Array(str, Split(str, "*")(1) & "*" & Split(str, "*")(0))
Dim myVar As Variant
For Each myVar In options
With Worksheets(1)
Set foundCell = .Cells.Find(What:=myVar, After:=.Cells(1, 1), _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
End With
If Not foundCell Is Nothing Then Exit For
Next myVar
If Not foundCell Is Nothing Then
Debug.Print foundCell.Address
End If
End Sub
We have two different strings that need to be seaerched for: "apples*oranges" and "oranges*apples". The split and the reverse is done pretty primitively:
options = Array(str, Split(str, "*")(1) & "*" & Split(str, "*")(0))
And then, using a For Each Loop with an early Exit For, the .Find() searches for the two strings.
Here is a simple loop alternative:
Sub ApplesAndOranges()
Dim r As Range, fruits As Range
Set fruits = Nothing
For Each r In ActiveSheet.UsedRange
v = r.Value
If v <> "" Then
If InStr(v, "apples") <> 0 And InStr(v, "oranges") <> 0 Then
If fruits Is Nothing Then
Set fruits = r
Else
Set fruits = Union(fruits, r)
End If
End If
End If
Next
MsgBox fruits.Address(0, 0)
End Sub
From the example, you see it returns all cells that contain both sub-strings.

Find cell with value, offset and copy range then paste basing data's date, then loop to findnext

With th following Excel Sheet.
I'm trying to do the following:
Find the cell with Value, let's say "Sam", in range("B17:B25")
Offset(0,5).resize(,8).copy
Find the Date value of the Data row, and paste Data to range("B4:M4") according to the data's Date.
Loop to find next.
Here is what I got so far, don't know how to loop:
Sub getDat()
Dim myFind As Range
Dim pasteLoc As Range
Dim payee, pasteMon As String
Range("B5:M12").ClearContents
With Sheet3.Cells
payee = Range("B2").Text
Set myFind = .Find(What:=payee, After:=Range("B16"), LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
If Not myFind Is Nothing Then
myFind.Offset(0, 3).Resize(, 8).Copy
pasteMon = myFind.Offset(0, 1).Text
With Range("B4:M4")
Set pasteLoc = .Find(What:=pasteMon, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
If Not pasteLoc Is Nothing Then
pasteLoc.Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=True
End If
End With
End If
End With
End Sub
Here is simplified version (not tested)
Sub getDat()
Range("B5:M12").ClearContents
Dim c As Range, r As Range
For Each c in Range("B16").CurrentRegion.Columns(1).Cells
If c = Range("B2") Then
Set r = Range("B4:M4").Find(c(, 2))
If Not r Is Nothing Then
r(2).Resize(8) = Application.Transpose(c(, 4).Resize(, 8))
End If
End If
Next
End Sub
Something like this For loop would work as well:
Sub getDat()
Dim payee As String
Dim lastrow As Long
lastrow = Cells(Rows.Count, "B").End(xlUp).Row
payee = Range("B2").Value
Range("B5:M12").ClearContents
For x = 17 To lastrow
If Cells(x, 2).Value = payee Then
For y = 2 To 13
If Cells(4, y).Value = Cells(x, 3).Value Then
Range("E" & x & ":L" & x).Copy
ActiveSheet.Range(Cells(5, y), Cells(12, y)).PasteSpecial Transpose:=True
Exit For
End If
Next y
End If
Next x
End Sub

Using the Find Function in VBA

1
2
3
4
.
.
So I have a sequence of numbers running from 1-20. I have the number "1" on top selected and I would like to search the entire column and find the number "9". The code works when I don't name the range "rng"; it finds the number and selects. But the code stops working when I name the range of number. What's wrong with the range function? could it be that if I define Dim rng as Range that when I later define the "Set rng=" I cannot have the ".Select" or ".Copy" extension on the end?
Sub macro2()
Dim rng As Range
Set rng = Range(ActiveCell, ActiveCell.End(xlDown)).Select
rng.Find(10).Select
End Sub
Also, If I want to sum the entire column from 1-20, on the last cell below the number "20" should I use the following code? because the application object doesn't seem to do it. Thank you!
rng.End(xlDown).Offset(1, 0).Select
Application.WorksheetFunction.Sum (rng.Value)
To look for 10 in the active column you could try this (which ends up selecting the first 10 - although Select in vba isn't normally needed other than taken the user to location at code end)
test that the found range exists (ie you can find 10 before proceeding)
you should also use xlWhole to avoid matching 100 if the current default for [lookAt] is xlPart
using search [After] as Cells(1, ActiveCell.Column , and [Search Direction] as xlNext finds the first value looking down.
code
Sub QuickFind()
Dim rng1 As Range
Set rng1 = ActiveCell.EntireColumn.Find(10, Cells(1, ActiveCell.Column), xlFormulas, xlWhole, , xlNext)
If Not rng1 Is Nothing Then
Application.Goto rng1
Else
MsgBox "10 not found"
End If
End Sub
Part 2
Sub Other()
Dim rng1 As Range
Set rng1 = Range(Cells(1, ActiveCell.Column), Cells(Rows.Count, ActiveCell.Column).End(xlUp))
rng1.Cells(rng1.Cells.Count).Offset(1, 0) = Application.WorksheetFunction.Sum(rng1.Value)
End Sub
Try this, I hope this will help u to find the specific row no as well as column name too. In code you can use
strRw = FindColumn(Sheet name, "Value which need to be found", True, "Cell Name",Row number)
sourceCOL = colname(FindColumn(Shee Name, "Value which need to be found", False, , 4))
Below is main function of find
Public Function FindColumn(colnocountWS As Worksheet, srcstr As String, Optional rowflag As Boolean, Optional bycol As String, Optional strw As Integer, Optional stcol As Integer) As Integer
Dim srcrng As Range 'range of search text
Dim srcAddr As String 'address of search text
Dim stcolnm As String
colnocountWS.Activate
If stcol <> 0 Then stcolnm = colname(stcol)
If stcol = 0 Then stcolnm = "A"
If strw = 0 Then strw = 1
colnocountWS.Range(stcolnm & strw).Select
If ActiveSheet.Range(stcolnm & strw) = srcstr Then
ActiveSheet.Range(stcolnm & strw).Select
FindColumn = 1
Else
If bycol = "" Then
Set srcrng = colnocountWS.Cells.Find(Trim(srcstr), after:=ActiveCell, LookIn:=xlValues _
, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Else
Set srcrng = colnocountWS.Cells.Find(Trim(srcstr), after:=ActiveCell, LookIn:=xlValues _
, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
End If
'ByPart
If srcrng Is Nothing Then
If bycol = "" Then
Set srcrng = colnocountWS.Cells.Find(Trim(srcstr), after:=ActiveCell, LookIn:=xlValues _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Else
Set srcrng = colnocountWS.Cells.Find(Trim(srcstr), after:=ActiveCell, LookIn:=xlValues _
, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
End If
End If
If srcrng Is Nothing Then
FindColumn = 0
Exit Function
Else
srcAddr = srcrng.Address
colnocountWS.Range(srcAddr).Select
FindColumn = ActiveCell.Column
If rowflag = True Then FindColumn = ActiveCell.Row
End If
End If
End Function
'this function find column name
Public Function colname(iFinalCol1 As Integer) As String
Dim colnm As String
On Error GoTo gg
If Mid(Cells(1, iFinalCol1).Address, 3, 1) = "$" Then
colnm = Mid(Cells(1, iFinalCol1).Address, 2, 1)
Else
colnm = Mid(Cells(1, iFinalCol1).Address, 2, 2)
End If
gg: colname = colnm
End Function

Resources