Excel の単一ドキュメント インターフェイスのプログラミング
Excel でのシングル ドキュメント インターフェイスのプログラミングの考慮事項について説明します。
Excel 2010 および Excel 2013 でのシングル ドキュメント インターフェイスとマルチ ドキュメント インターフェイスの比較
シングル ドキュメント インターフェイス (SDI) は Excel 2013 の新機能です。 SDI は、グラフィカル ユーザー インターフェイス (UI) アプリケーションをオペレーティング システムのウィンドウ マネージャーが独立して処理できる個別のウィンドウに表示する方法です。 Excel 2013 の場合、それぞれの Excel ウィンドウには 1 つのブックのみが含まれ、専用のリボン UI が含まれます (図 1 を参照)。 既定では新たにブックを開くと、同じ Excel インスタンスであっても、別の Excel ウィンドウに表示されます。
図 1. Excel 2013 でのシングル ドキュメント インターフェイス
これと対象的なのがマルチ ドキュメント インターフェイス (MDI) であり、単一の親ウィンドウに入れ子になった複数の子ウィンドウが含まれ、メニューまたはツール バーは親ウィンドウにだけあります。 Excel 2010 の場合、Excel の単一インスタンスの各ブックは、共通のリボン UI を利用します (図 2 を参照)。
図 2. Excel 2010 でのマルチ ドキュメント インターフェイス
Excel 2010 は MDI を使用します。これは、Excel の特定のインスタンスで開いているすべてのブックを保持する 1 つのアプリケーション レベルのウィンドウがあることを意味します。 ブックのウィンドウは Excel アプリ ウィンドウ内に配置でき、すべて同じリボン UI を共有します。 Excel の SDI は、各ブックに独自の最上位レベルのアプリ ウィンドウがあり、それに対応するリボン UI があることを意味します。
注:
Excel には MDI 互換性オプションはありません。
デュアル モニター システムでは、Excel の SDI を使用すると、各ブックを異なるモニターにドラッグすることによって、2 つのブックを並べて比較できます。 各ブックは相互に独立して動作します。
Excel 2010 と Excel 2013 の両方を使用できる場合は、以下の手順を実行することによって、SDI と MDI の動作を確認できます。
MDI インターフェイスと SDI インターフェイスのプロセスの数を比較するには
- Windows の [スタート] メニューで、Excel 2010 を選択します。
- 2 番目の Excel を開始します。 2 つの Excel ウィンドウが表示されることを確認します。
- Windows のタスク バーで、[タスク マネージャーの起動] を選択します。
- [プロセス] タブを選択し、2 つの [Excel.exe] エントリが表示されるまで下にスクロールします。 これにより、既定では、Excel が呼び出されるたびに 1 つの新しいインスタンスが開く (2 つの Excel インスタンス) ことがわかります。
- Excel の 2 つのインスタンスを閉じます。
- Windows の [スタート] メニューで、Excel 2013 を選択します。
- 2 番目の Excel を開始します。 2 つの Excel ウィンドウが表示されることを確認します。
- もう一度タスク マネージャーを起動します。
- [ プロセス ] タブで、 Excel.exeが表示されるまで下にスクロールします。 Excel を 2 回開きましたが、Excel の同じ 1 つのインスタンスに 2 つのブックが含まれることに注意してください。
Excel の 1 つのインスタンスの内部で SDI および MDI がどのように動作するのかを見るには、次の手順を実行してください。
MDI インターフェイスと SDI インターフェイスの Excel インスタンスの数を比較するには
- Windows の [スタート] メニューで、Excel 2010 を選択します。
- Excel ウィンドウを選択してアクティブにし、Book1 が現在のブックであることを確認します。
- Ctrl + N キーを押して別のブックを開きます。 Book2 が現在のブックになっていることを確認します。
- Book2 を最小化してから、Book1 を確認します。 両方のブックが Excel の同じインスタンスに含まれています。
- Excel を閉じます。
- Windows の [スタート] メニューで、Excel 2013 を選択します。
- Excel ウィンドウを選択してアクティブにし、Book1 が現在のブックであることを確認します。
- Ctrl + N キーを押して別のブックを開きます。 Book2 が別のウィンドウで (ただし、同じ Excel インスタンス) 開かれることを確認します。
- Excel を閉じます。
注:
次のコマンド ライン スイッチを使用して、Excel の複数のインスタンスを開くことができます: excel.exe /x。 このスイッチは、Excel を新しいプロセスで開始します。
この記事では、Excel UI での SDI の実装およびそれが Excel でのプログラミングに与える影響について説明します。
ユーザー インターフェイスの変更点
Excel ブックを開いた後でよく見ると、リボンの右上隅にウィンドウの状態ボタン ( 最小化、 最大化、 復元) が表示されなくなります。 図 3 は、Excel および Excel 2007 でのウィンドウ状態ボタンです。 最上位ウィンドウは単一のブックまたはブック ビューに直接結び付けられるようになったので、Excel のウィンドウ管理 UI は必要なくなりました。
図 3. Excel 2010 でのウィンドウ状態 UI
さらに、Excel 以降では、図 4 に示すように単一の Excel インスタンス ウィンドウ内に複数のブック ウィンドウが表示されることはなくなりました。
図 4. 単一の Excel インスタンス ウィンドウ内の複数のブック
再計算と数式
Excel の再計算は引き続き "グローバル" になります。つまり、Excel の同じインスタンス内のブック間で発生します。 Excel の同じインスタンスで開いているブック間で参照する数式は、一緒に計算に参加し、同じブックの計算モード (データ テーブルを除く自動、自動、手動) を共有します。
MDI では、ただ 1 つの数式バーを使用して、Excel のそのインスタンスで開かれているすべてのブックを処理します。 SDI では、ブックごとに 1 つの数式バーがあります。 SDI では、数式のブック間参照を編集するときは、図 5 に示すように、ソース ブックとターゲット ブックの両方の数式バーに、現在編集中の数式が表示されます。
図 5. ブック間数式の更新
カスタム作業ウィンドウ
MDI の最上位ウィンドウにアタッチされたカスタム作業ウィンドウが、SDI の特定のブックのウィンドウにアタッチされるようになりました。 別のブックに切り替えると、そのブック ウィンドウがアクティブになります。これは、開発者のコードがそのブックのカスタム作業ウィンドウを具体的に表示するように更新されない限り、必ずしもカスタム作業ウィンドウがアタッチされるとは限りません。
要約すると、開発者は次の作業を行う必要があります。
- カスタム作業ウィンドウを表示するブックの場合は、それを明示的に行うコードを記述します。
- すべてのカスタム作業ウィンドウに同じ状態を反映させる場合は、すべてのインスタンスでカスタム作業ウィンドウの状態の更新を明示的に処理します。 たとえば、ユーザーがチェック ボックスをオンにしたら、Excel のすべてのインスタンスのすべてのカスタム作業ウィンドウにそれを反映します。
カスタム リボン
カスタム リボンのタブとコントロールは、以前のバージョンの Excel ではアプリケーション インスタンスごとに 1 つのリボン UI と考えられていましたが、Excel では各ブックのリボンに反映されます。 カスタム リボンの開発者は、MDI では Excel のリボン UI の異なるインスタンスでのコントロールの複数のインスタンスについて考慮する必要はありませんでしたが、SDI ではこのような状況を考慮する必要があります。
開いているブック間ですべてのリボン UI コントロールを同じ状態にしておく場合は、次の操作を行う必要があります。
- コードがブック ウィンドウを順番に切り替えて、コントロールの状態を更新できるようにします。
または
- ユーザーが別のブックに切り替えたときにそのイベントを取得してウィンドウ切り替えの一部としてコントロールを更新できるように、コントロールの状態をキャッシュします。
さらに、リボンにアクセスするために を使用 Application.Commandbar
してカスタム UI コントロールを追加するコードを開発する場合を考えてみましょう。 後でそのコントロールにアクセスするときに、アクティブなブックがコントロールを追加したブックと同じではない可能性があることを考慮する必要があります。
VBA コードに関する考慮事項
SDI への移行により、すべての Excel アプリケーション レベルのウィンドウ メソッド、イベント、プロパティは影響を受けず、以前のバージョンの Excel (、Application.ActiveWindow
Application.Windows
、など) と同様に動作します。
Excel では、ブック レベルのすべてのウィンドウ メソッド、イベント、プロパティが最上位のウィンドウで動作するようになりました (たとえば、Workbook.WindowActivate
特定のブックに切り替えると、イベントは引き続きトリガーされ、Workbook.Resize
そのブックのサイズが変更されてもイベントはトリガーされ、ThisWorkbook.Windows(1).Height
、、ThisWorkbook.Windows(1).Width
ThisWorkbook.Windows(1).Left
、ThisWorkbook.Windows(1).Right
、ThisWorkbook.Windows(1).Minimize
ThisWorkbook.Windows(1).Maximize
、など、アクティブなブックの最上位ウィンドウで動作します)。
次の表では特殊なケースについて説明します。
表 1. SDI でのオブジェクト モデルの動作
関数 | 説明 | SDI による影響 |
---|---|---|
Application.Visible |
オブジェクトを表示するかどうかを表すブール型 (Boolean) の値を設定します。 読み取り/書き込みが可能です。 | すべてのウィンドウが非表示の場合:
|
Application.ShowWindowsInTaskbar |
True の 場合は、開いているブックごとに別の Windows タスク バー ボタンがあります。 既定値は True です。 値の取得と設定が可能なブール型 (Boolean) の値です。 | この設定は、Excel では非推奨です。 |
Application.Caption |
Microsoft Excel ウィンドウのタイトル バーに表示される名前を表す文字列型 (String) の値を取得、または設定します。 | Excel のそのインスタンスのすべてのウィンドウを更新します。 |
Application.Hwnd |
Excel ウィンドウの最上位レベルのウィンドウ ハンドルを示す長整数型 (Long) の値を返します。 読み取り専用です。 | アクティブなウィンドウのハンドルを返します。 |
Application.FormulaBarHeight |
ユーザーが数式バーの高さを行数で指定できるようにします。 値の取得と設定が可能な長整数型 (Long) の値です。 | Excel のそのインスタンスのすべてのウィンドウではなく、現在アクティブなブック ウィンドウで動作します。 |
Application.DisplayFormulaBar |
数式バーが表示されている場合は True を指定します。 読み取り/書き込みが可能な Boolean です。 | Excel のそのインスタンスのすべてのウィンドウで動作します。 |
Workbook.Windows |
指定したブック内のすべてのウィンドウを表す Windows コレクションを返します。 読み取り専用 Windows オブジェクト。 | 動作に変更はありません。 作業ウィンドウや追加ビューなど、このブックのウィンドウのコレクションを返します。 |
Workbook.WindowResize |
ブックのウィンドウ サイズを変更したときに発生します。 | 動作に変更はありません。 ブック ウィンドウ (最上位) のサイズが変更されるとトリガーされます。 |
Window.Caption |
ドキュメント ウィンドウのタイトル バーに表示される名前を表すバリアント型 (Variant) の値を取得または設定します。 | 動作に変更はありません。 |
Workbook.Protect(Password, Structure, Windows) |
変更できないようにブックを保護します。 | Windows パラメーターの値に関係なく (True または False)、ウィンドウ構造の保護は有効になりません。 True が指定されている場合、ランタイム エラーは表示されませんが、プロシージャ コールのその部分は NO-OP を返します。 |
注:
カスタム コードを変更しなくても、XLM コマンドは SDI Excel でも引き続き意図したとおりに動作します。
ブックの保護ウィンドウの非推奨化
SDI では、各ブックに専用の最上位ウィンドウがあり、復元、最小化、閉じるなどの操作を実行できます。 この最上位ウィンドウを移動またはサイズ変更したり、閉じたりするときに可能性のある混乱を最小限にするため、Excel での [ブックの保護] 機能の [ウィンドウ] オプションは使用できなくなっています (図 6 を参照)。 表 2 ではこの操作について詳しく説明します。
図 6. [ブックの保護] ダイアログ ボックスで無効になった [ウィンドウ] オプション
操作 | 動作 |
---|---|
以前のバージョンの Excel で作成されたブックを、[ブックの保護] を有効にして開く | Excel はウィンドウの位置とサイズの属性を認識しますが、ユーザーがこれらのウィンドウを配置したり閉じたりするのを禁止することはありません。 |
[シート構成とウィンドウの保護] ダイアログ ボックスを表示する | Excel ではダイアログ ボックスが表示されますが、 Windows オプションは無効になっています。 |
SDI の問題の解決策
以下では、SDI を使用すると発生する可能性がある問題の回避策について説明します。
赤い [X] [閉じる ] ボタンをクリックしてブックを閉じることはできません。そのブックは、モーダル ユーザー フォームを使用してプログラムによって開かれます。 この問題を回避するため、以下のコードをユーザー フォームの Layout イベント プロシージャに追加し、ユーザー フォームをモードレスとして開くことをお勧めします。
Private Sub UserForm_Layout() Static fSetModal As Boolean If fSetModal = False Then fSetModal = True Me.Hide Me.Show 1 End If End Sub
もう 1 つのオプションとしては、ブック ウィンドウを開き、他の何らかのウィンドウをアクティブにしてから、ブック ウィンドウを再びアクティブにします。 [閉じる] ボタンを使用してブックを閉じることができるようになるはずです。
VBA コードで複数のブックを開き、 DataEntryMode プロパティを使用してデータ入力とブックの終了を制御するとします。 Excel の SDI モデルでは、各ブックは専用のプロセスに含まれるので、あるブックで使用される DataEntryMode プロパティは他のブックの存在を認識せず、したがってそれらの相互作用にはほとんど影響を与えません。 この問題を回避するには、2 つのオプションがあります。
Window.Visible = False
またはSheet.Visible = False
を使用して、それぞれ余分なブックまたはワークシートを非表示にできます。 を使用Workbook.BeforeClose(Cancel) = True
して、終了イベントを検出して取り消します。コマンド バー コードおよび XLA ファイルによって Excel ブックに追加されたツールバーは、ブックを閉じて再び開くまで表示されません。 コマンド バーを使用した UI のカスタマイズは、Excel 2007 から非推奨になりました。 最善の解決策は、記事「Customizing the 2007 Office Fluent Ribbon for Developers」で詳細に説明されているように、XML ファイルを使用してリボンの UI をカスタマイズする方法です。
もう 1 つのオプションは、アプリケーション レベルのイベントを使用して、開く新しいブックを検出してから、ブックの代わりにを使用
Application.Windows
してリボン コントロールを追加することです。 この方法のサンプル コードを次に示します。Private Sub Workbook_Open() ToolBarsAdd End Sub Sub ToolBarsAdd() Dim oBar As CommandBar ToolBarsDelete Set oBar = Application.CommandBars.Add(Name:="MyToolBar") ' With oBar With .Controls.Add(Type:=msoControlButton) .OnAction = "SayHello" .FaceId = 800 End With End With oBar.Visible = True End Sub Sub SayHello() MsgBox "Hello from '" & ActiveWorkbook.Name & "'" End Sub
その後、ブックを閉じる前に、次のコードを使用してツールバーを削除します。
Private Sub Workbook_BeforeClose(Cancel As Boolean) ToolBarsDelete End Sub Sub ToolBarsDelete() Dim wnd As Window On Error Resume Next For Each wnd In Application.Windows wnd.Activate Application.CommandBars("MyToolBar ").Delete Next wnd End Sub
Excel 2010 では、既定では、すべての Excel ウィンドウの上部に、モードレス ユーザー フォームが最上位ウィンドウとして表示されます。 Excel 2013 のモードレス ユーザー フォームは、ユーザー フォームが表示されたときにアクティブであったブック ウィンドウの上にのみ表示されます。 Excel Most Valuable Professional (MVP) Jan Karel Pieterse は、 の Web ページ https://www.jkp-ads.com/articles/keepuserformontop.aspで問題の説明と解決策を提供します。
概要
Excel 2013 の新しいシングル ドキュメント インターフェイスにより、複数のブックの処理が容易になります。 利便性のため、ブックを別のモニターにドラッグすることもできます。 最上位ウィンドウとリボン UI メニューはブックごとに 1 つのみであることだけを憶えておいてください。 ブック間を移動するときにコントロールの状態と設定をキャッシュするように既存のコードを更新するときに、このことが必要になる場合があります。
関連項目
サポートとフィードバック
Office VBA またはこの説明書に関するご質問やフィードバックがありますか? サポートの受け方およびフィードバックをお寄せいただく方法のガイダンスについては、Office VBA のサポートおよびフィードバックを参照してください。