Runtime error '28': Out of stack space in Excel VBA - vba

I try to a create a workbook for my requirement. The first sheet include a cell which type is 'Text' and it is for DATE value.
I add Workbook_Open method for set today date when open the workbook as shown below.
Private Sub Workbook_Open()
Sheet1.Range("F6") = Date
End Sub
And I also add Worksheet_Change method for sheet of that cell. That is for validation check as below.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$F$6" Then
'Getting insertion date.
insertionDate = Sheet1.Range("F6")
'If date field is not empty
If insertionDate <> "" Then
Call MsgBox("Insertion Date must be inserted.")
End If
End If
End Sub
After that, I tested my code. When open the work book, I got the following error.
Run-time error '28':
Out of stack space
When click 'Debug' button, the cursor shown at the first line of Worksheet_Change method.
I has tried everything what I thought. But nothing is going on. Help me. Thank You.

I got it with this code. It is not satisfied for me but my problem is solved.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
If Target.Address = "$F$6" Then
'Getting insertion date.
insertionDate = Sheet1.Range("F6")
'If date field is not empty
If insertionDate <> "" Then
Call MsgBox("Insertion Date must be inserted.")
End If
End If
Application.EnableEvents = True
End Sub

Msgbox not need Call statement. Try to remove Call and test again.
And I have some reference from https://support.microsoft.com/en-us/kb/126090?wa=wsignin1.0. Its may be explain your error.

Possible sources of error marked in the code
Option Explicit ' Candidate
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$F$6" Then
'Getting insertion date.
Dim insertionDate as String ' Candidate
insertionDate = Sheet1.Range("F6").Text ' Candidate
'If date field is not empty
If insertionDate <> "" Then
MsgBox("Insertion Date must be inserted.") ' Candidate
End If
End If
End Sub
Make sure you placed Worksheet_Change in the sheet module.

Related

How do I error handle when a cell is blank and there are many routines

