VBA - Find next empty row - vba

Good day, I am newbie in VBA programming. need some help from experts :)
After i enter the date and click the generate button the code will find the date on the excel, but im done with this problem and here are my codes..
Dim Rng As Range
Dim FindDate As Date
FindDate = txtDate.Value
If Trim(FindDate) <> "" Then
With Sheets("Sheet2").Range("B:B")
Set Rng = .Find(What:=FindDate, After:=.Cells(.Cells.Count), LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True)
If Not Rng Is Nothing Then
Application.Goto Rng, True
Else
MsgBox "Nothing found"
End If
End With
End If
My next problem is, i need to select the empty cell next to the date.. Here is a screen shot

To answer your specific question, the simplest way would be:
Rng.Offset(, 1).Select
However, you ought to be aware that the Find() function when using dates can be a little unreliable. See this post for more info and links: VBA, goto cell with a certain value (type: date). Your case is particularly exposed to risk as the date is entered via a TextBox.
I have to say your code looks awfully similar to the OP's of that post. You really ought to credit code sources if you didn't write it yourself.
If I were you, I'd convert your textbox value to a Long and then search the cell values (using the .Value2 property which provides date values as Longs) for the matching Long. Code isn't much longer and could look like this:
Dim src As Range
Dim findDate As Date
Dim findVal As Long
Dim cell As Range
'Define the source data range
With Sheet2
Set src = .Range(.Cells(1, "B"), .Cells(.Rows.Count, "B").End(xlUp))
End With
'Acquire search date and convert to long
findDate = CDate(UserForm1.txtDate.Value)
findVal = CLng(findDate)
'Search for date
For Each cell In src.Cells
If cell.Value2 = findVal Then
Application.Goto cell, True
'Select the next cell to the right
cell.Offset(, 1).Select
End If
Next

you could
use a Function to try returning the wanted range
Function SetRange(FindDate As Date) As Range
If Trim(FindDate) <> "" And IsDate(FindDate) Then
With Sheets("Sheet2") '<--| reference wanted sheet
With .Range("B1", .cells(.Rows.Count, 2).End(xlUp)) '<--| reference its column "B" range from row 1 down to last not empty row
On Error Resume Next '<--| if subsequent 'Find()' avoid possible subsequent statement error to stop the Function
Set SetRange = .Find(What:=FindDate, After:=.cells(.cells.Count), LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True).Offset(, 1) '<--| try finding the passed 'FindDate' in referenced range and offset 1 column to the right
End With
End With
End If
End Function
and have your "Main" sub check it against Nothing before using it:
Option Explicit
Sub Main()
Dim Rng As Range
Set Rng = SetRange(txtDate.Text)
If Not Rng Is Nothing Then Rng.Select
End Sub

Related

Search Todays date in column and select cell

I found a code but I don't why it is not working, I'm barely new to VBA. Please help me..
What I am trying to achieve is I need to Search the day today from another wb.
Here's my complete code:
Sub Sample
Sheets("Database").Select
Dim i as Workbook
Dim c as Workbook
Set i = Workbooks("Workbook1.xlsm")
Set c = Workbooks.Open(FileName:=Range("U2").Value)
'U2 contains the link or path of the file.
ThisWorkbook.Activate
Sheets("Summary").Activate
Windows("Workbook1").Activate
Sheets("Database").Select
Workbooks(2).Activate
Sheets("Summary").Select
Dim FindString As Date
Dim Rng As Range
FindString = CLng(Date)
With Sheets("Summary").Range("A:A")
Set Rng = .Find(What:=FindString, After:=.Cells(.Cells.Count), LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlbyColumns, SearchDirection;=xlNext,MatchCase;=False)
If Not Rng Is nothing then
Application.Goto Rng, True
Else
Msgbox "Nothing Then"
End if
End with
End Sub
The other workbook that was recently opened contains Summary Sheet that has Dates on Column A:A
If you're getting a syntax error - the two parameters are defined with semi-colons ";" instead of colons ":"
SearchDirection;=xlNext,MatchCase;=False
becomes
SearchDirection:=xlNext,MatchCase:=False
Fix your syntax before testing - Use Debug | Compile
Activating and Selecting is not necessary and harmful
There are also some syntax errors
You may want to re-start from the following code:
Sub Sample
Dim dbSheet as Worksheet
Dim Rng As Range
Set dbSheet = Workbooks("Workbook1.xlsm").Sheets("Database") 'set the “database” worksheet
With Workbooks.Open(FileName:=dbSheet.Range("U2").Value).Sheets("Summary") 'open the workbook whose link is in “database” sheet cell U2 and reference its “Summary” sheet
With .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)) ' reference referenced sheet column A cells from row 1 down to last not empty row
Set Rng = .Find(What:=CLng(Date), After:=.Cells(.Rows.Count), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False) ' try finding current date starting from the cell at the top of referenced range
End With
End With
If Not Rng Is nothing then
Application.Goto Rng, True
Else
Msgbox "Nothing Then"
End if
End Sub
This code is untested but from the explanations in comments you can tweak it to reach the goal

