This walkthrough demonstrates how to use the CXlOper class to return a 2-dimensional array (vector) from an add-in function.
Two such functions are created, which construct the array result in two different ways:
To create the project using Visual Studio 6
To create the project using Visual Studio .NET or Visual Studio 2005
For more details about creating projects, see Creating an add-in project in the XLL+ User Guide.
Use the XLL+ Function Wizard to create a new add-in function and to add a pair of unsigned short integer arguments.
Note: If you do not know how to start the Function Wizard, or you cannot find the tool-bar, look at Installing the Function Wizard under Developer Studio 6 or Installing the Function Wizard under Visual Studio .NET or Visual Studio 2005.
Open the source file MatrixRes.cpp and click on the New XLL+ Function menu item or tool-button, to show the New Function dialog, and fill in the name, category and description as shown below.
Add new arguments Rows and Cols of type UShort (unsigned short integer), by typing into the arguments grid, as shown below. Note that the return type must be CXlOper.
Click on the OK button to close the Function Wizard and save the function.
The following function has been added to MatrixRes.cpp.
extern "C" __declspec( dllexport ) LPXLOPER NumericArray(USHORT Rows, USHORT Cols) { CXlOper xloResult; //}}XLP_SRC // TODO - Set the value of xloResult return xloResult.Ret(); }
Our task is going to be to populate xloResult with a numeric array.
Add the code below to set up a two-dimensional array of numbers. In the real world this would be a more useful data set, probably returned by a previously written function.
extern "C" __declspec( dllexport ) LPXLOPER NumericArray(USHORT Rows, USHORT Cols) { CXlOper xloResult; //}}XLP_SRC if (Rows == 0 || Cols == 0) { xloResult = xlerrNum; return xloResult.Ret(); } // Create and populate a 2-dimensional array of numbers double** apd = new double*[Rows]; for (USHORT i = 0; i < Rows; i++) { apd[i] = new double[Cols]; for (USHORT j = 0; j < Cols; j++) { apd[i][j] = (double)((i*100) + j); } } // Set the value of xloResult xloResult.FromDoubleArray(apd, Rows, Cols, TRUE); // Clean up temporary array for (i = 0; i < Rows; i++) delete[] apd[i]; delete[] apd; // Return contents of xloResult return xloResult.Ret(); }
The important function here is of course FromDoubleArray(). This populates xloResult with a copy of the numeric array apd. The fourth argument to FromDoubleArray(), BOOL bByRows, is set to TRUE, so that the array is laid out with rows representing the continuous data held in each pointer member of apd[]. To transpose the array, set the argument to FALSE. We can then safely delete apd, and return the contents of xloResult.
Use the XLL+ Function Wizard to create a new add-in function and to add an unsigned short integer arguments.
Activate the source file MatrixRes.cpp and click on the New XLL+ Function menu item or tool-button, to show the New Function dialog, and fill in the name, category and description as shown below.
Add a new argument Rows of type UShort (unsigned short integer), by typing into the arguments grid, as shown below. Note that the return type must be CXlOper.
Click on the OK button to close the Function Wizard and save the function.
The following function has been added to MatrixRes.cpp.
extern "C" __declspec( dllexport ) LPXLOPER MixedArray(USHORT Rows) { CXlOper xloResult; //}}XLP_SRC // TODO - Set the value of xloResult return xloResult.Ret(); }
Our task is going to be to populate xloResult with a mixed array.
Add the code below to set up a two-dimensional array of cells. Each row of cells contains a number and a string.
extern "C" __declspec( dllexport ) LPXLOPER MixedArray(USHORT Rows) { CXlOper xloResult; //}}XLP_SRC if (Rows == 0) { xloResult = xlerrNum; return xloResult.Ret(); } xloResult.AllocArray(Rows, 2); for (USHORT i = 0; i < Rows; i++) { xloResult.Cell(i, 0) = (double)i; xloResult.Cell(i, 1) = "A string"; } return xloResult.Ret(); }
First we test that Rows is non-zero, and fail if it is not.
Then we use AllocArray() to turn xloResult into an array with Rows rows and 2 columns.
Next, we populate each row of xloResult, using the Cell() method to access each cell.
Finally we return the contents of xloResult to Excel, as usual.
In a worksheet, select a range containing two rows and three columns, and type in the formula =NumericArray(2,3), as shown below.
Then press the key combination Shift+Ctrl+Enter to enter the formula as an array formula.
Walkthroughs | CXlOper::FromDoubleArray method | CXlOper::AllocArray method | CXlOper::Cell method