Option Explicit
'-------------------------------------------------------------------------------------------------------------------------
'Un UserForm détaché doit être un UserForm non Modal (UserForm.Show vbModeless).
'
'Un UserForm détaché est un UserForm dont le Owner initialement défini par Excel à sa Window de création a été forcé à 0
'via l'API SetWindowLongPtr UserFormHandle, GWL_HWNDPARENT, 0
'Cela pour éviter que la fermeture de sa Window de création ne le ferme également laissant les éventuelles autres
'Windows du classeur dépourvues du UserForm qui leur est potentiellement utile.
'
'Le problème est qu'à la fermeture du classeur, le UserForm normalement fermé à la fermeture de sa Window de création
'n'est pas fermé si un autre classeur est ouvert car tant que le classeur ou le complément créateur du UserForm est actif,
'l'instance du UserForm restera présente.
'
'Il faut donc un mécanisme de fermeture des UserForms détachés à la fermeture du classeur qui les a vu naître.
'-------------------------------------------------------------------------------------------------------------------------
'https://docs.microsoft.com/fr-fr/office/vba/api/excel.application(object)
Public WithEvents App As Application
Private Type UserFormWindowFree
    UserForm As Object
    Workbook As Workbook
End Type
Private TabUserFormWindowFree() As UserFormWindowFree
Private NbUserFormWindowFree As Integer
'------------------------------------------------
'Sub to call when setting the UserForm Owner to 0
'------------------------------------------------
Sub Add(UserForm As Object)
    Dim i As Integer
    'UserForm already stored ?
    For i = 1 To NbUserFormWindowFree
        If TabUserFormWindowFree(i).UserForm Is UserForm _
        And TabUserFormWindowFree(i).Workbook Is ActiveWorkbook Then Exit For
    Next i
    'Yes
    If i <= NbUserFormWindowFree Then Exit Sub
 
    'Add the UserForm
    NbUserFormWindowFree = NbUserFormWindowFree + 1
    ReDim Preserve TabUserFormWindowFree(1 To NbUserFormWindowFree)
    Set TabUserFormWindowFree(NbUserFormWindowFree).UserForm = UserForm
    Set TabUserFormWindowFree(NbUserFormWindowFree).Workbook = ActiveWorkbook
End Sub
'------------------------
'App_WorkbookBeforeClose
'------------------------
Private Sub App_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
    Dim i As Integer
    Dim k As Integer
    'Close Workbook UserForms
    i = 1
    Do While i <= NbUserFormWindowFree
        If TabUserFormWindowFree(i).Workbook Is Wb Then
            Unload TabUserFormWindowFree(i).UserForm
    
            'Remove table item
            For k = i To NbUserFormWindowFree - 1
                TabUserFormWindowFree(k) = TabUserFormWindowFree(k + 1)
            Next k
    
            NbUserFormWindowFree = NbUserFormWindowFree - 1
            If NbUserFormWindowFree = 0 Then
                Erase TabUserFormWindowFree
            Else
                ReDim Preserve TabUserFormWindowFree(1 To NbUserFormWindowFree)
            End If
    
            i = i - 1
        End If
 
        i = i + 1
    Loop
End Sub