I have a sheet with a lot of code that I have worked on throughout the last couple of years but I am new to VBA and did not incorporate any error handling. I tried a few things but I could never make it work. It did not really affect me until recently. Most of my routines are driven by a cell that contains a sales price (cell D5). I am using Worksheet_Change ByVal target as range to change things when different cells are changed so when the sales price is changed it starts running routines.
What I have noticed is that this particular routine is the first one that gives me a VBA error if I delete the sales price in cell D5. So I thought I can ask someone to give me a simple code to catch the empty cell before the routine fires and maybe a popup saying "Sales Price cannot be blank" and perhaps revert to the previous value of that cell. The debug error takes me to the line of code that starts with "If Sheets("Main").Range("D6").Value < 0.8001"
Sub Calc_MI()
If Sheets("Main").Range("D12").Value = "FHA" Then
Sheets("Main").Range("D16").Value = 0.85
Else
If Sheets("Main").Range("D6").Value < 0.8001 Or
Sheets("Main").Range("D12").Value = "VA" Then
Sheets("Main").Range("D16").Value = ""
Else
If Sheets("Main").Range("G14").Value > 0.45 Then
Sheets("Main").Range("D16").Value = (Sheets("Closing
Costs").Range("BP100").Value + Sheets("Closing
Costs").Range("BP101").Value + Sheets("Closing
Costs").Range("BP102").Value)
Else
Sheets("Main").Range("D16").Value = (Sheets("Closing
Costs").Range("BP100").Value + Sheets("Closing
Costs").Range("BP102").Value)
End If
End If
End If
End Sub
any help would be greatly appreciated :-)
you could place this in "Main" sheet code pane
Option Explicit
Dim oldVal As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$D$5" Then
If IsEmpty(Target) Then
MsgBox "Sales Price cannot be blank"
Application.EnableEvents = False ' disable events to prevent change event fire in an infinite loop
Target.Value = oldVal ' restore old backup value
Application.EnableEvents = True ' enable events back
End If
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Address = "$D$5" Then oldVal = Target.Value ' if D5 selected then backup its value
End Sub

VBA to update formula when a value changes in a refence range

I have an Excel formula that gives me the last Friday's date "=TODAY()-WEEKDAY(TODAY())-1" in cell A1
I want to update cell A1 only when the values in reference range in another worksheet B2:D469 changes.
Below is the code i am using but the issue is code only works when i manually make a change in the range. However values in the range gets updated when source pivot table refresh. I want code to get updated when i refresh the pivot table and the values in the range "B2:D469" changes.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Worksheets.("Source").Range("B2:D469")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
Worksheets.("Dashboard").Range ("A1").EnableCalculation = True
End If
End Sub
Range.Dependents
Range has a property Dependents which is a Range containing all cells that this Range affects, even if they are several steps removed. For example if C4 is "=B4" and B4 is "=A4", Range("A4").Dependents will include both B4 and C4.
So, in your case, if Target affects a cell you care about, it's included in the Range Target.Dependents. You can use this to accomplish your goal.
How to use it
Use the following as the code of ThisWorkbook. I've commented the heck out of it, but if you have questions feel free to ask in the comments.
Option Explicit
Private RangeToMonitor As Range
Private RangeToChange As Range
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
'---If this is the first change since the workbook has been opened, define the ranges---
If RangeToMonitor Is Nothing Then
Set RangeToMonitor = Worksheets("Source").Range("B2:D469")
Set RangeToChange = Worksheets("Dashboard").Range("A1")
End If
'---------------------------------------------------------------------------------------
'First, check to see if Target is in the RangeToMonitor
If Not Application.Intersect(Target, RangeToMonitor) Is Nothing Then
'If so, set your date. Rather than using a formula in the cell - which could go haywire if someone messes with it - just set it straight from VBA
RangeToChange.Value = Date - Weekday(Date) - 1
'Second, check to see if a change to Target *triggers* any recalculation of cells in RangeToMonitor.
'You can do this by looking at Dependents, which is all the cells affected by a change to Target, even several steps removed
ElseIf hasDependents(Target) Then
'(The above and below criteria cannot be done in one if condition because VBA boolean operators do not short circuit)
If Not (Application.Intersect(Target.Dependents, RangeToMonitor) Is Nothing) Then
RangeToChange.Value = Date - Weekday(Date) - 1
End If
End If
End Sub
'The reason for this function is that trying to use Target.Dependents when Target has no Dependents causes an error
'I use this function to verify that Target DOES have Dependents before attempting to find out if any of them affects RangeToMonitor
Private Function hasDependents(rng As Range)
On Error GoTo ErrHandler
Dim test As Long
test = rng.DirectDependents
hasDependents = True
Exit Function
ErrHandler:
If Err.Number = 1004 Then
'"No Cells Were Found"
'This error signifies that Target has no Dependents, so we can safely ignore the change and exit the event.
hasDependents = False
Else
Err.Raise Err.Number, , Err.Description
End If
End Function

VBA Nested IF statement

I want to show a message box when a specific cell has a particular value in it. I have done this with the following code;
If Range("P8") = "Y" Then
MsgBox "Message here"
End If
This is within the Worksheet_Change sub so shows the message box everytime another cell value changes. I have tried to get around this by adding a boolean variable, set to true when the messagebox has been shown the first time;
If Range("P8") = "Y" Then
If messageshown = False Then
messageshown = True
MsgBox "Message here"
Else
End If
Else
End If
However the message box still shows every time I change a cell in the worksheet. I have a feeling it';s to do with the way I have written the nested if statement but have tried various different ways and orders of where I place else and end if but to no avail.
Use the Target argument instead - this refers to the actual cell being changed, which is what you are interested in. Test the address of the Target to see if it's the cell you need and then act accordingly. This will stop the message showing when another cell is changed.
Private Sub Worksheet_Change(ByVal Target As Range)
With Target
If .Address = "$P$8" And .Value = "Y" Then MsgBox "Message here"
End With
End Sub
Try this code, it first checks which cell is changed, if it is anything but P8, it will not pop the messagebox.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$P$8" Then
If Range("P8") = "Y" Then
MsgBox "This works"
End If
End If
End Sub
As pointed out by Macro Man, there is a more optimal, more efficient option.

How to clear cell when enter invalid data in Excel using VBA

I have an Excel sheet in which I am accepting value from the user when user enter a value a VBA will run which check the data is valid or not and if the data is not valid it will prompt a message saying invalid data. Here is my code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$D$12" Or Target.Address = "$D$13" Or Target.Address = "$D$14" Or Target.Address = "$D$15" Then
Call Room
End If
End Sub
Room method is
Sub Room()
Dim lastRow As Long
If IsNumeric(Range("i17")) Then
If [I17] < 0 Then
MsgBox "msg "
End If
End If
End Sub
In I17 cell I have a formula
=C6-(D12+(2*D13) + (2*D14) + (3*D15))
My problem is when wrong data is enter in any of the cells (D12, D13, D14, D15) then the cell should be clear automatically after showing prompt message.
How can this be done?
The first thing that you should do is clean up how you check what Target is. It could be multiple cells (Fill Down, paste a range, ...). This is accomplished by intersecting Target with the range you are interested in, and We'll store into a range variable, for later. If there is no overlap, then intersect will return an empty object, which we can test for with is Nothing.
The next thing to note is that odd things (infinite recursion) can happen if we allow the Worksheet_Change event to fire by changing a cell. To prevent this, we will turn off events before calling Room, and turn it back on after we're done.
Next we pass the range that has changed into room, so we can modify it from within that subroutine.
And, finally we modify the affected range after displaying the message. Note that I have used a command to literally clear the cell. Since you are performing calculations based on that data, you might prefer to set it to default value, like 0, using a.value = 0 instead.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim a As Range
Set a = Intersect(Target, Range("D12:D15"))
If Not a Is Nothing Then
Application.EnableEvents = False
Room a
Application.EnableEvents = True
End If
End Sub
Sub Room(a As Range)
Dim lastRow As Long
If IsNumeric(Range("I17")) Then
If Range("I17").Value < 0 Then
MsgBox "msg "
a.ClearContents
End If
End If
End Sub
As a side note, I have a used a bad variable name a, since I don't know what that range represents. You should pick something that describes to future maintainers what is going on.
use this
Private Sub Worksheet_Change(ByVal Target As Range)
Dim t As Range
Set t = Intersect(Target, [D12:D15])
Application.EnableEvents = 0
If Not t Is Nothing Then
Call Room
If [I17] < 0 Then Target.Value = ""
End If
Application.EnableEvents = 1
End Sub

Excel - Run-time error '1004': Unable to set the hidden property of the range class

I am new to scripting and I am trying to improve a existing Macro. I recorded a macro to remove duplicate and added it in a Main function which calls some other functions, but I am getting this error when I add the macro I recorded:
Run-time error '1004': Unable to set the hidden property of the range class
The code looks like
Private Sub Worksheet_Change(ByVal Target As Range)
Dim changed As Range
Set changed = Intersect(Target, Range("J15"))
If Not changed Is Nothing Then
Range("A48:A136").EntireRow.Hidden = True
Select Case Target.Value
Case "Agriculture"
Range("A48:A96").EntireRow.Hidden = False
Case "Commercial"
Range("A97:A136").EntireRow.Hidden = False
Case "MDP"
Range("A48:A61").EntireRow.Hidden = False
End Select
Range("J15").Select
End If
End Sub
Some possible answers:
You have a comment in one of the selected cells
You have some drawn objects which don't resize with text
Your worksheet is protected
When you set a breakpoint on the first line of the event handler, and then press F8 to step through the macro, I'm assuming it crashes on the line:
Range("A48:A136").EntireRow.Hidden = True
When people say "You have a comment in one of the selected cells", keep in mind that THE COMMENT CAN BE IN A DIFFERENT COLUMN.
If a comment box is over the column you're trying to hide (like if you're hiding every column to the right and you have comments in a completely different column), this is the error you'll get.
If you try to manually hide the column, you'll get a different confusing error which is something along the lines of "hiding this column will push an object off of the sheet."
The comment box a few columns over is the object.
^ This would have saved me about 40 minutes of debugging.
try this :)
Private Sub Worksheet_Change(ByVal Target As Range)
ActiveWorkbook.Unprotect "password_here"
Dim changed As Range
Set changed = Intersect(Target, Range("J15"))
If Not changed Is Nothing Then
Range("A48:A136").EntireRow.Hidden = True
Select Case Target.Value
Case "Agriculture"
Range("A48:A96").EntireRow.Hidden = False
Case "Commercial"
Range("A97:A136").EntireRow.Hidden = False
Case "MDP"
Range("A48:A61").EntireRow.Hidden = False
End Select
Range("J15").Select
End If
ActiveWorkbook.Protect "password_here"
End Sub
This should work for you :)