c# - Excel 自动化 : Protect single worksheet from deletion by user

标签 c# excel vsto

VSTO 4.0/Office 2007

在 Excel 文档级自动化项目中,我有一个工作表 不得从工作簿中删除 .我担心粗心的用户可能会意外删除它,这目前会引起很多悲伤(异常(exception)情况很多)。

我无法保护整个工作簿,因为用户必须能够创建、删除和以其他方式修改此文件。需要保护一张纸不被删除,但我可能会忽略一些东西,所以如果存在这样的解决方案,我会全力以赴。例如,我可以想象我可以 Protect()Unprotect()工作表可见时的工作簿,但此解决方案似乎很困惑。

谷歌搜索 yielded以下 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 解决方案附加到激活和停用事件,所以有更多代码在哪里来自。

提前致谢。

最佳答案

我今天必须做一些非常相似的事情。只要您的一个“不可删除”工作表处于事件状态,我就会禁用工作表删除按钮。如果有删除工作表的键盘快捷键,我找不到。 (如果有,您也可以禁用它。)

这将出现在您的 ThisWorkbook 类(class)中:

    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();
    }

这将进入您的功能区 xml:
<commands>
    <command idMso="SheetDelete" getEnabled="deleteButton_GetEnabled" />
</commands>

我仍然对在 ThisWorkbook 中保留该功能区引用持怀疑态度,但到目前为止,还没有人在 the question I posted earlier 中提到更好的方法。 .希望这可以帮助!

关于c# - Excel 自动化 : Protect single worksheet from deletion by user,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3597549/

相关文章:

c# - NativeApplicationClient 和 OAuth2Authenticator 未解析

arrays - 二维数组作为字典的项目

excel - 用于 64 位 Visual Basic 的更新

c# - 使用 ASP.NET 在 IE8 中通过 https 下载文件

c# - 将字符串数组转换为 C# 中的串联字符串

c# - 当我没有可用的控件时如何调用()

c# - 使用 Agility Pack 设置外部加载网页的文本框内部文本

vba - 在 PowerPoint 中格式化多个文本选择

c# - 从 VSTO 插件获取 Outlook 窗口

c# - 事件 : Before Outlook close