xlfSelection woes

Feb 1, 2013 at 9:23 AM
First of all; Thanks Keith for making your C++ Excel XLL Add-In libary available, I like the fact that it is small, clean and stand-alone while disposing of all the hassles related to Excel memory management and much of the type conversion mess! The library is IMHO implemented according to best practice C++ standards and with exception safety in mind which makes it plug right in to my code. Good job!

Now, I have a question for the community: Have any of you experienced issues with the xlfSelection function?

My code looks like this:
OPERX selRef = ExcelX(xlfSelection);
OPERX selection = ExcelX(xlCoerce, selRef);
I found this text on another webpage somewhere:

_Using my XLL library you would get the xltypeMulti
corresponding to the selection using:

OPER x = Excel(xlCoerce, Excel(xlfSelection));

No memory leaks.An exception is throw if something fails.
Elements are accessed linearly using operator[] and 2d
using operator()._

But when I try my code with an entire column (or row) selected in Excel 2010 the first line returns a 'selRef' with selRef.xltype == xltypeErr.

Another strange thing is that if I select two cells in the sheet the first line returns a 'selRef' with selRef.xltype == xltypeRef (which is as expected) but the second line will give a 'selection' with selection.xltype == xltypeErr!

Anyone having ideas as to why this is happening?

One thing I noticed is that val.sref.count sometimes is != 1 even though it should always be one according to the documentation. I don't know if this might cause any issues though.

Thanks in advance for all help!

// Magnus
Coordinator
Feb 1, 2013 at 12:49 PM
Hi Magnus. Glad you like the library. Are you compiling with EXCEL12 defined? A code sample would be helpful to get to the bottom of this.

I've also noticed val.sref.count != 1 on occasion too. Have no idea why.
Feb 4, 2013 at 7:21 AM
Thanks for replying!
No EXCEL12 defined yet, I'm using another API which doesn't handle strings very well at all... :(
I'll wrap the API and give it a try with EXCEL12 defined, I'll post the code when I'm done.
Mar 5, 2013 at 10:34 AM
Well, I finally got around to isolating the code causing me trouble. Here it is:

.h-file:
#pragma once

#define EXCEL12
#include "xll/xll.h"

#ifndef CATEGORY
#define CATEGORY _T("PVCS Link")
#endif

typedef xll::traits<XLOPERX>::xcstr xcstr; // pointer to const string
typedef xll::traits<XLOPERX>::xword xword; // use for OPER and FP indices
.c-file
using namespace xll;

static AddInX xai_updatereq(
    // C function name, Excel macro name
    _T("?xll_updatereq"), _T("PVCS.UPDATEREQ")
);
int WINAPI
xll_updatereq(void) {
#pragma XLLEXPORT
    int result = 1;

    try {
        // Get selected values
        OPERX selRef = ExcelX(xlfSelection);
        OPERX selection = ExcelX(xlCoerce, selRef);

        // For each selected value ...
        for(xword i = 0; i < selection.size(); ++i) {

            // If a string is selected; try to find matching named range
            if(selection[i].xltype == xltypeStr) {
                OPERX requestId = selection[i]; // Name of the selected request
            }
        }
    }
    catch (std::exception const & ex) {
        XLL_WARNING(ex.what());
        result = 0;
    }

    return result;
}
If I select more than one range (two ranges in this example) in Excel, and call this function, the variable "selRef" looks like this:

selRef.xloper12.xltype == xltypeRef (0x0008)
selRef.xloper12.val.mref.lpmref.count == 2 (or whatever numer of ranges I select)
selRef.xloper12.val.mref.lpmref.reftbl Looks ok...

I.e. things generally looks fine, but when I run xlCoerce on "selRef" the variable "selection" looks like this:

selection.xloper12.xltype == xltypeErr (0x0010)

Which of course means that the selection loop will not work...

Am I doing something wrong here?

Thanks in advance!

// Magnus
Coordinator
Mar 5, 2013 at 1:21 PM
I beleive you need to retrieve the val.mref.lpmref.count XLMREFs in a loop, use each one to create an XLOPER of type xltypeSRef, and coerce that, but I haven't tested it.