Excel自动化:保护用户删除单个工作表

VSTO 4.0 / Office 2007

在Excel文档级自动化项目中,我有一个工作表, 不能从工作簿中删除 。 恐怕一个不小心的用户可能会意外删除它,这会导致很多悲伤(例外)。

我无法保护整个工作簿,因为用户必须能够创build,删除和修改此文件。 确切地说, 一张纸需要被保护以免被删除,但是我可能忽略了一些东西,所以如果存在这样的解决办法,我全是耳朵。 例如,我可以想象,当表单可见时,我可以Protect()Unprotect()工作簿,但是这个解决scheme似乎很麻烦。

谷歌search产生以下的VBA代码:

 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 

我不熟悉VBA,但是我尝试从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; } } 

这段代码似乎没有做任何事情。 你可能会问: “嗨,Gleno,你为什么要把OnAction设置为null” ,以及我不知道该怎么设置…链接的VBA解决scheme附加到Activate和Deactivate事件,所以有更多的代码来自哪里。

提前致谢。

今天我不得不做很类似的事情。 我只要禁用表单删除button,只要你的一个“不能删除”表是激活的。 如果有删除工作表的键盘快捷键,我找不到一个。 (如果有的话,你也可以禁用它。)

这将在你的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; } 

这将在你的丝带代码后面:

  public void InvalidateBuiltinControl(string controlID) { this.ribbon.InvalidateControlMso(controlID); } public bool deleteButton_GetEnabled(IRibbonControl control) { return Globals.ThisWorkbook.CanDeleteActiveSheet(); } 

这将在你的function区xml:

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

我仍然有点怀念在ThisWorkbook中的function参考,但到目前为止,没有人在我之前发布的问题中提到过更好的方法。 希望这可以帮助!

我有一个类似的问题,我知道如何保护工作表,但我需要打开保护之后,工作表已填充SQL连接的外部数据。 我无法find正确的事件来做到这一点。

这应该帮助你把它放在工作表的启动事件中:

Me.Protect(password:=“password”,allowFiltering:= True,allowSorting:= True,allowUsingPivotTables:= True)