您可以在文件中使用 Visual Basic for Applications (VBA) 程式碼,該文件屬於 Microsoft Office Word 或 Microsoft Office Excel 文件層級自訂的一部分。 您可以從自訂元件呼叫文件中的 VBA 程式碼,也可以設定專案,讓文件中的 VBA 程式碼呼叫自訂元件中的程式碼。
適用於: 本主題中的資訊適用於 Excel 和 Word 的文件層級專案。 如需詳細資訊,請參閱 Office 應用程式和專案類型所提供的功能。
VBA 程式碼在文件層級自訂中的行為
當您在 Visual Studio 中開啟專案時,文件會以設計模式開啟。 當文件處於設計模式時,VBA 程式碼不會執行,因此您可以在不執行 VBA 程式碼的情況下處理文件和程式碼。
當您執行解決方案時,VBA 和自訂元件中的事件處理常式都會挑選檔中引發的事件,而且這兩組程式碼都會執行。 您無法事先確定哪個程式碼將先於另一個程式碼執行;您必須透過對每個個別案例的測試來確定這一點。 如果兩組程式碼沒有仔細協調和測試,可能會得到意想不到的結果。
從自訂元件呼叫 VBA 程式碼
您可以在 Word 文件中呼叫巨集,也可以呼叫 Excel 活頁簿中的巨集和函數。 若要解決此問題,請使用下列其中一種方法:
針對 Word,呼叫 Application 類別中的 Run 方法。
針對 Excel,呼叫 Run 類別的 Application 方法。
對於每個方法,第一個參數會識別您要呼叫的巨集或函式的名稱,其餘的可選參數會指定要傳遞給巨集或函式的參數。 第一個參數可以有不同的 Word 和 Excel 格式:
針對 Word,第一個參數是字串,可以是範本、模組和巨集名稱的任意組合。 如果您指定文件名稱,您的程式碼只能在與目前內容相關的文件中執行巨集,而不僅僅是任何文件中的任何巨集。
針對 Excel,第一個參數可以是指定巨集名稱的字串、指出函式所在位置的 Range,或已註冊 DLL XLL 函式的代碼。 如果您傳遞字串,則會在活動工作表中對字串進行評估。
下列程式碼範例顯示如何從 Excel 文件層級專案中呼叫名為
MyMacro的巨集。 此範例假設MyMacro已在Sheet1中被定義。
Globals.Sheet1.Application.Run("MyMacro", missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing);
備註
如需在 Visual C# 中使用全域 missing 變數取代選擇性參數的相關資訊,請參閱 在 Office 解決方案中撰寫程式碼。
使用 VBA 從文件層級自訂中呼叫程式碼
您可以設定 Word 或 Excel 的文件層級專案,讓文件中的 Visual Basic for Applications (VBA) 程式碼可以呼叫自訂元件中的程式碼。 這在下列案例中很有用:
您想要使用與相同文件相關聯的文件層級自訂中的功能來擴充文件中的現有 VBA 程式碼。
您想要讓在文件層級自訂中開發的服務可供使用者使用,這些使用者可以透過在文件中撰寫 VBA 程式碼來存取服務。
Visual Studio 中的 Office 開發工具為 VSTO 增益集提供類似的功能。如果您要開發 VSTO 增益集,您可以從其他 Microsoft Office 解決方案呼叫 VSTO 增益集中的程式碼。 如需詳細資訊,請參閱 從其他 Office 解決方案呼叫 VSTO 增益集中的程式碼。
備註
此功能無法在 Word 範本專案中使用。 它只能用於 Word 文件、Excel 工作簿或 Excel 範本專案。
需求
在啟用 VBA 程式碼呼叫自訂元件之前,您的專案必須符合下列需求:
文件必須具有下列其中一個副檔名:
對於 Word 文件:.docm 或 .doc
對於 Excel: .xlsm、 .xltm、 .xls或 .xlt
文件必須已包含包含 VBA 程式碼的 VBA 專案。
必須允許文件中的 VBA 代碼在無需提示使用者啟用巨集的情況下執行。 您可以將 Office 專案的位置新增至 Word 或 Excel 信任中心設定中的信任位置清單,以信任 VBA 程式碼執行。
Office 專案必須至少包含一個公用類別,該類別中包含一個或多個您要向 VBA 公開的成員。
您可以將方法、屬性和事件公開給 VBA。 您公開的類別可以是主專案類別 (例如
ThisDocumentWord 或ThisWorkbook和Sheet1Excel) 或您在專案中定義的其他類別。 如需主機項目的詳細資訊,請參閱 主機項目和主機控制項概觀。
啟用 VBA 程式碼以呼叫自訂元件
您可以透過兩種不同的方式將自訂元件中的成員公開給檔中的 VBA 程式碼:
您可以將 Visual Basic 專案中主機專案類別的成員公開給 VBA。 若要這樣做,請在 [屬性] 視窗中將主機專案的 EnableVbaCallers 屬性設定為 True,同時主機專案 (也就是文件、工作表或活頁簿) 在設計工具中開啟。 Visual Studio 會自動執行讓 VBA 程式碼呼叫類別成員所需的所有工作。
您可以將 Visual C# 專案中任何公用類別中的成員,或 Visual Basic 專案中非主體專案類別中的成員公開給 VBA。 此選項可讓您更自由地選擇要公開給 VBA 的類別,但也需要更多手動步驟。
為此,您必須執行以下主要步驟:
將類別公開給 COM。
覆寫您的專案中主機專案類別的 GetAutomationObject 方法,以傳回要公開給 VBA 使用的類別實例。
將專案中任何主專案類別的 ReferenceAssemblyFromVbaProject 屬性設定為 True。 這會將自訂元件的類型程式庫內嵌到元件中,並將類型程式庫的參考新增至檔中的 VBA 專案。
如需詳細指示,請參閱 如何:在 Visual Basic 專案中將程式碼公開至 VBA 和 如何:在 Visual C# 專案中將程式碼公開至 VBA。
EnableVbaCallers 和 ReferenceAssemblyFromVbaProject 屬性僅在設計階段的 [屬性] 視窗中可用;它們無法在執行時期使用。 若要檢視屬性,請在 Visual Studio 中開啟主機專案的設計工具。 如需 Visual Studio 在您設定這些屬性時所執行之特定工作的詳細資訊,請參閱 主機專案屬性所執行的工作。
備註
如果活頁簿或文件尚未包含 VBA 程式碼,或不信任文件中的 VBA 程式碼執行,當您將 EnableVbaCallers 或 ReferenceAssemblyFromVbaProject 屬性設定為 True 時,您會收到錯誤訊息。 這是因為在此情況下,Visual Studio 無法修改檔中的 VBA 專案。
使用 VBA 程式碼中的成員來呼叫自訂組件
設定專案以啟用 VBA 程式碼呼叫自訂元件之後,Visual Studio 會將下列成員新增至檔中的 VBA 專案:
針對所有專案,Visual Studio 會新增名為
GetManagedClass的全域方法。對於使用 EnableVbaCallers 屬性公開主機項目類別成員的 Visual Basic 專案,Visual Studio 也會在 VBA 專案的
ThisDocument、ThisWorkbook、Sheet1、Sheet2或Sheet3模組中新增一個名為CallVSTOAssembly的屬性。您可以使用屬性
CallVSTOAssembly或GetManagedClass方法來存取您在專案中公開給 VBA 程式碼之類別的公用成員。
備註
當您開發和部署解決方案時,有數個不同的文件複本可供您新增 VBA 程式碼。 如需詳細資訊,請參閱 將 VBA 程式碼新增至檔的指導方針。
在 Visual Basic 專案中使用 CallVSTOAssembly 屬性
使用 CallVSTOAssembly 屬性來存取您新增至主機項目類別的公用成員。 例如,下列 VBA 巨集會呼叫一個名為 MyVSTOMethod 的方法,此方法是在 Excel 活頁簿專案中的 Sheet1 類別內定義的。
Sub MyMacro()
Sheet1.CallVSTOAssembly.MyVSTOMethod()
End Sub
此屬性是呼叫自訂元件比直接使用 GetManagedClass 方法更方便的方式。
CallVSTOAssembly 傳回一個物件,代表您公開給 VBA 的主機專案類別。 傳回物件的成員和方法參數會出現在 IntelliSense 中。
屬性 CallVSTOAssembly 具有類似下列程式碼的宣告。 此程式碼假設您已在 Excel 活頁簿專案中將 Sheet1 主機項目類別公開給 VBA,專案名稱為 ExcelWorkbook1。
Property Get CallVSTOAssembly() As ExcelWorkbook1.Sheet1
Set CallVSTOAssembly = GetManagedClass(Me)
End Property
使用 GetManagedClass 方法
若要使用全球 GetManagedClass 方法,請傳入與包含 GetAutomationObject 方法覆寫的主機項目類別對應的 VBA 物件。 然後,使用傳回的物件來存取您公開給 VBA 的類別。
例如,下列 VBA 巨集會呼叫名為 的 Excel 活頁簿專案MyVSTOMethod中主機專案類別中Sheet1定義的名為 ExcelWorkbook1 的方法。
Sub CallVSTOMethod
Dim VSTOSheet1 As ExcelWorkbook1.Sheet1
Set VSTOSheet1 = GetManagedClass(Sheet1)
VSTOSheet1.MyVSTOMethod
End Sub
該 GetManagedClass 方法具有以下宣告。
GetManagedClass(pdispInteropObject Object) As Object
這個方法會傳回一個物件,代表您公開給 VBA 的類別。 傳回物件的成員和方法參數會出現在 IntelliSense 中。
將 VBA 程式碼新增至文件的指導方針
文件有數個不同的複本,您可以在其中新增呼叫文件層級自訂的 VBA 程式碼。
當您開發和測試解決方案時,您可以在 Visual Studio 中偵錯或執行專案時開啟的文件中撰寫 VBA 程式碼 (也就是建置輸出資料夾中的文件)。 不過,您新增至此檔的任何 VBA 程式碼都會在您下次建置專案時覆寫,因為 Visual Studio 會將建置輸出資料夾中的檔取代為主要專案資料夾中的檔複本。
如果您想要儲存在偵錯或執行解決方案時新增至文件的 VBA 程式碼,請將 VBA 程式碼複製到專案資料夾中的文件中。 如需建置程式的詳細資訊,請參閱 建置辦公室解決方案。
當您準備好部署解決方案時,您可以在三個主要文件位置中新增 VBA 程式碼。
在開發電腦上的專案資料夾中
如果您可以完全控制文件中的 VBA 程式碼和自訂程式碼,則此位置會很方便。 因為檔位於開發電腦上,所以如果您變更自訂程式碼,您可以輕鬆修改 VBA 程式碼。 當您建置、偵錯和發佈解決方案時,您新增至此文件複本的 VBA 程式碼會保留在文件中。
當文件在設計工具中開啟時,您無法將 VBA 程式碼新增至文件。 您必須先在設計工具中關閉文件,然後直接在 Word 或 Excel 中開啟文件。
謹慎
如果您新增在開啟文件時執行的 VBA 程式碼,在極少數情況下,此程式碼可能會損毀文件或阻止它在設計工具中開啟。
在發佈或安裝資料夾中
在某些情況下,可能適合將 VBA 程式碼新增至發佈或安裝資料夾中的檔。 例如,如果 VBA 程式碼是由未安裝 Visual Studio 的電腦上由不同的開發人員撰寫和測試,您可以選擇此選項。
如果使用者直接從發佈資料夾安裝解決方案,則每次發佈解決方案時,都必須將 VBA 程式碼新增至檔。 當您發佈解決方案時,Visual Studio 會覆寫發佈位置中的文件。
如果使用者從與發佈資料夾不同的安裝資料夾安裝解決方案,您可以避免每次發佈解決方案時在檔中新增 VBA 程式碼。 當發佈更新準備好從發佈資料夾移至安裝資料夾時,請將檔案以外的所有檔案複製到安裝資料夾。
在使用者電腦上
如果終端使用者是具有 VBA 開發經驗且在文件層級自訂中呼叫您所提供服務的開發人員,您可以告訴他們如何在文件的複本中使用CallVSTOAssembly 屬性或 GetManagedClass 方法來呼叫您的程式碼。 當您發佈解決方案的更新時,使用者電腦上文件中的 VBA 程式碼不會被覆寫,因為發佈更新不會修改文件。
主機項目屬性所執行的工作
當您使用 EnableVbaCallers 和 ReferenceAssemblyFromVbaProject 屬性時,Visual Studio 會執行不同的工作集。
啟用VBA呼叫者
當您在 Visual Basic 專案中將主機專案的 EnableVbaCallers 屬性設定為 True 時,Visual Studio 會執行下列工作:
它會將 和 ComClassAttributeComVisibleAttribute 屬性新增至主機項目類別。
它會覆寫主機專案類別的 GetAutomationObject 方法。
它會將主機專案的 ReferenceAssemblyFromVbaProject 屬性設定為 True。
當您將 EnableVbaCallers 屬性設定回 False 時,Visual Studio 會執行下列工作:
它會從
ThisDocument類別中移除ComClassAttribute和ComVisibleAttribute屬性。它會從主機專案類別中移除 GetAutomationObject 方法。
備註
Visual Studio 不會自動將 ReferenceAssemblyFromVbaProject 屬性設定回 False。 您可以使用 [屬性] 視窗手動將此屬性設定為 False。
參考程序集從VBA專案
當 Visual Basic 或 Visual C# 專案中任何主機專案的 ReferenceAssemblyFromVbaProject 屬性設定為 True 時,Visual Studio 會執行下列工作:
它會產生自訂組件的類型資源庫,並將類型資源庫嵌入組件中。
它會在文件的 VBA 專案中,新增下列類型程式庫的參考:
自訂組件的類型庫。
Microsoft Visual Studio Tools for Office 執行引擎 9.0 類型程式庫。 此類型程式庫包含在 Visual Studio Tools for Office 執行階段中。
當 ReferenceAssemblyFromVbaProject 屬性設定回 False 時,Visual Studio 會執行下列工作:
它會從文件中的 VBA 專案中移除類型程式庫參考。
它會從組合中移除內嵌類型資源庫。
故障排除
下表列出一些常見錯誤,以及修正錯誤的建議。
| 錯誤 | 建議 |
|---|---|
| 設定 EnableVbaCallers 或 ReferenceAssemblyFromVbaProject 屬性之後,會出現錯誤訊息,指出檔不包含 VBA 專案,或您沒有存取檔中 VBA 專案的許可權。 | 請確定專案中的文件至少包含一個 VBA 巨集、VBA 專案具有足夠的信任來執行,且 VBA 專案不受密碼保護。 |
| 設定 EnableVbaCallers 或 ReferenceAssemblyFromVbaProject 屬性之後,錯誤訊息會指出 GuidAttribute 宣告遺失或損毀。 | 請確定 GuidAttribute 宣告位於專案中的 AssemblyInfo.cs 或 AssemblyInfo.vb 檔案中,且此屬性已設定為有效的 GUID。 |
| 設定 EnableVbaCallers 或 ReferenceAssemblyFromVbaProject 屬性之後,錯誤訊息會指出 指定的 AssemblyVersionAttribute 版本號碼無效。 | 請確定您專案中的 AssemblyInfo.cs 或 AssemblyInfo.vb 檔案的 AssemblyVersionAttribute 宣告已設定為有效的元件版本號碼。 如需查詢有效的組件版本號碼,請參閱 AssemblyVersionAttribute 類別。 |
| 重新命名自訂元件之後,呼叫自訂元件的 VBA 程式碼會停止運作。 | 如果您在將自訂元件公開給 VBA 程式碼之後變更自訂元件的名稱,則檔中的 VBA 專案與自訂元件之間的連結會中斷。 若要修正此問題,請將專案中的 ReferenceFromVbaAssembly 屬性變更為 False ,然後再變回 True,然後將 VBA 程式碼中舊元件名稱的任何參考取代為新的元件名稱。 |