Check if a macro was run with VBA - excel

I have a interactive workbook with 3 step-by-step buttons so the user can generate a report. I want 2nd macro to check if 1st macro was run and if not, warn the user with a Masgbox to run it first.
Is there a way to determine if a macro was run? Maybe putting a Call at the end of the first 2 macros where a public sub add +1 to a 'counter' variable?
For example:
Macro 2 check if counter = 1,
Macro 3 check if counter = 2
Thanks in advance.

Run Macros Sequentially
Public RunChecker As Long
Sub Macro1()
Select Case RunChecker
Case 1
MsgBox "You already ran Macro1. To continue, run Macro2.", vbExclamation
Exit Sub
Case 2
MsgBox "To continue, run Macro3.", vbCritical
Exit Sub
End Select
' Your code, e.g.:
MsgBox "Running1", vbInformation
RunChecker = 1
End Sub
Sub Macro2()
Select Case RunChecker
Case 0
MsgBox "You need to run Macro1 first.", vbCritical
Exit Sub
Case 2
MsgBox "You already ran Macro2. To continue, run Macro3.", vbExclamation
Exit Sub
End Select
' Your code, e.g.:
MsgBox "Running2", vbInformation
RunChecker = 2
End Sub
Sub Macro3()
Select Case RunChecker
Case 0
MsgBox "You already finished. To start again, run Macro1.", vbExclamation
Exit Sub
Case 1
MsgBox "You need to run Macro2 first.", vbCritical
Exit Sub
End Select
' Your code, e.g.:
MsgBox "Running3", vbInformation
RunChecker = 0
End Sub

Related

VBA Delete Cells with MsgBox?

I am trying to delete cells in a table.
The worksheet line is marked as debug.
but i can't find my mistake...
Code:
Sub clear_click()
If MsgBox("Del?", vbOKCancel) = vbCancel Then
Exit Sub
Else
Worksheets("calc").Range("G9:G12").ClearContents
End If
End Sub

Exit the main sub if a called sub calls `Exit Sub`

I have a sub that calls another sub and most often I need to exit the called sub and stop executing the rest of the sub that called it.
So I have the sub Add_Format_Button_Click that calls another sub:
call CheckEmptyComboboxValues
And most often CheckEmptyComboboxValues will end up on
Exit sub
But the Add_Format_Button_Click will continue executing the rest of it. This is where I need help because when CheckEmptyComboboxValues exits, I need the Add_Format_Button_Click to also exit.
Could someone help me solve this, seemingly simple problem?
EDIT: CheckEmptyComboboxValues contains tens if not hundreds of if statements that follow the structure of:
If Format_Layout.FilmType.Value = "" Then
MsgBox "Specify a film type!", , ("Film Type"): Exit sub
End If
So I guess I need to turn that exit sub value into something I can check in the main sub with an if statement like
if CheckEmptyComboboxValues .value = "Exit sub" Then
exit sub
3 solutions, each of them works for your case. I would go with the first or last solution. Depends a bit on the design of the rest of your project:
1. Function
Function CheckEmptyComboboxValues() As Boolean
If AnythingOddHappens Then
Exit Function
End If
CheckEmptyComboboxValues = True
End Function
The result of this function is only True if it runs through the end, whenever you exit it before it is False
Sub Example()
If Not CheckEmptyComboboxValues Then Exit Sub
'instead of
'Call CheckEmptyComboboxValues
End Sub
2. Procedure with cancel
Sub CheckEmptyComboboxValues(ByRef Cancel As Boolean)
If AnythingOddHappens Then
Cancel = True
Exit Sub
End If
End Sub
Sub Example()
Dim Cancel As Boolean
Call CheckEmptyComboboxValues(Cancel)
If Cancel Then Exit Sub
End Sub
This can be used, but here I see no advantage and would prefer the function above. This method can be useful if you already have a function with a return value and want an additional cancel or in case you write code for an event.
3. Throw an error
Sub CheckEmptyComboboxValues()
If AnythingOddHappens Then
Err.Raise vbObjectError + 513, "CheckEmptyComboboxValues", "Something odd happened"
Exit Sub
End If
End Sub
Sub Example()
On Error Goto ERR_HANDLER
Call CheckEmptyComboboxValues
Exit Sub
ERR_HANDLER:
MsgBox "check failed"
End Sub
This can be an advantage if you have multiple check procedures/functions that can throw errors. Compared with the first or second solution where you need to check the result of each single check procedure/function this solution needs only one error handler, and threfore comes with slim code.
This also has the advantage that the check procedure now can return different type of errors that your calling sub can use to provide further assistance to the user. While the first 2 solutions are more like "It didn't pass the check" the last solution can provide more detailed information like "It didn't pass the check because of A/B/C happened" depending on which error was raised.
Sub CheckEmptyComboboxValues()
If AnythingOddHappens Then
Err.Raise vbObjectError + 513, "CheckEmptyComboboxValues", "Something odd happened"
Exit Sub
End If
' more code here …
If AnythingDifferentOddHappens Then
Err.Raise vbObjectError + 514, "CheckEmptyComboboxValues", "Something different odd happened"
Exit Sub
End If
End Sub
Now you can use the different error numbers to provide a more detailde infomation to the user about what went wrong and not just something went wrong.
Sub Example()
On Error Goto ERR_HANDLER
Call CheckEmptyComboboxValues
Exit Sub
ERR_HANDLER: 'possibility to give a more detailed information
Select Case Err.Number
Case vbObjectError + 513
MsgBox "check A failed"
Case vbObjectError + 514
MsgBox "check B failed"
Case Else
MsgBox "Undefined fail"
End Select
End Sub
Rewrite CheckEmptyComboboxValues to a function which returns a boolean. In Add_Format_Button_Click you can then write
if CheckEmptyComboboxValues then
' You could give a message
Exit Sub
else
' rest of the code of
' Add_Format_Button_Click
end if
CheckEmptyComboboxValues might look like that
Function CheckEmptyComboboxValues as boolean
' code goes here
if .... then
CheckEmptyComboboxValues = False
exit function
else
' other code
end if
CheckEmptyComboboxValues = True
End Function
Update based on the edit
Function CheckEmptyComboboxValues() As Boolean
' ....
If Format_Layout.FilmType.Value = "" Then
MsgBox "Specify a film type!", , ("Film Type")
CheckEmptyComboboxValues = True
Exit Function
End If
' ....
CheckEmptyComboboxValues = False
End Function

