Forum Discussion
BillZab
Feb 23, 2023Copper Contributor
Exit from Excel Macro from sub
Hi Guys. I have the following code.
Sub DuplicateFile()
Dim Answer As Integer
Answer = MsgBox("Duplicate file found. Overwrite Y/N", vbExclamation + vbYesNo)
If Answer = vbYes Then
Exit Sub
Else
ActiveWorkbook.Close
End If
End Sub
If the user selects Yes, the file is overwritten. If the user selects No, then the sheet closes but the rest of the main sub continues. I need to close or exit the main sub after the AcriveWorkBook.Close command. I have tried both end sub and exit sub and both don't work. TIA.
Basically, you need the procedure to communicate the user's choice back to the "main sub". The good coding way to do this is to make a Function (i.e., not a Sub). The syntax (in VBA) to return a value from a function is to assign a value (whether a literal or from a variable) to the name of the function.
Suggested replacement:
Function PromptOnDuplicateFile() As String ' This function prompts the user for what action to take when a duplicate ' file is found; it returns a description of the user's choice. Dim Answer As VbMsgBoxResult Answer = MsgBox("Duplicate file found. Overwrite Y/N?" _ , vbExclamation + vbYesNo) '[could use vbYesNoCancel] If Answer = vbYes Then PromptOnDuplicateFile = "Overwrite" Exit Function ElseIf Answer = vbNo Then 'ActiveWorkbook.Close '[This is not central to what this function should do - prompt the user and return the result. It would better be performed from the "main sub".] PromptOnDuplicateFile = "Retry" Exit Function 'ElseIf Answer = vbCancel Then ' PromptOnDuplicateFile = "QuitTrying" ' Exit Function End If End Function
Note the "As String" on the Function statement, and the assignment statements of string values. (Returning a String rather than a Boolean allows you to change it readily to allow other options, such as "QuitTrying". That's not the most efficient code, but it makes the intent clear. And using VbMsgBoxResult rather than Integer allows VBE's Intellisense to help you code.)The invoking code (in the "main sub") should (preferably capture the return value from this function into a variable, and) then execute one of the different pieces of code, depending on the return value.
Dim NextAction As String NextAction = PromptOnDuplicateFile() If NextAction = "Overwrite" Then '[code for overwrite] Else ActiveWorkbook.Close If NextAction = "Retry" Then '[additional code for retry; possibly a GoTo <label>] ElseIf NextAction = "QuitTrying" Then '[code for that] End If End If
Please explain how you use DuplicateFile.
- BillZabCopper ContributorHi Hans. I have a sub that checks if the file the user is saving has a duplicate. If there is a duplicate file name I don't want it overwritten unless it is deliberate so I use the sub above to ask the user if they want the file overwritten. If the user selects Yes than the rest of the main sub runs and the file is overwritten. If the user selects No than Ideally I want to re-run the main sub from the beginning so the user can enter a new filename or as I am trying to do above is close the sheet and stop the main sub (I.e. Stop and exist the macro).
- SnowMan55Bronze Contributor
Basically, you need the procedure to communicate the user's choice back to the "main sub". The good coding way to do this is to make a Function (i.e., not a Sub). The syntax (in VBA) to return a value from a function is to assign a value (whether a literal or from a variable) to the name of the function.
Suggested replacement:
Function PromptOnDuplicateFile() As String ' This function prompts the user for what action to take when a duplicate ' file is found; it returns a description of the user's choice. Dim Answer As VbMsgBoxResult Answer = MsgBox("Duplicate file found. Overwrite Y/N?" _ , vbExclamation + vbYesNo) '[could use vbYesNoCancel] If Answer = vbYes Then PromptOnDuplicateFile = "Overwrite" Exit Function ElseIf Answer = vbNo Then 'ActiveWorkbook.Close '[This is not central to what this function should do - prompt the user and return the result. It would better be performed from the "main sub".] PromptOnDuplicateFile = "Retry" Exit Function 'ElseIf Answer = vbCancel Then ' PromptOnDuplicateFile = "QuitTrying" ' Exit Function End If End Function
Note the "As String" on the Function statement, and the assignment statements of string values. (Returning a String rather than a Boolean allows you to change it readily to allow other options, such as "QuitTrying". That's not the most efficient code, but it makes the intent clear. And using VbMsgBoxResult rather than Integer allows VBE's Intellisense to help you code.)The invoking code (in the "main sub") should (preferably capture the return value from this function into a variable, and) then execute one of the different pieces of code, depending on the return value.
Dim NextAction As String NextAction = PromptOnDuplicateFile() If NextAction = "Overwrite" Then '[code for overwrite] Else ActiveWorkbook.Close If NextAction = "Retry" Then '[additional code for retry; possibly a GoTo <label>] ElseIf NextAction = "QuitTrying" Then '[code for that] End If End If