VBA Array Formula and Goal Seek in IF Then Statement - excel

This code doesnt run. It first looks into a range, if 0 does not exist then select least negative value, by using array formula. Then goal seek to set selected cell to 0 by changing value of a cell on same row, left 4 columns. If 0 exists do nothing. Any help appreciated
Sub Test()
Dim Cel As Integer
For Each Cel In ThisWorkbook.Sheets("Sheet1").Range("V17:V57")
If Cel.Value <> 0 Then
Cel.Find(Application.WorksheetFunction.FormulaArray(MAX(IF(V17:V57<=0,V17:V57),MIN(V17:V57))))
Cel.Select
Cel.GoalSeek Goal:=0, ChangingCell:=Cel.Offset(0, -4)
End If
Next Cel
End Sub
Looks like the previous comments/responses were deleted. Here's the latest version of the code, modified as per previous responses. Still doesn't run. I removed .Activate at the end of Cel.Find. Now there's a compile Syntax error. Any help apprciated
Sub Test()
Dim Cel As Range
For Each Cel In ThisWorkbook.Sheets("Sheet1").Range("V17:V57").Cells
If Cel.Value <> 0 Then
Cel.Find(What:="MAX(IF(V17:V57<=0,V17:V57),MIN(V17:V57))", After:= _
ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
Cel.GoalSeek Goal:=0, ChangingCell:=Cel.Offset(0, -4)
End If
Next Cel
End Sub

Just delete the parentheses in your Find method.
Use:
Cel.Find What:="MAX(IF(V17:V57<=0,V17:V57),MIN(V17:V57))", After:= _
ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False
Instead of:
Cel.Find(What:="MAX(IF(V17:V57<=0,V17:V57),MIN(V17:V57))", After:= _
ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)

Related

Object variable or With block variable not set error (Find And Replace)

Here Is what i need to do :
First , I have Two sheets ("AM Production","PM Production") need to Find String "Pcs" In the each sheet and count the results then Excute macro multiple times depending on that count in both sheets (Every sheet with its own count) So i did the following : - I have Two Macros one counts pcs word in the sheet and the other excute the Second macro with that number.
Sub FindPcs()
Range("N1").Select
'Find
Cells.Find(What:="Pcs", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
'Found Nothing
'Replace
ActiveCell.Replace What:="Pcs", Replacement:="Done", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
'Copy To Above Cell
ActiveCell.Range("A1:B1").Select
Selection.Copy
ActiveCell.Offset(-1, 0).Range("A1").Select
ActiveSheet.Paste
ActiveCell.Offset(1, 0).Rows("1:1").EntireRow.Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
End Sub
The Action Macro :
Sub FindMultipleTimes()
Dim x As Integer
x = "=COUNTIF(C[10],""Pcs"")"
For i = 0 To x
Application.Run "PERSONAL.XLSB!FindPcs"
Next i
End Sub
I need to merge the two macros As The main idea is to find pcs in the "AM Production" sheet then execute Sub FindMultipleTimes() in the end when it find nothing it goes to "PM Production" and Repeat the Counting and Executing part .
Note :I tried the Range and If Nothing Method with find but it throws another error object required.
Thanks in Advance.
No need to call the macro multiple times, use a Do .. Loop Until loop.
Option Explicit
Sub FindMultipleTimes()
Dim sht
For Each sht In Array("AM Production", "PM Production")
FindPcs Sheets(sht)
Next
End Sub
Sub FindPcs(ws As Worksheet)
Dim fnd As Range, n As Long
Application.ScreenUpdating = False
With ws
Set fnd = .Cells.Find(What:="Pcs", After:=.Range("N1"), LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If Not fnd Is Nothing Then
Do
fnd.Replace What:="Pcs", Replacement:="Done", LookAt:=xlPart, _
MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
'Copy To Above Cell
fnd.Resize(1, 2).Copy fnd.Offset(-1)
fnd.EntireRow.Delete
n = n + 1
Set fnd = .Cells.FindNext
Loop Until fnd Is Nothing
End If
End With
Application.ScreenUpdating = True
MsgBox n & " found on " & ws.Name
End Sub

Highlight cells in a column from active cell down to Variable row

I would like some help finishing of this piece of code. I need to highlight cells in a column from active cell down to Variable row.
Snippet of my code:
Start = Cells.Find(What:="MEETING", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Offset(7, 0).Select
Range(ActiveCell & Stop).Select 'it is this bit that doesn't work
You rarely have to activate or select a range
Sub BrokenPiece()
Dim rStart As Range
Dim rStop As Range
Dim CompleteSelection As Range
Set rStart = Cells.Find(What:="MEETING", After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Not rStart Is Nothing Then
Set rStop = rStart.Offset(7, 0)
Set CompleteSelection = Range(rStart, rStop)
CompleteSelection.Select
End If
End Sub
If you want to find the address of the last occurrence of Note: in Columns(1).
DateStop = Columns(1).Find(What:="Note:", LookAt:=xlPart, SearchDirection:=xlPrevious, MatchCase:=False).Row - 2
You would first set your range
DateStop = Columns(1).Find(What:="Note:", LookAt:=xlPart, SearchDirection:=xlPrevious, MatchCase:=False)
Then make sure that you actually found something
If not DateStop is nothing then
Now there are to ways to get the row that you want
result = DateStop.Row -2
or
result = DateStop.Offset(-2).Row
If you choose the Offset method, you should test that DateStop.Row -2 is a valid row. In this you will not throw an error
If DateStop.Row -2 > 0 then
So let's put it together
Function DateStopRowMinus2()
Dim DateStop
Set DateStop = Columns(1).Find(What:="Note:", LookAt:=xlPart, SearchDirection:=xlPrevious, MatchCase:=False)
If Not DateStop Is Nothing Then
If DateStop.Row - 2 > 0 Then
DateStopRowMinus2 = DateStop.Offset(-2)
End If
End If
End Function
Notice when I referred to the Offset of DateStop, I didn't specify a column. That is because the Offset property takes two optional parameters
Offset([Row], [Column])
We know that they are optional because the parameters are enclosed in square brackets []. Here are some valid examples
Range("A10").Offset(2)
Range("A10").Offset(2, 0)
Range("A10").Offset(0, 2)
Range("A10").Offset(0, 2)
Range("A10").Offset(,2)
Range("A10").Offset(2, 2)

Ms Excel Replace value with the average of the previous and next values

I'm working with hourly weather data in Excel that has each hour of every day of the year along with the corresponding temperature value that was recorded.
Some of the values weren't recorded, and instead show up as just an "M" on the spreadsheet. For example, A32 = 28, A33 = M, A34 = 30. I want to replace that "M" with a formula to take the average of the previous and next values. I know how to do this manually, but I am having difficulty writing a Macro to find all the M's in the spreadsheet, then auto-replace it as stated above.
My main obstacle is getting excel to use the correct values when replacing the "M".
Here is my code
Sub MReplace()
'
' MReplace Macro
'
'
ActiveCell.Select
Cells.Find(What:="M", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
Cells.FindNext(After:=ActiveCell).Activate
ActiveCell.Offset(-8, 1).Range("A1").Select
Cells.Find(What:="M", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True _
, SearchFormat:=False).Activate
Cells.FindNext(After:=ActiveCell).Activate
ActiveCell.Replace What:="M", Replacement:="[****This is what I am having difficulty with****]", LookAt:=xlWhole, _
SearchOrder:=xlByRows, MatchCase:=True, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Find(What:="M", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True _
, SearchFormat:=False).Activate
End Sub
I have heard of something that you can put in to the code that can address the selected cell. I think it's cell() but I am not sure. Maybe that is a way to get it to work better?
Try this code:
Sub MReplace()
Dim ws As Worksheet
Dim cel As Range
Dim firstAddress As String
Set ws = ActiveSheet
Set cel = ws.Range("A:A").Find("M")
If Not cel Is Nothing Then
firstAddress = cel.Address
Do
cel.Value = (cel.Offset(1) + cel.Offset( -1)) / 2
Set cel = ws.Range("A:A").FindNext(cel)
hr = False
If Not cel Is Nothing Then
If cel.Address <> firstAddress Then
hr = True
End If
End If
Loop While hr
End If
End Sub
It loops through all the cells containing "M" and replaces it with the average of the one on the right and the one on the left. It will error on any that are in the first column as there is no column to the left.

Find method raise error 91 in excel Macro

I use a find method in the Excel macro for searching VLOOKUP in a cell, my goal is I need to know which formula that does not contain VLOOKUP, my method was running well, until in a cell there was
no VLOOKUP and macro kept debugging with the Run time error '91'
My question is how should I write the macro correctly so I wont get the debug until the activecell
contains *, below is my macro:
Sub findvlookup()
Do While Not ActiveCell.Value = "*"
If Selection.Find(What:="VLOOKUP", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate Then
ActiveCell.Offset(1, 0).Select
End If
Loop
End Sub
Thanks for the help
You don't need a loop to find the first occurrence of your 'What:=" string
Dim fndVL as Range
fndVL = Selection.Find(What:="VLOOKUP", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not fndVL is Nothing Then
MsgBox "Found it"
Else
NsgBox "Not found"
End If
If you want to find subsequent instances then have a look at FindNext and possibly use this within a loop.
Sub findvlookup()
Dim rngFind As Range
Do While Not ActiveCell.Value = "*"
Set rngFind = Selection.Find(What:="VLOOKUP", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not rngFind Is Nothing Then
ActiveCell.Offset(1, 0).Select
Else
Exit Sub
End If
Loop
End Sub
You are using Find method that technical details are Here.
You can find (in example) that:
Common Err.Numbers (9, 91) : the specified text wasn't in the target workbook.
And if you have a cell with an error value you will have another type of errors: like #Value

Loop finishing with error

I need to look for each row that has the phrase " Total" in it, insert rows above and below it, format other cells in and around that same row, remove the phrase " Total" from the cell, and repeat the process for all other rows in the report.
The macro I've developed, once it's found and replaced all of the instances of " Total", I get the Run-time error '91': Object variable or With block variable not set.
I would like to finish the loop without ending up with the error as this has to be executed on multiple sheets. Here is the meat of the code:
'EmployerSummariesAddedForRegionsOnTabs Macro
Dim FoundCell As Range, LastCell As Range
Dim FirstAddr As String
With Range("D3:D3000")
Range("D3").Select
Set LastCell = .Cells(.Cells.Count)
End With
Set FoundCell = Range("D1:D3000").Find(What:=" Total", After:=LastCell, LookIn:=xlValues, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Not FoundCell Is Nothing Then
FirstAddr = FoundCell.Address
End If
Do Until FoundCell Is Nothing
Set FoundCell = Range("D1:D3000").FindNext(After:=FoundCell)
COLUMNS("D:D").Select
Selection.Find(What:=" Total", After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Replace What:="Total", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
ActiveCell.Rows("1:1").EntireRow.Select
ActiveCell.Activate
Application.CutCopyMode = False
Selection.Insert Shift:=xlDown
ActiveCell.Offset(3, 0).Rows("1:1").EntireRow.Select
Selection.Insert Shift:=xlDown
.
.
.
If FoundCell.Address = FirstAddr Then
Exit Do
End If
Loop
Range("A1").Select
End Sub
There are two steps to creating an object variable. First you must declare the object variable.
this error occurs because you didn't set a object correctly it is quite the same as null refrence exception if you have programming experience.
I ran your code and it seems that it doesn't do anything at all! Not even an error! so I assume that your error must because of somewhere else in your code.
any way this lines replace any total in active worksheet with nothing:
Cells.Replace What:=" Total", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False

Resources