Auto Populate Formula to end of series in excel

I am having an issue with a piece of VBA in excel and am looking for assistance.
I require a piece of code to auto populate a formula in excel through a series of data, the series will vary in length and will occupy columns C:I.
I have been using this piece of code without issue for quiet a while:
Sub Auto_Fill_Formula()
Sheets("Sheet1").Select
Dim LstRow As Long
With Sheets("Sheet1")
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
.Range("A2:A" & LastRow).Formula = "Formula added here"
Application.CutCopyMode = False
End With
End Sub
However as the formula is being added to the leftmost column it only populates the first cell, cell A2.
How can I modify this code to work when the leftmost column is empty?
Thank you,
Wayne
You can use Find to find the last used row in C:I by searching backwards from row 1. You should also use Option Explicit to pick up typos in variable names (LstRow).
Sub Auto_Fill_Formula()
Sheets("Sheet1").Select
Dim LastRow As Long, r As Range
With Sheets("Sheet1")
Set r = .Range("C:I").Find(What:="*", After:=.Range("C1"), Lookat:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, MatchCase:=False, SearchFormat:=False)
If Not r Is Nothing Then
LastRow = r.Row
.Range("A2:A" & LastRow).Formula = "Formula added here"
End If
End With
End Sub

Use the Find function in VBA to find the first value above the active cell?

I am trying to get the row number of the result of a find function, I am using the following.
Set FindRow = ThisWorkbook.Sheets("Schedule").Range(ActiveCell.Address & ":n" & Sheets("Schedule").Cells(ActiveSheet.Rows.Count, 1).End(XlUP).Row).Find(What:="Assembly", SearchDirection:=xlPrevious, MatchCase:=False)
Msgbox (FindRow.Row)
This works fine but returns the last cell in the range that has the value in it.
If I alter the Search Direction to XlNext, this returns the next cell below with the value in it.
I would like it to search above the active cell for the next value.
Think you just need to specify the After parameter. Edit - on reflection depending on active cell the range you are searching could be any size so you need to explain what you mean by "above the active cell".
Sub x()
Dim FindRow As Range, r As Range
With ThisWorkbook.Sheets("Schedule")
Set r = .Range(ActiveCell.Address & ":N" & .Cells(.Rows.Count, 1).End(xlUp).Row)
Set FindRow = r.Find(What:="Assembly", after:=r(r.Cells.Count), SearchDirection:=xlNext, MatchCase:=False)
End With
If Not FindRow Is Nothing Then MsgBox (FindRow.Row)
End Sub

Search again if not found

