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

"forceFullCalc" is not necessary in current Excel #4269

Closed
1 of 8 tasks
ogasawara-k opened this issue Dec 10, 2024 · 6 comments · Fixed by #4271
Closed
1 of 8 tasks

"forceFullCalc" is not necessary in current Excel #4269

ogasawara-k opened this issue Dec 10, 2024 · 6 comments · Fixed by #4271

Comments

@ogasawara-k
Copy link

ogasawara-k commented Dec 10, 2024

This is:

- [x] a bug report
- [ ] a feature request
- [ ] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)

What is the expected behavior?

If I create a file in PhpSpreadsheet without calculating it (setPreCalculateFormulas(false)), when I open it in excel it will calculate automatically and I'm hoping there won't be a "Calculate" button.

$objWriter->writeAttribute('forceFullCalc', ($preCalculateFormulas) ? '0' : '1');

I wasn't able to trace the reason why "forceFullCalc" was added, but it wasn't there in the PHPExcel era.
Since "calcMode" is output as "auto", I think it's correct that "Calculate" is not displayed.

What is the current behavior?

When you open the created file in Excel, it will be Calculate (manual recalculation).
image

What are the steps to reproduce?

Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:

<?php

require __DIR__ . '/vendor/autoload.php';

// Create new Spreadsheet object
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();

// add code that show the issue here...
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', '=1+1');
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, \PhpOffice\PhpSpreadsheet\IOFactory::WRITER_XLSX);
$writer->setPreCalculateFormulas(false);
$writer->save(__DIR__ . '/sample.xlsx');

Open the file you created in Excel.

If this is an issue with reading a specific spreadsheet file, then it may be appropriate to provide a sample file that demonstrates the problem; but please keep it as small as possible, and sanitize any confidential information before uploading.

What features do you think are causing the issue

  • Reader
  • Writer
  • Styles
  • Data Validations
  • Formula Calculations
  • Charts
  • AutoFilter
  • Form Elements

Does an issue affect all spreadsheet file formats? If not, which formats are affected?

xlsx ( & xlsm )

Which versions of PhpSpreadsheet and PHP are affected?

PhpSpreadsheet: 3.6.0
PHP: 8.2.13
Excel: Office 2019 & Office365

@oleibman
Copy link
Collaborator

This was added by PR #515 to fix issue #456 in May 2018. Since it addresses a specific problem, I am reluctant to change it. Is the current implementation causing you any problems?

@oleibman
Copy link
Collaborator

I could add a forceFullCalc property to the writer, equal to null (default), true, or false. Default would act as today (so no compatibility break), but true/false would override the default. It would mean an extra call for you. Would that meet your needs?

@ogasawara-k
Copy link
Author

ogasawara-k commented Dec 11, 2024

I did the same thing with reference to #456 . (Since it's long, I've closed it with "details".)
  1. Create a very simple spreadsheet from Excel with:
    • a formula on A1 => '=A2*2'.
    • a value on A2 => 0
  2. Save the file from Excel
  3. Now open this file with the library and set value = 3 on A2
  4. Save a new xlsx file from the library
  5. Open the new xslx with Excel
  6. The formula on A1 is not updated

STEP1

Create a file in Excel (Excel 2019)

STEP2 - 4

Read, change value, and write

<?php

require __DIR__ . '/vendor/autoload.php';

// step2
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader(\PhpOffice\PhpSpreadsheet\IOFactory::READER_XLSX);
$spreadsheet = $reader->load(__DIR__ . '/step1.xlsx');

// step3
$spreadsheet->getActiveSheet()->setCellValue('A2', 3);

// step4
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, \PhpOffice\PhpSpreadsheet\IOFactory::WRITER_XLSX);
$writer->setPreCalculateFormulas(false);
$writer->save(__DIR__ . '/step3.xlsx');

STEP5 - 6

original
image

remove-forceFullCalc
image

The version of Excel confirmed in step 6

  • Excel 2019 (Microsoft® Excel® 2019 MSO (Version 2411 Build 16.0.18227.20082) 64-bit)
  • Excel 2016 (Microsoft® Excel® 2016 MSO (バージョン 2410 ビルド 16.0.18129.20158) 32 ビット)
  • Microsoft 365 (Microsoft® Excel® for Microsoft 365 MSO (バージョン 2411 ビルド 16.0.18227.20082) 64ビット)

It didn't reproduce.


The current problem is that if you open even one Book in which "Calculate" is displayed, "Calculate" will also be displayed in other Books until you close Excel.

image

The whole of Excel goes into recalculation mode, so if you close other workbooks that you haven't changed, a dialog box will appear asking if you want to save them.
I can't force users not to open other workbooks, so I'm in trouble.

If you can also specify whether to output "forceFullCalc" using "setPreCalculateFormulas", you can deal with any problems at your own risk.

@oleibman
Copy link
Collaborator

Thank you for teaching me about the details trick. And for all the research. I agree that I can't reproduce the problem. But I am in no doubt that the people reporting it had a genuine problem which forceFullCalc solved. It sounds like you are okay with my proposal for a new property, so I will proceed along those lines.

I confirm your statement that one forceFullCalc affects all open spreadsheets. I find that ... strange.

oleibman added a commit to oleibman/PhpSpreadsheet that referenced this issue Dec 11, 2024
Fix PHPOffice#4269. In response to issue PHPOffice#456 PR PHPOffice#515, `forceFullCalc` was added to workbook.xml whenever `preCalculateFormulas` was set to false. It is not clear why this should have been needed; attempts to reproduce the error in the original 6.5-year-old issue are unable to reproduce it today. Nevertheless, it is, or was, there for a reason.

Today, the forceFullCalc option sets an option where formulas *might* not be recalculated when a cell used in the formula changes. I have not succeeded in finding a situation where it doesn't automatically recalculate, but it probably exists on complicated spreadsheets. To overcome this possibility, Excel offers a button which can be used to recalculate on demand. By itself, this might not be a terrible problem. However, it seems to come with the strange property that any spreadsheets opened at the same time as a forceFullCalc spreadsheet operate as if they too specified forceFullCalc. That *is* a problem, especially since users when closing a spreasheet affected in this way will be prompted to save it even when they haven't changed anything.

I am not willing to make a BC change at this time, although I might consider it in future (PR PHPOffice#4240). For now, I am adding a new property `forceFullCalc` with setter (no getter needed) to Xlsx Writer. That property can be `null` (default, in which case the Xml attribute is set as today), or `false` or `true` (in which case the Xml attribute will be set to the Writer attribute). I think that, when `preCalculateFormulas` is set to false, the calling application should give consideration to setting `forceFullCalc` to false as well. All other situations should just use the default.
@LucaRed
Copy link

LucaRed commented Dec 27, 2024

one forceFullCalc affects all open spreadsheets. I find that ... strange.

I'll add this for future reference: the option affects all open spreadsheets because different files may reference each other.

It's the same reason why it's (almost) 2025 and Excel still cannot open two files with the same filename at the same time.

@oleibman
Copy link
Collaborator

@LucaRed Thank you for the explanation. It is helpful to at least understand why things work the way they do.

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

Successfully merging a pull request may close this issue.

3 participants