最近、小さなExcelアドインを作成する必要がありました。 ところで、その前は、.NETからのMS Officeでの経験は、Office Primary Interop Assembliesを使用してExcelでレポートを生成する簡単なユーティリティに限定されていました。 そして、オフィスがAspose.NETのライセンスを購入したとき、COMを介したオフィスとのやり取りは、悪い夢のように忘れられていました。 だから、トピックを理解し始めて、私は初心者のための健全なロシア語のチュートリアルの欠如に不愉快に驚きました。 今、私はこのギャップを埋めたいです。 例として、ボタンをクリックするだけで、現在のシートに現在の月の日のリストを生成し、休日を強調表示するアドインを作成します。 興味のあるカットをお願いします!
序文の代わりに
私自身、MS Officeの開発の専門家ではないことを事前に予約しておきたいと思います。また、鍛冶屋に対する私の決定を批判する人がいるかもしれません。 まあ、私は建設的な批判に喜んでいるでしょう。 また、この記事はExcelアドインを作成するための包括的なガイドではなく、ExcelアドインのアーキテクチャまたはMicrosoft.Office.Core名前空間の内容を詳細に説明することを目的としていません。 これは入門記事であり、初心者が新しいトピックをナビゲートするのに役立ち、何か意味のあるアドインを作成するプロセスをガイドしてくれることを願っています。 それでは始めましょう!
ソリューションを準備します
スタジオを開いて、Excel 2010アドインなどの新しいプロジェクトを作成しましょう。 SampleAddInと呼びましょう。
すべてがあなたのために正しいことが判明した場合(そして、ここで正確に何が起こる可能性がありますか?..)、次の構造を持つソリューションが表示されます。
スタジオが生成した唯一のファイルはThisAddIn.csです。
public partial class ThisAddIn { private void ThisAddIn_Startup(object sender, System.EventArgs e) { } private void ThisAddIn_Shutdown(object sender, System.EventArgs e) { } #region VSTO generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InternalStartup() { this.Startup += new System.EventHandler(ThisAddIn_Startup); this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown); } #endregion }
ここではすべてが簡単です。アドインの開始と終了のイベントハンドラーを登録するだけです。 もちろん、アドインは何もしませんが、F5キーを押すと、通常のプロジェクトとして既に開始できます。 特に素晴らしいのは、この段階では展開に煩わされないことです。 スタジオ自体が、必要なセキュリティ設定でExcelを起動し、アドインをオフにします。 すべてがうまくいった場合、Excelを起動すると、次の碑文が表示されます。
インターフェースを描く
タイプRibbonの要素をソリューションに追加し、SampleRibbonと呼びます
デザイナーで、そこにボタンを追加します。
そして、タブ、グループ、ボタンの名前を設定します。
また、ボタンクリックハンドラーも作成します。
public partial class SampleRibbon { private void SampleRibbon_Load(object sender, RibbonUIEventArgs e) { } private void button1_Click(object sender, RibbonControlEventArgs e) { MessageBox.Show("Hello, world!"); } }
プロジェクトを実行してみましょう。 すべてを正しく行った場合、Excelには、メッセージボックスが表示されるボタンをクリックすることで、ボタンが付いた新しいタブがあります。
少し深く掘る
現時点では、2つの問題に直面しています:第1に、ThisAddInクラスに、実行中のExcelインスタンスへのアクセスを提供するApplicationフィールドがある場合、Ribbonクラスには類のないものがあるため、Excelワークシートと対話する方法が明確ではありません。 第二に、私たち皆が知っているように、表示ロジックとビジネスロジックの混合は、コード内のスパゲッティのかなりの部分に対する優れた準備です。 したがって、これらの2つの問題を取り除くためにコードを変更すると同時に、何もアクションを行わずにリボンをExcelに構築した「魔法」を理解します。
ThisAddInクラスが実際に継承されるAddInBaseクラスのCreateRibbonExtensibilityObjectメソッドは、アドインでカスタムフィードを作成します。 神に感謝します。この方法は慎重に仮想化されているため、それをオーバーロードしても問題はありません。 まず、コードをThisAddInクラスに追加します。
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject() { return null; }
そして、プロジェクトを実行します。 出来上がり! タブが消えました。 次に、SampleRibbonクラスを変更します。
public partial class SampleRibbon { public event Action ButtonClicked; private void SampleRibbon_Load(object sender, RibbonUIEventArgs e) { } private void button1_Click(object sender, RibbonControlEventArgs e) { if (ButtonClicked != null) ButtonClicked(); } }
そして、クラスThisAddIn:
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject() { var ribbon = new SampleRibbon(); ribbon.ButtonClicked += ribbon_ButtonClicked; return Globals.Factory.GetRibbonFactory().CreateRibbonManager(new IRibbonExtension[] { ribbon }); } private void ribbon_ButtonClicked() { MessageBox.Show("Hello, world!"); }
プロジェクトを実行します。 すべてを正しく行った場合、タブが再表示され、ボタンを押すと、以前と同様にメッセージボックスが表示されます。
細胞を扱う
今、この騒ぎが実際に始まったのは、テーブルの生成です。 最初に、セル装飾用のヘルパーメソッドをいくつか作成します。
public static void MarkBold(dynamic border) { border.Weight = XlBorderWeight.xlMedium; }
このメソッドは、セルの境界線を太字にします。 ところで、.NET 4.0以降では、引数の種類border-dynamic-に注意してください。COMオブジェクトを操作するのに非常に便利な方法です。 突然あなたが知らない場合、例えばこの記事を読むことをお勧めします。 便宜上、さらに2つのメソッドを作成します。
public enum Border { Left = 1, Right = 2, Top = 3, Bottom = 4 } private void MarkCell(dynamic cell, DateTime day) { if (day.DayOfWeek == DayOfWeek.Saturday) { MarkBold(cell.Borders[Border.Left]); MarkBold(cell.Borders[Border.Top]); MarkBold(cell.Borders[Border.Bottom]); } if (day.DayOfWeek == DayOfWeek.Sunday) { MarkBold(cell.Borders[Border.Right]); MarkBold(cell.Borders[Border.Top]); MarkBold(cell.Borders[Border.Bottom]); } cell.Columns[1].ColumnWidth = 4; }
ここで、月の曜日のリストを取得するコードを作成します。
private static IEnumerable<DateTime> GetDaysOfCurrentMonth() { var today = DateTime.Today; var dayIter = new DateTime(today.Year, today.Month, 1); while (dayIter.Month == today.Month) { yield return dayIter; dayIter = dayIter.AddDays(1); } }
そして、それをすべてまとめてください:
private void ribbon_ButtonClicked() { GenerateTable(Application.ActiveWorkbook.ActiveSheet, 1, 1); } private void GenerateTable(dynamic wSheet, int row, int column) { var currentMonth = GetDaysOfCurrentMonth().ToArray(); for (int i = 0; i < currentMonth.Length; i++) { wSheet.Cells[row, column + i] = currentMonth[i].Day; MarkCell(wSheet.Cells[row, column + i], currentMonth[i]); } }
どこでも間違いを犯していない場合は、プロジェクトを開始してタブのボタンをクリックすると、次のようなものが表示されます。
結論の代わりに
これですべてです。この記事を読んだ後、.NET用のExcelアドインの作成に関する基本的な理解を得たと思います。 さらに読むには、もちろん、MSDNとこのブログをお勧めします。このトピックを勉強するとき、私は大いに役立ちました。 皆さん、幸運を祈ります。ご清聴ありがとうございました!