From 022aa1ad6916300b94829945da2d8e868e4f2a80 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 22 Jan 2008 14:48:51 +0000 Subject: [PATCH] Fix from bug #41726 - support signed offsets from relative areas and references git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@614211 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 1 + src/documentation/content/xdocs/status.xml | 1 + .../poi/hssf/record/SharedFormulaRecord.java | 59 +++++++++++------- .../poi/hssf/data/SharedFormulaTest.xls | Bin 0 -> 31232 bytes .../poi/hssf/usermodel/TestFormulas.java | 11 ++++ 5 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 src/testcases/org/apache/poi/hssf/data/SharedFormulaTest.xls diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index bc95d9b7a..a2bd40d73 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -36,6 +36,7 @@ + 41726 - Fix how we handle signed cell offsets in relative areas and references 44233 - Support for getting and setting a flag on the sheet, which tells excel to re-calculate all formulas on it at next reload 44201 - Enable cloning of sheets with data validation rules 44200 - Enable cloning of sheets with notes diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 122cab85c..56b868b87 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -33,6 +33,7 @@ + 41726 - Fix how we handle signed cell offsets in relative areas and references 44233 - Support for getting and setting a flag on the sheet, which tells excel to re-calculate all formulas on it at next reload 44201 - Enable cloning of sheets with data validation rules 44200 - Enable cloning of sheets with notes diff --git a/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java b/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java index e2871ac5c..ae250246d 100755 --- a/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java +++ b/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java @@ -156,8 +156,8 @@ public class SharedFormulaRecord protected void fillFields(RecordInputStream in) { - field_1_first_row = in.readShort(); - field_2_last_row = in.readShort(); + field_1_first_row = in.readUShort(); + field_2_last_row = in.readUShort(); field_3_first_column = in.readUByte(); field_4_last_column = in.readUByte(); field_5_reserved = in.readShort(); @@ -200,48 +200,48 @@ public class SharedFormulaRecord Ptg ptg = (Ptg) field_7_parsed_expr.get(k); if (ptg instanceof RefNPtg) { RefNPtg refNPtg = (RefNPtg)ptg; - ptg = new ReferencePtg( (short)(formulaRow + refNPtg.getRow()), - (byte)(formulaColumn + refNPtg.getColumn()), + ptg = new ReferencePtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()), + fixupRelativeColumn(formulaColumn,refNPtg.getColumn(),refNPtg.isColRelative()), refNPtg.isRowRelative(), refNPtg.isColRelative()); } else if (ptg instanceof RefNVPtg) { RefNVPtg refNVPtg = (RefNVPtg)ptg; - ptg = new RefVPtg( (short)(formulaRow + refNVPtg.getRow()), - (byte)(formulaColumn + refNVPtg.getColumn()), - refNVPtg.isRowRelative(), - refNVPtg.isColRelative()); + ptg = new RefVPtg(fixupRelativeRow(formulaRow,refNVPtg.getRow(),refNVPtg.isRowRelative()), + fixupRelativeColumn(formulaColumn,refNVPtg.getColumn(),refNVPtg.isColRelative()), + refNVPtg.isRowRelative(), + refNVPtg.isColRelative()); } else if (ptg instanceof RefNAPtg) { RefNAPtg refNAPtg = (RefNAPtg)ptg; - ptg = new RefAPtg( (short)(formulaRow + refNAPtg.getRow()), - (byte)(formulaColumn + refNAPtg.getColumn()), + ptg = new RefAPtg( fixupRelativeRow(formulaRow,refNAPtg.getRow(),refNAPtg.isRowRelative()), + fixupRelativeColumn(formulaColumn,refNAPtg.getColumn(),refNAPtg.isColRelative()), refNAPtg.isRowRelative(), refNAPtg.isColRelative()); } else if (ptg instanceof AreaNPtg) { AreaNPtg areaNPtg = (AreaNPtg)ptg; - ptg = new AreaPtg((short)(formulaRow + areaNPtg.getFirstRow()), - (short)(formulaRow + areaNPtg.getLastRow()), - (short)(formulaColumn + areaNPtg.getFirstColumn()), - (short)(formulaColumn + areaNPtg.getLastColumn()), + ptg = new AreaPtg(fixupRelativeRow(formulaRow,areaNPtg.getFirstRow(),areaNPtg.isFirstRowRelative()), + fixupRelativeRow(formulaRow,areaNPtg.getLastRow(),areaNPtg.isLastRowRelative()), + fixupRelativeColumn(formulaColumn,areaNPtg.getFirstColumn(),areaNPtg.isFirstColRelative()), + fixupRelativeColumn(formulaColumn,areaNPtg.getLastColumn(),areaNPtg.isLastColRelative()), areaNPtg.isFirstRowRelative(), areaNPtg.isLastRowRelative(), areaNPtg.isFirstColRelative(), areaNPtg.isLastColRelative()); } else if (ptg instanceof AreaNVPtg) { AreaNVPtg areaNVPtg = (AreaNVPtg)ptg; - ptg = new AreaVPtg((short)(formulaRow + areaNVPtg.getFirstRow()), - (short)(formulaRow + areaNVPtg.getLastRow()), - (short)(formulaColumn + areaNVPtg.getFirstColumn()), - (short)(formulaColumn + areaNVPtg.getLastColumn()), + ptg = new AreaVPtg(fixupRelativeRow(formulaRow,areaNVPtg.getFirstRow(),areaNVPtg.isFirstRowRelative()), + fixupRelativeRow(formulaRow,areaNVPtg.getLastRow(),areaNVPtg.isLastRowRelative()), + fixupRelativeColumn(formulaColumn,areaNVPtg.getFirstColumn(),areaNVPtg.isFirstColRelative()), + fixupRelativeColumn(formulaColumn,areaNVPtg.getLastColumn(),areaNVPtg.isLastColRelative()), areaNVPtg.isFirstRowRelative(), areaNVPtg.isLastRowRelative(), areaNVPtg.isFirstColRelative(), areaNVPtg.isLastColRelative()); } else if (ptg instanceof AreaNAPtg) { AreaNAPtg areaNAPtg = (AreaNAPtg)ptg; - ptg = new AreaAPtg((short)(formulaRow + areaNAPtg.getFirstRow()), - (short)(formulaRow + areaNAPtg.getLastRow()), - (short)(formulaColumn + areaNAPtg.getFirstColumn()), - (short)(formulaColumn + areaNAPtg.getLastColumn()), + ptg = new AreaAPtg(fixupRelativeRow(formulaRow,areaNAPtg.getFirstRow(),areaNAPtg.isFirstRowRelative()), + fixupRelativeRow(formulaRow,areaNAPtg.getLastRow(),areaNAPtg.isLastRowRelative()), + fixupRelativeColumn(formulaColumn,areaNAPtg.getFirstColumn(),areaNAPtg.isFirstColRelative()), + fixupRelativeColumn(formulaColumn,areaNAPtg.getLastColumn(),areaNAPtg.isLastColRelative()), areaNAPtg.isFirstRowRelative(), areaNAPtg.isLastRowRelative(), areaNAPtg.isFirstColRelative(), @@ -256,6 +256,21 @@ public class SharedFormulaRecord throw new RuntimeException("Shared Formula Conversion: Coding Error"); } } + + private short fixupRelativeColumn(int currentcolumn, short column, boolean relative) { + if(relative) { + if((column&128)!=0) column=(short)(column-256); + column+=currentcolumn; + } + return column; + } + + private short fixupRelativeRow(int currentrow, short row, boolean relative) { + if(relative) { + row+=currentrow; + } + return row; + } /** * Mirroring formula records so it is registered in the ValueRecordsAggregate diff --git a/src/testcases/org/apache/poi/hssf/data/SharedFormulaTest.xls b/src/testcases/org/apache/poi/hssf/data/SharedFormulaTest.xls new file mode 100644 index 0000000000000000000000000000000000000000..8db77d98240c13b88bcf3ab6cd50ef5cc5084bb2 GIT binary patch literal 31232 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