2017-10-18 25 views
-1

J'ai créé un objet UserForm dans Excel 2016 qui utilise des fonctions UDF; J'aimerais pouvoir exécuter UserForm sans ouvrir la feuille Excel et permettre l'ouverture et la manipulation d'autres classeurs Excel en même temps que l'outil est actif. Certaines solutions que j'ai trouvé disent utiliser les éléments suivants:Comment faire un VBA UserForm basé sur Excel agir seul?

Private Sub MyForm_Initialize() 
    Application.Visible = False 
    UserForm1.Activate 
End Sub 

Cependant, cela laisse Excel ouvert en arrière-plan après l'UserForm est fermé, et toutes les autres feuilles Excel actives sont cachés et ne peut pas être facilement manipulé.

Existe-t-il un moyen de faire en sorte que l'UserForm agisse essentiellement en tant qu'application autonome sans utiliser VBA.net?

+2

Je recommande réécrivant comme une question autonome et affichant une réponse à votre question ([oui cela est autorisé sur le SO] (https://stackoverflow.com/help/self-answer)) –

+1

[donc] est Q & A, pas un forum de discussion. Le champ Question héberge des questions, les champs de réponses contiennent des réponses, et les titres n'ont pas de [RESOLU] ou de [SOLUTION] ou d'autres balises gênantes dans le titre. S'il vous plaît [modifier] votre message afin qu'il * ressemble * à un Q & A. À l'heure actuelle, on ne sait pas exactement ce que vous demandez. –

+0

Vous utilisez donc un formulaire utilisateur à partir d'un classeur non visible pour agir en tant que fenêtre de contrôle pour exécuter des fonctions prédéfinies sur d'autres classeurs? Bonne idée. –

Répondre

-1

ceci est votre Workbook_Open avec le code réarrangé

Private Sub WorkBook_Open() 

    If Workbooks.Count = 1 Then Application.Visible = False 

    Workbooks("MyBook.xlsm").Windows(1).Visible = False 

    UserForm1.Show vbModeless 

End Sub 
0
code

ira dans plusieurs endroits différents, l'objet "ThisWorkbook" et le code "UserForm". "ThisWorkbook" contient du code qui déterminera si l'objet UserForm est le seul fichier Excel (classeur) ouvert, et si c'est le cas, il masquera l'application Excel et masquera le classeur lui-même. et si d'autres classeurs sont ouverts, il masque simplement le classeur. Je l'ai configuré pour masquer l'application et le classeur dans les deux cas de sorte qu'une nouvelle instance d'Excel puisse être ouverte après que l'objet UserForm s'exécute sans extraire le classeur associé à l'objet UserForm. Le code pour cela est ci-dessous (va dans l'objet « ThisWorkbook »):

Private Sub WorkBook_Open() 
    Dim wb As Workbook 
    Set wb = Workbooks("MyBook.xlsm") 
    If Workbooks.Count > 1 Then 

     wb.Windows(1).Visible = False 
    Else 
     wb.Windows(1).Visible = False 
     Application.Visible = False 
    End If 
    UserForm1.Show vbModeless 
    'Put defaults and populations here 
End Sub 

Le UserForm1.Show vbModeless permet d'Excel à utiliser tandis que le UserForm est actif. Quelques notes sur cette section:

  • « UserForm1 » est le nom de mon UserForm, changer cela au nom de la vôtre
  • Là où je Set wb = Workbooks("") change à l'intérieur des guillemets pour le nom du classeur la UserForm est dans
  • la déclaration IfElse pourrait être éliminé et déplacé vers le If, si vous n'avez pas besoin de toute autre action sur l'ouverture sans autres classeurs ouverts

le La section suivante du code va dans le code UserForm. J'ai un bouton mis en place pour afficher le classeur Excel afin de le modifier et ainsi de suite, vous pourriez avoir une région sur laquelle vous cliquez si vous ne voulez pas qu'un bouton apparaisse. Lorsque vous souhaitez activer la feuille Excel et l'application devra être activée. Je décharge (désactive) la chose active (l'UserForm). Ce morceau de code n'est pas nécessaire si l'utilisateur n'a pas besoin d'accéder à la feuille de calcul:

Private Sub See_Excel_Click() 

    Dim wb As Workbook 
    Set wb = Workbooks("MyBook.xlsm") 
    wb.Windows(1).Visible = True 
    Application.Visible = True 
    wb.Sheets("Sheet1").Activate 

    Unload Me 

End Sub 

Dans le userform il devrait y avoir un moyen de gérer ce qui se passe lorsque le UserForm est fermé, comme l'application Excel et Le classeur restera ouvert caché en arrière-plan. J'ai l'action fermer le classeur et l'application. Une note rapide, si vous définissez le Cancel = True alors le bouton rouge x ne fermera pas le formulaire utilisateur. Le code que j'utilise pour ceci est:

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) 

    If CloseMode = 0 Then 
     Cancel = False 
     Dim wb As Workbook 
     Set wb = Workbooks("MyBook.xlsm") 
     wb.Windows(1).Visible = True 
     Application.Visible = True 
     ThisWorkbook.Saved = True 
     ThisWorkbook.Activate 

    If Workbooks.Count > 1 Then 
      ActiveWorkbook.Close 
     Else 
      Application.Quit 
    End If 

    End If 

End Sub 

C'est pour le code qui va dans l'UserForm. Et le code qui est nécessaire pour que l'UserForm dans VBA agisse comme sa propre application tout en permettant à Excel de fonctionner normalement en même temps que l'UserForm.

Pour résumer ce qui se passe:

  1. Lorsque le classeur est lancé le classeur est caché, et si aucun autre classeur est ouvert, la l'application Excel est caché.
  2. Le UserForm est lancé pour permettre Excel à utiliser en même temps
  3. Lorsque la feuille de calcul est activée Excel est à nouveau réactivée et l'application et non cacher la feuille de calcul
  4. Lorsque le formulaire utilisateur est fermé , le classeur est fermé et s'il n'y a pas d'autres classeurs, l'application Excel est fermée
  5. Si vous définissez des valeurs par défaut ou remplissez ComboBox, placez-les dans le code objet "WorkBook".
0

Si votre problème est d'ouvrir tous les classeurs, vous pouvez ajouter une procédure pour les fermer tous.

Sub Close_xls() 
Dim objXl as Object 
On error Go To GenerateXlErr 
Set objXl = GetObject(, "Excel.Application") 
If not (ObjXl is Nothing) Then 
    ObjXl.Application.DisplayAlerts = False 
    ObjXl.Workbooks.Close 
    ObjXl.Quit 
    set ObjXl = Nothing 
End If 
Exit Sub 
GenerateXLErr: 
If Err.number = 432 or err.number = 429 THen 
    Resume Next 
End If 
End Sub