Forum Discussion

BillZab's avatar
BillZab
Copper Contributor
Feb 23, 2023
Solved

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.

  • BillZab 

    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

     

    • BillZab's avatar
      BillZab
      Copper Contributor
      Hi 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).
      • SnowMan55's avatar
        SnowMan55
        Bronze Contributor

        BillZab 

        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

         

Resources