如何為 Excel 使用 Visual C++ 建置增益集 (XLL)

文章翻譯 文章翻譯
文章編號: 178474 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

結論

一個 XLL 是一個加入-,您可以使用任何編譯器支援建置 DLL (動態連結程式庫) 建置的 Microsoft Excel 中。這份文件被設計來協助您開始建置 XLL Microsoft Visual C++。若要依照本文所述的步驟,您應該有建置 DLL 的經驗,您應該有 Microsoft Excel 97 開發人員之套件包含必要的標頭和程式庫檔案來建置一個 XLL。

其他相關資訊

建立一個 XLL 步驟

  1. 建立新的 MFC AppWizard (.dll) 專案,稱為 Anewxll。
  2. 將 Xlcall.h、 Framewrk.h、 Framewrk.c 及 Xlcall32.lib 從 Microsoft Excel 97 開發人員套件複製到您的專案目錄。
  3. 重新命名 Framewrk.cpp Framewrk.c。
  4. 將 Framewrk.cpp 新增至專案來源檔案。
  5. 將下列程式碼加入 # include 行,才能避免編譯器錯誤關於先行編譯標頭的 Framewrk.cpp 頂端:
    
          #include "stdafx.h"
    					
  6. 變更下列這一行中 Framewrk.cpp:
          #include "..\..\include\xlcall.h"
    					
    到:
          #include "xlcall.h"
    					
  7. 按一下 [專案] 功能表上的 [設定]。按一下 [連結] 索引標籤,然後將 Xlcall32.lib 新增至物件/程式庫模組編輯方塊。
  8. 將下列程式碼加入 # include 陳述式以 Anewxll.cpp 頂端:
          #include "xlcall.h"
          #include "framewrk.h"
    					
    注意: 的專案適當地是現在安裝程式,而且應該編譯,但是,您尚未新增 XLL 支援還。剩餘的步驟提供您可以加入以取得您開始 XLL 一些範例程式碼。

  9. 將下列程式碼附加至 Anewxll.cpp: 範例程式碼-----------
          //================================================================
          // Commonly used global variables
          int err;
          char buf[8192];
          char txt[8192];
    
          // Function registering table
          int nFuncs;
    
          // proc, type_text, function_text, arg, macro_type, category,
          // shortcut_text, help_topic, function_help
          static LPSTR func[][9] = {
          {" MyFunc", " JJJ", " MyFunc", " ", " 1", " MyCat", " ", " ", " "},
          {" MyMotd", " I", " MyMotd", " ", " 1", " MyCat", " ", " ", " "},
          {0,0,0,0, 0, 0, 0}
          };
    
          // Menu table
          int nMenuItems;
    
          static LPSTR menu[][5] = {
          {" &MyMenu", " ", " ", " Joe's Xll menu!!!", " "},
          {" M.O.T.D."," MyMotd", " ", " Message of the Day!", " "},
          {0, 0, 0, 0, 0}
          };
    
          // Initialization routine
          BOOL __stdcall xlAutoOpen(void) {
             AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
    
             // DEBUG output to indicate when called
             AfxMessageBox("xlAutoOpen() called!", MB_SETFOREGROUND);
    
             int i, j;
    
             // Get XLL file name
             static XLOPER xDll;
             Excel(xlGetName, &xDll, 0);
    
             // Prefix strengths with their length & count items
             // Note the framework's TempStr() function prefixes the
             // lengths anyway, but this is for other code that might
             // use the arrays
             for(nFuncs=0;     func[nFuncs][0];     nFuncs++) {
                 for(i=0; i<9; i++) {
                     func[nFuncs][i][0]     = (BYTE) strlen(func[nFuncs][i]+1);
                 }
    
             }
    
             for(nMenuItems=0; menu[nMenuItems][0]; nMenuItems++) {
                 for(i=0; i<5; i++) {
                 menu[nMenuItems][i][0] = (BYTE) strlen(menu[nMenuItems][i]+1);
                 }
             }
    
             // Loop through the function list, and register the functions
             for(i=0; i<nFuncs; i++) {
    
                // Register a function
                err = Excel(xlfRegister, 0, 9, (LPXLOPER)&xDll,
                   (LPXLOPER)TempStr(func[i][0]),
                   (LPXLOPER)TempStr(func[i][1]),
                   (LPXLOPER)TempStr(func[i][2]),
                   (LPXLOPER)TempStr(func[i][3]),
                   (LPXLOPER)TempStr(func[i][4]),
                   (LPXLOPER)TempStr(func[i][5]),
                   (LPXLOPER)TempStr(func[i][6]),
                   (LPXLOPER)TempStr(func[i][7]),
                   (LPXLOPER)TempStr(func[i][8])
                   );
    
                if(err != xlretSuccess) {
                 sprintf(buf, "xlfRegister for function %d, err = %d", i, err);
                 AfxMessageBox(buf, MB_SETFOREGROUND);
                }
             }
    
             // Free XLL file name from the xlGetName call made earlier
             Excel(xlFree, 0, 1, (LPXLOPER)&xDll);
    
             // Menu support section
             static XLOPER xMenu;
             static XLOPER xMenuList[10*5];
             ASSERT(nMenuItems< 10);
    
             // Build menu
             xMenu.xltype            = xltypeMulti;
             xMenu.val.array.lparray = &xMenuList[0];
             xMenu.val.array.rows    = nMenuItems;
             xMenu.val.array.columns = 5;
    
             for(i=0; i<nMenuItems; i++) {
                 for(j=0; j<5; j++) {
                     xMenuList[j+i*5].xltype  = xltypeStr;
                     xMenuList[j+i*5].val.str = menu[i][j];
                 }
             }
    
             // Add menu
            Excel(xlfAddMenu,0,3,TempNum(1),(LPXLOPER)&xMenu,TempStr(" Help"));
    
             // Finished
             return 1;
          }
    
          // Cleanup routine
          BOOL __stdcall xlAutoClose(void) {
             ::MessageBox(NULL, "xlAutoClose()", "Debug", MB_SETFOREGROUND );
    
             // Delete menu
             Excel(xlfDeleteMenu, 0, 2, TempNum(1), TempStr(" MyMenu"));
    
             return 1;
          }
    
          // Support for descriptive information about the add-in(s)
          // You can add a new customized title for the user, but
          // unfortunately, only an add-in written in Microsoft Visual Basic
          // can add a description string.
          LPXLOPER _stdcall xlAddInManagerInfo(LPXLOPER xAction) {
             static XLOPER xInfo, xIntAction;
    
             // Find out what action must be taken
             Excel(xlCoerce, &xIntAction, 2, xAction, TempInt(xltypeInt));
    
             // DEBUG output to indicate when called
             sprintf(buf, "xlAddInManagerInfo(%ld)", (long)xIntAction.val.w);
             ::MessageBox(NULL, "xlAddInManagerInfo()", "Debug",
                 MB_SETFOREGROUND );
    
             // Set title if asked
             if(xIntAction.val.w == 1) {
                 xInfo.xltype = xltypeStr;
                 xInfo.val.str = " My Add-in!!!!";
                 xInfo.val.str[0] = (char)strlen(&xInfo.val.str[1]);
             }
             else {
                 xInfo.xltype = xltypeErr;
                 xInfo.val.err = xlerrValue;
             }
    
             return (LPXLOPER)&xInfo;
          }
    
            short __stdcall MyMotd(void) {
             char *name[] = {
                "Rebekah",
                "Brent",
                "John",
                "Joseph",
                "Robert",
                "Sara",
                0
             };
             char *quote[] = {
                "An apple a day, keeps the doctor away!",
                "Carpe Diem: Seize the Day!",
                "What you dare to dream, dare to do!",
                "I think, therefore I am.",
                "A place for everything, and everything in its place.",
                "Home is where the heart is.",
    
                0
             };
    
             int nNames, nQuotes;
    
             for(nNames=0; name[nNames]; nNames++);
             for(nQuotes=0; quote[nQuotes]; nQuotes++);
    
             sprintf(buf, "%s says '%s'", name[rand()%nNames],
                quote[rand()%nQuotes]);
             ::MessageBox(NULL, buf, "XLL MOTD", MB_SETFOREGROUND );
    
             return 0;
          }
    
          // Example function that returns the product of its two parameters
          long __stdcall MyFunc(long parm1, long parm2) {
           sprintf(buf, "You sent %ld and %ld to MyFunc()!", parm1, parm2);
           ::MessageBox(NULL, buf, "MyFunc() in Anewxll!!!", MB_SETFOREGROUND);
    
           return parm1 * parm2;
          }
          //=================================================================
    					
  10. Anewxll.def 檔案的結尾加入下列行:
          xlAutoOpen
          xlAutoClose
          xlAddInManagerInfo
          MyMotd
          MyFunc
    					
  11. 您現在可以編譯專案,以產生 DLL,稱為 Anewxll.dll。 一旦編譯 DLL 將它重新命名為 Anewxll.xll。

使用 Microsoft Excel 增益集

  1. 在 Microsoft Excel 中啟動新的活頁簿。
  2. 按一下 [工具] 功能表上的 [增益集]。瀏覽至新增 Anewxll.xll,按一下 [確定]。 請注意當您在 [增益集] 對話方塊中按一下 [確定] xlAutoOpen 函式執行。
  3. 按一下 [MyMenu] 功能表上的 [M.O.T.D]。 按一下功能表項目時 MyMotd 函式會執行,以顯示與引號 MessageBox,例如"Rebekah 寫著 '一天,一個蘋果保持醫生離開'!"。
  4. 在一個儲存格加入下列公式:
    =MYFUNC(2,6)
    					
    MYFUNC 傳回 12 2 和 6 的乘積。

  5. 按一下 [工具] 功能表上的 [增益集]。清除增益集] 核取方塊,然後按一下 [確定]。 注意當您按一下 [確定] 在 [增益集] 對話方塊,xlAutoClose 函式執行。

額外的備忘稿

如果您使用的 Microsoft Visual C++ 6.0,您在偵錯模式中進行編譯時,也將會失敗前面的範例。為 Visual 的 C + + 6.0 的字串常值都放在讀取會建置在偵錯中的唯一記憶體,和技巧 XLL 開發人員使用長度前置字元其字串會造成存取違規,就會發生失敗。為一個工作-周圍,可以在您的專案設定中移除/ZI 編譯器參數,或只是測試發行組建。如需詳細資訊請參閱下列的 「 Microsoft 知識庫 」 中的文件:
198477PRB: 使用/ZI 可能會造成存取違規

?考

如更多資訊有關 XLL 請參閱:
Microsoft Excel 97 開發人員套件 (ISBN: 1-57231-498-2)

屬性

文章編號: 178474 - 上次校閱: 2007年2月12日 - 版次: 4.3
這篇文章中的資訊適用於:
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Visual C++ 4.0 Standard Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 6.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Visual C++, 32-bit Learning Edition 6.0
關鍵字:?
kbmt kbhowto KB178474 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:178474
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com