//------------------------------------------------------------------- bool coerce_to_int(const xloper *p_op, int &w) { if(!p_op || (p_op->xltype & (xltypeMissing | xltypeNil))) return false; if(p_op->xltype == xltypeInt) { w = p_op->val.w; return true; } if(p_op->xltype == xltypeErr) { w = p_op->val.err; return true; } // xloper is not an integer type, so try to convert it. xloper ret_val; if(!coerce_xloper(p_op, ret_val, xltypeInt)) return false; w = ret_val.val.w; return true; }
//------------------------------------------------------------------- cpp_xloper::cpp_xloper(WORD &rows, WORD &cols, xloper *input_oper) { Clear(); // Ask Excel to convert the reference to an array (xltypeMulti) if(!coerce_xloper(input_oper, m_Op, xltypeMulti)) { rows = cols = 0; } else { rows = m_Op.val.array.rows; cols = m_Op.val.array.columns; // Ensure destructor will tell Excel to free memory m_XLtoFree = true; } }
//------------------------------------------------------------------- // Allocate and populate an array of doubles based on input xloper //------------------------------------------------------------------- double *coerce_to_double_array(const xloper *p_op, double invalid_value, RW &cols, COL &rows) { if(!p_op || (p_op->xltype & (xltypeMissing | xltypeNil))) return NULL; // xloper is not an xloper array type, so try to convert it. xloper ret_val; if(!coerce_xloper(p_op, ret_val, xltypeMulti)) return NULL; // Allocate the space for the array of doubles cols = ret_val.val.array.columns; rows = ret_val.val.array.rows; int size = rows * cols; double *d_array = (double *)malloc(size * sizeof(double)); if(!d_array) { // Must free array memory allocated by xlCoerce Excel4(xlFree, 0, 1, &ret_val); return NULL; } // Get the cell values one-by-one as doubles and place in the array. // Store the array row-by-row in memory. xloper *p_elt = ret_val.val.array.lparray; if(!p_elt) // array could not be created { // Must free array memory allocated by xlCoerce Excel4(xlFree, 0, 1, &ret_val); free(d_array); return NULL; } double *p = d_array; for(; size--; p++) if(!coerce_to_double(p_elt++, *p)) *p = invalid_value; Excel4(xlFree, 0, 1, &ret_val); return d_array; // caller must free this }
//------------------------------------------------------------------- bool coerce_to_string(const xloper *p_op, char *&text) { char *str; xloper ret_val; text = NULL; // can test this or the return value for failure if(!p_op || (p_op->xltype & (xltypeMissing | xltypeNil)) != 0) return false; if(p_op->xltype != xltypeStr) { // xloper is not a string type, so try to convert it. if(!coerce_xloper(p_op, ret_val, xltypeStr)) return false; str = ret_val.val.str; } else if(!(str = p_op->val.str)) // make a working copy of the ptr return false; size_t len = (BYTE)str[0]; if((text = (char *)malloc(len + 1)) == NULL) // caller must free this { if(p_op->xltype != xltypeStr) Excel4(xlFree, 0, 1, &ret_val); return false; } if(len) memcpy(text, str + 1, len); text[len] = 0; // xloper string may not me null terminated // If the string from which the copy was made was created in a call // to coerce_xloper above, then need to free it with a call to xlFree if(p_op->xltype != xltypeStr) Excel4(xlFree, 0, 1, &ret_val); return true; }
//------------------------------------------------------------------- bool coerce_to_bool(const xloper *p_op, bool &b) { if(!p_op || (p_op->xltype & (xltypeMissing | xltypeNil))) return false; if(p_op->xltype == xltypeBool) { b = (p_op->val.xbool != 0); return true; } // xloper is not a Boolean number type, so try to convert it. xloper ret_val; if(!coerce_xloper(p_op, ret_val, xltypeBool)) return false; b = (ret_val.val.xbool != 0); return true; }
//------------------------------------------------------------------- bool coerce_to_double(const xloper *p_op, double &d) { if(!p_op || (p_op->xltype & (xltypeMissing | xltypeNil)) != 0) return false; if(p_op->xltype == xltypeNum) { d = p_op->val.num; return true; } // xloper is not a floating point number type, so try to convert it. xloper ret_val; if(!coerce_xloper(p_op, ret_val, xltypeNum)) return false; d = ret_val.val.num; return true; }