Forum > FPSpreadsheet

Circular reference when insert a row

(1/1)

jollytall:
I have a very simple program:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project1; {$mode objfpc}{$H+} uses  sysutils,  fpsTypes,  fpspreadsheet; var  WB : TsWorkbook;  WS : TsWorksheet;beginWB := TsWorkbook.Create;WB.Options := WB.Options + [boAutoCalc];WS := WB.AddWorksheet('Sheet1');WS.WriteFormula(WS.GetCell(0,0), '=-A2');WS.WriteNumber(1, 0, 0);WS.InsertRow(0);WB.Free;end. and the InsertRow crashes with Circular reference.

Instead of =-A2, I tried to use -A2 (I guess it is the same, as = is removed very early in the storing process), =+A2 and +A2 and they all fail. Trying =A2 and A2 work well. For negative I could only make -1*A2 work, but as in my real program I make my much more complicated formulas from many little pieces, it is not an easy option.

I tried to debug the differences between =A2 and =+A2. Both get to unit fpsExprParser, line 2087 (function TsExpressionParser.IterateNodes) but from there the next step is either line 4289 (procedure TsCellExprNode.IterateNodes), the descendant method for the good one or line 2919 (procedure TsExprNode.IterateNodes) the ancestor dummy method. So it seems that FExprnode is not set correctly.
Of course, if AutoCalc is not switched on then the error does not appear until later someone, e.g. in another program tries to use the spreadsheet made here.

What can I do?

wp:
Please try the new revision that I just committed to CCR. The unary expression node did not implement its own IterateNodes method.

If you don't use svn make the following modifications to fpsexprparser.pas:

* In the interface part of the unit add this line to the public section of class TsUnaryOperationExprNode:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---    procedure IterateNodes(AProc: TsExprNodeProc; AData1, AData2: Pointer;      var MustRebuildFormulas: boolean); override;
* In the implementation part of the unit add this code:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TsUnaryOperationExprNode.IterateNodes(AProc: TsExprNodeProc;  AData1, AData2: Pointer; var MustRebuildFormulas: Boolean);begin  FOperand.IterateNodes(AProc, AData1, AData2, MustRebuildFormulas);end;

jollytall:
Thank you. It works!

Navigation

[0] Message Index

Go to full version