The OPER class is a variant datatype that corresponds to a cell or range of cells in an Excel spreadsheet. It can be a number, string, boolean, reference, error, range, missing, nil, simple reference, or integer. It is a struct with a member called xltype that can be any of the following values.

#define xltypeNum        0x0001
#define xltypeStr        0x0002
#define xltypeBool       0x0004
#define xltypeRef        0x0008
#define xltypeErr        0x0010
#define xltypeFlow       0x0020
#define xltypeMulti      0x0040
#define xltypeMissing    0x0080
#define xltypeNil        0x0100
#define xltypeSRef       0x0400
#define xltypeInt        0x0800

#define xlbitXLFree      0x1000
#define xlbitDLLFree     0x4000

#define xltypeBigData	(xltypeStr | xltypeInt)

Here is the Microsoft XLOPER struct from XLCALL.H:

typedef struct xloper 
{
    union 
    {
        double num;	                  /* xltypeNum */
        LPSTR str;                   /* xltypeStr */
#ifdef __cplusplus
        WORD xbool;	                  /* xltypeBool */
#else	
        WORD bool;                   /* xltypeBool */
#endif	
        WORD err;                    /* xltypeErr */
        short int w;                 /* xltypeInt */
        struct 
        {
            WORD count;              /* always = 1 */
            XLREF ref;
        } sref;                      /* xltypeSRef */
        struct 
        {
            XLMREF *lpmref;
            DWORD idSheet;
        } mref;                      /* xltypeRef */
        struct 
        {
            struct xloper *lparray;
            WORD rows;
            WORD columns;
        } array;                     /* xltypeMulti */
       // ...flow and bigdata removed...
    } val;
    WORD xltype;
} XLOPER, *LPXLOPER;

C++ is a strongly typed language, but the OPER class is a wrapper around the XLOPER struct that was designed to behave just as you would expect a variant to behave.

OPER o;
assert (o.xltype == xltypeNil);
	
o = 1.23; // or o = Num(1.23);
assert (o.xltype == xltypeNum);
assert (o.val.num = 1.23);
assert (o == 1.23 && 1.23 == o);
	
o = OPER("string"); // or o = Str("string")
assert (o.xltype == xltypeStr);
assert (o == OPER("sTrInG")); // case insensitve

o = true; // or o = Bool(true);
assert (o.xltype == xltypeBool);
assert (o);

o = Err(xlerrValue); // #VALUE!
assert (o.xltype == xltypeErr); 
assert (o.val.err == xlerrValue);

o = Excel<XLOPER>(xlfEvaluate, OPER("{1,2,3;4,5,6}"));
// or o = OPER(2, 3); o(0, 0) = 1; ...; o(1, 2) = 6;
assert (o.xltype == xltypeMulti);
assert (o.val.array.rows == 2);
assert (o.val.array.columns == 3);
assert (o.val.array.lparray[3].val.num == 4);
assert (o[3] == 4);    // same using 1-d index
assert (o(1, 0) == 4); // same using 2-d index

assert (Missing().xltype == xltypeMissing);
assert (Nil().xltype == xltypeNil);

o = 123;
assert (o.xltype == xltypeNum); // not xltypeInt!
assert (o == 123);
o = Int(123); // if you really need an int
assert (o.xltype == xltypeInt);
assert (o.val.w == 123); // 16-bit short int
assert (o == 123);

Don't do o = "a naked string" or the character pointer gets converted to a double and o will have xltype == xltypeNum and o.val.num equal to the value of the character pointer. You can only bend C++ so far.

The function Excel takes OPERs as arguments and gives you access to all of Excel's functionality.

Last edited Jun 27, 2011 at 2:34 AM by keithalewis, version 7

Comments

No comments yet.