Using drop down list linked to macros

This is my first time using a drop down list. I was wondering if there was a way to assign a macro to each of the items in the drop down list.
For an example if I selected BZ1A I would want it to run the sub I have called BZ1A.
Run Macros From Drop Down
Copy the first code into the sheet module of the worksheet containing the drop down, e.g. Sheet1 (the name in parentheses in the VBE Project Explorer).
Adjust the values in the constants section.
Put your codes into the same module, e.g. Module1. Otherwise you will have to modify the code.
In this example the drop down list is in cell A1 of worksheet Sheet1 and contains the list (values) Sub1, Sub2, Sub3.
Sheet Module e.g. Sheet1
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const CellAddress As String = "A1"
Const ModuleName As String = "Module1"
If Target.Cells.CountLarge = 1 Then
If Not Intersect(Range(CellAddress), Target) Is Nothing Then
Application.EnableEvents = False
On Error GoTo clearError
Application.Run ModuleName & "." & Target.Value
Application.EnableEvents = True
End If
End If
Exit Sub
clearError:
MsgBox "Run-time error '" & Err.Number & "': " & Err.Description
Resume Next
End Sub
Standard Module e.g. Module1 (Example)
Option Explicit
Sub Sub1()
MsgBox "Running 'Sub1'"
End Sub
Sub Sub2()
MsgBox "Running 'Sub2'"
End Sub
Sub Sub3()
MsgBox "Running 'Sub3'"
End Sub

How to proceed when object is not found?

I am searching for a blank cell in a table. Want to have a msg or run a command when there is no blank cell. I tried below versions but none of them worked
Sub Macro1()
ActiveSheet.ListObjects("Tabel1").DataBodyRange.Select
Selection.SpecialCells(xlCellTypeBlanks).Select
On Error GoTo Line1
Line1:
MsgBox "no blank cell is found"
End Sub
and also this one
Sub Macro1()
ActiveSheet.ListObjects("Tabel1").DataBodyRange.Select
Selection.SpecialCells(xlCellTypeBlanks).Select
If Selection = "" Then
MsgBox "no blank cell is found"
End If
End Sub
I suggest to catch the error and check if BlankCells is Nothing.
Sub Macro1()
Dim BlankCells As Range
On Error Resume Next 'supress all error messages until …Goto 0
Set BlankCells = ActiveSheet.ListObjects("Tabel1").DataBodyRange.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0 'never forget to re-activate error reporting immedeately!
If BlankCells Is Nothing Then
MsgBox "no blank cell is found"
Else
MsgBox BlankCells.Cells.Count & " blank cell(s) found"
End If
End Sub
You might benefit from reading …
How to avoid using Select in Excel VBA.
VBA Error Handling – A Complete Guide
No need for selects and selection, you could try:
Sub try()
On Error GoTo noblanks
MsgBox ActiveSheet.ListObjects("Tabel1").DataBodyRange.SpecialCells(xlCellTypeBlanks).Count & " blank cells are found"
Exit Sub
noblanks:
MsgBox "no blank cell is found"
End Sub

.range(ContRow&":"&ContRow).entirerow.Delete

This is the line I'm having trouble with:
.range(ContRow&":"&ContRow).entirerow.Delete
This is the macro:
Sub Cont_Delete()
With Sheet1
If MsgBox("Are you sure you want to delete this record?", vbYesNo, "Delete
Record") = vbNo Then Exit Sub
If .Range("B3").Value = Empty Then Exit Sub
ContRow = .Range("B3").Value.Range(ContRow&":"&ContRow).EntireRow.Delete.Range("D18").Select
End With
End Sub
Error message:
Syntax error and compile error expected: list separator or )
you are concatenating code lines
you most probably need this:
Sub Cont_Delete()
With Sheet1
If IsEmpty(.Range("B3")) Then Exit Sub
If MsgBox("Are you sure you want to delete this record?", vbYesNo, "Delete Record ") = vbNo Then Exit Sub
.Rows(.Range("B3").Value).EntireRow.Delete
.Range("D18").Select
End With
End Sub

Resources