xlsgen bug fixes

Generate Excel files. Speed. Flexibility. Depth. Robustness.

 

Subscribe our RSS feed

xlsgen 4.5.0.83 : Improved tables (II)


Build 4.5.0.83 of xlsgen adds support for database connections in table objects.

Before this build, you could program and run SQL requests but the result would not become an actual Excel table object fetched with the database data. It would just be rows fetched with database data. Likewise if you created an actual Excel table object in xlsgen, you couldn't program and run an SQL request from it.

This is put together in this build. You can now create an actual Excel table object, program and run an SQL request that will bound the table rows to the underlying database. And even better, xlsgen creates the database connection in the Excel file so you can reuse it elsewhere.

Here is how it works,


xlsgen::IXlsWorkbookPtr workbook;
workbook = engine->New( L"output.xlsx" );

xlsgen::IXlsWorksheetPtr worksheet = workbook->AddWorksheet("SheetX");

xlsgen::IXlsTablePtr table = worksheet->NewTable[3][2];

table->DataSource->CommandTimeout = 40;
table->DataSource->ConnectionTimeout = 120;
#ifndef _WIN64
table->DataSource->ConnectionString = L"Provider=MSDASQL;Driver={Microsoft Access Driver (*.mdb)};Dbq=c:\\datasource\\db1.mdb;uid=;pwd=;";
#else
table->DataSource->ConnectionString = L"Provider=MSDASQL;Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=c:\\datasource\\db1.mdb;uid=;pwd=;";
#endif

table->DataSource->SQLStatement = L"select * from Table1";

int nbrows = table->DataResults->RowCount;
int nbcolumns = table->DataResults->Columns->Count;

_bstr_t column1 = table->DataResults->Columns->Item[1]->Name;
_bstr_t column2 = table->DataResults->Columns->Item[2]->Name;
_bstr_t column3 = table->DataResults->Columns->Item[3]->Name;
_bstr_t column4 = table->DataResults->Columns->Item[4]->Name;
_bstr_t column5 = table->DataResults->Columns->Item[5]->Name;

_bstr_t definedName = table->DataResults->Name;

xlsgen::IXlsStylePtr styleDate = worksheet->NewStyle();
styleDate->Format = L"dd/mm/yyyy";

xlsgen::IXlsStylePtr styleBackground = worksheet->NewStyle();
styleBackground->Pattern->BackgroundColor = 0xFF0000;

table->DataResults->Columns->Item[4]->DataStyle = styleBackground;

table->DataResults->Insert();

workbook->Close();



Posted on 23-December-2019 10:19 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.82 : Improved tables


Build 4.5.0.82 improves the handling of tables, particularly Excel table objects.

In xlsgen, tables can be used in a variety of ways. They were initially introduced as a way to program and run SQL requests. Then, when business intelligence capabilities were introduced to xlsgen, tables were the underlying model for manipulating data (i.e. InferFromWorksheet()). Actual Excel tables were available, see tables for more information, but were not quite first-class citizen. For instance, what you couldn't do is for example add totals to them even though the table object model in xlsgen exposes subtotals beneath table breaks. The reality was that many of the table features were for "xlsgen" tables, not Excel table objects.

In this build, total rows are not ignored anymore for Excel table objects. It works like this :


xlsgen::IXlsTablePtr table = worksheet->Tables->Add();

table->DataSource->Range = L"R3C2:R6C6";

table->DataResults->Style->BuiltinStyle = xlsgen::tablestyle_light03;

// we have an "age" column in the table

xlsgen::IXlsTableBreaksPtr br = wksht->Tables->Item[1]->DataResults->Columns->ItemByName[L"age"]->Breaks;

// compute the average of "age"

br->Subtotals->Add( wksht->Tables->Item[1]->DataResults->Columns->ItemByName[L"age"] )->BuiltinFunction = xlsgen::subtotalfunc_average;




Also, table objects are now exposed in the automatic source code generator. It exposes table range definition, style and totals.

Posted on 23-December-2019 10:11 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.81 : Fix for rendering rotating text


Build 4.5.0.81 of xlsgen improves how rotated text is handled in rendering scenarios. Particularly this is an edge case that is fixed, where the rotate angle is very high (more than 45 degrees) and the room for rotating the text is small (cell has tight width and height).

