XLL+ Class Library (7.0)

MyCorrel Example

This example demonstrates how to read vector inputs and pass them to a 'real-world' function.

CopyC++
#include <math.h> 
 
// Function:    CalculateCorrel 
// Returns:     double 
// Description: Calculate the correlation of a series 
 
double CalculateCorrel(int nSamples, const double* pdX, 
                       const double* pdY)
{
    int i, j;
    double d, adSum[2], adSum2[2], dSumProd;
    const double* pdIn[2] = { pdX, pdY };
    double adSd[2], dCorrel;

    adSum[0] = adSum[1] = adSum2[0] = adSum2[1] = 0.0;
    dSumProd = 0.0;

    for ( i = 0; i < nSamples; i++ )
    {
        for ( j = 0; j < 2; j++ )
        {
            d = pdIn[j][i];
            adSum[j] += d;
            adSum2[j] += d * d;
        }
        dSumProd += pdIn[0][i] * pdIn[1][i];
    }

    for ( j = 0; j < 2; j++ )
        adSd[j] = sqrt((adSum2[j] - (adSum[j] * adSum[j] / nSamples))
                     / nSamples);

    if ( ( adSd[0] == 0.0 ) && ( adSd[1] == 0.0 ) )
        dCorrel = 1.0;
    else if ( ( adSd[0] == 0.0 ) || ( adSd[1] == 0.0 ) )
        dCorrel = 0.0;
    else
        dCorrel = (dSumProd - ((adSum[0] * adSum[1]) / nSamples))
                / ( nSamples * adSd[0] * adSd[1]);

    return dCorrel;
}

// Function:    MyCorrel 
// Returns:     LPXLOPER 
// Description: Calculate the correlation of two series 
 
//{{XLP_SRC(MyCorrel) 
    // NOTE - the FunctionWizard will add and remove mapping code here. 
    //    DO NOT EDIT what you see in these blocks of generated code! 
 
#pragma region MyCorrel support code
IMPLEMENT_XLLFN4(MyCorrel, MyCorrel_4, MyCorrel_12, "RPP", "UQQ", L"MyCorrel", 
    0, L"X,Y", 0, L"14", 0, L"Calculate the correlation of two series", 0, 
    L"First series\0Second series\0", 0, 0, L"{MyCorrel,,,Calculate the correl"
    L"ation of two series,14,1,0,U,{{0,{X,Double,10,,First series,,{{{,},{,siz"
    L"eOfX}}},,}},{0,{Y,Double,10,,Second series,,{{{,},{,sizeOfX}}},,}}},{},3"
    L",,0,0,,,,0,0}", 1, 0, 0)
CXlOper* MyCorrel_Impl(CXlOper&, const CXlOper*, const CXlOper*);
extern "C" __declspec(dllexport)
LPXLOPER12 MyCorrel_12(LPXLOPER12 X, LPXLOPER12 Y)
{
    XLL_FIX_STATE;
    CXlOper xloResult, X__port(X), Y__port(Y);
    try {
        CXlStructuredExceptionHandler _seh_;
        xloResult.HandleResult(MyCorrel_Impl(xloResult, &X__port, &Y__port));
    }
    catch(const CXlRuntimeException& ex) {
        CXllApp::Instance()->DisplayException(xloResult, ex);
    }
    XLP_CATCH_CLR_EXCEPTIONS_TO(xloResult)
    return xloResult.Ret12();
}
extern "C" __declspec(dllexport)
LPXLOPER4 MyCorrel_4(LPXLOPER4 X, LPXLOPER4 Y)
{
    XLL_FIX_STATE;
    CXlOper xloResult, X__port(X), Y__port(Y);
    try {
        CXlStructuredExceptionHandler _seh_;
        xloResult.HandleResult(MyCorrel_Impl(xloResult, &X__port, &Y__port));
    }
    catch(const CXlRuntimeException& ex) {
        CXllApp::Instance()->DisplayException(xloResult, ex);
    }
    XLP_CATCH_CLR_EXCEPTIONS_TO(xloResult)
    return xloResult.Ret4();
}

#pragma endregion

CXlOper* MyCorrel_Impl(CXlOper& xloResult, const CXlOper* X_op, const CXlOper* 
    Y_op)
{
    // Input buffers 
    std::vector<double> X;
    std::vector<double> Y;
    // Named bounds 
    long sizeOfX = -1;
    // Validate and translate inputs
    XlReadVector(*X_op, X, L"X", XLA_TRUNC_ONEMPTY|XLA_TRUNC_ONBLANK, &sizeOfX);
    XlReadVector(*Y_op, Y, L"Y", XLA_TRUNC_ONEMPTY|XLA_TRUNC_ONBLANK, &sizeOfX);
    // End of generated code 
//}}XLP_SRC 
 
    if (X.size() < 2)
        throw CXlRuntimeException("expeted at least two cells for X");

    // Call the real-world function & return the result
    xloResult = CalculateCorrel((int)X.size(), &X[0], &Y[0]);
    return xloResult.Ret();
}

Uses

CXlOper::Ret