使用 Visual c + + 的 Office 自動化

摘要

本文會從 Visual c + + 中的 Microsoft Office 自動開始回答常見的問題。

其他相關資訊

目錄

  1. 何謂自動化?

  2. 我是 [自動化] 的新功能,我可以在哪裡找到適當的資源來進一步瞭解?

  3. 我是否有幾種不同的方式可以使用自動化?

  4. 什麼是 COM?

  5. 我要如何附加至 Office 應用程式的執行實例?

  6. 如何傳遞選用的參數?

  7. 如何捕捉由 Office 應用程式所公開的事件?

  8. 我的自動化程式碼太慢了。 如何加速專案?

  9. 這些大型錯誤值(例如-2147352573 或0x80030002)代表什麼?

  10. 什麼是型別程式庫?

  11. 我的自動化程式碼與 Microsoft Excel 95 合作,但無法使用 Microsoft Excel 97。 這麼?

  12. 為什麼程式完成後,我會自動繼續在記憶體中?

  13. 我知道我想要做的是 Microsoft Office 應用程式使用者,但我要如何以程式設計方式使用自動化?

  14. 我可以自動化內嵌的 Microsoft Office 應用程式嗎?

  15. 如何在 Microsoft Office 檔中存取我的檔案屬性?

問題與解答

  1. 何謂自動化? 自動化(以前稱為 OLE 自動化)是一種技術,可讓您利用現有程式的功能,並將它併入您自己的應用程式中。 例如,您可以在您的應用程式中使用 Microsoft Word 的拼寫及文法檢查功能,而使用者將看不到 Microsoft Word。 您甚至可以使用所有 Microsoft Excel 圖表、列印及資料分析工具。 這種技術可大大簡化並加速開發。

  2. 我是 [自動化] 的新功能,我可以在哪裡找到適當的資源來進一步瞭解? David Kruglinski 的第24章: "在 Visual c + + 內" (ISBN: 1-57231-565-2)提供一般概覽以及一些極佳的範例。 此外,Microsoft 知識庫也是一個很好的資訊來源。 本文本身就是良好的開始,您可以在下列 Microsoft 知識庫文章中找到更具體的參考資料:

    152023 尋找資源以學習 OLE 自動化 如果您喜歡使用範例進行學習,請參閱 Microsoft 知識庫中的下列文章:

    179706 HOWTO 使用 MFC 自動執行 Excel & 建立新活頁簿/設定其格式

  3. 我是否有幾種不同的方式可以使用自動化? 您可以使用自動化的三種基本方法: MFC、#import 和 C/c + +:

    • 有了 MFC,請使用 Visual c + + ClassWizard 從 Microsoft Office 型別程式庫產生「包裝類別」。 這些類別以及其他 MFC 類別(例如 COleVariant、COleSafeArray、COleException)簡化自動化的工作。 此方法通常是建議的方式,大多數的 Microsoft 知識庫範例都使用 MFC。

    • #import (可供 Visual c + + 5.0 使用的新指令)會從指定的型別程式庫建立 VC + + 「智慧指標」。 這個功能非常強大,但由於在 Microsoft Office 應用程式中使用時通常會發生參照計數問題,因此通常不建議您這麼做。

    • C/c + + 自動化更加困難,但有時候需要避免使用 MFC 進行額外的開銷,或 #import 的問題。 基本上,您可以使用這類 Api 做為 CoCreateInstance (),以及諸如 IDispatch 與 IUnknown 之類的 COM 介面。

    請務必注意,從 c + + 的自動化與純 C 的自動化稍有不同,因為 COM 是在 c + + 類別周圍設計的。 如需詳細資訊,請參閱下列 Microsoft 知識庫中適用于 C 範例的文章:

    181473 HOWTO:從 C 應用程式使用 OLE 自動化

  4. 什麼是 COM? 自動化是以元件物件模型(COM)為基礎。 COM 是一個以介面為基礎的標準軟體架構,設計成將程式碼分割成獨立的物件。 您可以將它看作是對物件進行程式設計(OOP)範例的延伸,但適用于個別的應用程式。 每個物件都會公開一組介面,而與物件的所有通訊(例如初始化、通知和資料傳輸)都是透過這些介面進行。 COM 也是隨作業系統一起安裝的動態連結程式庫(Dll)所提供的一組服務。 自動化會使用許多這類服務。 其中一個範例是「封送處理」服務,會將用戶端應用程式的呼叫封裝在伺服器應用程式介面的成員函數中,並將它們及其引數傳遞到伺服器應用程式。 它會使伺服器的介面顯示在用戶端的記憶體空間中,而當用戶端在自己的處理空間中執行時,就不會發生這種情況。 封送處理也會傳回來自伺服器方法的傳回值,並將它們安全地放在整個程式界限中,並將它安全地加入用戶端的呼叫。 各種 COM 文件庫提供的自動化功能有許多其他服務。 Kraig Brockschmidt、ISBN 1-55615-843-2、"內部 COM" (由 Dale Rogerson-ISBN 1-57231-349-8)和「自動化程式師參考」(ISBN 1-57231-584-9)等相關資訊的來源。

  5. 我要如何附加至 Office 應用程式的執行實例? 使用 GetActiveObject () API。 自動化伺服器會透過 RegisterActiveObject () API,在 ROT (執行物件資料表)中註冊自己。 自動化用戶端可以使用下列程式碼來取得執行中的實例:

          // Translate server ProgID into a CLSID. ClsidFromProgID      // gets this information from the registry.      CLSID clsid;      CLSIDFromProgID(L"Excel.Application", &clsid);        // Get an interface to the running instance, if any..      IUnknown *pUnk;      HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);      ASSERT(!FAILED(hr));      // Get IDispatch interface for Automation...      IDispatch *pDisp;      hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pDisp);      ASSERT(!FAILED(hr));      // Release the no-longer-needed IUnknown...      pUnk->Release();

    注意:如果有多個實例在執行您想要附加的 Office 應用程式,您將只能使用 GetActiveObject () API 附加到已啟動的第一個實例。 在理論上,您可以針對每個個別實例逐一查看 ROT,但如果另一個實例已經在 ROT 中,Office app 就不會自行註冊,因為名字物件本身總是相同的(無法辨識它)。 這表示您不能附加到除第一種情況以外的任何實例。 不過,由於 Office app 也會在 ROT 中註冊他們的檔,因此您可以將 ROT 的附加到其他實例,方法是先反覆運算 ROT 以尋找特定檔、將它附加到其中,然後從它取得應用程式物件。 下列 Microsoft 知識庫文章中有一些程式碼,可用於反覆運算 ROT 及尋找檔案名稱:

    190985 HOWTO:從 OCX 中取得 Excel 或 Word 檔的 IDispatch 您不需要在 PowerPoint 中執行此動作,因為它是單一實例應用程式;您只能有其中一個實例正在執行。

  6. 如何傳遞選用的參數? 某些方法具有 "optional" 參數。 在 Visual Basic 中,您可以在呼叫方法時隨意省略它們。 不過,當您使用 Visual c + + 進行呼叫時,您必須傳遞一個特殊的變數,其 VT_ERROR 是 vt,而. scode 欄位是 DISP_E_PARAMNOTFOUND。 那是:

          // VARIANT used in place of optional-parameters.      VARIANT varOpt;      varOpt.vt = VT_ERROR;      varOpt.scode = DISP_E_PARAMNOTFOUND;

    這實際上是 Visual Basic 在幕後進行的工作。

  7. 如何捕捉由 Office 應用程式所公開的事件? 您基本上要實現您想要捕捉的事件介面(「sink」),並設定與應用程式的通知連接("來源")。 下列文章提供 Microsoft Word 的逐步範例:

    183599 HOWTO:使用 VC + + 捕捉 Microsoft Word97 應用程式事件 一般來說,若要設定通知連接,您可以取得伺服器的 IConnectionPointContainer,並使用事件介面的 IID 呼叫 FindConnectionPoint ()。 這可讓您使用 IConnectionPoint 介面,而且所有剩餘的介面都是以事件介面的實例呼叫 Advise ()。 當這些事件發生時,伺服器會在這個介面上撥號。

  8. 我的自動化程式碼太慢了。 如何加速專案? 自動化之速度問題的常見原因,就是重複讀取及寫入資料。 這對於 Excel 自動化用戶端而言是常見的做法。 不過,大部分的人都不知道這個資料通常可以使用 SAFEARRAY 來撰寫或讀取。 如需詳細資訊及資訊性範例,請參閱下列 Microsoft 知識庫文章:

    186120 HOWTO:使用 MFC 自動執行 Excel,並以陣列填入範圍

    186122 HOWTO:使用 MFC 自動執行 Excel & 從範圍取得陣列

    179706 HOWTO:使用 MFC 自動執行 Excel 並建立/格式化新的活頁簿 此外,請務必指出使用剪貼簿有時可以改善效能。 例如,您可以將資料複製到剪貼簿,然後使用 [自動化] 告知伺服器貼上。 或反之亦然;告訴伺服器複製到剪貼簿,並貼到您的應用程式中。

  9. 這些大型錯誤值(例如-2147352573 或0x80030002 均值)有何意義? 這些值稱為 HRESULTs,並在 winerror.h 中定義。 數位是相當大的,因為第一個位代表是否為錯誤結果。 您可以使用 Visual c + + 隨附的 ErrLook 實用程式,將這些數位轉換成有意義的描述。 如果您想以程式設計方式取得錯誤的描述,您可以使用 FormatMessage () API。 如需有關使用 FormatMessage ()的詳細資訊和範例,請參閱下列 Microsoft 知識庫文章:

    186063 資訊:翻譯 VB/VBA 的自動化錯誤

    122957 範例: Decode32 和 Decode16 OLE 錯誤碼解碼器工具注意:如果您使用的是 Visual c + + 6.0,且在 [調試監視] 視窗中包含此值的變數,請將 ",hr" (不含引號)附加至它,讓 Visual c + + 為您翻譯!

  10. 什麼是型別程式庫? 型別程式庫類似 C/c + + 頭檔案。 它包含伺服器發佈的介面、方法和屬性。 您可以使用 Visual c + + 隨附的 OLE/COM 物件檢視器(Oleview)來查看型別程式庫。 以下是 Microsoft Office 95、97和2000的型別程式庫檔案名清單: Office Application | Type library ------------------------+---------------- Word 95 and prior | wb70en32.tlb Excel 95 and prior | xl5en32.olb Powerpoint 95 and prior | Powerpoint.tlb Access 95 and prior | msaccess.tlb Binder 95 | binder.tlb Schedule+ | sp7en32.olb Project | pj4en32.olb Team Manager | mstmgr1.olb Word 97 | msword8.olb Excel 97 | excel8.olb Powerpoint 97 | msppt8.olb Access 97 | msacc8.olb Binder 97 | msbdr8.olb Graph 97 | graph8.olb Outlook 97 | msoutl8.olb Outlook 98 | msoutl85.olb Word 2000 | msword9.olb Excel 2000 | excel9.olb Powerpoint 2000 | msppt9.olb Access 2000 | msacc9.olb Outlook 2000 | msoutl9.olb Word 2002 | msword.olb Excel 2002 | excel.exe Powerpoint 2002 | msppt.olb Access 2002 | msacc.olb Outlook 2002 | msoutl.olb

  1. 我的自動化程式碼使用 Excel 95,但無法使用 Excel 97。 發生了什麼事情? Excel 的物件模型已從版本95變更為97。 Excel 95 在單一的 IDispatch 實現中實現其所有方法和屬性。 這意味著您通常可以從物件 Y 呼叫物件 X 的方法。這不是良好的設計,因此在 Office 97 中,每個物件都有自己的獨立 Idispatch 實現。 這表示如果您要求來自物件 X 的方法或屬性是從個別物件 Y 開始,您會收到錯誤0x80020003,-2147352573,「找不到成員」。 若要避免這種錯誤,您必須確認您要進行呼叫的基礎 IDispatch 介面是語義正確的。 如需詳細資訊,請參閱下列 Microsoft 知識庫文章:

    172108 HOWTO:疑難排解「找不到成員」、0x80020003 錯誤

  2. 程式完成後,我會自動執行的應用程式會保留在記憶體中。 發生了什麼事情? 很可能是因為您忘記釋放取得的介面,因此需要進行追蹤。 以下是一些一般建議,以及要尋找的事項:

    • 如果您使用的是 #import,您很可能會遇到與它相關聯的其中一個參照計數錯誤。 通常會發生錯誤的情況,但通常是使用其他自動化方法之一。 #import 無法搭配 Office 應用程式使用,因為其型別程式庫和使用方式相當複雜。 此外,這類參照計數問題難以追蹤,因為許多介面層級的 COM 呼叫都是在使用 #import 時,在幕後運作。

    • 檢查您是否呼叫任何傳回 IDispatch * (LPDISPATCH)的方法(例如 [開啟] 或 [新增]),並忽略傳回值。 如果您是這樣,您就會放棄這個傳回的介面,而且需要變更您的程式碼,以便在不再需要時再放開。

    • 逐漸注釋掉您程式碼的區段,直到問題消失為止,然後再以謹慎方式新增,以追蹤問題的開始位置。

    • 請注意,如果使用者已 [接觸] 應用程式,某些應用程式將會持續執行。 如果在您自動化時發生這種情況,應用程式可能會在之後持續執行。 Office 應用程式在應用程式物件上有一個「UserControl」屬性,您可以讀取/寫入該屬性來變更此行為。

    • 此外,某些應用程式也會決定在發生足夠的使用者介面 "action" 時,保持執行。 如果您要將應用程式退出,請在應用程式物件上呼叫它的 Quit ()方法。 在呼叫 Quit 時,Word 會關閉,而不考慮其參照計數。 這不是預期的 COM 行為。 不過,Excel 會正確地隱藏本身,但在所有未處理的介面發行前一直保持繼續運作。 一般來說,如果您想要應用程式結束,您應該釋放所有未處理的參照,且只需呼叫 Quit ()。

  3. 我知道我想要做的是 Office 應用程式使用者,但如何透過自動化以程式設計方式執行此動作? 您感興趣的是您需要使用的物件、方法和屬性。 若要瞭解如何在 Word、Excel 和 Powerpoint 的物件模型上流覽,請根據您要做為使用者所做的動作,使用宏錄製器。 只要從 [工具] 功能表選擇 [宏] > [錄製新宏],執行您感興趣的工作,然後選擇 [宏] [停止錄製]。 完成錄製之後,請選擇 [工具] 功能表中的 [Macro\Macros],選取您錄製的宏,然後按一下 [編輯]。 這會將您帶到所產生的 VBA 程式碼,以完成您錄製的工作。 請記住,在大多數情況下,錄製的宏不會是最佳的程式碼,但它非常適合快速範例。

  4. 我可以自動化內嵌的 Office 應用程式嗎? 完全. 秘訣是取得 IDispatch 指標:這在 Visual c + + 技術注意事項39(TN039)中提供。 如需逐步範例,請參閱下列 Microsoft 知識庫文章:

    184663 HOWTO:使用 MFC 內嵌及自動化 Microsoft Excel 工作表

  5. 如何在 Office 檔中存取我的檔摘要資訊? 您可以透過 [自動化] 或直接透過 IPropertyStorage 存取檔案屬性。 下列 Microsoft 知識庫文章示範每個方法:

    179494 HOWTO:使用自動化來檢索內建檔案屬性

    186898 HOWTO:直接使用 VC + + 讀取複合檔案屬性

Need more help?

Expand your skills
Explore Training
Get new features first
Join Microsoft Insiders

Was this information helpful?

Thank you for your feedback!

Thank you for your feedback! It sounds like it might be helpful to connect you to one of our Office support agents.

×