From 9a6855375e81067021ff0808f3b7a0c36d68afca Mon Sep 17 00:00:00 2001 From: cherry Date: Mon, 29 Jan 2024 10:18:21 +0800 Subject: [PATCH] This closes #1792, support to update defined names reference when rename worksheet (#1797) --- adjust.go | 27 +++++++++++++++++++++++++++ sheet.go | 6 ++++++ sheet_test.go | 19 +++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/adjust.go b/adjust.go index 9346bd1..5d60040 100644 --- a/adjust.go +++ b/adjust.go @@ -454,6 +454,33 @@ func (f *File) adjustFormulaRef(sheet, sheetN, formula string, keepRelative bool return val, nil } +// adjustRangeSheetName returns replaced range reference by given source and +// target sheet name. +func adjustRangeSheetName(rng, source, target string) string { + cellRefs := strings.Split(rng, ",") + for i, cellRef := range cellRefs { + rangeRefs := strings.Split(cellRef, ":") + for j, rangeRef := range rangeRefs { + parts := strings.Split(rangeRef, "!") + for k, part := range parts { + singleQuote := strings.HasPrefix(part, "'") && strings.HasSuffix(part, "'") + if singleQuote { + part = strings.TrimPrefix(strings.TrimSuffix(part, "'"), "'") + } + if part == source { + if part = target; singleQuote { + part = "'" + part + "'" + } + } + parts[k] = part + } + rangeRefs[j] = strings.Join(parts, "!") + } + cellRefs[i] = strings.Join(rangeRefs, ":") + } + return strings.Join(cellRefs, ",") +} + // arrayFormulaOperandToken defines meta fields for transforming the array // formula to the normal formula. type arrayFormulaOperandToken struct { diff --git a/sheet.go b/sheet.go index ff07231..315507d 100644 --- a/sheet.go +++ b/sheet.go @@ -374,6 +374,12 @@ func (f *File) SetSheetName(source, target string) error { delete(f.sheetMap, source) } } + if wb.DefinedNames == nil { + return err + } + for i, dn := range wb.DefinedNames.DefinedName { + wb.DefinedNames.DefinedName[i].Data = adjustRangeSheetName(dn.Data, source, target) + } return err } diff --git a/sheet_test.go b/sheet_test.go index eb9e571..271262e 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -467,6 +467,25 @@ func TestSetSheetName(t *testing.T) { assert.Equal(t, "Sheet1", f.GetSheetName(0)) // Test set sheet name with invalid sheet name assert.EqualError(t, f.SetSheetName("Sheet:1", "Sheet1"), ErrSheetNameInvalid.Error()) + + // Test set worksheet name with existing defined name and auto filter + assert.NoError(t, f.AutoFilter("Sheet1", "A1:A2", nil)) + assert.NoError(t, f.SetDefinedName(&DefinedName{ + Name: "Name1", + RefersTo: "$B$2", + })) + assert.NoError(t, f.SetDefinedName(&DefinedName{ + Name: "Name2", + RefersTo: "$A1$2:A2", + })) + assert.NoError(t, f.SetDefinedName(&DefinedName{ + Name: "Name3", + RefersTo: "Sheet1!$A$1:'Sheet1'!A1:Sheet1!$A$1,Sheet1!A1:Sheet3!A1,Sheet3!A1", + })) + assert.NoError(t, f.SetSheetName("Sheet1", "Sheet2")) + for i, expected := range []string{"'Sheet2'!$A$1:$A$2", "$B$2", "$A1$2:A2", "Sheet2!$A$1:'Sheet2'!A1:Sheet2!$A$1,Sheet2!A1:Sheet3!A1,Sheet3!A1"} { + assert.Equal(t, expected, f.WorkBook.DefinedNames.DefinedName[i].Data) + } } func TestWorksheetWriter(t *testing.T) { -- GitLab