Click or drag to resize


Below is a complete example of how to call the sqrt function from the <cmath> standard library.

 1// sample.cpp - Simple example of using AddIn.
 2#include <cmath>
 3#include "../xll/xll.h"
 4#include "../xll/shfb/entities.h"
 6using namespace xll;
 8AddIn xai_sample(
 9    Document(L"sample") // top level documentation
10    .Documentation(LR"(
11This object will generate a Sandcastle Helpfile Builder project file.
14AddIn xal_sample_category(
15    Document(L"Example")
16    .Documentation(LR"(
17This object will generate documentation for the Example category.
21// Information Excel needs to register add-in.
22AddIn xai_function(
23    // Function returning a pointer to an OPER with C++ name xll_function and Excel name XLL.FUNCTION.
24    // Don't forget prepend a question mark to the C++ name.
25    //                     |
26    //                     v
27    Function(XLL_LPOPER, L"?xll_function", L"XLL.FUNCTION")
28    // First argument is a double called x with an argument description and default value of 2
29    .Arg(XLL_DOUBLE, L"x", L"is the first double argument.", L"2")
30    // Paste function category.
31    .Category(L"Example")
32    // Insert Function description.
33    .FunctionHelp(L"Help on XLL.FUNCTION goes here.")
34    // Create entry for this function in Sandcastle Help File Builder project file.
35    .Alias(L"XLL.FUNCTION.ALIAS") // alternate name
36    .Documentation(
37        PARA_(
38            L"Free-form documentation for " C_(L"XLL.FUNCTION") L" goes here."
39        )
40        PARA_(L"But you can include MAML directives.")
41        PARA_(L"This is " B_(L"bold") " and so is " B_("this"))
42        PARA_(L"Math: " MATH_(int_ SUB_(minus_ infin_) SUP_(infin_) L"e" SUP_(L"x" sup2_ L"/2") L" dx"))
43    )
44    .Remarks(
45        L"This is a remark. "
46        L"This is " B_(L"bold") L" and this is " I_(L"italic")
47        PARA_(L"This is a paragraph.")
48    )
49    .Examples(LR"(
50This is an example.
52It has two paragraphs.
55// Calling convention *must* be WINAPI (aka __stdcall) for Excel.
56LPOPER WINAPI xll_function(double x)
58    // Be sure to export your function.
59#pragma XLLEXPORT
60    static OPER result;
62    try {
63        ensure(x >= 0);
64        result = sqrt(x); // OPER's act like Excel cells.
65    }
66    catch (const std::exception& ex) {
67        XLL_ERROR(ex.what());
69        result = OPER(xlerr::Num);
70    }
72    return &result;

Let's go through it line by line.

Line 2 pulls in everything you need to create an Excel add-in.

Line 4 saves you the trouble of typing xll:: in front of the names of things.

Line 6 is where the real action starts. When your add-in is opened in Excel, this object gets constructed. It tells Excel everything it needs to know to call your code, and let's you supply information to people that need to understand what your code does.

Line 7 is where you create a Function. The function returns a double, calls the C++ function xll_double when you enter =XLL.DOUBLE in Excel.

You can specify the arguments your function takes using the named parameter idiom. Line 8 indicates the first argument is a 64-bit floating point number. In the function wizard it will be called "x" and the individual argument help will be "is the number to double." These strings can be anything, so use your imagination to come up with something that your users will find helpful.

Line 9 is a short description of what your functions does and line 10 specifies the category to use in the Function Wizard.

Notice how the AddIn arguments appear in the Function Wizard:

Line 12 says the function returns a double, uses an old-fashioned calling convention , and begins the definition of the C++ function Excel will call. Be sure to put WINAPI between the return type and the function name. If you forget there will be no warning and your code will mysteriously fail at random times.

Unlike Unix, Windows does not export functions from shared libraries by default. Line 14 does that for you. Unlike WINAPI, if you forget this you will be warned.

Since we are returning a pointer to an OPER we need to make sure what it is pointing at sticks around after the function returns. Line 15 declares the OPER to be static so the pointer being returned in line 22 isn't pointing at garbage.

If you know something about C++ you might find line 18 confusing. C++ is strongly typed but you are assigning a double to an OPER. You can also assign a string and a bool to an OPER and the right thing happens.