So I have a part in my macro that I want to add what I assume needs to be an "Else" portion, but I am not that good with macros and am asking for help.
Range("Z1").Copy
Dim FindString As String
Dim Rng As Range
FindString = Sheets("Pull").Range("Y1").Value
If Trim(FindString) <> "" Then
With Sheets("HourTracker").Range("A:A")
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Application.Goto Rng, True
Else
MsgBox "Nothing found"
End If
End With
ActiveCell.Offset(0, 1).Activate
Selection.PasteSpecial xlPasteValues
Application.DisplayAlerts = True
End If
End Sub
So what I want this to do, is instead of "MsgBox "Nothing Found"", I want it to essentially perform the same thing as above, but copy cell Z2, and search for the value of Y2 in the same sheet "HourTracker" then paste the value. I have no idea on how to accomplish this, and all my attempts have failed. Any help would be much appreciated. Let me know if you need more clarification, thank you in advance!!!
Sounds to me like you're looking for a loop.
Sub findStuff()
Application.DisplayAlerts = False
' The item you want to paste
Dim PasteString As String
' The item you're looking for
Dim FindString As String
' The range that may containing FindString
Dim Rng As Range
' The variable used to loop through your range
Dim iCounter as Long
' loop through the first cell in column Y to the last used cell
For iCounter = 1 To Sheets("Pull").Cells(Rows.Count, 25).End(xlUp).Row
' PasteString = the current cell in column Z
PasteString = Sheets("Pull").Cells(iCounter, 26).Value
' FindString = the current cell in column Y
FindString = Sheets("Pull").Cells(iCounter, 25).Value
If Trim(FindString) <> "" Then
With Sheets("HourTracker").Range("A:A")
' Find the cell containing FindString
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
' There's no need to activate/ select the cell.
' You can directly set the value with .Value
Rng.Offset(0, 1).Value = PasteString
Else
' Do nothing
End If
End With
Else
' Do nothing
End If
Next
Application.DisplayAlerts = True
End Sub
Every time the compiler hits Next it will start again at For but raise the value of iCounter by 1. We can use Cells to accomplish this since Cells takes the row and column arguments as numbers, not strings (like Range). The syntax is simply Cells(Row #, Column #). Therefore, every time the For . . . Next loops around again, iCounter will go up by one and you'll search in the next row.
Instead of using .Paste, you can set the value of a cell directly with .Value. Pasting is pretty slow and using .Value is much faster.
Cells().End(xlUp).Row is a method used to find the last used cell in a range. See Error in finding last used cell in VBA for a much better explanation than I can give here.

VBA, goto cell with a certain value (type: date)

I have code as follow:
Sub Find_First()
Dim FindString As String
Dim Rng As Range
FindString = Range("A1")
If Trim(FindString) <> "" Then
With Sheets("Kalendarz").Range("A5:LY5")
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Application.Goto Rng, True
Else
MsgBox "Nothing found"
End If
End With
End If
End Sub
but it doesn't work with date format, any suggestion?
More details: In A1 cell I will enter a date, In 5. row I have a list of every day in 2016. I want to (after run macro) go to cell with date from cell A1.
Using the Find function to locate a date is notoriously tricky in Excel VBA. The function relies on your search date being formatted in the same way as Excel's default setting. In addition, you need to ensure that the search string is converted to a date within the Find function, using CDate. Ozgrid has a good article on it: http://www.ozgrid.com/VBA/find-dates.htm
I have amended your code below to accommodate those requirements and added an extra With Sheets... statement to ensure the FindString uses the Range from your target sheet.
However, because of the unpredictability of users' adjusting date formats, I prefer a VBA loop, using Value2 which is Excel's numerical representation of the date, so cannot be fiddled with. The Ozgrid article prefers not to use VBA loops when a Find function is so much faster, but I guess it's a matter of personal preference and I feel a bespoke loop is more reliable.
Up to you which one you want to go with.
The Find method:
Sub Find_First()
Dim FindString As String
Dim Rng As Range
With Sheets("Kalendarz")
FindString = .Range("A1")
If Trim(FindString) <> "" Then
With .Range("A5:LY5")
Set Rng = .Find(What:=CDate(FindString), _
After:=.Cells(1), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Application.Goto Rng, True
Else
MsgBox "Nothing found"
End If
End With
End If
End With
End Sub
The VBA loop method:
Sub Find_First_VBA_Loop()
Dim dateVal As Long
Dim cell As Range
With Sheets("Kalendarz")
dateVal = .Range("A1").Value2
For Each cell In .Range("A5:LY5").Cells
If dateVal = cell.Value2 Then
Application.Goto cell, True
Exit For
End If
Next
End With
End Sub