Skip to content

Commit

Permalink
Add cell, tablecols, tablerows functions
Browse files Browse the repository at this point in the history
  • Loading branch information
stevencohn committed Aug 17, 2024
1 parent b4b543f commit 62f6b55
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 106 deletions.
8 changes: 1 addition & 7 deletions OneMore/Commands/Tables/AddFormulaCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,11 @@ public override async Task Execute(params object[] args)
if (cells.Count == 1)
{
dialog.SetCellNames(cells[0].Coordinates);
dialog.SetResultRow(cells[0].RowNum);
}
else
{
dialog.SetCellNames(
$"{cells[0].Coordinates} - {cells[cells.Count - 1].Coordinates}");

if (range == TableSelectionRange.Rows)
{
dialog.SetResultRow(cells[cells.Count - 1].RowNum);
}
}

var cell = cells[0];
Expand Down Expand Up @@ -162,7 +156,7 @@ private void StoreFormula(
return;
}

var regex = new Regex(Processor.OffsetPattern);
var regex = new Regex(Processor.AddressPattern);

int offset = 0;
foreach (var cell in cells)
Expand Down
3 changes: 3 additions & 0 deletions OneMore/Commands/Tables/FormulaDialog.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 9 additions & 11 deletions OneMore/Commands/Tables/FormulaDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ internal partial class FormulaDialog : UI.MoreForm
{
private readonly int helpHeight;
private readonly Calculator calculator;
private int resultRow;


public FormulaDialog()
Expand Down Expand Up @@ -49,7 +48,7 @@ public FormulaDialog()

formatBox.SelectedIndex = 0;

calculator = new Calculator();
calculator = new Calculator(null);
calculator.ProcessSymbol += ResolveSymbol;
}

Expand Down Expand Up @@ -81,12 +80,6 @@ public void SetCellNames(string names)
}


public void SetResultRow(int row)
{
resultRow = row;
}


public bool Tagged
{
get => tagBox.Checked;
Expand All @@ -102,36 +95,41 @@ private void ChangedFormula(object sender, EventArgs e)
{
try
{
calculator.Execute(formula, indexOffset: resultRow);
calculator.Execute(formula, 0, 0);
validStatusLabel.ForeColor = manager.GetColor("ControlText");
validStatusLabel.Text = Resx.word_OK;
tooltip.SetToolTip(validStatusLabel, string.Empty);
okButton.Enabled = true;
}
catch
catch (Exception exc)
{
validStatusLabel.ForeColor = manager.GetColor("ErrorText");
validStatusLabel.Text = Resx.FormulaDialog_status_Invalid;
tooltip.SetToolTip(validStatusLabel, exc.Message);
okButton.Enabled = false;
}
}
else
{
validStatusLabel.ForeColor = manager.GetColor("ControlText");
validStatusLabel.Text = Resx.FormulaDialog_status_Empty;
tooltip.SetToolTip(validStatusLabel, string.Empty);
okButton.Enabled = false;
}
}


private void ResolveSymbol(object sender, SymbolEventArgs e)
{
if (Regex.Match(e.Name, Processor.OffsetPattern).Success)
if (Regex.Match(e.Name, Processor.AddressPattern).Success)
{
logger.Verbose($"ResolveSymbol({e.Name}) OK");
e.SetResult(1.0);
e.Status = SymbolStatus.OK;
}
else
{
logger.Verbose($"ResolveSymbol({e.Name}) undefined");
e.Status = SymbolStatus.UndefinedSymbol;
}
}
Expand Down
3 changes: 3 additions & 0 deletions OneMore/Commands/Tables/FormulaDialog.resx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ Cell reference: A1, A2, ... ZZZ999
Cell range: A1:A22
Relative range in a column: A1:A-1</value>
</data>
<metadata name="tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
Expand Down
54 changes: 23 additions & 31 deletions OneMore/Commands/Tables/Formulas/Calculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,16 @@ private enum State
// to signify a unary negative; 0x80 follows DEL/0x7F just out of ASCII range
private const string UnaryMinus = "\x80";

private int indexOffset;
private Models.Table table;
private Coordinates coordinates;


/// <summary>
/// Initialize a new instance
/// </summary>
public Calculator()
public Calculator(Models.Table table)
{
this.table = table;
}


