Пишем надстройку Excel на Excel-DNA. Часть 2

от автора

Введение

Это продолжение статьи о создании надстройки для Excel с помощью библиотеки Excel-DNA о сборке простой надстройки с пользовательской формулой. Здесь рассмотрим как сделать свою панель с кнопками, взаимодействовать с рабочей книгой, выводить уведомления, а также получить доступ к элементам интерфейса Excel.

Создание панели

Панели Ribbon описываются в XML. Простейшая выглядит так:

<customUI xmlns='http://schemas.microsoft.com/office/2006/01/customui'>     <ribbon>         <tabs>             <tab id='MyAddinTab' label='My Addin Tab'>                 <group id='MyAddinGroup' label='My Addin Group'>                     <button id='Button1' label='Button 1' size='large' imageMso='HappyFace' />                     <button id='Button2' label='Button 2' size='large' imageMso='SadFace' />                     <button id='Button3' label='Button 3' size='large' imageMso='Piggy' />                 </group>             </tab>         </tabs>     </ribbon> </customUI> 

Тег tab описывает вкладки на панели инструментов, group — группы элементов, которые визуально отделяются друг от друга вертикальной чертой, button — элементы кнопок.

Для того чтобы отобразить такую панель в Excel нужно наследовать классу ExcelRibbon и переопределить метод GetCustomUI в котором возвращаем XML панели.

using ExcelDna.Integration.CustomUI;    namespace ExcelAddIn.Controllers;    public class RibbonController : ExcelRibbon {     public override string GetCustomUI(string ribbonID)     {         return @"<customUI xmlns='http://schemas.microsoft.com/office/2006/01/customui'>       <ribbon>         <tabs>           <tab id='MyAddinTab' label='My Addin Tab'>             <group id='MyAddinGroup' label='My Addin Group'>                 <button id='Button1' label='Button 1' size='large' imageMso='HappyFace' />                 <button id='Button2' label='Button 2' size='large' imageMso='SadFace' />                 <button id='Button3' label='Button 3' size='large' imageMso='Piggy' />             </group>           </tab>         </tabs>       </ribbon>     </customUI>";     } } 
Результат

Результат

Фабрика инструментов

Определим абстрактный класс инструмента, который будет вызываться кнопкой:

namespace ExcelAddIn.Tools;    public abstract class Tool : IDisposable {     public abstract void Execute();        public void Dispose()     {         Dispose(true);         GC.SuppressFinalize(this);     }      protected abstract void Dispose(bool disposing); } 

И фабрику этих инструментов:

using ExcelDna.Integration.CustomUI;    namespace ExcelAddIn.Tools;    public static class ToolFactory {     public static Tool GetTool(IRibbonControl control)     {         return control.Id switch         {             "Button1" => new Button1Tool(),             "Button2" => new Button2Tool(),             "Button3" => new Button3Tool(),             _ => throw new NotImplementedException(control.Id)         };     } } 

Чтобы кнопка заработала, нужно добавить в её описание атрибут onAction с именем метода который будем выполнять.

using ExcelDna.Integration.CustomUI; using ExcelAddIn.Tools;   namespace ExcelAddIn.Controllers;    public class RibbonController : ExcelRibbon {     public override string GetCustomUI(string ribbonID)     {         return @"<customUI xmlns='http://schemas.microsoft.com/office/2006/01/customui'>       <ribbon>         <tabs>           <tab id='MyAddinTab' label='My Addin Tab'>             <group id='MyAddinGroup' label='My Addin Group'>                 <button id='Button1' label='Button 1' size='large' imageMso='HappyFace' onAction='OnToolPressed'/>                 <button id='Button2' label='Button 2' size='large' imageMso='SadFace' onAction='OnToolPressed'/>                 <button id='Button3' label='Button 3' size='large' imageMso='Piggy' onAction='OnToolPressed'/>             </group>           </tab>         </tabs>       </ribbon>     </customUI>";     }          public void OnToolPressed(IRibbonControl control)     {         using var tool = ToolFactory.GetTool(control);         tool.Execute();     } } 

Первый инструмент

Пусть первая кнопка просто покажет нам сообщение в MessageBox.

Чтобы надстройка смогла работать с Windows Forms нужно добавить в .csproj строку:

  <PropertyGroup> ...     <UseWindowsForms>true</UseWindowsForms>   </PropertyGroup> 

Теперь сделаем класс-наследник абстрактного класса Tool:

namespace ExcelAddIn.Tools;   public class Button1Tool : Tool {     public override void Execute()     {         MessageBox.Show($"Message from {nameof(Button1Tool)}");     }       protected override void Dispose(bool disposing)     {     } } 
Проверяем работу

Проверяем работу

Получаем доступ к рабочей книге

Взаимодействие с Excel — его рабочими книгами, листами, интерфейсом — осуществляется через интерфейс Application.

Чтобы получить к нему доступ нужно установить пакет ExcelDna.Interop:

dotnet add package ExcelDna.Interop 

Объект Application является свойством класса ExcelDnaUtil.

Пусть вторая кнопка инкрементирует текущую ячейку:

using Application = Microsoft.Office.Interop.Excel.Application;    namespace ExcelAddIn.Tools;    public class Button2Tool : Tool {     private readonly Application app;      public Button2Tool()     {         app = (Application)ExcelDnaUtil.Application;     }          public override void Execute()     {         if (app.ActiveCell == null)         {             return;         }         double? cellValue = app.ActiveCell.Cells.Value2;         if (cellValue != null)         {             app.ActiveCell.Cells.Value2 = ++cellValue;         }     }        protected override void Dispose(bool disposing)     {      } } 
Работа второй кнопки

Работа второй кнопки

Строка состояния

В нижней части окна Excel есть строка состояния, куда можно выводить сервисную информацию.

Это бывает полезно для отображения процесса какой-либо ресурсоемкой задачи.

После окончания работы необходимо сбросить строку, передав ей значение false. Это вернет контроль над ней приложению Excel, иначе в ней зависнет последнее переданное нами сообщение.

using Application = Microsoft.Office.Interop.Excel.Application;    namespace ExcelAddIn.Tools;    public class Button3Tool : Tool {     private readonly Application app;          public Button3Tool()     {         app = (Application)ExcelDnaUtil.Application;     }      public override void Execute()     {         for (int i = 0; i < 10;)         {             Thread.Sleep(400);             app.StatusBar = $"Выполнено {++i * 10}%...";         }     }      protected override void Dispose(bool disposing)     {         app.StatusBar = false;     } } 
Работа строки состояния

Работа строки состояния

Заключение

В этой статье описываются основы создания собственной панели инструментов надстройки и её взаимодействие с Excel.

Код к этой и предыдущей статье лежит в репозитории https://gitea.cebotari.ru/chebser/ExcelAddIn


ссылка на оригинал статьи https://habr.com/ru/articles/741732/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *