Cómo generar un complemento (XLL) para Excel con Visual C++

IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.

Haga clic aquí para ver el artículo original (en inglés): 178474
Este artículo se ha archivado. Se ofrece "tal cual" y no se volverá a actualizar.
Resumen
Un XLL es un complemento para Microsoft Excel que se puede generar con cualquier compilador que admite la creación de DLL (bibliotecas de vínculos dinámicos). En este artículo está diseñado para empezar a generar los XLL con Microsoft Visual C++. Siga los pasos descritos en este artículo, debe tener alguna experiencia generar archivos DLL y debe tener el Kit del programador de Microsoft Excel 97, que contiene los archivos de encabezado y biblioteca necesarios para generar un XLL.
Más información

Pasos para crear un XLL

  1. Cree un nuevo proyecto de MFC AppWizard (.dll) denominado Anewxll.
  2. Copie el xlcall.h, Framewrk.h, Framewrk.c y Xlcall32.lib del Kit del programador de Microsoft Excel 97 al su directorio de proyecto.
  3. Cambie el nombre Framewrk.c Framewrk.cpp.
  4. Agregar Framewrk.cpp a los archivos de origen del proyecto.
  5. Agregue el siguiente # include línea hasta la parte superior de Framewrk.cpp para evitar errores del compilador sobre encabezados precompilados:
          #include "stdafx.h"					
  6. Cambie la línea siguiente en Framewrk.cpp:
          #include "..\..\include\xlcall.h"					
    a:
          #include "xlcall.h"					
  7. Haga clic en configuración en el menú proyecto. Haga clic en la ficha de vínculo y agregar Xlcall32.lib al objeto o cuadro de edición módulos de biblioteca.
  8. Agregue las siguientes instrucciones a la parte superior de Anewxll.cpp # include:
          #include "xlcall.h"      #include "framewrk.h"					
    Nota: el proyecto es el programa de instalación ahora correctamente y debe compilar, sin embargo, todavía no has agregado compatibilidad XLL. Los pasos restantes proporcionan algún código de ejemplo que puede agregar a los XLL para comenzar.

  9. Anexe el código siguiente a Anewxll.cpp: código de ejemplo-----------
          //================================================================      // 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. Agregue las líneas siguientes al final del archivo Anewxll.def:
          xlAutoOpen      xlAutoClose      xlAddInManagerInfo      MyMotd      MyFunc					
  11. Ahora puede compilar el proyecto para generar una DLL denominada Anewxll.dll. Una vez compilada la DLL, cambiarle el nombre a Anewxll.xll.

Con el complemento de Microsoft Excel

  1. Inicie un libro nuevo en Microsoft Excel.
  2. Haga clic en complementos en el menú Herramientas. Vaya a agregar Anewxll.xll y haga clic en Aceptar. Observe que, cuando hace clic en Aceptar en el cuadro de diálogo Complementos, ejecuta la función xlAutoOpen.
  3. Haga clic en M.O.T.D en el menú MyMenu. Cuando se hace clic en el elemento de menú, la función MyMotd se ejecutará para mostrar un cuadro de mensaje con una oferta, como "Rebekah indica 'Un Apple un día, mantiene al doctor fuera'!".
  4. En una celda, agregue la siguiente fórmula:
    =MYFUNC(2,6)					
    MYFUNC devuelve 12, el producto de 2 y 6.

  5. Haga clic en complementos en el menú Herramientas. Desactive la casilla de verificación complemento y haga clic en Aceptar. Observe que, al hacer clic en Aceptar en el cuadro de diálogo Complementos, ejecuta la función xlAutoClose.

Notas adicionales

Si está utilizando Microsoft Visual C++ 6.0, el ejemplo anterior produce un error cuando se compila en modo de depuración. El error se produce porque como de Visual C++ 6.0, cadena literales se colocan en leer genera sólo memoria de depuración, y el truco que los desarrolladores de XLL utilicen para la longitud de prefijo sus cadenas produce una infracción de acceso. Como una solución alternativa, puede quitar el modificador de compilador /Zi en su configuración del proyecto o sólo se prueba una generación de lanzamiento. Para obtener más información, vea el artículo siguiente en Microsoft Knowledge Base:
198477PRB: Uso de /Zi puede producir infracción de acceso
Referencias
Para obtener más información acerca de los XLL, vea:
Kit de desarrollo de Microsoft Excel 97 (ISBN: 1-57231-498-2)
XLL vc xlcall xlcall32 xlmhowto

Propiedades

Id. de artículo: 178474 - Última revisión: 12/05/2015 08:15:02 - Revisión: 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, Microsoft Visual C++ 5.0 Professional, Microsoft Visual C++ 6.0 Professional, Microsoft Visual C++, 32-bit Learning Edition 6.0

  • kbnosurvey kbarchive kbmt kbhowto KB178474 KbMtes
Comentarios