Excel 中單一檔介面的程式設計
瞭解 Excel 中單一檔介面的程式設計考慮。
比較 Excel 2010 和 Excel 2013 中的單一和多個檔介面
Excel 2013 的新功能是單一檔介面 (SDI) 。 SDI 是將圖形使用者介面 (UI) 應用程式組織成作業系統視窗管理員個別處理的個別視窗的方法。 在 Excel 2013 中,每個 Excel 視窗只能包含一個活頁簿,而且每個視窗都有自己的功能區 UI (請參閱圖 1) 。 根據預設,當您開啟新的活頁簿時,它會顯示在另一個 Excel 視窗中,即使它是相同的 Excel 實例也一樣。
圖 1: Single Document Interface in Excel 2013
這與多文檔介面 (MDI) 形成對比,其中單一父視窗用來包含多個巢狀子視窗,只有父視窗具有功能表或工具列。 在 Excel 2010 中,單一 Excel 實例中的每個活頁簿都會使用通用功能區 UI (請參閱圖 2) 。
圖 2: Multiple Document Interface in Excel 2010
Excel 2010 使用 MDI,這表示有單一應用層級視窗,其中會保存在特定 Excel 實例中開啟的所有活頁簿。 活頁簿的視窗可以排列在 Excel 應用程式視窗內,全都共用相同的功能區 UI。 Excel 中的 SDI 表示每個活頁簿都會有自己的最上層應用程式視窗,並有自己的對應功能區 UI。
注意事項
Excel 中沒有 MDI 相容性選項。
在雙監視器系統中,Excel 中的 SDI 會將每個活頁簿拖曳至不同的監視器,以啟用兩個活頁簿的並存比較。 每個活頁簿各自獨立運作。
若要查看 SDI 和 MDI 的運作方式,如果您同時提供 Excel 2010 和 Excel 2013,請執行下列步驟。
對比 MDI 和 SDI 介面的進程數目
- 在 Windows [開始] 功能表上,啟動 Excel 2010。
- 開始第二次出現 Excel。 確認已顯示兩個 Excel 視窗。
- 在 Windows 工作列上,選擇 [啟動工作管理員],然後選取 [ 啟動工作管理員]。
- 選擇 [ 進程] 索引 標籤,然後向下捲動,直到您看到兩 個Excel.exe 專案為止。 這會告訴您,根據預設,每次在兩個 Excel 實例) (呼叫 Excel 時,Excel 都會開啟新的實例。
- 關閉 Excel 的兩個實例。
- 在 [Windows 開始] 功能表上,選擇 [Excel 2013]。
- 開始第二次出現 Excel。 確認已顯示兩個 Excel 視窗。
- 再次啟動工作管理員。
- 在 [ 進程] 索引 標籤上向下捲動,直到您看到 Excel.exe為止。 請注意,雖然您已開啟兩次 Excel,但兩個活頁簿都包含在相同的單一 Excel 實例中。
若要查看 SDI 和 MDI 在 Excel 實例內的運作方式,請執行下列步驟。
比較 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 中不再需要 Windows 管理 UI。
圖 3: Windows state UI in Excel 2010
此外,從 Excel 開始,單一 Excel 實例視窗內不再有多個活頁簿視窗,如圖 4 所示。
圖 4: 單一 Excel 實例視窗中的多個活頁簿
重新計算和公式
Excel 中的重新計算仍為「全域」,這表示它們會在相同 Excel 實例的活頁簿之間發生。 在相同 Excel 實例中開啟之活頁簿間參考的公式會一起參與計算,並且會共用相同的活頁簿計算模式, (自動、自動,但資料表除外,以及手動) 。
在 MDI 中,只有一個公式列可處理該 Excel 實例中所有開啟的活頁簿。 在 SDI 中,每個活頁簿都有一個公式列。 針對 SDI,在公式中編輯跨書籍參考時,來源和目標活頁簿公式列都會顯示目前正在編輯的公式,如圖 5 所示。
圖 5: Updating cross-workbook formulas
自訂工作窗格
附加至 MDI 中最上層視窗的自訂工作窗格現在會附加至 SDI 中特定活頁簿的視窗。 切換至不同的活頁簿將會啟動該活頁簿視窗,除非開發人員的程式碼更新為特別顯示該活頁簿的自訂工作窗格,否則該活頁簿視窗不一定會附加自訂工作窗格。
總而言之,身為開發人員,您會想要:
- 請確定您想要顯示自訂工作窗格的任何活頁簿,都會撰寫程式碼來明確執行此動作。
- 如果您想要讓所有自訂工作窗格反映相同的狀態,請確定您明確地處理所有實例的自訂工作窗格狀態更新。 例如,使用者會將核取方塊切換為 [開啟],而您想要將它反映在 Excel 所有實例的所有自訂工作窗格中。
自訂功能區
在舊版 Excel 中,假設每個應用程式實例有單一功能區 UI 的自訂功能區索引標籤和控制項,現在會傳播到 Excel 中的每個活頁簿功能區。 雖然在 MDI 中,自訂功能區開發人員不需要在 Excel 功能區 UI 的不同實例上考慮其控制項的多個實例,但使用 SDI,則必須考慮這種情況。
如果您想要讓所有功能區 UI 控制項在開啟的活頁簿上保持相同的狀態,您必須:
- 請確定程式碼能夠迴圈流覽活頁簿視窗,並更新控制項的狀態。
OR
- 快取控制項的狀態,以便當使用者切換到另一個活頁簿時,可以擷取該事件,並將控制項更新為視窗切換的一部分。
此外,請考慮開發程式碼以使用 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).Minimize
ThisWorkbook.Windows(1).Left
ThisWorkbook.Windows(1).Right
ThisWorkbook.Windows(1).Maximize
等則會在使用中活頁簿) 的最上層視窗上運作。
下表列出特殊案例。
表 1. 使用 SDI 的物件模型行為
函數 | 描述 | SDI 含意 |
---|---|---|
Application.Visible |
會傳回或設定 Boolean 值,以決定是否可以看見此物件。 讀取/寫入。 | 如果所有視窗都已隱藏:
|
Application.ShowWindowsInTaskbar |
如果 每個開啟的活頁簿都有個別的 Windows 工作列按鈕,則為 True。 預設值為 True。 讀取/寫入的 Boolean。 | 此設定在 Excel 中已被取代。 |
Application.Caption |
會傳回或設定 String 值,代表出現在 Microsoft Excel 主視窗標題列中的名稱。 | 更新該 Excel 實例的所有視窗。 |
Application.Hwnd |
會傳回 Long,此屬性指出 Microsoft Excel 視窗的最上層視窗控制碼。 唯讀。 | 會傳回使用中視窗的控制碼。 |
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 中運作。
取代保護活頁簿 Windows
在 SDI 中,每個活頁簿都有自己的最上層視窗,可供您還原、最小化和關閉。 若要將您在未移動、調整大小或關閉此最上層視窗時可能遇到的任何混淆降至最低,在 Excel 中保護活頁簿功能中的 Windows 選項已無法再使用 (請參閱圖 6) 。 表 2 進一步說明此動作。
圖 6: [保護活頁簿] 對話方塊的 Windows 選項已停用
動作 | 行為 |
---|---|
開啟在舊版 Excel 中建立的活頁簿,並啟用視窗保護 | Excel 會辨識視窗位置和大小屬性,但不會防止使用者排列或關閉這些視窗。 |
檢視 [保護結構和 Windows ] 對話方塊 | Excel 會顯示對話方塊,但已停用 Windows 選項。 |
SDI 問題的解決方案
下一節提供使用 SDI 時可能會遇到問題的因應措施。
當活頁簿是透過強制回應使用者表單以程式設計方式開啟時,無法按一下紅色的 [X] [關閉 ] 按鈕來關閉活頁簿。 若要解決此問題,建議您將下列程式碼新增至使用者表單 版面配置 事件程序,然後以非模式開啟使用者表單。
Private Sub UserForm_Layout() Static fSetModal As Boolean If fSetModal = False Then fSetModal = True Me.Hide Me.Show 1 End If End Sub
另一個選項是開啟活頁簿視窗、啟動任何其他視窗,然後重新啟用活頁簿視窗。 您現在應該可以使用 [關閉] 按鈕 來關閉 活頁簿。
假設您的 VBA 程式碼會開啟多個活頁簿,並使用 DataEntryMode 屬性來控制資料輸入和活頁簿關閉。 在 Excel SDI 模型中,因為每個活頁簿都包含在自己的進程中,所以一個活頁簿中使用的 DataEntryMode 屬性無法辨識其他活頁簿的存在,因此對它們的互動沒有影響。 若要解決此問題,有幾個選項。 您可以分別使用
Window.Visible = False
或 來隱藏額外的活頁簿或Sheet.Visible = False
工作表。 使用Workbook.BeforeClose(Cancel) = True
偵測並取消任何關閉事件。在您關閉並重新開啟活頁簿之後,才會顯示透過命令列程式碼和 XLA 檔案新增至 Excel 活頁簿的工具列。 從 Excel 2007 開始,使用命令列自訂 UI 已被取代。 最佳解決方案是使用 XML 檔案來自訂功能區 UI,如自訂適用于開發人員的 2007 Office Fluent 功能區一文中所述
另一個選項是使用應用層級事件來偵測開啟的新活頁簿,然後使用
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 最有價值的專業 (MVP) Jan Karel Pieterse 會在 https://www.jkp-ads.com/articles/keepuserformontop.asp 網頁上提供問題的說明和解決方案。
摘要
Excel 2013 中新的單一檔介面可讓您輕鬆地使用多個活頁簿。 為了方便起見,您甚至可以將活頁簿拖曳至不同的監視器。 您只需要記住,每個活頁簿只有一個最上層視窗和一個功能區 UI 功能表。 當您從活頁簿移至活頁簿時,可能需要更新任何現有的程式碼,以快取控制項和設定的狀態。
另請參閱
支援和意見反應
有關於 Office VBA 或這份文件的問題或意見反應嗎? 如需取得支援服務並提供意見反應的相關指導,請參閱 Office VBA 支援與意見反應。