It is a time to remind client and server applications using PDF output (one of our rendering outputs), that the quality of the rendering is slightly affected by the actual engine that is used. Notably,


  • native PDF generation (vectors) [default engine]

    C/C++ code
    // worksheet level
    workbook->PDFEngine = xlsgen::pdfengine_text;
    worksheet->Export->ExportAsPDF(L"output.pdf");

    // workbook level
    workbook = engine->Open(L"input.xlsm", L"outputAllWorksheets.pdf");
    workbook->PDFEngine = xlsgen::pdfengine_text;
    workbook->Close();


  • GDI-based PDF generation (screen DPI resolution, usually 96 DPI)


    C/C++ code
    // worksheet level
    workbook->PDFEngine = xlsgen::pdfengine_bitmap;
    worksheet->Export->ExportAsPDF(L"output.pdf");

    // workbook level
    workbook = engine->Open(L"input.xlsm", L"outputAllWorksheets.pdf");
    workbook->PDFEngine = xlsgen::pdfengine_bitmap;
    workbook->Close();


  • GDI-based virtual PDF printing (printer DPI resolution, usually 600 DPI)


    C/C++ code
    // worksheet level
    worksheet->PrintWith(L"PDFCreator", L""); // PDFCreator is a popular (and free) virtual PDF printer

    // workbook level
    workbook = engine->Open(L"input.xlsm", L"");
    workbook->PrintWith(L"PDFCreator", L"");
    workbook->Close();
Posted on 12-December-2019 08:43 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.80 : Try parse formula


Build 4.5.0.80 of xlsgen adds support for testing the parsing of formulas. Typically, writing a formula in a cell or to an object returns an exception if there is a problem, but it does not tell what the problem is. This parsing error is specifically the purpose of the introduced TryParseFormula method available at the workbook level.


typedef enum
{
[helpstring("Formula parsing error, no error")] parseformula_noerror = 0,
[helpstring("Formula parsing error, syntax error")] parseformula_syntaxerror = 1,
[helpstring("Formula parsing error, out of memory")] parseformula_outofmemory = 2,
[helpstring("Formula parsing error, not enough parameters")] parseformula_notenoughparams = 3,
[helpstring("Formula parsing error, too many parameters")] parseformula_toomanyparams = 4,
[helpstring("Formula parsing error, impaired parenthesis")] parseformula_impairedparenthesis = 5,
[helpstring("Formula parsing error, impaired brace")] parseformula_impairedbrace = 6,
[helpstring("Formula parsing error, division by zero")] parseformula_divisionbyzero = 7,
[helpstring("Formula parsing error, function does not exist")] parseformula_functionnotexist = 8,
[helpstring("Formula parsing error, wrong argument separator")] parseformula_wrongargumentseparator = 9

} enumParseFormulaError;


It works like this :

C/C++ code

xlsgen::enumParseFormulaError error = workbook->TryParseFormula(L"=SUMXYZ(5;3;A2)"); // returns parseformula_functionnotexist because SUMXYZ() does not exist



Posted on 05-December-2019 23:19 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.79 : Fix pack


Build 4.5.0.79 of xlsgen is a fix pack. It has the following :

- pivot tables now use localized strings. For instance, "Grand Total" is no longer hardcoded. It follows the current formula language (which you can set from the corresponding property in the workbook object, and which is one of EN/FR/DE/IT/PO/ES).

- fixed an edge case in rendering cells when the content has multiple lines separated by carriage returns, but no room vertically to show everything and the wrap flag set to off. Excel in this case ignores carriage returns. This is what xlsgen does now.

Posted on 03-December-2019 14:41 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.78 : UI-related pivot table settings (II)


Build 4.5.0.78 xlsgen follows previous build (4.5.0.77) related to pivot table UI settings in Excel.

This build writes back the UI settings listed below, including existing pivot tables, i.e. pivot tables that were not created using xlsgen.

Also the automatic source code generator now generates the corresponding source code for those.

Pivot table UI settings (in Excel) :
- EnablePivotTableUI (yes/no) : when set to no, the entire user interface for manipulating pivot tables is hidden
- ShowDetails (yes/no) : when set to no, non-aggregate values do not appear
- EnableFieldListUI (yes/no) : when set to no, the field list view is hidden
- EnableFieldPropertiesUI (yes/no) : when set to no, field properties dialog does not appear (looks like a bug for the end user because Excel does not gray out the menu)
- ShowFieldHeaders (yes/no) : when set to no, hides field elements

And also, in pivot table data source options,
- RefreshEnabled (yes/no)

Posted on 02-December-2019 12:06 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.77 : UI-related pivot table settings


Build 4.5.0.77 of xlsgen adds a number of user interface properties to the object model, for pivot tables. Those properties affect the experience of viewing or working with pivot tables in Excel.

They are :

