I use the following formula in excel
=AVERAGEIFS(B4:B440;A4:A440;"<"&A441;A4:A440;">"&EDATE(A441;-6))
to get the average of a range of values, based on the values in an adjacent column. However I need to apply this formula for more than a thousand dates (column A contains dates). I have a macro, which asks the user to specify sheet name and date (using dialog boxes). So I would like to add some code, that takes the date specified by the user and replaces cell A441 from the above formula with it. Then copy the average, so that I can paste it where desired. Here is what I tried coding so far, with no success:
Sub Find()
Dim FindString As Date
Dim Sumact As Range
Dim Analyst As Double
Dim shname As String
Do Until WorksheetExists(shname)
shname = InputBox("Enter sheet name")
If Not WorksheetExists(shname) Then MsgBox shname & " doesn't exist!", vbExclamation
Loop
Sheets(shname).Select
FindString = InputBox("Enter a Search value")
If Trim(FindString) <> "" Then
With Sheets(shname).Range("A:A")
Set Sumact = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Sumact Is Nothing Then
Application.Goto Sumact, True
Else
MsgBox "Nothing found"
End If
End With
End If
Set Analyst = Application.AverageIf(Range(("B:B"), ("A:A")), "<Sumact")
Selection.Copy
End Sub
You do not Set a variable unless you are setting an object like the cell returned by the Range.Find method. Assigning a double to a var should be simply equal (e.g. =).
Sub Make_AVERAGEIFS()
Dim FindString As Date
Dim Sumact As Range
Dim Analyst As Double
Dim shname As String
Dim d As Integer, m As Integer, y As Integer
Do Until WorksheetExists(shname)
shname = InputBox("Enter sheet name")
If Not WorksheetExists(shname) Then MsgBox shname & " doesn't exist!", vbExclamation
Loop
With worksSheets(shname)
.Activate
FindString = InputBox("Enter a Search value")
If Trim(FindString) <> "" Then
With .Range("A:A")
Set Sumact = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Sumact Is Nothing Then
Application.Goto Sumact, True
Else
MsgBox "Nothing found"
End If
End With
End If
If IsDate(Sumact) Then
d = Day(Sumact): m = Month(Sumact): y = Year(Sumact)
Analyst = Application.AverageIfs(.Columns(2), _
.Columns(1), "<" & DateSerial(y, m, d), _
.Columns(1), ">" & DateSerial(y, m - 6, d))
End If
End With
Selection.Copy
End Sub
I suppose that searching for the date in column A is one way to check that the user has input a valid date but there must be other, less complicated methods. The IsDate Function that I have used above is one.
Related
I want the macro below transferred to a UDF but I do not know how.
I want a udf where I select the Findstring and return it in the cell where is place the udf.
Can someone help me?
Sub Find_pipe()
Dim Findstring As String
Dim Location As String
Dim Rng As Range
Sub Find_First()
Dim Findstring As String
Dim Rng As Range
Findstring = InputBox("vul naam van leiding in")
If Trim(Findstring) <> "" Then
With Sheets("scenario 1V2").Range("A1:BP150")
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.Offset(1), True
Application.Goto ThisWorkbook.Worksheets("D en L berekening").Range("A1"), True
ThisWorkbook.Worksheets("D en L berekening").Range("U10").Value = Rng.Offset(1).Value
Else
MsgBox "Nothing found"
End If
End With
End If
End Sub
Try this:
Function FindPipe(Findstring As String)
Application.Volatile 'You need this if your UDF needs to update after changes in
' the search range
Dim f As Range
If Trim(Findstring) <> "" Then
With ThisWorkbook.Sheets("scenario 1V2").Range("A1:BP150")
Set f = .Find(What:=Findstring, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
End With
If Not f Is Nothing Then
FindPipe = f.Offset(1).Value
Else
FindPipe = "Not found"
End If
Else
FindPipe = ""
End If
End Function
Note the range to be searched is hard-coded in the UDF, so Excel doesn't know to recalculate your UDF if the search range is updated. I added Application.Volatile to take care of that but it may slow your workbook if you have a lot of formulas pointing to that UDF.
I would like to find a cell in a worksheet containing a specific string.
I won't know precisely how many columns or rows there will be in the spreadsheet, hence why I wanted to do it with CurrentRegion.
This is what I was trying:
=FIND("Data String", Range("A1").CurrentRegion)
You should have a look into the Microsoft References: Range.Find Method (Excel).
.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
Example:
Dim rngFound as Range
With Worksheets("MySheetName").Cells
Set rngFound = .Find("MySearchString", LookIn:=xlValues)
If Not rngFound Is Nothing Then
'something is found
else
'nothing found
End If
End With
searches the whole sheet
Try This
FindString = Sheets("Sheet1").Range("D1").Value
---------- This will select the next Cell in range with the inputbox value
Sub Find_First()
Dim FindString As String
Dim Rng As Range
FindString = InputBox("Enter a Search value")
If Trim(FindString) <> "" Then
With Sheets("Sheet1").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
End If
End Sub
Find Value
I am putting together a attendance sheet for my workplace. Its going to be partly automated, when a user enters his phone number in the input box his attendance is marked for the day, there is also a input box for the date i.e. just the date not month and year.
Structure of the excel sheet: 2 columns have name and phone number respectively and rest are 1-31 days of the month.
so when a user enter a phone number and date a P (for present) appears under the date column in the same row as the phone number.
Problem : the cell that is being selected by the code is the header which has the dates from 1-31
where am i going wrong?
Please Help.
Thank You
Sub Find_mobilenumber()
Dim FindString As String
Dim FindString1 As String
Dim Rng As Range
FindString = InputBox("Enter Your Mobile Number")
FindString1 = InputBox("Enter todays Date - e.g 21 for 21/03/2015")
If Trim(FindString) <> "" Then
If Trim(FindString1) <> "" Then
With Sheets("Sheet1").Range("D:D") 'searches all of column D
With Sheets("Sheet1").Range("7:7") 'searches all of column 7
Set Rng = .Find(What:=FindString1, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Application.Goto Rng, True 'value found
If Cell.Value = FindString Goto
MsgBox "Client Checked In"
Else
MsgBox "Client Not Registered" 'value not found
End If
End With
End With
End If
End If
End Sub
Rather than nesting With...End With statements, you can break the search into two easier-to-describe steps: (1) Finding the appropriate row, and (2) Finding the appropriate column. Let's say your design looks like this:
You could adjust your script to populate the "Present" table like so:
Option Explicit
Public Sub Find_mobilenumber()
Dim strMobileNumber As String, strDayOfMonth As String
Dim rngMobileNumbers As Range, rngDaysOfMonth As Range, rng As Range
Dim lngTargetRow As Long, lngTargetCol As Long
Dim wks As Worksheet
'Set references
Set wks = ThisWorkbook.Worksheets("Sheet1")
'Collect mobile number and day of month from user
strMobileNumber = CStr(InputBox("Enter Your Mobile Number"))
strDayOfMonth = CStr(InputBox("Enter todays Date - e.g 21 for 21/03/2015"))
'Stop the script if input is blank
If Trim(strMobileNumber) = "" Or Trim(strDayOfMonth) = "" Then
Call ClientNotRegistered
Exit Sub
End If
'Find the appropriate row by matching mobile number
Set rngMobileNumbers = wks.Range("D:D")
Set rng = rngMobileNumbers.Find(What:=strMobileNumber, LookAt:=xlWhole)
If rng Is Nothing Then
Call ClientNotRegistered
Exit Sub
End If
lngTargetRow = rng.Row
'Find the appropriate column by matching day of month number
Set rngDaysOfMonth = wks.Range("7:7")
Set rng = rngDaysOfMonth.Find(What:=strDayOfMonth, LookAt:=xlWhole)
If rng Is Nothing Then
Call ClientNotRegistered
Exit Sub
End If
lngTargetCol = rng.Column
'Write a "P" in the resulting cell
wks.Cells(lngTargetRow, lngTargetCol) = "P"
MsgBox "Client Checked In"
End Sub
'DRY solution for not found
Public Sub ClientNotRegistered()
MsgBox "Client Not Registered"
End Sub
You start a With block here, but do nothing with it
With Sheets("Sheet1").Range("D:D")
I presume this is where you meant to check the D column for mobile numbers?
How about this revision?
Sub Find_mobilenumber()
Dim FindString As String
Dim FindString1 As String
Dim PhoneRng As Range
Dim Rng As Range
FindString = InputBox("Enter Your Mobile Number")
FindString1 = InputBox("Enter todays Date - e.g 21 for 21/03/2015")
If Trim(FindString) <> "" Then
If Trim(FindString1) <> "" Then
With Sheets("Sheet1").Range("D:D") 'searches for phone no in column D
Set PhoneRng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
End With
With Sheets("Sheet1").Range("7:7") 'searches all of column 7
Set Rng = .Find(What:=FindString1, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
End With
On Error GoTo ErrorHandler
Intersect(Rng.EntireColumn, PhoneRng.EntireRow).Value = "P"
MsgBox ("Client Checked In")
End If
End If
Exit Sub
ErrorHandler:
MsgBox ("Client Not Registered")
End Sub
I am trying to write a macro that will prompt the user to enter a value and do the following:
- Search for the value in column B and select the first cell where the value is found
- Return the correspondong value in column L and M of the selected cell's row within a message box
- Then once the user hits "ok", the macro will find and select the next cell in column B with the search criteria, and repeat the above steps
- Once all of the cells with the search criteria in column B have been searched and found, a message box will communicate that all matches have been found and close loop
Below is the code I have started out with, and being a beginner with VB, I can't figure out why my loop isn't working correctly... Please help!
Sub Macro1()
Dim response As String, FndRow As Long, NoMatch As Boolean, LastRow As Long
response = InputBox("Please enter the Column Name to find matching Source File Field Name.")
If response = "" Then Exit Sub
On Error Resume Next
Range("B5").Select
NoMatch = False
LastRow = 0
Do Until NoMatch = True
FndRow = Cells.Find(What:=response, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Row
If FndRow = 0 Then
MsgBox response & " could not be found."
NoMatch = True
ElseIf FndRow < LastRow Then
MsgBox "All " & response & " matches have been found."
NoMatch = True
Else
Range("B" & FndRow).Select
MsgBox "Source File Name: " & Range("L" & FndRow).Value & vbNewLine & "File Column Name: " & Range("M" & FndRow).Value
LastRow = FndRow
End If
Loop
End Sub
I would use a filter instead of a find loop:
Sub tgr()
Dim rngVis As Range
Dim VisCell As Range
Dim sFind As String
sFind = InputBox("Please enter the Column Name to find matching Source File Field Name.")
If Len(Trim(sFind)) = 0 Then Exit Sub 'Pressed cancel
Application.ScreenUpdating = False
With Intersect(ActiveSheet.UsedRange, ActiveSheet.Columns("B"))
.AutoFilter 1, sFind
On Error Resume Next
Set rngVis = .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
.AutoFilter
End With
Application.ScreenUpdating = True
If rngVis Is Nothing Then
MsgBox sFind & " could not be found."
Else
For Each VisCell In rngVis.Cells
MsgBox "Source File Name: " & VisCell.Worksheet.Cells(VisCell.Row, "L").Text & vbNewLine & _
"File Column Name: " & VisCell.Worksheet.Cells(VisCell.Row, "M").Text
Next VisCell
End If
End Sub
your Find is acting strangely because you are looking for match 'horizontally'. You need to use SearchOrder:=xlByColumns
FndRow = Cells.Find(What:=response, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Row
I am trying to use a text box and command button to search my entire workbook for a specific word or value. For example, "3132" or "Work Instructions". So far I am able to search the sheet that I am on but I cannot search the rest of the workbook. Plus, some of the worksheets are hidden. Any insight to this would be beneficial and help me out a ton! I have listed my currect program below:
Private Sub CommandButton6_Click()
Dim strFindWhat As String
strFindWhat = TextBox1.Text
On Error GoTo ErrorMessage
Cells.Find(What:=strFindWhat, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False).Select
Exit Sub
ErrorMessage:
MsgBox ("The data you are searching for does not exist")
End Sub
Have a good one!
Try something like this, which uses FindNext method while looping over the Sheets in the Workbook.
Sub FindLoopSheets()
Dim srchString$
Dim w As Integer
Dim wsName As String
Dim rng As Range
Dim fndRange As Range
Dim nxtRange As Range
srchString = Application.InputBox("Enter the value to search for", "Search Query")
If srchString = vbNullString Then
MsgBox "No value entered.", vbInformation
Exit Sub
End If
For w = 1 To Sheets.Count
With Sheets(w)
wsName = .Name
Debug.Print "Beginning search on " & wsName
Set rng = .Cells.Find(What:=srchString, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False)
If Not rng Is Nothing Then
Set fndRange = rng
Do
Set nxtRange = .Cells.FindNext(After:=fndRange)
Debug.Print Sheets(w).Name & "!" & nxtRange.Address
Set fndRange = nxtRange
Loop Until fndRange.Address = rng.Address
Else:
Debug.Print srchString & " was not found on " & wsName
End If
End With
Next w
End Sub
You need to loop through the array of worksheet objects in the workbook.worksheets collection.