Bugfix Praveen
diff --git a/EPPlus/ExcelNamedRangeCollection.cs b/EPPlus/ExcelNamedRangeCollection.cs
index 8ea6462..3f6a493 100644
--- a/EPPlus/ExcelNamedRangeCollection.cs
+++ b/EPPlus/ExcelNamedRangeCollection.cs
@@ -81,6 +81,22 @@
private void AddName(string Name, ExcelNamedRange item)
{
+ // Is 'Name' already present
+ if (_dic.ContainsKey(Name))
+ {
+ int index = _dic[Name];
+ if ((0 <= index) && (index < _list.Count))
+ {
+ ExcelNamedRange listItem = _list[index];
+ if ((listItem != null) && (listItem.FullAddress == item.FullAddress))
+ return;
+
+ throw new Exception(string.Format("Name '{0}' is defined in the worksheet more than once. First as '{1}' and second as '{2}'.", Name, listItem.FullAddress, item.FullAddress));
+ }
+
+ throw new Exception(string.Format("Name '{0}' is defined in the worksheet more than once.", Name));
+ }
+
_dic.Add(Name, _list.Count);
_list.Add(item);
}
diff --git a/EPPlus/FormulaParsing/CalculateExtentions.cs b/EPPlus/FormulaParsing/CalculateExtentions.cs
index 6763f3b..1ec584a 100644
--- a/EPPlus/FormulaParsing/CalculateExtentions.cs
+++ b/EPPlus/FormulaParsing/CalculateExtentions.cs
@@ -153,6 +153,11 @@
}
Thread.Sleep(0);
}
+ catch (OfficeOpenXml.FormulaParsing.Excel.Functions.FunctionException functionex)
+ {
+ // Excel function is not supported by EPPlus
+ throw (functionex);
+ }
catch (FormatException fe)
{
throw (fe);
diff --git a/EPPlus/FormulaParsing/Excel/Functions/FunctionRepository.cs b/EPPlus/FormulaParsing/Excel/Functions/FunctionRepository.cs
index ca4a769..4b90546 100644
--- a/EPPlus/FormulaParsing/Excel/Functions/FunctionRepository.cs
+++ b/EPPlus/FormulaParsing/Excel/Functions/FunctionRepository.cs
@@ -33,6 +33,29 @@
namespace OfficeOpenXml.FormulaParsing.Excel.Functions
{
+ // Used to report the names of Excel functions that are not supported by EPPlus
+ public class FunctionException : SystemException
+ {
+ // Summary:
+ // Initializes a new instance of the System.FunctionException class.
+ public FunctionException()
+ : base()
+ {
+ }
+ //
+ // Summary:
+ // Initializes a new instance of the System.FunctionException class with a specified
+ // error message.
+ //
+ // Parameters:
+ // message:
+ // The message that describes the error.
+ public FunctionException(string message)
+ : base(message)
+ {
+ }
+ }
+
/// <summary>
/// This class provides methods for accessing/modifying VBA Functions.
/// </summary>
@@ -69,6 +92,9 @@
{
if(!_functions.ContainsKey(name.ToLower(CultureInfo.InvariantCulture)))
{
+ // Report that Excel function is not supported by EPPlus
+ throw new FunctionException(string.Format("Excel function '{0}' is not supported in formulas.", name));
+
//throw new InvalidOperationException("Non supported function: " + name);
//throw new ExcelErrorValueException("Non supported function: " + name, ExcelErrorValue.Create(eErrorType.Name));
return null;
diff --git a/EPPlus/FormulaParsing/ExpressionGraph/CompileResult.cs b/EPPlus/FormulaParsing/ExpressionGraph/CompileResult.cs
index 8074af0..d1959c6 100644
--- a/EPPlus/FormulaParsing/ExpressionGraph/CompileResult.cs
+++ b/EPPlus/FormulaParsing/ExpressionGraph/CompileResult.cs
@@ -102,7 +102,14 @@
}
else if (IsNumericString)
{
- return double.Parse(Result.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture);
+ try
+ {
+ return double.Parse(Result.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture);
+ }
+ catch (Exception ex)
+ {
+ return 0;
+ }
}
else if (Result is ExcelDataProvider.IRangeInfo)
{
diff --git a/EPPlus/FormulaParsing/ExpressionGraph/DecimalExpression.cs b/EPPlus/FormulaParsing/ExpressionGraph/DecimalExpression.cs
index 1182d2d..6e3ba50 100644
--- a/EPPlus/FormulaParsing/ExpressionGraph/DecimalExpression.cs
+++ b/EPPlus/FormulaParsing/ExpressionGraph/DecimalExpression.cs
@@ -65,5 +65,11 @@
result = _negate ? result * -1 : result;
return new CompileResult(result, DataType.Decimal);
}
+
+ public bool IsNegated
+ {
+ get { return _negate; }
+ }
+
}
}
diff --git a/EPPlus/FormulaParsing/ExpressionGraph/ExcelAddressExpression.cs b/EPPlus/FormulaParsing/ExpressionGraph/ExcelAddressExpression.cs
index c034117..186c726 100644
--- a/EPPlus/FormulaParsing/ExpressionGraph/ExcelAddressExpression.cs
+++ b/EPPlus/FormulaParsing/ExpressionGraph/ExcelAddressExpression.cs
@@ -118,5 +118,11 @@
compileResult.IsHiddenCell = cell.IsHiddenRow;
return compileResult;
}
+
+ public bool IsNegated
+ {
+ get { return _negate; }
+ }
+
}
}
diff --git a/EPPlus/FormulaParsing/ExpressionGraph/Expression.cs b/EPPlus/FormulaParsing/ExpressionGraph/Expression.cs
index 61ab6b3..277b78a 100644
--- a/EPPlus/FormulaParsing/ExpressionGraph/Expression.cs
+++ b/EPPlus/FormulaParsing/ExpressionGraph/Expression.cs
@@ -39,7 +39,7 @@
{
public abstract class Expression
{
- protected string ExpressionString { get; private set; }
+ public string ExpressionString { get; private set; }
private readonly List<Expression> _children = new List<Expression>();
public IEnumerable<Expression> Children { get { return _children; } }
public Expression Next { get; set; }
diff --git a/EPPlus/FormulaParsing/ExpressionGraph/GroupExpression.cs b/EPPlus/FormulaParsing/ExpressionGraph/GroupExpression.cs
index cad1339..e8dba20 100644
--- a/EPPlus/FormulaParsing/ExpressionGraph/GroupExpression.cs
+++ b/EPPlus/FormulaParsing/ExpressionGraph/GroupExpression.cs
@@ -67,5 +67,11 @@
{
get { return true; }
}
+
+ public bool IsNegated
+ {
+ get { return _isNegated; }
+ }
+
}
}
diff --git a/EPPlus/FormulaParsing/ExpressionGraph/IntegerExpression.cs b/EPPlus/FormulaParsing/ExpressionGraph/IntegerExpression.cs
index 6178660..4e57168 100644
--- a/EPPlus/FormulaParsing/ExpressionGraph/IntegerExpression.cs
+++ b/EPPlus/FormulaParsing/ExpressionGraph/IntegerExpression.cs
@@ -65,5 +65,11 @@
result = _negate ? result*-1 : result;
return new CompileResult(result, DataType.Integer);
}
+
+ public bool IsNegated
+ {
+ get { return _negate; }
+ }
+
}
}
diff --git a/EPPlus/FormulaParsing/FormulaParser.cs b/EPPlus/FormulaParsing/FormulaParser.cs
index 64dd6cc..e025114 100644
--- a/EPPlus/FormulaParsing/FormulaParser.cs
+++ b/EPPlus/FormulaParsing/FormulaParser.cs
@@ -218,6 +218,17 @@
}
}
+ // Praveen's Formula Parser
+ public ExpressionGraph.ExpressionGraph ParseToGraph(string formula)
+ {
+ using (var scope = _parsingContext.Scopes.NewScope(RangeAddress.Empty))
+ {
+ var tokens = _lexer.Tokenize(formula);
+ var graph = _graphBuilder.Build(tokens);
+ return graph;
+ }
+ }
+
public IFormulaParserLogger Logger
{
get { return _parsingContext.Configuration.Logger; }
diff --git a/EPPlus/FormulaParsing/FormulaParserManager.cs b/EPPlus/FormulaParsing/FormulaParserManager.cs
index 7137b99..aa9658b 100644
--- a/EPPlus/FormulaParsing/FormulaParserManager.cs
+++ b/EPPlus/FormulaParsing/FormulaParserManager.cs
@@ -97,6 +97,12 @@
return _parser.Parse(formula);
}
+ // Praveen's Parser Support
+ public ExpressionGraph.ExpressionGraph ParseToGraph(string formula)
+ {
+ return _parser.ParseToGraph(formula);
+ }
+
/// <summary>
/// Attaches a logger to the <see cref="FormulaParser"/>.
/// </summary>
diff --git a/EPPlus/FormulaParsing/LexicalAnalysis/SourceCodeTokenizer.cs b/EPPlus/FormulaParsing/LexicalAnalysis/SourceCodeTokenizer.cs
index 60b9e9c..a0d5d47 100644
--- a/EPPlus/FormulaParsing/LexicalAnalysis/SourceCodeTokenizer.cs
+++ b/EPPlus/FormulaParsing/LexicalAnalysis/SourceCodeTokenizer.cs
@@ -71,6 +71,8 @@
// MA 1401: Ignore leading plus in formula.
input = input.TrimStart('+');
var context = new TokenizerContext(input);
+
+ bool isSingleQuoteString = false;
for (int i = 0; i<context.FormulaChars.Length;i++)
{
var c = context.FormulaChars[i];
@@ -90,6 +92,12 @@
context.AppendToCurrentToken(c);
continue;
}
+ // CHANGE 2
+ if ((isSingleQuoteString && c != '\'') || (!isSingleQuoteString && c != '"'))
+ {
+ context.AppendToCurrentToken(c);
+ continue;
+ }
}
if (tokenSeparator.TokenType == TokenType.OpeningBracket)
{
@@ -119,9 +127,11 @@
}
if (tokenSeparator.TokenType == TokenType.String)
{
+ // CHANGE3 :
+ isSingleQuoteString = (c == '\'');
if (context.LastToken != null && context.LastToken.TokenType == TokenType.OpeningEnumerable)
{
- context.AppendToCurrentToken(c);
+ // context.AppendToCurrentToken(c); // Praveen's change of 10/28/2015
context.ToggleIsInString();
continue;
}
diff --git a/EPPlus/FormulaParsing/LexicalAnalysis/TokenSeparatorProvider.cs b/EPPlus/FormulaParsing/LexicalAnalysis/TokenSeparatorProvider.cs
index 61df09a..d11ccd6 100644
--- a/EPPlus/FormulaParsing/LexicalAnalysis/TokenSeparatorProvider.cs
+++ b/EPPlus/FormulaParsing/LexicalAnalysis/TokenSeparatorProvider.cs
@@ -59,7 +59,7 @@
_tokens.Add(")", new Token(")", TokenType.ClosingParenthesis));
_tokens.Add("{", new Token("{", TokenType.OpeningEnumerable));
_tokens.Add("}", new Token("}", TokenType.ClosingEnumerable));
- _tokens.Add("'", new Token("'", TokenType.String));
+ _tokens.Add("'", new Token("'", TokenType.String));
_tokens.Add("\"", new Token("\"", TokenType.String));
_tokens.Add(",", new Token(",", TokenType.Comma));
_tokens.Add(";", new Token(";", TokenType.SemiColon));
diff --git a/EPPlus/FormulaParsing/LexicalAnalysis/TokenizerContext.cs b/EPPlus/FormulaParsing/LexicalAnalysis/TokenizerContext.cs
index 5518a5c..6a28142 100644
--- a/EPPlus/FormulaParsing/LexicalAnalysis/TokenizerContext.cs
+++ b/EPPlus/FormulaParsing/LexicalAnalysis/TokenizerContext.cs
@@ -85,7 +85,7 @@
public bool CurrentTokenHasValue
{
- get { return !string.IsNullOrEmpty(CurrentToken.Trim()); }
+ get { return !string.IsNullOrEmpty(this.IsInString ? CurrentToken : CurrentToken.Trim()); }
}
public void NewToken()