diff --git a/components/fpspreadsheet/examples/other/defined_names/demo_read_definednames.lpr b/components/fpspreadsheet/examples/other/defined_names/demo_read_definednames.lpr index 15a096ba1..b2c02e3d7 100644 --- a/components/fpspreadsheet/examples/other/defined_names/demo_read_definednames.lpr +++ b/components/fpspreadsheet/examples/other/defined_names/demo_read_definednames.lpr @@ -6,7 +6,7 @@ var wb: TsWorkbook; ws: TsWorksheet; cell: PCell; - i: Integer; + i, j: Integer; fn: String; begin {$IFDEF ODS} @@ -26,7 +26,7 @@ begin WriteLn('DEFINED NAMES (GLOBAL)'); for i := 0 to wb.DefinedNames.Count-1 do - WriteLn(' ', wb.DefinedNames[i].Name, ' --> ', wb.DefinedNames[i].RangeAsString(wb)); + WriteLn(' "', wb.DefinedNames[i].Name, '" --> ', wb.DefinedNames[i].RangeAsString(wb)); WriteLn('--------------------------------------------------------'); @@ -35,6 +35,13 @@ begin ws := wb.GetWorksheetByIndex(i); WriteLn('WORKSHEET "', ws.Name, '"'); + WriteLn(' DEFINED NAMES (LOCAL)'); + if ws.DefinedNames.Count = 0 then + WriteLn(' (none)') + else + for j := 0 to ws.DefinedNames.Count-1 do + WriteLn(' "', ws.DefinedNames[i].Name, '" --> ', ws.DefinedNames[i].RangeAsString(wb)); + WriteLn(' CELLS'); for cell in ws.Cells do begin diff --git a/components/fpspreadsheet/examples/other/defined_names/demo_write_definednames.lpr b/components/fpspreadsheet/examples/other/defined_names/demo_write_definednames.lpr index 1d3b0fbfa..c557f1d20 100644 --- a/components/fpspreadsheet/examples/other/defined_names/demo_write_definednames.lpr +++ b/components/fpspreadsheet/examples/other/defined_names/demo_write_definednames.lpr @@ -17,6 +17,7 @@ begin ws := wb.AddWorksheet('Simple'); wsIdx0 := wb.GetWorksheetIndex(ws); + // ... global scope wb.DefinedNames.Add('distance', wsIdx0, 1, 2); ws.WriteText(1, 1, 'distance'); ws.WriteNumber(1, 2, 120); ws.WriteFormula(1, 3, '=distance'); @@ -26,6 +27,11 @@ begin wb.DefinedNames.Add('speed', wsIdx0, 3, 2); ws.WriteText(3, 1, 'speed'); ws.WriteFormula(3, 2, '=distance/time'); + // ... worksheet scope + ws.WriteText(4, 1, 'local'); ws.WriteNumber(4, 2, 123.456); + ws.DefinedNames.Add('local', wsIdx0, 4, 2); + ws.WriteFormula(4, 3, '=local'); + {----------} // Cell range as defined name diff --git a/components/fpspreadsheet/source/common/fpsexprparser.pas b/components/fpspreadsheet/source/common/fpsexprparser.pas index c4fdc4b87..7c24fd3f9 100644 --- a/components/fpspreadsheet/source/common/fpsexprparser.pas +++ b/components/fpspreadsheet/source/common/fpsexprparser.pas @@ -2427,6 +2427,15 @@ var defName: TsDefinedName; begin sheet := TsWorksheet(FWorksheet); + + // FIXME: This code does not distinguish between local and global scope! + + for i := 0 to sheet.Definednames.Count-1 do + begin + defName := sheet.DefinedNames[i]; + Identifiers.AddCellRangeVariable(defName.Name, defName.Range); + end; + book := TsWorkbook(sheet.Workbook); for i := 0 to book.DefinedNames.Count-1 do begin diff --git a/components/fpspreadsheet/source/common/fpspreadsheet.pas b/components/fpspreadsheet/source/common/fpspreadsheet.pas index d3841395b..8b89d2c12 100644 --- a/components/fpspreadsheet/source/common/fpspreadsheet.pas +++ b/components/fpspreadsheet/source/common/fpspreadsheet.pas @@ -75,6 +75,7 @@ type FWorkbook: TsWorkbook; FCells: TsCells; FComments: TsComments; + FDefinedNames: TsDefinedNames; FMergedCells: TsMergedCells; FHyperlinks: TsHyperlinks; FFormulas: TsFormulas; @@ -673,6 +674,8 @@ type property CryptoInfo: TsCryptoInfo read FCryptoInfo write FCryptoInfo; {@@ List of all comment records } property Comments: TsComments read FComments; + {@@ List of local defined names } + property DefinedNames: TsDefinedNames read FDefinedNames; {@@ List of merged cells (contains TsCellRange records) } property MergedCells: TsMergedCells read FMergedCells; {@@ List of hyperlink information records } @@ -962,7 +965,7 @@ type property CryptoInfo: TsCryptoInfo read FCryptoInfo write FCryptoInfo; {property RevisionsCrypto: TsCryptoInfo read FRevisionsCrypto write FRevisionsCrypto;} - { Globally defined names } + { Global defined names } property DefinedNames: TsDefinedNames read FDefinedNames write FDefinedNames; {@@ Workbook metadata} @@ -1245,6 +1248,7 @@ begin FRows := TIndexedAVLTree.Create(@CompareRows); FCols := TIndexedAVLTree.Create(@CompareCols); FComments := TsComments.Create; + FDefinedNames := TsDefinedNames.Create; FMergedCells := TsMergedCells.Create; FHyperlinks := TsHyperlinks.Create; FFormulas := TsFormulas.Create; @@ -1291,6 +1295,7 @@ begin FRows.Free; FCols.Free; FComments.Free; + FDefinedNames.Free; FMergedCells.Free; FHyperlinks.Free; FFormulas.Free; diff --git a/components/fpspreadsheet/source/common/xlsxooxml.pas b/components/fpspreadsheet/source/common/xlsxooxml.pas index a820e5f3b..e81def875 100644 --- a/components/fpspreadsheet/source/common/xlsxooxml.pas +++ b/components/fpspreadsheet/source/common/xlsxooxml.pas @@ -2476,7 +2476,15 @@ begin if sheetName2 = '' then sheetName2 := sheetName1; sheetIdx1 := book.GetWorksheetIndex(sheetName1); sheetIdx2 := book.GetWorksheetIndex(sheetName2); - book.DefinedNames.Add(nameStr, sheetIdx1, sheetIdx2, r1, c1, r2, c2); + s := GetAttrValue(node, 'localSheetId'); + if s <> '' then + begin + // local defined name + sheet := book.GetWorksheetByIndex(StrToInt(s)); + sheet.DefinedNames.Add(nameStr, sheetIdx1, sheetIdx2, r1, c1, r2, c2); + end else + // global defined name + book.DefinedNames.Add(nameStr, sheetIdx1, sheetIdx2, r1, c1, r2, c2); end; end; node := node.NextSibling; @@ -7565,6 +7573,18 @@ begin ); end; + for j := 0 to book.GetWorksheetCount-1 do + begin + sheet := book.GetWorksheetByIndex(j); + for i := 0 to sheet.DefinedNames.Count-1 do + begin + defName := sheet.DefinedNames[i]; + sTotal := sTotal + Format('%s', + [defName.Name, i, defName.RangeAsString(FWorkbook) ] + ); + end; + end; + // Write print ranges and repeatedly printed rows and columns for i := 0 to (Workbook as TsWorkbook).GetWorksheetCount-1 do begin