From f481e9d3de608b2db844038f69632bb08727b2ae Mon Sep 17 00:00:00 2001 From: MarkHung Date: Sun, 24 Dec 2017 16:41:27 +0800 Subject: [PATCH 1/4] Fix FormulaR1C1 Translate Issue --- EPPlus/ExcelCellBase.cs | 192 ++++++++++++------- EPPlusTest/FormulaParsing/FormulaR1C1Test.cs | 138 +++++++++++++ 2 files changed, 258 insertions(+), 72 deletions(-) create mode 100644 EPPlusTest/FormulaParsing/FormulaR1C1Test.cs diff --git a/EPPlus/ExcelCellBase.cs b/EPPlus/ExcelCellBase.cs index 32359656..5a413036 100644 --- a/EPPlus/ExcelCellBase.cs +++ b/EPPlus/ExcelCellBase.cs @@ -111,50 +111,21 @@ private static string Translate(string value, dlgTransl addressTranslator, int r { if (value == "") return ""; - bool isText = false; - string ret = ""; - string part = ""; - char prevTQ = (char)0; - for (int pos = 0; pos < value.Length; pos++) + + var lexer = new Lexer(SourceCodeTokenizer.Default, new SyntacticAnalyzer()); + var tokens = lexer.Tokenize(value); + foreach (var token in tokens) { - char c = value[pos]; - if (((c == '"' || c=='\'') && !isText) || (isText && c == prevTQ)) - { - if (isText == false && part != "" && prevTQ==c) - { - ret += addressTranslator(part, row, col, rowIncr, colIncr); - part = ""; - prevTQ = (char)0; - } - isText = !isText; - prevTQ = c; - ret += c; - } - else if (isText) + //Console.WriteLine($"{token.TokenType} : {token.Value}"); + if (token.TokenType == TokenType.ExcelAddress || token.TokenType.Equals(TokenType.NameValue)) { - ret += c; + var part = addressTranslator(token.Value, row, col, rowIncr, colIncr); + //Console.Write($"==> " + part); + token.Value = part; } - else - { - if ((c == '-' || c == '+' || c == '*' || c == '/' || - c == '=' || c == '^' || c == ',' || c == ':' || - c == '<' || c == '>' || c == '(' || c == ')' || c == '!' || - c == ' ' || c == '&' || c == '%') && - (pos == 0 || value[pos - 1] != '[')) //Last part to allow for R1C1 style [-x] - { - ret += addressTranslator(part, row, col, rowIncr, colIncr) + c; - part = ""; - } - else - { - part += c; - } - } - } - if (part != "") - { - ret += addressTranslator(part, row, col, rowIncr, colIncr); + } + var ret = string.Join("", tokens.Select(x => x.Value).ToArray()); return ret; } /// @@ -167,42 +138,47 @@ private static string Translate(string value, dlgTransl addressTranslator, int r /// /// private static string ToR1C1(string part, int row, int col, int rowIncr, int colIncr) + { + int delim = part.IndexOf(':'); + if (delim > 0) + { + string p1 = ToR1C1_1(part.Substring(0, delim), row, col, rowIncr, colIncr); + string p2 = ToR1C1_1(part.Substring(delim + 1), row, col, rowIncr, colIncr); + if (p1.Equals(p2)) + return p1; + return p1 + ":" + p2; + } + + else + return ToR1C1_1(part, row, col, rowIncr, colIncr); + } + private static string ToR1C1_1(string part, int row, int col, int rowIncr, int colIncr) { int addrRow, addrCol; - string Ret = "R"; - if (GetRowCol(part, out addrRow, out addrCol, false)) + bool fixRow, fixCol; + StringBuilder sb = new StringBuilder(); + if (GetRowCol(part, out addrRow, out addrCol, false, out fixRow, out fixCol)) { - if (addrRow == 0 || addrCol == 0) + if (addrRow == 0 && addrCol == 0) { return part; } - if (part.IndexOf('$', 1) > 0) - { - Ret += addrRow.ToString(); - } - else if (addrRow - row != 0) + if (addrRow > 0) { - Ret += string.Format("[{0}]", addrRow - row); + sb.Append(fixRow ? $"R{addrRow}" : (addrRow == row ? "R" : $"R[{addrRow - row}]")); } - - if (Utils.ConvertUtil._invariantCompareInfo.IsPrefix(part, "$")) - { - return Ret + "C" + addrCol; - } - else if (addrCol - col != 0) + if (addrCol > 0) { - return Ret + "C" + string.Format("[{0}]", addrCol - col); - } - else - { - return Ret + "C"; + sb.Append(fixCol ? $"C{addrCol}" : (addrCol == col ? "C" : $"C[{addrCol - col}]")); } + return sb.ToString(); } else { return part; } } + /// /// Translates to absolute address /// @@ -213,35 +189,91 @@ private static string ToR1C1(string part, int row, int col, int rowIncr, int col /// /// private static string ToAbs(string part, int row, int col, int rowIncr, int colIncr) + { + int delim = part.IndexOf(':'); + if (delim > 0) + { + string p1 = ToAbs_1(part.Substring(0, delim), row, col, rowIncr, colIncr); + string p2 = ToAbs_1(part.Substring(delim + 1), row, col, rowIncr, colIncr); + if (p1.Equals(p2)) + return p1; + return p1 + ":" + p2; + } + else + return ToAbs_1(part, row, col, rowIncr, colIncr); + } + private static string ToAbs_1(string part, int row, int col, int rowIncr, int colIncr) { string check = Utils.ConvertUtil._invariantTextInfo.ToUpper(part); - + // Bug int rStart = check.IndexOf("R"); - if (rStart != 0) + int cStart = check.IndexOf("C"); + //if (rStart != 0) + // return part; + if (rStart != 0 && cStart != 0) return part; - if (part.Length == 1) //R + if (part.Length == 1) //R or C { - return GetAddress(row, col); + if (rStart == 0) + { + //return GetAddress(row); + return $"{row}:{row}"; + } + else + { + var cLetter = GetColumnLetter(col); + return $"{cLetter}:{cLetter}"; + } + } - int cStart = check.IndexOf("C"); bool absoluteRow, absoluteCol; if (cStart == -1) { - int RNum = GetRC(part, row, out absoluteRow); + int RNum = GetRC(part.Substring(1), row, out absoluteRow); if (RNum > int.MinValue) { - return GetAddress(RNum, absoluteRow, col, false); + return GetAddressRow(RNum, absoluteRow); } else { return part; } } - else + if (rStart == -1) { - int RNum = GetRC(part.Substring(1, cStart - 1), row, out absoluteRow); - int CNum = GetRC(part.Substring(cStart + 1, part.Length - cStart - 1), col, out absoluteCol); + int CNum = GetRC(part.Substring(1), col, out absoluteCol); + if (CNum > int.MinValue) + { + return GetAddressCol(CNum, absoluteCol); + } + else + { + return part; + } + } + { + int RNum, CNum; + if (1 == cStart) + { + RNum = row; + absoluteRow = false; + } + else + { + RNum = GetRC(part.Substring(1, cStart - 1), row, out absoluteRow); + } + if ((part.Length - 1) == cStart) + { + CNum = col; + absoluteCol = false; + } + else + { + CNum = GetRC(part.Substring(cStart + 1, part.Length - cStart - 1), col, out absoluteCol); + } + + if (RNum > int.MinValue && CNum > int.MinValue) { return GetAddress(RNum, absoluteRow, CNum, absoluteCol); @@ -466,7 +498,10 @@ internal static bool GetRowColFromAddress(string CellAddress, out int row, out i { return GetRowCol(CellAddress, out row, out col, true, out fixedRow, out fixedCol); } - + internal static bool IsAlpha(char c) + { + return c >= 'A' && c <= 'Z'; + } /// /// Get the row/column for a Cell-address /// @@ -520,7 +555,7 @@ internal static bool GetRowCol(string address, out int row, out int col, bool th } else if (c == '$') { - if (i == colStartIx) + if (IsAlpha(address[i+1])) { colStartIx++; fixedCol = true; @@ -559,6 +594,19 @@ private static int GetColumn(string sCol) return col; } #region GetAddress + public static string GetAddressRow(int Row, bool Absolute = false) + { + if (Absolute) + return $"${Row}:${Row}"; + return $"{Row}:{Row}"; + } + public static string GetAddressCol(int Col, bool Absolute = false) + { + var colLetter = GetColumnLetter(Col); + if (Absolute) + return $"${colLetter}:${colLetter}"; + return $"{colLetter}:{colLetter}"; + } /// /// Returns the AlphaNumeric representation that Excel expects for a Cell Address /// diff --git a/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs b/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs new file mode 100644 index 00000000..1c1aac32 --- /dev/null +++ b/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OfficeOpenXml; + +namespace EPPlusTest.FormulaParsing +{ + [TestClass] + public class FormulaR1C1Tests + { + private ExcelPackage _package; + private ExcelWorksheet _sheet; + [TestInitialize] + public void Initialize() + { + _package = new ExcelPackage(); + var s1 = _package.Workbook.Worksheets.Add("test"); + s1.Cells["A1"].Value = 1; + s1.Cells["A2"].Value = 2; + s1.Cells["A3"].Value = 3; + s1.Cells["A4"].Value = 4; + + s1.Cells["B1"].Value = 5; + s1.Cells["B2"].Value = 6; + s1.Cells["B3"].Value = 7; + s1.Cells["B4"].Value = 8; + + s1.Cells["C1"].Value = 5; + s1.Cells["C2"].Value = 6; + s1.Cells["C3"].Value = 7; + s1.Cells["C4"].Value = 8; + + _sheet = s1; + } + + [TestCleanup] + public void Cleanup() + { + _package.Dispose(); + } + + [TestMethod] + public void RC2() + { + string fR1C1 = "RC2"; + _sheet.Cells[5, 1].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 1].Formula; + _sheet.Cells[5, 1].Formula = f; + Assert.AreEqual(fR1C1, _sheet.Cells[5,1].FormulaR1C1); + } + [TestMethod] + public void C() + { + string fR1C1 = "SUMIFS(C,C2,RC1)"; + _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 3].Formula; + _sheet.Cells[5, 3].Formula = f; + Assert.AreEqual(fR1C1, _sheet.Cells[5, 3].FormulaR1C1); + } + [TestMethod] + public void C2Abs() + { + string fR1C1 = "SUM(C2)"; + _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 3].Formula; + Assert.AreEqual("SUM($B:$B)", f); + } + [TestMethod] + public void C2() + { + string fR1C1 = "SUM(C2)"; + _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 3].Formula; + _sheet.Cells[5, 3].Formula = f; + Assert.AreEqual(fR1C1, _sheet.Cells[5, 3].FormulaR1C1); + } + [TestMethod] + public void R2Abs() + { + string fR1C1 = "SUM(R2)"; + _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 3].Formula; + Assert.AreEqual("SUM($2:$2)",f); + } + [TestMethod] + public void R2() + { + string fR1C1 = "SUM(R2)"; + _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 3].Formula; + _sheet.Cells[5, 3].Formula = f; + Assert.AreEqual(fR1C1, _sheet.Cells[5, 3].FormulaR1C1); + } + [TestMethod] + public void RCRelativeToAB() + { + string fR1C1 = "SUMIFS(C,C2,RC1)"; + _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 3].Formula; + Assert.AreEqual("SUMIFS(C:C,$B:$B,$A5)", f); + } + [TestMethod] + public void RCRelativeToABToR1C1() + { + string fR1C1 = "SUMIFS(C,C2,RC1)"; + _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 3].Formula; + _sheet.Cells[5, 3].Formula = f; + Assert.AreEqual(fR1C1, _sheet.Cells[5, 3].FormulaR1C1); + } + [TestMethod] + public void RCRelativeToABToR1C1_2() + { + string fR1C1 = "SUM(RC9:RC[-1])"; + _sheet.Cells[5, 13].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 13].Formula; + Assert.AreEqual("SUM($I5:L5)", f); + _sheet.Cells[5, 13].Formula = f; + Assert.AreEqual(fR1C1, _sheet.Cells[5, 13].FormulaR1C1); + + //"RC{colShort} - SUM(RC21:RC12)"; + } + [TestMethod] + public void RCFixToABToR1C1_2() + { + string fR1C1 = "RC28-SUM(RC12:RC21)"; + _sheet.Cells[6, 13].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[6, 13].Formula; + Assert.AreEqual("$AB6-SUM($L6:$U6)", f); + _sheet.Cells[6, 13].Formula = f; + Assert.AreEqual(fR1C1, _sheet.Cells[6, 13].FormulaR1C1); + + } + } +} From c4349d329aa61fada2b1e630cf6b7ef3bfcf5ef9 Mon Sep 17 00:00:00 2001 From: MarkHung Date: Tue, 26 Dec 2017 11:47:31 +0800 Subject: [PATCH 2/4] BugFix: process address with sheet name --- EPPlus/ExcelCellBase.cs | 23 ++++++++++++++++---- EPPlusTest/EPPlusTest.csproj | 1 + EPPlusTest/FormulaParsing/FormulaR1C1Test.cs | 8 +++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/EPPlus/ExcelCellBase.cs b/EPPlus/ExcelCellBase.cs index 5a413036..7ff2c18a 100644 --- a/EPPlus/ExcelCellBase.cs +++ b/EPPlus/ExcelCellBase.cs @@ -139,6 +139,13 @@ private static string Translate(string value, dlgTransl addressTranslator, int r /// private static string ToR1C1(string part, int row, int col, int rowIncr, int colIncr) { + int shInd = part.IndexOf('!'); + string sh = ""; + if (shInd > 0) + { + sh = part.Substring(0, shInd + 1); + part = part.Substring(shInd + 1); + } int delim = part.IndexOf(':'); if (delim > 0) { @@ -146,11 +153,11 @@ private static string ToR1C1(string part, int row, int col, int rowIncr, int col string p2 = ToR1C1_1(part.Substring(delim + 1), row, col, rowIncr, colIncr); if (p1.Equals(p2)) return p1; - return p1 + ":" + p2; + return sh + p1 + ":" + p2; } else - return ToR1C1_1(part, row, col, rowIncr, colIncr); + return sh + ToR1C1_1(part, row, col, rowIncr, colIncr); } private static string ToR1C1_1(string part, int row, int col, int rowIncr, int colIncr) { @@ -190,6 +197,14 @@ private static string ToR1C1_1(string part, int row, int col, int rowIncr, int c /// private static string ToAbs(string part, int row, int col, int rowIncr, int colIncr) { + int shInd = part.IndexOf('!'); + string sh = ""; + if (shInd > 0) + { + sh = part.Substring(0, shInd + 1); + part = part.Substring(shInd + 1); + } + int delim = part.IndexOf(':'); if (delim > 0) { @@ -197,10 +212,10 @@ private static string ToAbs(string part, int row, int col, int rowIncr, int colI string p2 = ToAbs_1(part.Substring(delim + 1), row, col, rowIncr, colIncr); if (p1.Equals(p2)) return p1; - return p1 + ":" + p2; + return sh + p1 + ":" + p2; } else - return ToAbs_1(part, row, col, rowIncr, colIncr); + return sh + ToAbs_1(part, row, col, rowIncr, colIncr); } private static string ToAbs_1(string part, int row, int col, int rowIncr, int colIncr) { diff --git a/EPPlusTest/EPPlusTest.csproj b/EPPlusTest/EPPlusTest.csproj index 95efa9bb..b1fac8e6 100644 --- a/EPPlusTest/EPPlusTest.csproj +++ b/EPPlusTest/EPPlusTest.csproj @@ -114,6 +114,7 @@ + diff --git a/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs b/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs index 1c1aac32..299e59ed 100644 --- a/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs +++ b/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs @@ -69,6 +69,14 @@ public void C2Abs() Assert.AreEqual("SUM($B:$B)", f); } [TestMethod] + public void C2AbsWithSheet() + { + string fR1C1 = "SUM(A!C2)"; + _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; + string f = _sheet.Cells[5, 3].Formula; + Assert.AreEqual("SUM(A!$B:$B)", f); + } + [TestMethod] public void C2() { string fR1C1 = "SUM(C2)"; From 076bbe5bf755e606422a47fc0f9213e4544def72 Mon Sep 17 00:00:00 2001 From: MarkHung Date: Thu, 4 Jan 2018 11:33:01 +0800 Subject: [PATCH 3/4] . --- EPPlus/EPPlus.csproj | 1774 +++++++++++++++++++++--------------------- 1 file changed, 887 insertions(+), 887 deletions(-) diff --git a/EPPlus/EPPlus.csproj b/EPPlus/EPPlus.csproj index a6c03aab..b7f3a284 100644 --- a/EPPlus/EPPlus.csproj +++ b/EPPlus/EPPlus.csproj @@ -1,894 +1,894 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {BE4A6343-F411-44A3-8D6F-F40747ED7BA5} - Library - Properties - OfficeOpenXml - EPPlus - true - OpenOfficeXml.snk - - - - - - - - - - - - - 3.5 - v3.5 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - Client - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\EPPlus.XML - AllRules.ruleset - AnyCPU - 15191, CS1591 - false - true - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\EPPlus.XML - AllRules.ruleset - AnyCPU - false - - - bin\ - false - - - - - ..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client\PresentationFramework.dll - - - - ..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client\System.configuration.dll - - - C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll - - - - - - - ..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client\WindowsBase.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - Code - - - - - - - - - - - - - - - - - - Code - - - - - Code - - - - Code - - - - - Code - - - Code - - - - - Code - - - Code - - - - - - - - - - - - - - - - - Code - - - - - - - - - - - - - - - - - - - Code - - - - - - - - - - Code - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - - - Code - - - - Code - - - Code - - - - - - Code - - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - - - - - - - - - Code - - - Code - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {BE4A6343-F411-44A3-8D6F-F40747ED7BA5} + Library + Properties + OfficeOpenXml + EPPlus + true + OpenOfficeXml.snk + + + + + + + + + + + + + 3.5 + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + Client + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + bin\Debug\EPPlus.XML + AllRules.ruleset + AnyCPU + 15191, CS1591 + false + true + + + pdbonly + true + ..\..\..\lib\ + TRACE + prompt + 4 + bin\Release\EPPlus.XML + AllRules.ruleset + AnyCPU + false + + + bin\ + false + + + + + ..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client\PresentationFramework.dll + + + + ..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client\System.configuration.dll + + + C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll + + + + + + + ..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client\WindowsBase.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Code + + + + + + + + + + + + + + + + + + Code + + + + + Code + + + + Code + + + + + Code + + + Code + + + + + Code + + + Code + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + Code + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + Code + + + + Code + + + Code + + + + + + Code + + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + + + + + Code + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + - - - - - - + --> + + + + + + \ No newline at end of file From 30ffc06eee61c72695a57578c0fae13c79a08805 Mon Sep 17 00:00:00 2001 From: MarkHung Date: Fri, 19 Jan 2018 15:21:59 +0800 Subject: [PATCH 4/4] Modity Test --- EPPlusTest/FormulaParsing/FormulaR1C1Test.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs b/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs index 299e59ed..39f9568b 100644 --- a/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs +++ b/EPPlusTest/FormulaParsing/FormulaR1C1Test.cs @@ -13,6 +13,7 @@ public class FormulaR1C1Tests { private ExcelPackage _package; private ExcelWorksheet _sheet; + private ExcelWorksheet _sheet2; [TestInitialize] public void Initialize() { @@ -34,6 +35,7 @@ public void Initialize() s1.Cells["C4"].Value = 8; _sheet = s1; + _sheet2 = _package.Workbook.Worksheets.Add("test2",s1); } [TestCleanup] @@ -92,6 +94,12 @@ public void R2Abs() _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; string f = _sheet.Cells[5, 3].Formula; Assert.AreEqual("SUM($2:$2)",f); + + fR1C1 = "SUM(TEST2!R2)"; + _sheet.Cells[5, 3].FormulaR1C1 = fR1C1; + f = _sheet.Cells[5, 3].Formula; + Assert.AreEqual("SUM(TEST2!$2:$2)", f); + } [TestMethod] public void R2()