Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible way to enforce autocalc of formula: #322

Open
Sasawaws opened this issue Jan 24, 2025 · 4 comments
Open

Possible way to enforce autocalc of formula: #322

Sasawaws opened this issue Jan 24, 2025 · 4 comments

Comments

@Sasawaws
Copy link

Sasawaws commented Jan 24, 2025

https://stackoverflow.com/questions/18355691/set-xlsx-to-recalculate-formulae-on-open

Autocalc on load isn't working for me using libreoffice to load the xlsx files.

Trying various things from here

https://stackoverflow.com/questions/18355691/set-xlsx-to-recalculate-formulae-on-open

by editing the xml files directly indicates that this problem persists regardless of the options for calcPr however omitting the value for the cell with the formula results in the cell always being recalculated.

So in the worksheet changing "<v>0</v>" -> "" means it gets automatically computed on load.

This can be implemented in the library very simply by commenting out two lines:

"../OpenXLSX/sources/XLFormula.cpp":144

// ===== If the cell node doesn't have a value child node, create it.
if (m_cellNode->child("f").empty()) m_cellNode->append_child("f");
// if (m_cellNode->child("v").empty()) m_cellNode->append_child("v"); // removed to force recalc on load <<<<<

// ===== Remove the formula type and shared index attributes, if they exist.
m_cellNode->child("f").remove_attribute("t");
m_cellNode->child("f").remove_attribute("si");

// ===== Set the text of the value node.
m_cellNode->child("f").text().set(formulaString);
// if (resetValue) m_cellNode->child("v").text().set(0); // removed to force recalc on load <<<<<

@aral-matrix
Copy link
Collaborator

I took the liberty to edit in a link to the source code you are referencing.

@aral-matrix
Copy link
Collaborator

aral-matrix commented Jan 24, 2025

My comment from the other issue:
----------------------------
Also, I just saw this - does that happen to work?
https://github.com/troldal/OpenXLSX/blob/master/OpenXLSX/sources/XLWorkbook.cpp#L650

void XLWorkbook::setFullCalculationOnLoad()

It is not automatically invoked anywhere - and it might be a permanent flag that is undesirable for worksheets with a lot of computations - but I never tried if this at least successfully forces recalculation on load.

@aral-matrix
Copy link
Collaborator

aral-matrix commented Jan 24, 2025

In addition to your suggestion of not creating the "v" entry if it does not exist - I am thinking to add an XLCellValueProxy method "clearValue" that would do only a remove_child("v").

However, I just saw that - contrary to the comments - XLCellValueProxy& XLCellValueProxy::clear() does not clear the formula node (it does however clear the cell type, which may be too much).
https://github.com/troldal/OpenXLSX/blob/master/OpenXLSX/sources/XLCellValue.cpp#L187

So could you try if - using the existing code - adding a cell.value().clear() after setting your formula also accomplishes the desired autocalculation?

@Sasawaws
Copy link
Author

void XLWorkbook::setFullCalculationOnLoad()

This offers:
getOrCreateAttribute("forceFullCalc").set_value(true);
getOrCreateAttribute("fullCalcOnLoad").set_value(true);

I tried by editing the xml - this didn't seem to do anything
I tried by editing the xml - this didn't seem to do anything
I don't recall trying "forceFullCalc".

I note that there is also another calcPr flag saved in these files, something about last calc with a number set. I tried with and without that flag (editing the html) and that didn't seem to help.

removing the value for a cell definitely helped (bear in mind I'm only testing with LO) and it didn't care about the calcPr flags.

At this point I edited the source, recompiled and got on with using it and my triage of the problem stopped.

Based on this, although untested, I wouldn't be sure that setFullCalculationOnLoad() works.

" adding a cell.value().clear()" testing - sorry this will have to wait for another day!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants