diff --git a/ClosedXML/Excel/Cells/XLCell.cs b/ClosedXML/Excel/Cells/XLCell.cs index 1ba9da4..f190093 100644 --- a/ClosedXML/Excel/Cells/XLCell.cs +++ b/ClosedXML/Excel/Cells/XLCell.cs @@ -15,6 +15,8 @@ using Attributes; using ClosedXML.Extensions; + [DebuggerDisplay("{Address}")] + internal class XLCell : IXLCell, IXLStylized { public static readonly DateTime BaseDate = new DateTime(1899, 12, 30); diff --git a/ClosedXML/Excel/Coordinates/IXLAddress.cs b/ClosedXML/Excel/Coordinates/IXLAddress.cs index bc70a90..6158251 100644 --- a/ClosedXML/Excel/Coordinates/IXLAddress.cs +++ b/ClosedXML/Excel/Coordinates/IXLAddress.cs @@ -5,18 +5,27 @@ { public interface IXLAddress : IEqualityComparer, IEquatable { - IXLWorksheet Worksheet { get; } - Int32 RowNumber { get; } - Int32 ColumnNumber { get; } String ColumnLetter { get; } - Boolean FixedRow { get; } + Int32 ColumnNumber { get; } Boolean FixedColumn { get; } - String ToStringRelative(); - String ToStringRelative(Boolean includeSheet); - String ToStringFixed(); - String ToStringFixed(XLReferenceStyle referenceStyle); - String ToStringFixed(XLReferenceStyle referenceStyle, Boolean includeSheet); - String ToString(XLReferenceStyle referenceStyle); + Boolean FixedRow { get; } + Int32 RowNumber { get; } String UniqueId { get; } + IXLWorksheet Worksheet { get; } + + String ToString(XLReferenceStyle referenceStyle); + + String ToString(XLReferenceStyle referenceStyle, Boolean includeSheet); + + String ToStringFixed(); + + String ToStringFixed(XLReferenceStyle referenceStyle); + + String ToStringFixed(XLReferenceStyle referenceStyle, Boolean includeSheet); + + String ToStringRelative(); + + + String ToStringRelative(Boolean includeSheet); } } diff --git a/ClosedXML/Excel/Coordinates/XLAddress.cs b/ClosedXML/Excel/Coordinates/XLAddress.cs index b1d7ff8..81f4977 100644 --- a/ClosedXML/Excel/Coordinates/XLAddress.cs +++ b/ClosedXML/Excel/Coordinates/XLAddress.cs @@ -7,6 +7,7 @@ internal class XLAddress : IXLAddress { #region Static + /// /// Create address without worksheet. For calculation only! /// @@ -72,22 +73,32 @@ } return new XLAddress(worksheet, rowNumber, columnLetter, fixedRow, fixedColumn); } - #endregion + + #endregion Static + #region Private fields + [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool _fixedRow; + [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool _fixedColumn; + [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string _columnLetter; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly int _rowNumber; + [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly int _columnNumber; + private string _trimmedAddress; - #endregion + + #endregion Private fields + #region Constructors + /// /// Initializes a new struct using a mixed notation. Attention: without worksheet for calculation only! /// @@ -99,6 +110,7 @@ : this(null, rowNumber, columnLetter, fixedRow, fixedColumn) { } + /// /// Initializes a new struct using a mixed notation. /// @@ -124,6 +136,7 @@ : this(null, rowNumber, columnNumber, fixedRow, fixedColumn) { } + /// /// Initializes a new struct using R1C1 notation. /// @@ -142,12 +155,14 @@ _columnLetter = null; _fixedColumn = fixedColumn; _fixedRow = fixedRow; - - } - #endregion + + #endregion Constructors + #region Properties + public XLWorksheet Worksheet { get; internal set; } + IXLWorksheet IXLAddress.Worksheet { [DebuggerStepThrough] @@ -195,8 +210,11 @@ { get { return _columnLetter ?? (_columnLetter = XLHelper.GetColumnLetterFromNumber(_columnNumber)); } } - #endregion + + #endregion Properties + #region Overrides + public override string ToString() { String retVal = ColumnLetter; @@ -214,31 +232,45 @@ public string ToString(XLReferenceStyle referenceStyle) { - if (referenceStyle == XLReferenceStyle.A1) - { - return ColumnLetter + _rowNumber.ToInvariantString(); - } - if (referenceStyle == XLReferenceStyle.R1C1) - { - return String.Format("R{0}C{1}", _rowNumber.ToInvariantString(), ColumnNumber); - } - if (HasWorksheet && Worksheet.Workbook.ReferenceStyle == XLReferenceStyle.R1C1) - { - return String.Format("R{0}C{1}", _rowNumber.ToInvariantString(), ColumnNumber); - } - return ColumnLetter + _rowNumber.ToInvariantString(); + return ToString(referenceStyle, false); } - #endregion + + public string ToString(XLReferenceStyle referenceStyle, bool includeSheet) + { + string address = string.Empty; + if (referenceStyle == XLReferenceStyle.A1) + + address = ColumnLetter + _rowNumber.ToInvariantString(); + else if (referenceStyle == XLReferenceStyle.R1C1) + + address = String.Format("R{0}C{1}", _rowNumber.ToInvariantString(), ColumnNumber); + else if (HasWorksheet && Worksheet.Workbook.ReferenceStyle == XLReferenceStyle.R1C1) + + address = String.Format("R{0}C{1}", _rowNumber.ToInvariantString(), ColumnNumber); + else + address = ColumnLetter + _rowNumber.ToInvariantString(); + + if (includeSheet) + return String.Format("{0}!{1}", + Worksheet.Name.WrapSheetNameInQuotesIfRequired(), + address); + + return address; + } + + #endregion Overrides + #region Methods + public string GetTrimmedAddress() { return _trimmedAddress ?? (_trimmedAddress = ColumnLetter + _rowNumber.ToInvariantString()); } + #endregion Methods - - #endregion #region Operator Overloads + public static XLAddress operator +(XLAddress left, XLAddress right) { return new XLAddress(left.Worksheet, @@ -288,9 +320,13 @@ { return !(left == right); } - #endregion + + #endregion Operator Overloads + #region Interface Requirements + #region IEqualityComparer Members + public Boolean Equals(IXLAddress x, IXLAddress y) { return x == y; @@ -315,8 +351,11 @@ { return _rowNumber ^ _columnNumber; } - #endregion + + #endregion IEqualityComparer Members + #region IEquatable Members + public bool Equals(IXLAddress other) { var right = other as XLAddress; @@ -329,10 +368,12 @@ public override Boolean Equals(Object other) { - return Equals((XLAddress) other); + return Equals((XLAddress)other); } - #endregion - #endregion + + #endregion IEquatable Members + + #endregion Interface Requirements public String ToStringRelative() { diff --git a/ClosedXML/Excel/Hyperlinks/XLHyperlink_Internal.cs b/ClosedXML/Excel/Hyperlinks/XLHyperlink_Internal.cs index 2e5bebe..caf81d2 100644 --- a/ClosedXML/Excel/Hyperlinks/XLHyperlink_Internal.cs +++ b/ClosedXML/Excel/Hyperlinks/XLHyperlink_Internal.cs @@ -5,7 +5,7 @@ public partial class XLHyperlink { internal XLHyperlink() - { + { } @@ -36,7 +36,7 @@ else { _internalAddress = address; - IsExternal = false; + IsExternal = false; } } } @@ -51,14 +51,14 @@ internal void SetValues(IXLCell cell, String tooltip) { Tooltip = tooltip; - _internalAddress = cell.Address.ToString(); + _internalAddress = cell.Address.ToString(XLReferenceStyle.A1, true); IsExternal = false; } internal void SetValues(IXLRangeBase range, String tooltip) { Tooltip = tooltip; - _internalAddress = range.RangeAddress.ToString(); + _internalAddress = range.RangeAddress.ToString(XLReferenceStyle.A1, true); IsExternal = false; } diff --git a/ClosedXML/Excel/Ranges/IXLRangeAddress.cs b/ClosedXML/Excel/Ranges/IXLRangeAddress.cs index 9da98e4..86ed2b1 100644 --- a/ClosedXML/Excel/Ranges/IXLRangeAddress.cs +++ b/ClosedXML/Excel/Ranges/IXLRangeAddress.cs @@ -4,8 +4,6 @@ { public interface IXLRangeAddress { - IXLWorksheet Worksheet { get; } - /// /// Gets or sets the first address in the range. /// @@ -13,13 +11,7 @@ /// The first address. /// IXLAddress FirstAddress { get; set; } - /// - /// Gets or sets the last address in the range. - /// - /// - /// The last address. - /// - IXLAddress LastAddress { get; set; } + /// /// Gets or sets a value indicating whether this range is invalid. /// @@ -28,10 +20,28 @@ /// Boolean IsInvalid { get; set; } - String ToStringRelative(); - String ToStringRelative(Boolean includeSheet); + /// + /// Gets or sets the last address in the range. + /// + /// + /// The last address. + /// + IXLAddress LastAddress { get; set; } + + IXLWorksheet Worksheet { get; } + + String ToString(XLReferenceStyle referenceStyle); + + String ToString(XLReferenceStyle referenceStyle, Boolean includeSheet); + String ToStringFixed(); + String ToStringFixed(XLReferenceStyle referenceStyle); + String ToStringFixed(XLReferenceStyle referenceStyle, Boolean includeSheet); + + String ToStringRelative(); + + String ToStringRelative(Boolean includeSheet); } } diff --git a/ClosedXML/Excel/Ranges/XLRangeAddress.cs b/ClosedXML/Excel/Ranges/XLRangeAddress.cs index fbe5135..13f986a 100644 --- a/ClosedXML/Excel/Ranges/XLRangeAddress.cs +++ b/ClosedXML/Excel/Ranges/XLRangeAddress.cs @@ -1,7 +1,6 @@ using ClosedXML.Extensions; using System; using System.Diagnostics; -using System.Globalization; using System.Linq; namespace ClosedXML.Excel @@ -10,16 +9,18 @@ { #region Private fields - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private XLAddress _firstAddress; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] private XLAddress _lastAddress; + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + private XLAddress _firstAddress; - #endregion + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + private XLAddress _lastAddress; + + #endregion Private fields #region Constructor - public XLRangeAddress(XLRangeAddress rangeAddress): this(rangeAddress.FirstAddress, rangeAddress.LastAddress) + public XLRangeAddress(XLRangeAddress rangeAddress) : this(rangeAddress.FirstAddress, rangeAddress.LastAddress) { - } public XLRangeAddress(XLAddress firstAddress, XLAddress lastAddress) @@ -73,7 +74,7 @@ Worksheet = worksheet; } - #endregion + #endregion Constructor #region Public properties @@ -122,10 +123,9 @@ set { LastAddress = value as XLAddress; } } - public bool IsInvalid { get; set; } - #endregion + #endregion Public properties #region Public methods @@ -168,7 +168,20 @@ public override string ToString() { - return _firstAddress + ":" + _lastAddress; + return String.Concat(_firstAddress, ':', _lastAddress); + } + + public string ToString(XLReferenceStyle referenceStyle) + { + return ToString(referenceStyle, false); + } + + public string ToString(XLReferenceStyle referenceStyle, bool includeSheet) + { + if (referenceStyle == XLReferenceStyle.R1C1) + return ToStringFixed(referenceStyle, true); + else + return ToStringRelative(includeSheet); } public override bool Equals(object obj) @@ -187,6 +200,6 @@ ^ LastAddress.GetHashCode(); } - #endregion + #endregion Public methods } } diff --git a/ClosedXML_Tests/ClosedXML_Tests.csproj b/ClosedXML_Tests/ClosedXML_Tests.csproj index 152dbca..cca56e5 100644 --- a/ClosedXML_Tests/ClosedXML_Tests.csproj +++ b/ClosedXML_Tests/ClosedXML_Tests.csproj @@ -86,6 +86,7 @@ + diff --git a/ClosedXML_Tests/Excel/Coordinates/XLAddressTests.cs b/ClosedXML_Tests/Excel/Coordinates/XLAddressTests.cs index 4d0329f..686c1f4 100644 --- a/ClosedXML_Tests/Excel/Coordinates/XLAddressTests.cs +++ b/ClosedXML_Tests/Excel/Coordinates/XLAddressTests.cs @@ -9,13 +9,14 @@ [Test] public void ToStringTest() { - IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1"); + var ws = new XLWorkbook().Worksheets.Add("Sheet1"); IXLAddress address = ws.Cell(1, 1).Address; Assert.AreEqual("A1", address.ToString()); Assert.AreEqual("A1", address.ToString(XLReferenceStyle.A1)); Assert.AreEqual("R1C1", address.ToString(XLReferenceStyle.R1C1)); Assert.AreEqual("A1", address.ToString(XLReferenceStyle.Default)); + Assert.AreEqual("Sheet1!A1", address.ToString(XLReferenceStyle.Default, true)); Assert.AreEqual("A1", address.ToStringRelative()); Assert.AreEqual("Sheet1!A1", address.ToStringRelative(true)); @@ -39,6 +40,7 @@ Assert.AreEqual("A1", address.ToString(XLReferenceStyle.A1)); Assert.AreEqual("R1C1", address.ToString(XLReferenceStyle.R1C1)); Assert.AreEqual("A1", address.ToString(XLReferenceStyle.Default)); + Assert.AreEqual("'Sheet 1'!A1", address.ToString(XLReferenceStyle.Default, true)); Assert.AreEqual("A1", address.ToStringRelative()); Assert.AreEqual("'Sheet 1'!A1", address.ToStringRelative(true)); diff --git a/ClosedXML_Tests/Excel/Misc/HyperlinkTests.cs b/ClosedXML_Tests/Excel/Misc/HyperlinkTests.cs new file mode 100644 index 0000000..95b2431 --- /dev/null +++ b/ClosedXML_Tests/Excel/Misc/HyperlinkTests.cs @@ -0,0 +1,32 @@ +using ClosedXML.Excel; +using NUnit.Framework; + +namespace ClosedXML_Tests.Excel.Misc +{ + [TestFixture] + public class HyperlinkTests + { + [Test] + public void TestHyperlinks() + { + using (var wb = new XLWorkbook()) + { + var ws1 = wb.Worksheets.Add("Sheet1"); + var ws2 = wb.Worksheets.Add("Sheet2"); + + var targetCell = ws2.Cell("A1"); + var targetRange = ws2.Range("A1", "B1"); + + var linkCell1 = ws1.Cell("A1"); + linkCell1.Value = "Link to IXLCell"; + linkCell1.Hyperlink = new XLHyperlink(targetCell); + Assert.AreEqual("Sheet2!A1", linkCell1.Hyperlink.InternalAddress); + + var linkRange1 = ws1.Cell("A2"); + linkRange1.Value = "Link to IXLRangeBase"; + linkRange1.Hyperlink = new XLHyperlink(targetRange); + Assert.AreEqual("Sheet2!A1:B1", linkRange1.Hyperlink.InternalAddress); + } + } + } +} diff --git a/ClosedXML_Tests/Excel/Ranges/XLRangeAddressTests.cs b/ClosedXML_Tests/Excel/Ranges/XLRangeAddressTests.cs index 669e811..c103c6e 100644 --- a/ClosedXML_Tests/Excel/Ranges/XLRangeAddressTests.cs +++ b/ClosedXML_Tests/Excel/Ranges/XLRangeAddressTests.cs @@ -13,6 +13,7 @@ IXLRangeAddress address = ws.Cell(1, 1).AsRange().RangeAddress; Assert.AreEqual("A1:A1", address.ToString()); + Assert.AreEqual("Sheet1!R1C1:R1C1", address.ToString(XLReferenceStyle.R1C1, true)); Assert.AreEqual("A1:A1", address.ToStringRelative()); Assert.AreEqual("Sheet1!A1:A1", address.ToStringRelative(true)); @@ -33,6 +34,7 @@ IXLRangeAddress address = ws.Cell(1, 1).AsRange().RangeAddress; Assert.AreEqual("A1:A1", address.ToString()); + Assert.AreEqual("'Sheet 1'!R1C1:R1C1", address.ToString(XLReferenceStyle.R1C1, true)); Assert.AreEqual("A1:A1", address.ToStringRelative()); Assert.AreEqual("'Sheet 1'!A1:A1", address.ToStringRelative(true));