Exemple #1
0
/*
***************************************************************************
** Standard Excel function to provide the library name to Excel.
***************************************************************************
*/
XLFUNC(LPXLOPER) xlAddInManagerInfo(LPXLOPER xAction)
{
    static XLOPER xInfo, xIntAction;
    static char xLibName[JPMCDS_MAX_LIB_NAME];
    LPXLOPER pxInfo;

    /*
    ** This code coerces the passed-in value to an integer. This is how the
    ** code determines what is being requested. If it receives a 1, 
    ** it returns a string representing the long name. If it receives 
    ** anything else, it returns a #VALUE! error.
    */
    Excel(xlCoerce, &xIntAction, 2, xAction, TempInt(xltypeInt));

    if(xIntAction.val.w == 1)
    {
        xInfo.xltype = xltypeStr;
        xLibName[0] = strlen(gtoLibName);
        strncpy (xLibName+1, gtoLibName, xLibName[0]);
        xInfo.val.str = xLibName;
    }
    else
    {
        xInfo.xltype = xltypeErr;
        xInfo.val.err = xlerrValue;
    }

    Excel(xlFree, 0, 1, (LPXLOPER) &xIntAction ,0);    
    pxInfo = &xInfo;

    return pxInfo;
}
Exemple #2
0
XLL_DEC OPER *ohRemoveInvalidColumns(OPER *xInputRange) {

    // initialize Function Call object
    boost::shared_ptr<reposit::FunctionCall> functionCall;

    reposit::Xloper xMulti;
    static OPER xRet;
    xRet.val.array.lparray = 0;

    try {
        functionCall = boost::shared_ptr<reposit::FunctionCall>
            (new reposit::FunctionCall("ohRemoveInvalidColumns"));

        Excel(xlCoerce, &xMulti, 2, xInputRange, TempInt(xltypeMulti));

        int numValidCols = countValidColumns(xMulti());
        if (!numValidCols) return 0;
        int numRows = xMulti->val.array.rows;

        xRet.val.array.rows = numRows;
        xRet.val.array.columns = numValidCols;
        xRet.val.array.lparray = new OPER[numRows * numValidCols]; 
        xRet.xltype = xltypeMulti | xlbitDLLFree;

        for (int i=0; i<xMulti->val.array.rows; ++i) {
			int j2 = 0;
            for (int j=0; j<xMulti->val.array.columns; ++j) {
				if (columnIsValid(xMulti(), j)) {
					int indexSource = i * xMulti->val.array.columns + j;
					int indexTarget = i * numValidCols + j2;
					operToOper(&xRet.val.array.lparray[indexTarget], 
						&xMulti->val.array.lparray[indexSource]);
					j2++;
				}
            }
        }

        return &xRet;

    } catch (const std::exception &e) {

        // free any memory that may have been allocated

        if (xRet.xltype & xltypeMulti && xRet.val.array.lparray) {
            for (int i=0; i<xRet.val.array.columns * xRet.val.array.rows; ++i) {
                if (xRet.val.array.lparray[i].xltype & xltypeStr && xRet.val.array.lparray[i].val.str)
                    delete [] xRet.val.array.lparray[i].val.str;
            }
            delete [] xRet.val.array.lparray;
        }

        // log the exception and return a null pointer (#NUM!) to Excel

        reposit::RepositoryXL::instance().logError(e.what(), functionCall);
        return 0;
    }
}
Exemple #3
0
XLL_DEC OPER *ohFilter(
        OPER *xInput,
        OPER *flags) {

    // declare a shared pointer to the Function Call object

    boost::shared_ptr<ObjectHandler::FunctionCall> functionCall;

    try {

        // instantiate the Function Call object
    
        functionCall = boost::shared_ptr<ObjectHandler::FunctionCall>(
            new ObjectHandler::FunctionCall("ohFilter"));

        // convert input datatypes to C++ datatypes

        std::vector<bool> flagsCpp = ObjectHandler::operToVector<bool>(*flags, "flags");

        const OPER *xMulti;
        ObjectHandler::Xloper xTemp;
        if (xInput->xltype == xltypeMulti) {
            xMulti = xInput;
        } else {
            Excel(xlCoerce, &xTemp, 2, xInput, TempInt(xltypeMulti));
            xMulti = &xTemp;
        }

        int sizeInput = xMulti->val.array.rows * xMulti->val.array.columns;
        OH_REQUIRE(sizeInput == flagsCpp.size(),
            "size mismatch between value vector (" << sizeInput << 
            ") and flag vector (" << flagsCpp.size() << ")");


        static OPER xRet;
        xRet.val.array.rows = count(flagsCpp.begin(), flagsCpp.end(), true);
        xRet.val.array.columns = 1;
        xRet.val.array.lparray = new OPER[xRet.val.array.rows]; 
        xRet.xltype = xltypeMulti | xlbitDLLFree;

        int idx = 0;
        for (int i=0; i<sizeInput; i++) {
            if (flagsCpp[i]) {
                operToOper(&xRet.val.array.lparray[idx++], &xMulti->val.array.lparray[i]);
            }
        }

        return &xRet;

    } catch (const std::exception &e) {
        ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall);
        return 0;
    }
}
Exemple #4
0
/*
***************************************************************************
** Standard Excel function for addin unloaded event.
***************************************************************************
*/
XLFUNC(int) xlAutoRemove(void)
{
    char buf[JPMCDS_MAX_LIB_NAME+32];
    strcpy(buf, " ");
    strcat(buf, gtoLibName);
    strcat(buf, " add-in has been removed");
    
    Excel(xlcAlert, 0, 2, TempStr(buf), TempInt(2));
    
    return 1;
}
Exemple #5
0
/*
***************************************************************************
** Standard Excel function for addin loaded event.
***************************************************************************
*/
XLFUNC(int) xlAutoAdd(void)
{
    char buf[JPMCDS_MAX_LIB_NAME+32];
    strcpy(buf, " ");
    strcat(buf, gtoLibName);
    strcat(buf, " add-in has been loaded");
    
    /* Display a dialog box indicating that the XLL was successfully added */
    Excel(xlcAlert, 0, 2, TempStr(buf), TempInt(2));

    return 1;
}
Exemple #6
0
QuantLib::Array operToQlArray(const OPER &xVector,
                              const std::string paramName) {
    OPER xTemp;
    bool excelToFree = false;
    bool xllToFree = false;
    try {
        RP_REQUIRE(!(xVector.xltype & xltypeErr),
                   "input value '" << paramName << "' has type=error");
        if (xVector.xltype & (xltypeMissing | xltypeNil))
            return QuantLib::Array();

        const OPER *xMulti;

        if (xVector.xltype == xltypeMulti) {
            xMulti = &xVector;
        } else if (xVector.xltype == xltypeStr) {
            splitOper(&xVector, &xTemp);
            xMulti = &xTemp;
            xllToFree = true;
        } else {
            Excel(xlCoerce, &xTemp, 2, &xVector, TempInt(xltypeMulti));
            xMulti = &xTemp;
            excelToFree = true;
        }

        int size = xMulti->val.array.rows * xMulti->val.array.columns;
        QuantLib::Array a(size);
        for (int i=0; i<size; ++i) {
            a[i] = reposit::convert2<double>(reposit::ConvertOper(xMulti->val.array.lparray[i]));
        }

        if (excelToFree) {
            Excel(xlFree, 0, 1, &xTemp);
        } else if (xllToFree) {
            freeOper(&xTemp);
        }

        return a;
    } catch (const std::exception &e) {
        if (excelToFree) {
            Excel(xlFree, 0, 1, &xTemp);
        } else if (xllToFree) {
            freeOper(&xTemp);
        }
        RP_FAIL("operToVector: error converting parameter '" << paramName << "' : " << e.what());
    }
}
Exemple #7
0
DLLEXPORT XLOPER *xlAddInManagerInfo(XLOPER *xlAction) {

    XLOPER xlReturn;
    static XLOPER xlLongName;

    // Coerce the argument XLOPER to an integer.
    Excel(xlCoerce, &xlReturn, 2, xlAction, TempInt(xltypeInt));

    // The only valid argument value is 1. In this case we return the
    // long name for the XLL. Any other value should result in the
    // return of a #VALUE! error.
    if (1 == xlReturn.val.w) {
        ObjectHandler::scalarToOper(std::string("ObjectHandler 1.2.0"), xlLongName);
    } else {
        xlLongName.xltype = xltypeErr;
        xlLongName.val.err = xlerrValue;
    }

    return &xlLongName;
}
Exemple #8
0
/*
***************************************************************************
** Standard Excel addin entry point.
***************************************************************************
*/
XLFUNC(short) xlAutoOpen(void)
{
    int      xlret;
    char     buf[128];
    XLOPER   xDLL;
    LPXLOPER pxDLL = &xDLL;
    size_t   i;

    xlret = Excel(xlGetName, pxDLL, 0);
    if (xlret != xlretSuccess)
    {
        sprintf(buf, " Excel get DLL name function failed: %s", JpmcdsExcelFormatReturnStatus(xlret));
        Excel(xlcAlert,0,2,TempStr(buf),TempInt(2));
        return 1;
    }

    for (i = 0 ; i < gtoFuncDefCount ; i++)
        RegisterFunction(pxDLL, FNPREFIX, gtoFuncDefList[i]);

    Excel(xlFree,0,1,pxDLL);
    return 1;
}
Exemple #9
0
    std::vector<std::vector<T> > operToMatrixImpl(
        const ConvertOper &xMatrix, 
        const std::string &paramName) {

        try {
            if (xMatrix.missing()) return std::vector<std::vector<T> >();

            OH_REQUIRE(!xMatrix.error(), "input value has type=error");

            const OPER *xMulti;
            Xloper xCoerce;  // Freed automatically

            if (xMatrix->xltype == xltypeMulti)
                xMulti = xMatrix.get();
            else {
                Excel(xlCoerce, &xCoerce, 2, xMatrix.get(), TempInt(xltypeMulti));
                xMulti = &xCoerce;
            }

            std::vector<std::vector<T> > ret;
            ret.reserve(xMulti->val.array.rows);
            for (int i=0; i<xMulti->val.array.rows; ++i) {
                std::vector<T> row;
                row.reserve(xMulti->val.array.columns);
                for (int j=0; j<xMulti->val.array.columns; ++j) {
                    row.push_back(convert2<T>(ConvertOper(xMulti->val.array.lparray[i * xMulti->val.array.columns + j])));                
                }
                ret.push_back(row);
            }

            return ret;
        } catch (const std::exception &e) {
            OH_FAIL("operToMatrixImpl: error converting parameter '" << paramName 
                << "' to type '" << typeid(T).name() << "' : " << e.what());
        }
    }
