As you return to DevStudio, you will see that the wizard has inserted the following source code at the end of your C++ file. The code that is interestingly different from our previous example, NORMSDIST2, is marked below.
// Function: NORMSINV2 // Purpose: Returns the inverse of the standard normal cumulative distribution. The distribution has a mean of zero and a standard deviation of one. //{{XLP_SRC(NORMSINV2) // NOTE - the FunctionWizard will add and remove mapping code here. // DO NOT EDIT what you see in these blocks of generated code! IMPLEMENT_XLLFN2(NORMSINV2, "RB", "NORMSINV2", "Probability", "Statistical", "Returns the inverse of the standard normal" " cumulative distribution. The distribution has a mean of" " zero and a standard deviation of one.", "Probability is a" " probability corresponding to the normal distribution, a" " number between 0 and 1 exclusive", "\0", 1) extern "C" __declspec( dllexport ) LPXLOPER NORMSINV2(double Probability) { CXlOper xloResult; //}}XLP_SRC // TODO - Set the value of xloResult return xloResult.Ret(); }
Note each of the changed pieces of code:
CXlOper is a C++ class, which performs many useful tasks when managing data that is to be shared with Excel. It represents a value of variable type. Among the types of value it can hold are:
The CXlOper assigment operator, '=', is overloaded, which means that we can use code like the following to set its values:
CXlOper xloResult; xloResult = 9.9; // Set the type to double, and the value to 9.9 xloResult = "abc"; // Set the type to string, and the value to "abc" xloResult = xlerrValue; // Set the type to error, and the value to #VALUE!
Other assignment operators allow you to set a CXlOper's value to an array.
The CXlOper class is used throughout XLL+ to hold values that are shared with Excel. If you request data from Excel, for example to get the current language settings, it will be returned in a CXlOper.
See CXlOper in the class reference for full details of CXlOper.
Add code to the function to call our stand-alone function, as shown below:
extern "C" __declspec( dllexport )
LPXLOPER NORMSINV2(double Probability)
{
CXlOper xloResult;
//}}XLP_SRC
double Z;
if (InverseCumNormal(Probability, &Z))
xloResult = Z;
else
xloResult = xlerrNum;
return xloResult.Ret();
}
Depending on whether InverseCumNormal() succeeds we will either set CXlOper to contain the result of the calculation, or set it to contain the error code xlerrNum.
xlerrNum appears in Excel as #NUM!. For a full list of error codes, see Error codes.
xloResult is a local variable, and therefore goes out of scope at the end of the function. This means that its destructor will be called, and its value will be destroyed, and will therefore not be available to Excel. The Ret() method deals with this problem. It carries out three steps:
All this work is essential but dull, and is completely handled by the Ret() method, so that you need not concern yourself with it further.
Our second add-in function is now complete and we're ready to build and test it.