XLL_DEC OPER *ohRemoveInvalidColumns(OPER *xInputRange) { // initialize Function Call object boost::shared_ptr<reposit::FunctionCall> functionCall; reposit::Xloper xMulti; static OPER xRet; xRet.val.array.lparray = 0; try { functionCall = boost::shared_ptr<reposit::FunctionCall> (new reposit::FunctionCall("ohRemoveInvalidColumns")); Excel(xlCoerce, &xMulti, 2, xInputRange, TempInt(xltypeMulti)); int numValidCols = countValidColumns(xMulti()); if (!numValidCols) return 0; int numRows = xMulti->val.array.rows; xRet.val.array.rows = numRows; xRet.val.array.columns = numValidCols; xRet.val.array.lparray = new OPER[numRows * numValidCols]; xRet.xltype = xltypeMulti | xlbitDLLFree; for (int i=0; i<xMulti->val.array.rows; ++i) { int j2 = 0; for (int j=0; j<xMulti->val.array.columns; ++j) { if (columnIsValid(xMulti(), j)) { int indexSource = i * xMulti->val.array.columns + j; int indexTarget = i * numValidCols + j2; operToOper(&xRet.val.array.lparray[indexTarget], &xMulti->val.array.lparray[indexSource]); j2++; } } } return &xRet; } catch (const std::exception &e) { // free any memory that may have been allocated if (xRet.xltype & xltypeMulti && xRet.val.array.lparray) { for (int i=0; i<xRet.val.array.columns * xRet.val.array.rows; ++i) { if (xRet.val.array.lparray[i].xltype & xltypeStr && xRet.val.array.lparray[i].val.str) delete [] xRet.val.array.lparray[i].val.str; } delete [] xRet.val.array.lparray; } // log the exception and return a null pointer (#NUM!) to Excel reposit::RepositoryXL::instance().logError(e.what(), functionCall); return 0; } }
XLL_DEC OPER *ohFilter( OPER *xInput, OPER *flags) { // declare a shared pointer to the Function Call object boost::shared_ptr<ObjectHandler::FunctionCall> functionCall; try { // instantiate the Function Call object functionCall = boost::shared_ptr<ObjectHandler::FunctionCall>( new ObjectHandler::FunctionCall("ohFilter")); // convert input datatypes to C++ datatypes std::vector<bool> flagsCpp = ObjectHandler::operToVector<bool>(*flags, "flags"); const OPER *xMulti; ObjectHandler::Xloper xTemp; if (xInput->xltype == xltypeMulti) { xMulti = xInput; } else { Excel(xlCoerce, &xTemp, 2, xInput, TempInt(xltypeMulti)); xMulti = &xTemp; } int sizeInput = xMulti->val.array.rows * xMulti->val.array.columns; OH_REQUIRE(sizeInput == flagsCpp.size(), "size mismatch between value vector (" << sizeInput << ") and flag vector (" << flagsCpp.size() << ")"); static OPER xRet; xRet.val.array.rows = count(flagsCpp.begin(), flagsCpp.end(), true); xRet.val.array.columns = 1; xRet.val.array.lparray = new OPER[xRet.val.array.rows]; xRet.xltype = xltypeMulti | xlbitDLLFree; int idx = 0; for (int i=0; i<sizeInput; i++) { if (flagsCpp[i]) { operToOper(&xRet.val.array.lparray[idx++], &xMulti->val.array.lparray[i]); } } return &xRet; } catch (const std::exception &e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall); return 0; } }