I am creating a visual basic application for a friend. Anyway I am trying to create a function that returns "exit sub" to the sub calling the function. I have seen some ways around this by returning a value like 1 or 2 and inserting a if in calling sub. just wondering if there is a short hand for returning exit sub that I haven't learned yet.
Private Sub Button1.click() Handles Button1.Click
tryactive()
endsub
Private Function tryactive()
Try
AppActivate("your aplication")
Catch ex As Exception
Dim msgboxresponse = MsgBox("please start your application", 0, "Can't find your application")
If msgboxresponse = MsgBoxResult.Ok Then
Exit Sub <------ this is the problem i want to send this back to calling sub
End If
End Try
End Function
Code is much bigger and a lot more buttons. That's why i'm asking if there's a better way to do this. Any help is appreciated.
First of all, you cannot use an Exit Sub inside a Function. It should be an Exit Function. But based on what you want to happen (I guess), try this.
Private Sub Button1_Click() Handles Button1.Click
If TryActive() = False Then
Exit Sub
End If
'Your code you want to execute if TryActive() is True
End Sub
Private Function TryActive() as Boolean
Try
AppActivate("your aplication")
Return True
Catch ex As Exception
Dim msgboxresponse = MsgBox("please start your application", 0, "Can't find your application")
If msgboxresponse = MsgBoxResult.Ok Then
Return False
End If
End Try
End Function
Related
I have been creating a tool which extracts data from other Excel files and does various types of analysis. Because of these numerous different analyses, I have had to create multiple subs which are then all called upon in a "master" sub, which is activated when the user presses a button.
The issue I'm having is with error handling to stop the macro when there's an issue or when the user is trying to stop the code themselves - e.g. a pop-up box appears with a "continue or stop" type scenario. However, I can't work out how to make the macros stop! Using Exit Sub doesn't work because the master sub will then just jump to the next sub in the queue.
See example below - the user presses the button to activate master_sub. If within the sub1 stage the user selects "No" or "Cancel" in a MsgBox, sub1 will end (if using Exit Sub) but master_sub will then just go on to sub2 and sub3. How do I make master_sub stop based upon an input/action within sub1?
Sub sub1()
Dim MyMsg as Variant
MyMsg = msgbox("Do you wish to continue?", vbYesNo)
If MyMsg = 7 then 'If user clicks "No"
Exit Sub
Else
'Do stuff
End if
End Sub
Sub sub2()
'More stuff
End Sub
Sub sub3()
'Other stuff
End Sub
master_sub()
call sub1
call sub2
call sub3
End Sub
Instead of using Exit Sub Throw a custom exception and catch it in your master_sub.
Something like
Sub sub1()
Dim MyMsg as Variant
MyMsg = msgbox("Do you wish to continue?", vbYesNo)
If MyMsg = 7 then 'If user clicks "No"
Throw new MyException
Else
'Do stuff
End if
End Sub
master_sub()
Try
call sub1
call sub2
call sub3
Catch ex as MyException
'Do something if you want
End Try
End Sub
The "how does master_sub" detect when one of the child methods has been cancelled can be solved like this:
Sub master_sub()
Dim result As Boolean
result = Sub1()
If (result = False) Then
Exit Sub
End If
result = Sub2()
If (result = False) Then
Exit Sub
End If
result = Sub3()
If (result = False) Then
Exit Sub
End If
End Sub
Function Sub1() As Boolean
Return True
End Function
Function Sub2() As Boolean
Return False
End Function
Function Sub3() As Boolean
Return True
End Function
I've kept it very simple, but basically by changing from a Sub to a Function you can have each method return a value and decide in your main routine (master_sub) what to do depending on the value returned.
Using: Access 2013 with ADO connection to SQL Server back-end database
A form in my Access database is dynamically bound at runtime to the results of a SELECT stored-procedure from SQL Server, and allows the user to make changes to the record.
It has 2 buttons: Save and Cancel.
It is shown as a pop-up, modal, dialog form, and it has a (Windows) Close button at the top right corner.
I've put VBA code to ask the user whether he wants to Save, Ignore or Cancel the close action.
But there are problems and it gives the aforementioned error if Cancel is clicked. There are also other problems, like, after the error occurs once, then any further commands (Save or Cancel or closing the form) don't work - I think this is because the VBA interpreter has halted due to the earlier error. Another complication is that arises - I now need to end the MS-Access process from Windows Task Manager, doing this and then restarting the database and then opening this form will give an error and the form won't load. When the form is then opened in Design mode, I can see the connection string for the form is saved in the Form's Record Source property (this happens only sometimes), and which looks something like this:
{ ? = call dbo.tbBeneficiary_S(?) }.
Here is my code:
Dim CancelCloseFlag As Boolean
Dim SavePrompt As Boolean
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim a As Integer
If SavePrompt Then
a = MsgBox("Do you want to save changes?", vbQuestion + vbYesNoCancel, "Changes made")
Select Case a
Case vbNo:
Me.Undo
CancelCloseFlag = False
Case vbYes:
'do nothing; it will save the changes
CancelCloseFlag = False
Case vbCancel:
Cancel = True
CancelCloseFlag = True
End Select
End If
End Sub
Private Sub Form_Dirty(Cancel As Integer)
SavePrompt = True
End Sub
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 2169 Then
Response = acDataErrContinue
End If
End Sub
Private Sub Form_Load()
LoadBeneficiaryDetails
End Sub
Private Sub Form_Unload(Cancel As Integer)
If CancelCloseFlag Then
Cancel = True
End If
End Sub
Private Sub btCancel_Click()
If Me.Dirty Then
SavePrompt = True
End If
DoCmd.Close
End Sub
Private Sub btSave_Click()
SavePrompt = False
DoCmd.Close
End Sub
I'm stuck and would like to know how others go about this issue? Basically I want to offer the user the choice Save, Ignore, Cancel when the user attempts to close the form with either Cancel button or the (Windows) close button. If the user chooses Cancel, then it should just return to the form without changing or undoing any changes to the data. The solution may be simple but it escapes my overworked mind.
Thanks in advance!
Please try the following code - I tested against all six scenarios and the proper action is taken.
Option Compare Database
Option Explicit
Dim blnAction As Integer
Dim blnBeenThereDoneThat As Boolean
Private Sub Form_BeforeUpdate(Cancel As Integer)
If blnBeenThereDoneThat = True Then Exit Sub
blnBeenThereDoneThat = True
blnAction = MsgBox("Do you want to save changes?", vbQuestion + vbYesNoCancel, "Changes made")
Select Case blnAction
Case vbNo:
Me.Undo
Case vbYes:
'do nothing; it will save the changes
Case vbCancel:
Cancel = True
End Select
End Sub
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 2169 Then
Response = acDataErrContinue
End If
End Sub
Private Sub Form_Load()
LoadBeneficiaryDetails
End Sub
Private Sub Form_Unload(Cancel As Integer)
If blnAction = vbCancel Then
blnBeenThereDoneThat = False
Cancel = True
End If
End Sub
Private Sub btCancel_Click()
If Me.Dirty Then
Form_BeforeUpdate (0)
End If
If blnAction = vbCancel Then
blnBeenThereDoneThat = False
Exit Sub
ElseIf blnAction = vbYes Then
DoCmd.Close
Else
DoCmd.Close
End If
End Sub
Private Sub btSave_Click()
If Me.Dirty Then
Form_BeforeUpdate (0)
End If
If blnAction = vbCancel Then
Exit Sub
Else
DoCmd.Close
End If
End Sub
I have a BackgroundWorker that includes a class ExcelOutput, used to output various data to a workbook, and I should mention straight away that bw.WorkerSupportsCancellation = True is set.
At each stage of the output I'm checking for errors in ExcelOutput using Try/Catch, and if necessary displaying an error (using a function called ErroReport().
In conjunction with the error message, I want to cancel the BackgroundWorker to avoid further errors. To that end I have added the OutputWorker property to the ExcelOutput class and I set that to be a copy of my BackgroundWorker in the bw_DoWork() method.
However, the cancellation carried out in ExcelOutput.ErroReport() is not working, and I don't know why.
Note that I've tested the value of bw.CancellationPending and it is set to True after an error. I've also tested that the If condition following is working by showing a message box, and that also works. For some reason it seems as though the Exit Sub command is ignored though.
Can anyone suggest what I am doing wrong? Thanks.
Here is how the bw_DoWork() function from the BackgroundWorker class is set up -
Private Sub bw_DoWork(ByVal sender As Object,
ByVal e As DoWorkEventArgs)
Dim Excel As New ExcelOutput ' Create a new instance of the ExcelOutput class
Dim CurrentRow As Integer = 4 ' Set the first output row
'** Include a copy of the OutputWorker in the ExcelOutput (so that the OutputWorker can be cancelled)
Excel.OutputWorker = Me
If bw.CancellationPending = True Then
e.Cancel = True
Exit Sub
Else
Excel.Prepare()
End If
If bw.CancellationPending = True Then
e.Cancel = True
Exit Sub
Else
CurrentRow = Excel.OutputGroup("General", Headers, Data, 4)
End If
' More stuff here...
End Sub
Here is how the ErrorReport() function from the ExcelOutput class is set up -
Private Sub ErrorReport(ByVal Ex As Exception,
Optional ByVal CustomMessage As String = "")
Call Me.ResetRange() ' Destroy the 'Range' object
Dim ErrorMessage As String = "Message: " & Ex.Message ' Set the default message
If CustomMessage <> "" Then ErrorMessage = CustomMessage & vbCrLf & vbCrLf & Ex.Message
Dim Result As Integer = MessageBox.Show(ErrorMessage,
"An Error Has Occured",
MessageBoxButtons.OK,
MessageBoxIcon.Stop)
'** Close the workbook (if it's open) and stop the OutputWorker *'
Try
Call Me.WB.Close(SaveChanges:=False)
If Me.OutputWorker.WorkerSupportsCancellation = True Then
Me.OutputWorker.CancelAsync()
End If
Catch
End Try
End Sub
You should try to add the DoWorkEventsArgs as parameter to your ErrorReport function.
Private Sub ErrorReport(ByVal Ex As Exception,
Optional ByVal CustomMessage As String = "",
ByVal e As DoWorkEventsArgs)
Call Me.WB.Close(SaveChanges:=False)
If e.WorkerSupportsCancellation = True Then
e.CancelAsync()
End If
You'll be able to cancel the Backgroundworker.
I have a method-A() that is called from multiple methods,
On a condition in method-A, i have to terminate the macro.
i saw one option as Exit sub but this will just exit the current sub ie:method-A() and the remaining program continues.
how to handle this.
Sub mainMethod()
method-A()
end Sub
Sub method-A()
if (true) Then
'Terminate the macro. that is exit method-A() and also mainMethod()
end Sub
Edit after comment:
Just use end where you want to terminate ALL code.
Sub mainMethod()
method_A()
end Sub
Sub method-A()
if (true) Then End
'Terminate the macro. that is exit method-A() and also mainMethod()
end Sub
Original Answer: All you need to do is make methodA a function and return this function as FALSE if you want to exit the main method as per the following code:
Sub mainMethod()
'Run the custom function and if it returns false exit the main method
If Not method_A Then Exit Sub
'If method_A returns TRUE then the code keeps going
MsgBox "Method_A was TRUE!"
End Sub
Function method_A() As Boolean
Dim bSomeBool As Boolean
'Code does stuff
bSomeBool = True
'Check your condition
If bSomeBool Then
'Set this function as false and exit
method_A = False
Exit Function
End If
'If bSomeBool = False then keep going
End Function
I need a function to Hide a form in cross -thread operation. I write this code but it close the form and not only hide it:
Dim objHideMyForm As delegateUpdateApps = AddressOf HideFree
Private Sub HideFree()
Try
Me.Hide()
Catch
End Try
End Sub
Public Sub HideMe()
Me.Invoke(objHideMyForm)
End Sub
Usually you would simply call:
Me.ParentForm.Close()