diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/NamedRanges/XLNamedRange.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/NamedRanges/XLNamedRange.cs index a99e010..a2958fb 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/NamedRanges/XLNamedRange.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/NamedRanges/XLNamedRange.cs @@ -8,11 +8,7 @@ internal class XLNamedRange: IXLNamedRange { - private static readonly Regex _namedRangeReferenceRegex = - new Regex( - @"^('?(?[^'!]+)'?!(?.+))|((?[^\[]+)\[(?[^\]]+)\])$", - RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture - ); + private List _rangeList = new List(); private readonly XLNamedRanges _namedRanges; public XLNamedRange(XLNamedRanges namedRanges , String rangeName, String range, String comment = null) @@ -39,7 +35,7 @@ var ranges = new XLRanges(); foreach (var rangeToAdd in from rangeAddress in _rangeList.SelectMany(c=>c.Split(',')).Where(s=>s[0] != '"') - let match = _namedRangeReferenceRegex.Match(rangeAddress) + let match = XLHelper.NamedRangeReferenceRegex.Match(rangeAddress) select match.Groups["Sheet"].Success ? _namedRanges.Workbook.WorksheetsInternal.Worksheet(match.Groups["Sheet"].Value).Range(match.Groups["Range"].Value) as IXLRangeBase diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs index 687b1a1..7155e2d 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; namespace ClosedXML.Excel { @@ -551,7 +552,14 @@ var targetSheet = (XLWorksheet)workbook.WorksheetsInternal.Add(newSheetName, position); Internals.CellsCollection.GetCells().ForEach(c => targetSheet.Cell(c.Address).CopyFrom(c, false)); - DataValidations.ForEach(dv => targetSheet.DataValidations.Add(new XLDataValidation(dv))); + DataValidations.ForEach(dv => + { + var newDv = new XLDataValidation(dv); + newDv.Value = ReplaceRelativeSheet(newSheetName, dv.Value); + newDv.MinValue = ReplaceRelativeSheet(newSheetName, dv.MinValue); + newDv.MaxValue = ReplaceRelativeSheet(newSheetName, dv.MaxValue); + targetSheet.DataValidations.Add(newDv); + }); Internals.ColumnsCollection.ForEach( kp => targetSheet.Internals.ColumnsCollection.Add(kp.Key, new XLColumn(kp.Value))); Internals.RowsCollection.ForEach(kp => targetSheet.Internals.RowsCollection.Add(kp.Key, new XLRow(kp.Value))); @@ -608,6 +616,34 @@ return targetSheet; } + private String ReplaceRelativeSheet(string newSheetName, String value) + { + if (StringExtensions.IsNullOrWhiteSpace(value)) return value; + + var newValue = new StringBuilder(); + var addresses = value.Split(','); + foreach (var address in addresses) + { + var pair = address.Split('!'); + if (pair.Length == 2) + { + String sheetName = pair[0]; + if (sheetName.StartsWith("'")) + sheetName = sheetName.Substring(1, sheetName.Length - 2); + + String name = sheetName.ToLower().Equals(Name.ToLower()) + ? newSheetName + : sheetName; + newValue.Append(String.Format("'{0}'!{1}", name, pair[1])); + } + else + { + newValue.Append(address); + } + } + return newValue.ToString(); + } + public new IXLHyperlinks Hyperlinks { get; private set; } IXLDataValidations IXLWorksheet.DataValidations diff --git a/ClosedXML/ClosedXML/ClosedXML/ExcelHelper.cs b/ClosedXML/ClosedXML/ClosedXML/ExcelHelper.cs index 1a3c9f1..4a84b09 100644 --- a/ClosedXML/ClosedXML/ClosedXML/ExcelHelper.cs +++ b/ClosedXML/ClosedXML/ClosedXML/ExcelHelper.cs @@ -160,25 +160,14 @@ + @"\Z" ); + public static readonly Regex NamedRangeReferenceRegex = + new Regex( @"^('?(?[^'!]+)'?!(?.+))|((?
[^\[]+)\[(?[^\]]+)\])$", + RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture + ); + public static Boolean IsValidRangeAddress(String rangeAddress) { return A1SimpleRegex.IsMatch(rangeAddress); - //if (StringExtensions.IsNullOrWhiteSpace(rangeAddress)) - // return false; - - //string addressToUse = rangeAddress.Contains("!") - // ? rangeAddress.Substring(rangeAddress.IndexOf("!") + 1) - // : rangeAddress; - - //if (addressToUse.Contains(':')) - //{ - // var arrRange = addressToUse.Split(':'); - // string firstPart = arrRange[0]; - // string secondPart = arrRange[1]; - // return IsValidA1Address(firstPart) && IsValidA1Address(secondPart); - //} - - //return IsValidA1Address(addressToUse); } public static int GetRowFromAddress1(string cellAddressString) diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/Resource/Examples/Misc/DataValidation.xlsx b/ClosedXML/ClosedXML/ClosedXML_Tests/Resource/Examples/Misc/DataValidation.xlsx index 566addb..8fba4bc 100644 --- a/ClosedXML/ClosedXML/ClosedXML_Tests/Resource/Examples/Misc/DataValidation.xlsx +++ b/ClosedXML/ClosedXML/ClosedXML_Tests/Resource/Examples/Misc/DataValidation.xlsx Binary files differ