in pivot table options
- EnablePivotTableUI (yes/no) : when set to no, the entire user interface for manipulating pivot tables is hidden
- ShowDetails (yes/no) : when set to no, non-aggregate values do not appear
- EnableFieldListUI (yes/no) : when set to no, the field list view is hidden
- EnableFieldPropertiesUI (yes/no) : when set to no, field properties dialog does not appear (looks like a bug for the end user because Excel does not gray out the menu)
- ShowFieldHeaders (yes/no) : when set to no, hides field elements

And also, in pivot table data source options,
- RefreshEnabled (yes/no) : when set to no, makes it impossible for the user to refresh the data source associated to the pivot table

Posted on 28-November-2019 16:11 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.76 : Edit table ranges (II)


Build 4.5.0.76 of xlsgen follows previous build 4.5.0.75 and adds another table property, DataRange, in order to differentiate :

- data rows : DataRange property
- header + data + totals : Range property

Both are read and write properties.

Posted on 28-November-2019 16:04 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.75 : Edit table ranges


Build 4.5.0.75 of xlsgen allows to edit ranges of existing tables. This applies to XLSX (and their variants) and XLSB files.


To obtain the cell range,

C++ code


_bstr_t range = worksheet->Tables->ItemByName[L"Table1"]->DataSource->Range; // returns a cell range of the form RxCx:RyCy




To change it,

C++ code


worksheet->Tables->ItemByName[L"Table1"]->DataSource->Range = L"R1C1:R15C10";




Alternatively, if the scenario knows in advance that all it needs is to add a new row to the table,

C++ code


worksheet->Tables->ItemByName[L"Table1"]->DataSource->AddRow();



Posted on 28-November-2019 09:10 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.74 : Support for XMATCH/XLOOKUP functions



Build 4.5.0.74 of xlsgen adds read, write and calculation support for XMATCH() and XLOOKUP() functions.

Those functions have been recently introduced by Microsoft as part of Office 365 insider preview and they'll be made available with an Office 365 subscription in 2020. They will never be supported in any existing Excel version (2007/2010/2013/2016/2019).

xlsgen supports them right now.

XMATCH() and XLOOKUP() are, according to Microsoft, more powerful versions of MATCH() and LOOKUP() functions.

They are indeed more powerful in the sense that MATCH() has several lookup algorithms, it does not go only top to bottom. And XLOOKUP() is more powerful than traditional LOOKUP()/HLOOKUP()/VLOOKUP() functions in the sense that the same function supports looking up in all directions, also it has a "if not found" fallback parameter which can be set optionally, and finally the return range is arbitrarily set. In other words, XMATCH() and XLOOKUP() can replace complex combinations of simpler functions sometimes.

Syntax : (optional arguments are square braced)

XMATCH(lookup_value, lookup_array, [match_mode], [search_mode])

XLOOKUP(lookup_value, lookup_array, return_array, [if_not_found], [match_mode], [search_mode])


match_mode is {0 = exact, 1 = lesser approximation, -1 = higher approximation, 2 = exact with wildcard characters}

search_mode is {1 = top-to-bottom search, -1 = bottom-to-top, 2 = half split top to bottom, -2 = half split bottom to top}

Posted on 17-November-2019 13:00 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.73 : Fix pack (III)


Build 4.5.0.73 of xlsgen fixes two problems related to rendering :

1) correct page margin inclusion (right edge)

2) in header/footer, any content in the center portion can span along the entire width of the page, excluding margins, not just the third of the width of the page, excluding margins.

Posted on 14-October-2019 12:02 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.72 : Fix pack (II)


Build 4.5.0.72 of xlsgen includes a number of fixes :

1) better handle fitToWidth and fitToTall page setup settings from XLSX files

2) improved fit-to-page algorithm when either fitToWidth or fitToTall is unspecified

3) localize PDF bookmarks in the PDF bookmarks bar by taking into account the current formula language

4) improved position of pictures when rendering pages with repeat columns or rows

5) avoid picture duplicates in XLSX and XLSB files (and their variants, XLSM, XLST, ...)

6) merged cells pre-write for rendering needs

Posted on 08-October-2019 00:10 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.71 : Fix pack


Build 4.5.0.71 of xlsgen is a pack of 2 fixes.

1) Support for the variant of =CEILING(number, significance) function introduced by Microsoft in Excel 2013. A silent behavorial change was introduced which allows the number to be negative while the significative to remain positive in order to ask for the rounding be the smallest integer instead of highest integer.

2) More fixing of internal shared formulas in cell manipulation scenarios.

Posted on 02-October-2019 00:49 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.70 : Querying objects by name


Build 4.5.0.70 of xlsgen adds object name setting and querying. This applies to shapes, pictures, text boxes, vector shapes and charts.