Exemple #10
0
    void loop(
              const boost::shared_ptr<FunctionCall> &functionCall,
              LoopFunction &loopFunction, 
              OPER *xIn, 
              XLOPER &xOut) {

        // FIXME - xTemp may not be cleaned up properly in the event of an exception.
        OPER xTemp, *xMulti;
        bool excelToFree = false;
        bool xllToFree = false;

        // If the input is an array then take its address & carry on
        if (xIn->xltype == xltypeMulti) {
            xMulti = xIn;
        // If the input is a list then call split on it
        } else if (isList(xIn)) {
            splitOper(xIn, &xTemp);
            xMulti = &xTemp;
            xllToFree = true;
        // If the input is a scalar then just call the function once & return
        } else if (xIn->xltype == xltypeNum
        ||  xIn->xltype == xltypeBool
        ||  xIn->xltype == xltypeStr) {
            LoopIteration<LoopFunction, InputType, OutputType>()(
                loopFunction, *xIn, xOut, true);
            return;
        // Some other input (e.g. a reference) - try to convert to an array
        } else {
            Excel(xlCoerce, &xTemp, 2, xIn, TempInt(xltypeMulti));
            xMulti = &xTemp;
            excelToFree = true;
        }

        xOut.val.array.rows = xMulti->val.array.rows;
        xOut.val.array.columns = xMulti->val.array.columns;
        int numCells = xMulti->val.array.rows * xMulti->val.array.columns;
        xOut.val.array.lparray = new XLOPER[numCells]; 
        xOut.xltype = xltypeMulti | xlbitDLLFree;

        int errorCount = 0;
        std::ostringstream err;
        LoopIteration<LoopFunction, InputType, OutputType> loopIteration;
        for (int i=0; i<numCells; ++i) {
            try {
                loopIteration(loopFunction, 
                    xMulti->val.array.lparray[i],
                    xOut.val.array.lparray[i],
                    false);
            } catch (const std::exception &e) {
                xOut.val.array.lparray[i].xltype = xltypeErr;
                xOut.val.array.lparray[i].val.err = xlerrNum;

                if (errorCount > ERROR_LIMIT) {
                    // Limit exceeded.  Take no action.  For performance reasons we test
                    // this case first since it's most common on big loop w/many errors
                    ;
                } else if (errorCount < ERROR_LIMIT) {
                    err << std::endl << std::endl 
                        << "iteration #" << i << " - " << e.what();
                    errorCount++;
                } else { // errorCount == ERROR_LIMIT
                    err << std::endl << std::endl 
                        << "iteration #" << i << " - " << e.what()
                        << std::endl << std::endl 
                        << "Count of failed iterations in looping function hit "
                        << "limit of " << ERROR_LIMIT + 1 << " - logging discontinued";
                    errorCount++;
                }
            }
        }

        if (errorCount)
            RepositoryXL::instance().logError(err.str(), functionCall);

        // Free memory
        if (excelToFree) {
            Excel(xlFree, 0, 1, &xTemp);
        } else if (xllToFree) {
            freeOper(&xTemp);
        }

    }
