diff --git a/.gitignore b/.gitignore index 59a6fce5..fe762b50 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ examples/* !examples/logo.png !examples/logo_small.png !examples/Makefile +!examples/vbaProject.bin cov-int libxlsxwriter-coverity.tgz build diff --git a/docs/images/macros.png b/docs/images/macros.png index 1e335e2d..fdee27f4 100644 Binary files a/docs/images/macros.png and b/docs/images/macros.png differ diff --git a/docs/src/working_with_macros.dox b/docs/src/working_with_macros.dox index 22240e9c..f60fb082 100644 --- a/docs/src/working_with_macros.dox +++ b/docs/src/working_with_macros.dox @@ -82,6 +82,33 @@ or else Excel will complain and possibly not open the file: lxw_workbook *workbook = new_workbook("macro.xlsm"); @endcode +It is also possible to assign a macro to a button that is inserted into a +worksheet using the `worksheet_insert_button()` function: + +@code + lxw_button_options options = {.caption = "Press Me", + .macro = "say_hello"}; + + worksheet_insert_button(worksheet, 2, 1, &options); +@endcode + +See the full example at @ref macro.c. + +It may be necessary to specify a more explicit macro name prefixed by the +workbook VBA name as follows: + + +@code + lxw_button_options options = {.caption = "Press Me", + .macro = "ThisWorkbook.say_hello"}; + + worksheet_insert_button(worksheet, 2, 1, &options); +@endcode + +@note Button is the only VBA Control supported by libxlsxwriter and due to the +implementation effort required it is unlikely that any other form elements +will be added in the future. + @section ww_macros_codenames Setting the VBA codenames @@ -113,6 +140,8 @@ clarity: +@note This step is particularly important for macros created with non-English +versions of Excel. @section ww_macros_debugging What to do if it doesn't work diff --git a/examples/macro.c b/examples/macro.c index 4ea2907b..bdb9973b 100644 --- a/examples/macro.c +++ b/examples/macro.c @@ -6,6 +6,10 @@ * The vba_extract.py utility from the libxlsxwriter examples directory can be * used to extract the vbaProject.bin file. * + * This example connects the macro to a button (the only Excel/VBA form object + * supported by libxlsxwriter) but that isn't a requirement for adding a macro + * file to the workbook. + * * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org */ @@ -13,13 +17,22 @@ int main() { + /* Note the xlsm extension of the filename */ lxw_workbook *workbook = workbook_new("macro.xlsm"); lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); - /* Add a macro that will execute when the file is opened. */ + worksheet_set_column(worksheet, COLS("A:A"), 30, NULL); + + /* Add a macro file extracted from an Excel workbook. */ workbook_add_vba_project(workbook, "vbaProject.bin"); - worksheet_write_string(worksheet, 0, 0, "Overwrite this", NULL); + worksheet_write_string(worksheet, 2, 0, "Press the button to say hello.", NULL); + + lxw_button_options options = {.caption = "Press Me", .macro = "say_hello", + .width = 80, .height = 30}; + + worksheet_insert_button(worksheet, 2, 1, &options); + return workbook_close(workbook); } diff --git a/examples/vbaProject.bin b/examples/vbaProject.bin new file mode 100644 index 00000000..accdab24 Binary files /dev/null and b/examples/vbaProject.bin differ diff --git a/include/xlsxwriter/worksheet.h b/include/xlsxwriter/worksheet.h index 8a86e167..29c94dff 100644 --- a/include/xlsxwriter/worksheet.h +++ b/include/xlsxwriter/worksheet.h @@ -4306,10 +4306,36 @@ lxw_error worksheet_conditional_format_range(lxw_worksheet *worksheet, lxw_col_t last_col, lxw_conditional_format *conditional_format); - -lxw_error worksheet_insert_button(lxw_worksheet *worksheet, lxw_row_t row_num, - lxw_col_t col_num, - lxw_button_options *options); +/** + * @brief Insert a button object into a worksheet. + * + * @param worksheet Pointer to a lxw_worksheet instance to be updated. + * @param row The zero indexed row number. + * @param col The zero indexed column number. + * @param options A #lxw_button_options object to set the button properties. + * + * @return A #lxw_error code. + * + * The `%worksheet_insert_button()` function can be used to insert an Excel + * form button into a worksheet. This function is generally only useful when + * used in conjunction with the `workbook_add_vba_project()` function to tie + * the button to a macro from an embedded VBA project: + * + * @code + * lxw_button_options options = {.caption = "Press Me", + * .macro = "say_hello"}; + * + * worksheet_insert_button(worksheet, 2, 1, &options); + * @endcode + * + * @image html macros.png + * + * The button properties are set using the lxw_button_options struct. + * + * See also @ref working_with_macros + */ +lxw_error worksheet_insert_button(lxw_worksheet *worksheet, lxw_row_t row, + lxw_col_t col, lxw_button_options *options); /** * @brief Add an Excel table to a worksheet.