In Excel, object names appear in the same list than defined named, even though technically speaking they are not because they have no formula attached to it. Some of those names can be edited using the corresponding ribbon name field.

Querying a known name is a convenient method for getting an object and doing something with it, such as calculating depending formulas, rendering it and so on. Querying a known name in xlsgen is achieved by first getting the objects collection in question (for instance the charts collection for the current worksheet) and then use the ItemByName property to obtain the object by just passing the name as argument.

In xlsgen, when new objects such as shapes, pictures, text boxes, vector shapes and charts are created, they have no name by default. You can add one by just using the Name property which is a read/write property.

This works with all Excel file types.

Posted on 29-September-2019 10:22 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.69 : Improved page order print/rendering


Build 4.5.0.69 of xlsgen improves the page order algorithm in print/preview/PDF/XPS scenarios.

Prior to this build, pages would be rendered by xlsgen in a top-down then left-right algorithm with no API available to change that.

The page setup object has a new property, PageNumberLeftToRight, which when set to TRUE does the opposite, i.e. pages are rendered in a left-right then top-down algorithm.

Posted on 24-September-2019 20:37 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.68 : Fix pack (III)


Build 4.5.0.68 of xlsgen has 6 fixes :

1) fix picture duplication for XLS files (mso drawing solver container records correctly placed)

2) migrate form controls from XLS files to XLSX/XLSB files

3) migrate shape arrows properly from XLS files to XLSB/XLSB files

4) automatic source code generator exposes more accurate column width (floating point values)

5) sparkline rendering of "same min and max property for all sparklines" in XLSX/XLSB files

6) translation of formula error codes such as #VALUE! in the 6 formula languages (english, french, german, spanish, italian and portuguese). So #NAME? appears as #¿NOMBRE? in spanish, #VALUE! appears as #WERT! in german, and so on. Don't forget to set the formula language before processing a formula (reading or writing) with the workbook FormulaLanguage property.

Posted on 24-September-2019 20:33 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.67 : Fix pack (II)


Build 4.5.0.67 of xlsgen has two fixes :

1) case of formula corruption on row manipulation (insertion/deletion)

2) range selection allows max column and max row of current worksheet

Posted on 20-September-2019 10:36 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.66 : Fix pack


Build 4.5.0.66 of xlsgen is a fix pack.

1) incorrect sparklines minimum and maximum axis options handling for XLSX files

2) incorrect picture migration from XLS to XLSX or XLSB files, related to changing the sign of internal offsets

Posted on 14-September-2019 11:03 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.65 : Python support in automatic source code generator


The automatic source code generator can already create source code in VB, VB.NET, VBScript, C++, C# and Java from an arbitrary Excel file, by just passing the file to it. Build 4.5.0.65 of xlsgen adds Python to the list of supported languages.


Support for Python in the xlsgen automatic source code generator

Here is an example of what it produces from an existing Excel file :


#
# Automatically generated Python code for xlsgen
#
# Produced by xlsgen code generator (c) ARsT design.
# For more info, see http://xlsgen.arstdesign.com
#

#
# Setting up Python for use in xlsgen :
#
# - Download python MSI installer (for instance python 2.7.10, 17 MB) from
# https://www.python.org/downloads/release/python-2710/
#
# - Double-click on python-2.7.10.msi in order to install the software
#
# - Download the python COM types library from
# https://pypi.python.org/pypi/comtypes
# (deep download link is https://github.com/enthought/comtypes/archive/1.1.2.zip)
#
# - Extract the /comtypes folder from the COM types library
# into the \Lib folder, where is the Python 2.7.10 install folder.
#
#
# In order to run the project, use the following command :
# \python.exe test.py
#


#
# Excel workbook creation
#

import comtypes.client
from comtypes.client import CreateObject

engine = CreateObject("ExcelGenerator.ARsTDesign")

xlsgen = comtypes.client.GetModule(["{2BDEA919-2489-4ED2-8F55-C12D74DAD9B8}", 1, 0])

wbk = engine.New("myfile.xlsx")

wbk.Theme = xlsgen.workbooktheme_classic

#
# Worksheet "MU_REPORT"
#

wksht001 = wbk.AddWorksheet( "MU_REPORT" )

#
# Worksheet "Data Dictionary"
#

wksht002 = wbk.AddWorksheet( "Data Dictionary" )

#
# Worksheet "SheetNew"
#

wksht003 = wbk.AddWorksheet( "SheetNew" )

#
# declaration of dynamic named ranges
#

dynrange0000 = wksht001.NewDynamicRange("_ftnref1")
dynrange0000.Formula = "='Data Dictionary'!$C$8"