Expand All @@ -82,9 +84,9 @@ public Calculator()
/// accomodate a dynamically growing table of rows without having to update the formula.
/// </param>
/// <returns></returns>
public double Execute(string expression, int indexOffset)
public double Execute(string expression, int colNumber, int rowNumber)
{
this.indexOffset = indexOffset;
coordinates = new Coordinates(colNumber, rowNumber);

var result = ExecuteInternal(expression);
if (result.Type == FormulaValueType.Double)
Expand Down Expand Up @@ -311,8 +313,7 @@ private string ParseSymbolToken(TextParser parser)
{
int start = parser.Position;
var c = parser.Peek();
while (char.IsLetterOrDigit(c) || c == '<' || c == '>' || c == '!' || c == '_' ||
(c == '-' && indexOffset > 0))
while (char.IsLetterOrDigit(c) || c == '<' || c == '>' || c == '!' || c == '_')
{
parser.MoveAhead();
c = parser.Peek();
Expand All @@ -335,10 +336,17 @@ private FormulaValue EvaluateFunction(TextParser parser, string name, int pos)
// parse function parameters
var parameters = ParseParameters(parser);

var Fn = MathFunctions.Find(name);
if (Fn != null)
var function = MathFunctions.Find(name);
if (function != null)
{
return new FormulaValue(Fn(parameters));
if (function.Spacial)
{
parameters.Add(new FormulaValue(table));
parameters.Add(coordinates.ColNumber);
parameters.Add(coordinates.RowNumber);
}

return new FormulaValue(function.Fn(parameters));
}

double result = default;
Expand Down Expand Up @@ -475,31 +483,15 @@ private FormulaValues EvaluateCellReferences(string cell1, string cell2, int p1,
if (!match.Success)
throw new FormulaException(string.Format(ErrUndefinedSymbol, cell1), p1);

if (int.Parse(match.Groups["r"].Value) == 0)
{
// do not include result cell (or off-table) in calculations
throw new FormulaException("row offset cannot be zero");
}

var col1 = match.Groups["c"].Value;
var row1 = match.Groups["r"].Value;

// cell2...
var col1 = match.Groups[1].Value;
var row1 = match.Groups[2].Value;

match = Regex.Match(cell2, Processor.OffsetPattern);
match = Regex.Match(cell2, Processor.AddressPattern);
if (!match.Success)
throw new FormulaException(string.Format(ErrUndefinedSymbol, cell2), p2);

if (int.Parse(match.Groups["r"].Value) == 0)
{
// do not include result cell (or off-table) in calculations
throw new FormulaException("row offset cannot be zero");
}

var col2 = match.Groups["c"].Value;
var row2 = match.Groups["o"].Success && indexOffset > 0
? $"{indexOffset - int.Parse(match.Groups["r"].Value)}"
: match.Groups["r"].Value;
var col2 = match.Groups[1].Value;
var row2 = match.Groups[2].Value;

// validate...

Expand Down Expand Up @@ -612,7 +604,7 @@ private FormulaValue EvaluateSymbol(string name, int pos)
// ask consumer to resolve symbol reference
if (ProcessSymbol != null)
{
var args = new SymbolEventArgs(name, indexOffset);
var args = new SymbolEventArgs(name, coordinates);

ProcessSymbol(this, args);
if (args.Status == SymbolStatus.OK)
Expand Down
22 changes: 22 additions & 0 deletions OneMore/Commands/Tables/Formulas/Coordinates.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//************************************************************************************************
// Copyright © 2024 Steven M Cohn. All rights reserved.
//************************************************************************************************

namespace River.OneMoreAddIn.Commands.Tables.Formulas
{

internal class Coordinates
{
public Coordinates(int col, int row)
{
ColNumber = col;
RowNumber = row;
}


public int ColNumber { get; private set; }


public int RowNumber { get; private set; }
}
}
18 changes: 6 additions & 12 deletions OneMore/Commands/Tables/Formulas/FormulaValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,17 @@ internal enum FormulaValueType
Boolean,
Double,
String,
Table,
Unknown
}


/// <summary>
/// Allowed operators in first character of a countif comparison
/// </summary>
internal enum CountIfOperator
{
GreaterThan,
LessThan,
NotEqual
}


/// <summary>
/// Boxy formula value representing a double, string, or boolean value.
/// </summary>
internal class FormulaValue
{
public FormulaValueType Type { get; private set; }
public CountIfOperator Operator { get; private set; }
public object Value { get; private set; }
public double DoubleValue { get => (double)Value; }

Expand All @@ -60,6 +49,11 @@ public FormulaValue(string value)
Value = value;
Type = FormulaValueType.String;
}
public FormulaValue(Models.Table value)
{
Value = value;
Type = FormulaValueType.Table;
}

public int CompareTo(FormulaValue template)
{
Expand Down
Loading

0 comments on commit 62f6b55

Please sign in to comment.