The extended types we have looked at so far are simple to use.
Some other extended types may need extra information in order to work.
For example, we might add a FixedLengthString
type,
which will reject a string that is not of a certain length.
The developer needs to be able to specify what the required length
actually is, and this can of course vary for different arguments.
The solution to this issue is to add a Parameter to the extended type's definition.
Use the XLL+ Options/Extensions page
to load the file FixedLengthString.xpe
from the XLL+
extensions
sub-directory (as described in
Extended types).
Use the View button to examine the type in the XLL+ Extensions window.
Observe that the type has a parameter, Length, which is defined as an integer. The parameter has the property AvailableAtRuntime set to true, so it's value will be passed to the converter class.
In Visual Studio, create a new add-in function and add an argument of type FixedLengthString. A new column appears in the XLL+ Function Wizard, to let you specify the Length parameter.
The code generated for a type with parameters is more complex than the usual code.
CXlOper* StringFn_Impl(CXlOper& xloResult, const CXlStringArg& Product_op) { // Input buffers CString Product; // Validate and translate inputs XlReadScalarEx(Product_op, Product, FixedLengthStringConverter(), CScalarConvertParams<CString>(L"Product", 0, 0, -1).SetIntParam(0, 4)); // End of generated code //}}XLP_SRC ... }
The Wizard has generated code that passes the value of the Length
parameter to the validation function, by calling
SetIntParam(0, 4)
, i.e. setting the value of the first
integer parameter to 4
.
Open up FixedLengthStringConverter.h
in the XLL+ include\extensions
sub-directory,
and you can see how the parameter value is used:
class FixedLengthStringConverter : public CXlUserConverterBase<CString, CString> { public: virtual bool ConvertFromExcel(const CString& xlValue, CString& outerValue, const ParamsType& params) const { if (xlValue.GetLength() != params.GetIntParam(0)) return false; outerValue = xlValue; return true; } protected: virtual std::string GetTypeName(const ParamsType& params) const { char buf[128]; _snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%d-character string", params.GetIntParam(0)); return buf; } ... };
The parameter value is used in two places:
If the input fails the length test, an error message like the following is returned:
#ERROR: Expected 4-character string for Product
For more examples of extended types with parameters see the files in the
extensions
directory (and their matching header files in
include\extensions
).