wksht001.Cell[1,1].HtmlLabel = "<font size=11 name=\"Calibri\">EHR Certification Number</font>"
wksht001.Cell[1,2].HtmlLabel = "<font size=11 name=\"Calibri\">Vendor Name</font>"
wksht001.Cell[1,3].HtmlLabel = "<font size=11 name=\"Calibri\">EHR Product CHP Id</font>"
wksht001.Cell[1,4].HtmlLabel = "<font size=11 name=\"Calibri\">EHR Product Name</font>"
wksht001.Cell[1,5].HtmlLabel = "<font size=11 name=\"Calibri\">EHR Product Version</font>"
wksht001.Cell[1,6].HtmlLabel = "<font size=11 name=\"Calibri\">Product Classification</font>"
wksht001.Cell[1,7].HtmlLabel = "<font size=11 name=\"Calibri\">Product Setting</font>"
wksht001.Cell[1,8].HtmlLabel = "<font size=11 name=\"Calibri\">Product Certification Edition Yr</font>"
wksht001.Cell[1,9].HtmlLabel = "<font size=11 name=\"Calibri\">Attestation Month</font>"
wksht001.Cell[1,10].HtmlLabel = "<font size=11 name=\"Calibri\">Attestation Year</font>"
wksht001.Cell[1,11].HtmlLabel = "<font size=11 name=\"Calibri\">Business State/Territory</font>"
wksht001.Cell[1,12].HtmlLabel = "<font size=11 name=\"Calibri\">Provider Type</font>"
wksht001.Cell[1,13].HtmlLabel = "<font size=11 name=\"Calibri\">Specialty</font>"
wksht001.Cell[1,14].HtmlLabel = "<font size=11 name=\"Calibri\">Program Year</font>"
wksht001.Cell[1,15].HtmlLabel = "<font size=11 name=\"Calibri\">Payment Year</font>"
wksht001.Cell[1,16].HtmlLabel = "<font size=11 name=\"Calibri\">Provider Stage Number</font>"
wksht001.Cell[1,17].HtmlLabel = "<font size=11 name=\"Calibri\">Program Type</font>"
wksht001.Cell[1,18].HtmlLabel = "<font size=11 name=\"Calibri\">Attestation_ID</font>"
wksht001.Cell[1,19].HtmlLabel = "<font size=11 name=\"Calibri\">Provider_ID</font>"
wksht001.Cell[2,1].HtmlLabel = "<font size=11 name=\"Calibri\">30000001SVGWEAS</font>"
wksht001.Cell[2,2].HtmlLabel = "<font size=11 name=\"Calibri\">NextGen Healthcare</font>"
wksht001.Cell[2,3].HtmlLabel = "<font size=11 name=\"Calibri\">CHP-007425</font>"
wksht001.Cell[2,4].HtmlLabel = "<font size=11 name=\"Calibri\">NextGen Ambulatory EHR</font>"



pivotTable003s0 = wksht003.NewPivotTable();
pivotTable003s0.DataSource.Range = "'MU_REPORT'!A1:S300"
pivotTable003s0.Options.Layout = xlsgen.pivottablelayout_outline
pivotTable003s0.Options.BuiltInPivotTableStyle = xlsgen.pivottablestyle_light16
pivotTable003s0.Options.ShowRowHeaders = True
pivotTable003s0.Options.ShowColumnHeaders = True
pivotTable003s0.Options.ShowRowStripes = False
pivotTable003s0.Options.ShowColumnStripes = False
pivotTable003s0.Options.ShowGrandTotalsForRows = True
pivotTable003s0.Options.ShowGrandTotalsForColumns = True
pf003s0r1 = pivotTable003s0.Rows.AddByName("EHR Product Name")
pf003s0r1.SortAscending = True
pf003s0r2 = pivotTable003s0.Rows.AddByName("Vendor Name")
pf003s0r3 = pivotTable003s0.Rows.AddByName("EHR Product Version")
pf003s0d1 = pivotTable003s0.Data.AddByName("Specialty")
pf003s0d1.AggregateFunction = xlsgen.aggrpivotfunction_count
pivotTable003s0.InsertAt(2, 2)

#
# Excel workbook epilogue
#


wbk.Close()


Posted on 23-August-2019 21:44 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

xlsgen 4.5.0.64 : Fix pack


Build 4.5.0.64 of xlsgen is a fix pack, including the following :

- better rewrite protected ranges from existing files

- better handle empty non-zero strings from some XLSB records

- handle corrupt files with right or bottom shape anchors outside the sheet

Posted on 13-August-2019 12:19 | Category: xlsgen, Excel generator | Tags: generating Excel spreadsheets

 

 

<-- previous page