2010-08-30 2 views
1

VSTO 4.0/Office 2007Excel Автоматизация: защита одного листа от удаления пользователем

В проекте автоматизации на уровне документа Excel, у меня есть рабочий лист, который не должен быть удален из книги. Я боюсь, что небрежный пользователь может случайно удалить его, что в настоящее время вызывает много горя (исключения в изобилии).

Я не могу защитить всю книгу, потому что пользователь должен иметь возможность создавать, удалять и иным образом модифицировать этот файл. Точно один лист должен быть защищен от удаления, но я могу что-то игнорировать, поэтому, если существует такое решение, я все уши. Например, я мог представить, что я могу писать книгу, когда лист виден, но это решение кажется беспорядочным.

погуглить 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; 
    } 
} 

Этот код кажется делать точно ничего. Вы можете спросить «Привет, Глено, почему вы устанавливаете OnAction на нуль», ну я не знаю, что его установить ... Связанное решение VBA присоединяется к активации и деактивации событий, поэтому есть еще код, пришли из.

Заранее спасибо.

ответ

2

Мне пришлось сегодня сделать что-то очень похожее. Я бы просто отключил кнопки удаления листа каждый раз, когда ваш единственный «неустранимый» лист активен. Если есть комбинация клавиш для удаления листа, я не могу ее найти. (Если есть, то вы можете отключить это тоже.)

Это будет идти в классе 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(); 
    } 

И это будет идти в вашей ленте XML:

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

Я еще немного подозрительным, держась этой ссылке ленты в ThisWorkbo хорошо, но пока никто не упомянул лучший способ в the question I posted earlier. Надеюсь это поможет!

+0

Спасибо, Ник. Если мне когда-нибудь придется снова работать с моделью офисных объектов, это будет слишком рано. :) – Gleno

+0

Хахаха. Я скажу вам, теперь это лучше, чем было несколько лет назад! –

1

У меня возникла аналогичная проблема, когда я знаю, как защитить рабочий лист, но мне нужно включить защиту после того, как лист был заполнен внешними данными из SQL-соединения. Я не могу найти правильное событие для этого.

Это должно помочь вам положить его в случае запуска на листе:

Me.Protect (пароль: = "пароль", allowFiltering: = True, allowSorting: = True, allowUsingPivotTables: = True)

Смежные вопросы