Exemple #11
0
 const XLOPER *FunctionCall::callerArray() {
     if (!xMulti_->xltype) Excel(xlCoerce, &xMulti_, 2, &xCaller_, TempInt(xltypeMulti));
     return &xMulti_;
 }
Exemple #12
0
/*
***************************************************************************
** Function to register one function given by its add-in function 
** definition.
***************************************************************************
*/
static void RegisterFunction(LPXLOPER  pxDLL, char *prefix, TFuncDef *funcDef)
{
    int status = FAILURE;

    /*
    ** These are all pascal strings to be used with string type OPERs
    ** for calls to Excel. We will want to use standard C-string
    ** functionality while building the strings, so we need an extra
    ** character at the end. Thus 257 is the maximum length.
    */
    static char errMsg[257];
    static char argTypes[33];  /* Argument types - a string of P's */
    static char argNames[257]; /* Argument names */
    static char funcName[257]; /* Function name */
    static char cFuncName[257];/* C-function name */
    static char catName[257];  /* Category name */
    static char funcDesc[257]; /* function description */

    size_t    nameLen;
    size_t    numArgs;
    size_t    lenArgNames;
    TBoolean  namesAreTooLong;
    size_t    maxArgs = sizeof(argTypes)-2;
    size_t    maxLenArgNames = sizeof(argNames)-2;
    size_t    ipos;
    size_t    nargs;

    /* Define the category name as a pascal string. */
    catName[0] = strlen(FUNCTION_CATEGORY);
    strcpy (catName+1, FUNCTION_CATEGORY);

    /* Define the function name as a pascal string. */
    funcName[0] = strlen(prefix) + strlen(funcDef->name) + 1;
    strcpy (funcName+1, prefix);
    strcat (funcName, "_");
    strcat (funcName, funcDef->name);
    strncpy (cFuncName, funcName, sizeof(funcName));
    maxLenArgNames -= (funcName[0] + 2); /* it seems to be this way! */

    /*
    ***********************************************************************
    ** Define the list of argument types as a pascal string.
    **
    ** There is always one output, plus the standard inputs.
    **
    ** If the function is an object constructor then the base name is
    ** needed.
    ***********************************************************************
    */
    numArgs = 1 + funcDef->numInputs;
    if (numArgs > maxArgs)
    {
        sprintf (errMsg+1, "%s: Too many arguments (%d)\n", funcName+1, numArgs);
        goto done;
    }
    argTypes[0] = (char)numArgs;
    memset (argTypes+1, '\0', maxArgs+1);
    memset (argTypes+1, 'P', numArgs);

    /*
    ***********************************************************************
    ** Build up the list of argument names as a pascal string.
    **
    ** For convenience, there will be a comma at the beginning of the
    ** string in the short term!
    **
    ** If this exceeds the maximum length, then we will use a short format.
    ***********************************************************************
    */
    namesAreTooLong = FALSE;
    lenArgNames     = 0;
    argNames[1]     = '\0'; /* Start with an empty string */
    for (ipos = 0; ipos < funcDef->numInputs; ++ipos)
    {
        TParamDef *paramDef;

        paramDef = funcDef->params + ipos;
        nameLen  = strlen(paramDef->name);

        if ((lenArgNames + nameLen + 1) > maxLenArgNames)
        {
            namesAreTooLong = TRUE;
            break; /* No need to do any more... */
        }
        else
        {
            argNames[lenArgNames] = ',';
            ++lenArgNames;
            strcpy (argNames+lenArgNames, paramDef->name);
            lenArgNames += nameLen;
        }
    }

    if (namesAreTooLong)
    {
        sprintf (errMsg+1, "%s: Argument names are too long for Excel. Maximum length = %ld.", funcName+1, maxLenArgNames);
        goto done;
    }

    argNames[0] = (char)(lenArgNames);

    /* Define the function description as a pascal string. */
    if (funcDef->description != NULL)
    {
        funcDesc[0] = ' ';
        strncpy(funcDesc + 1, funcDef->description, 255);
        funcDesc[256] = '\0';
    }
    else
    {
        funcDesc[0] = ' ';
        funcDesc[1] = '\0';
    }

    /*
    ** Since we use TempStr, it doesn't matter what is in the first character
    ** of the strings, since TempStr replaces it with the string length.
    **
    ** As it happens, it should be the correct length already!
    */
    nargs = funcDef->numInputs;
    if (nargs > 20) nargs = 20;    /* Excel has limit of 30 LXOPERS - so cannot register remaining parameters descriptions */

    Excel (xlfRegister, 
           0,               /* not interested in any return details */
           10 + nargs,  /* number of input parameters in this registration call */
           pxDLL,
           TempStr(funcName),
           TempStr(argTypes),
           TempStr(cFuncName),
           TempStr(argNames),
           TempStr(" 1"),
           TempStr(catName),
           TempStr(" "),        /* hot key / short cut */
           TempStr(" "),        /* help id, eg. "alib.hlp!123" */
           TempStr(funcDesc),    /* function description */
           /* argument descriptions */
           ParameterDescription(funcDef, 0),
           ParameterDescription(funcDef, 1),
           ParameterDescription(funcDef, 2),
           ParameterDescription(funcDef, 3),
           ParameterDescription(funcDef, 4),
           ParameterDescription(funcDef, 5),
           ParameterDescription(funcDef, 6),
           ParameterDescription(funcDef, 7),
           ParameterDescription(funcDef, 8),
           ParameterDescription(funcDef, 9),
           ParameterDescription(funcDef, 10),
           ParameterDescription(funcDef, 11),
           ParameterDescription(funcDef, 12),
           ParameterDescription(funcDef, 13),
           ParameterDescription(funcDef, 14),
           ParameterDescription(funcDef, 15),
           ParameterDescription(funcDef, 16),
           ParameterDescription(funcDef, 17),
           ParameterDescription(funcDef, 18),
           ParameterDescription(funcDef, 19));

    status = SUCCESS;

done:

    if (status != SUCCESS)
    {
        Excel (xlcAlert, 0, 2, TempStr(errMsg), TempInt(2));
    }
}