HOWTO: Handle an input with mixed types
Reference: Q0042
Article last modified on 24-Aug-2007
The information in this article applies to:
- XLL+ for Visual Studio .NET - 3, 4.1, 4.2, 4.3.1, 5.0
- XLL+ for Visual Studio 6 - 3, 4.1, 4.2, 4.3.1, 5.0
- XLL+ for Visual Studio 2005 - 5.0
How to handle an input with mixed types
Issue
I have an area on a spreadsheet with mixtures of types - strings, booleans and numbers. How do I read them in my add-in function.
Summary
- Set the argument's type to be COper.
- Use COper methods to inspect the input, including the following: COper::Cell(), COper::GetDims(), COper::IsBool(), COper::IsDouble(), COper::IsString().
Argument type: COper
Use the XLL+ Function Wizard to set the argument's type to COper.
Inspecting the COper
Use the method COper::GetDims() to get the dimensions of the input array. Use COper::Cell() to inspect any cell within the array.
Use any of the following methods to inspect the type and contents of each cell:
COper::IsBool() | COper::ToBool() |
COper::IsDouble() | COper::ToDouble() |
COper::IsString() | COper::ToString() |
The example function below takes an array of mixed type, reads each cell and sorts the values into numbers, booleans and strings.
// Function: MixedInputFn // Purpose: Reads an input array of mixed types //{{XLP_SRC(MixedInputFn) // NOTE - the FunctionWizard will add and remove mapping code here. // DO NOT EDIT what you see in these blocks of generated code! IMPLEMENT_XLLFN2(MixedInputFn, "RP", "MixedInputFn", "Mixed", "User Defined", "Reads an input array of mixed types", "An array containing mixed types\000", "\0appscope=1\0", 1) extern "C" __declspec( dllexport ) LPXLOPER MixedInputFn(const COper* Mixed) { XLL_FIX_STATE; CXlOper xloResult; //}}XLP_SRC // Buffers to hold values of each type std::vector<std::string> strings; std::vector<bool> booleans; std::vector<double> numbers; // Inspect size USHORT rows, cols; Mixed->GetDims(rows, cols); // Inspect each cell for (USHORT r = 0; r < rows; r++) { for (USHORT c = 0; c < cols; c++) { const COper& cell = Mixed->Cell(r, c); if (cell.IsDouble()) { numbers.push_back(cell.ToDouble()); } else if (cell.IsBool()) { booleans.push_back(!!cell.ToBool()); } else if (cell.IsString()) { strings.push_back(cell.ToString()); } } } // Get the size of the largest result vector size_t maxRows = numbers.size(); if (booleans.size() > maxRows) maxRows = booleans.size(); if (strings.size() > maxRows) maxRows = strings.size(); // Arrange the results in 3 columns xloResult.AllocArray(maxRows, 3); size_t i; for (i = 0; i < numbers.size(); i++) xloResult.Cell(i, 0) = numbers[i]; for (i = 0; i < booleans.size(); i++) xloResult.Cell(i, 1) = booleans[i]; for (i = 0; i < strings.size(); i++) xloResult.Cell(i, 2) = strings[i]; return xloResult.Ret(); }