2010-08-30 10 views
1

VSTO 4.0/Office 2007Automation Excel: Protéger feuille unique de la suppression par l'utilisateur

Dans un projet d'automatisation au niveau du document Excel, j'ai une feuille de calcul qui ne doit pas être supprimé du classeur. J'ai peur qu'un utilisateur imprudent puisse le supprimer par accident, ce qui provoque actuellement beaucoup de chagrin (exceptions à gogo).

Je ne peux pas protéger l'ensemble du classeur, car l'utilisateur doit pouvoir créer, supprimer et modifier ce fichier. Exactement une feuille doit être protégé contre la suppression, mais je peux être négliger quelque chose, donc s'il existe une telle solution, je suis tout ouïe. Par exemple, je pourrais imaginer que je peux Protect() et Unprotect() le classeur lorsque la feuille est visible, mais cette solution semble malpropre.

recherche sur Google yielded le code VBA suivant:

Private Sub Worksheet_Activate() 
Dim CB As CommandBar 
Dim Ctrl As CommandBarControl 
For Each CB In Application.CommandBars 
Set Ctrl = CB.FindControl(ID:=847, recursive:=True) 
If Not Ctrl Is Nothing Then 
Ctrl.OnAction = "RefuseToDelete" 
Ctrl.State = msoButtonUp 
End If 
Next 
End Sub 

Je ne suis pas familier avec VBA, mais j'ai essayé d'exécuter ce à partir de la méthode de démarrage généré VSTO:

private void Sheet1_Startup(object sender, System.EventArgs e) 
{ 
    //Is there a neater way to iterate through all Office Collections? 
    for (var i = 1; i <= Application.CommandBars.Count; i++) 
    { 
     var commandBar = Application.CommandBars[i]; 
     //847 is a magical constant that any fule no has something to do with sheet deletion 
     var control = commandBar.FindControl(Id: 847, Recursive: true); 
     if (control != null) control.OnAction = null; 
    } 
} 

Ce code semble faire exactement rien. Vous pouvez demander "Hey, Gleno, pourquoi mettez-vous OnAction à zéro", bien je ne sais pas quoi mettre à ... La solution VBA liée attache à Activer et désactiver les événements, donc il y a plus de code où vient de.

Merci d'avance.

Répondre

2

Je devais faire quelque chose de très similaire aujourd'hui. Je voudrais juste désactiver les boutons de suppression de feuille chaque fois que votre feuille "undeleteable" est active. S'il y a un raccourci clavier pour supprimer une feuille, je ne peux pas en trouver un. (Si oui, vous pouvez désactiver aussi.)

Cela irait dans votre classe ThisWorkbook:

private void ThisWorkbook_Startup(object sender, System.EventArgs e) 
    { 
     this.SheetActivate += (sh) => 
      { 
       this.ribbon.InvalidateBuiltinControl("SheetDelete"); 
      }; 
    } 

    public bool CanDeleteActiveSheet() 
    { 
     if (this.ActiveSheet == null) 
      return true; 

     // Replace Sheet1 with your sheet's CodeName 
     return ((Excel.Worksheet)this.ActiveSheet).CodeName != "Sheet1"; 
    } 

    // Keep a local reference to the ribbon in your ThisWorkbook class 
    // so you can call InvalidateControl() from it. 
    Ribbon ribbon; 
    protected override IRibbonExtensibility CreateRibbonExtensibilityObject() 
    { 
     this.ribbon = new Ribbon(); 
     return this.ribbon; 
    } 

Cela irait dans votre code de ruban derrière:

public void InvalidateBuiltinControl(string controlID) 
    { 
     this.ribbon.InvalidateControlMso(controlID); 
    } 

    public bool deleteButton_GetEnabled(IRibbonControl control) 
    { 
     return Globals.ThisWorkbook.CanDeleteActiveSheet(); 
    } 

et ceci allez dans votre xml ruban:

<commands> 
    <command idMso="SheetDelete" getEnabled="deleteButton_GetEnabled" /> 
</commands> 

Je suis toujours un peu méfiant de tenir sur cette référence du ruban dans ThisWorkbo ok, mais jusqu'à présent, personne n'a mentionné une meilleure façon de the question I posted earlier. J'espère que cela t'aides!

+0

Merci Nick. Si je devais à nouveau travailler avec le modèle d'objet de bureau, ce serait trop tôt. :) – Gleno

+0

Hahaha. Je vais te le dire, c'est mieux maintenant que ce n'était il y a quelques années! –

1

J'ai un problème similaire où je sais comment protéger la feuille de calcul, mais je dois activer la protection après que la feuille a été remplie avec des données externes à partir d'une connexion SQL. Je ne peux pas localiser l'événement correct pour le faire.

Cela devrait vous aider à mettre dans l'événement de démarrage pour la feuille de calcul:

Me.Protect (mot de passe: = "mot de passe", allowFiltering: = True, AllowSorting: = True, allowUsingPivotTables: = True)

Questions connexes