public int Compare(GroupEntry x1, GroupEntry y1) { Debug.Assert(x1 != null && y1 != null && x1.Sort != null, "Illegal arguments to GroupEntryCompare", "Compare requires object to be of type GroupEntry and that sort be defined."); int rc = 0; foreach (SortBy sb in x1.Sort.Items) { TypeCode tc = sb.SortExpression.Type; int index = x1.Group.GetIndex(rpt); wc.Data.CurrentGroups[index] = x1; object o1 = sb.SortExpression.Evaluate(rpt, wc.Data.Data[x1.StartRow]); index = y1.Group.GetIndex(rpt); wc.Data.CurrentGroups[index] = y1; object o2 = sb.SortExpression.Evaluate(rpt, wc.Data.Data[y1.StartRow]); rc = Filter.ApplyCompare(tc, o1, o2); if (rc != 0) { if (sb.Direction == SortDirectionEnum.Descending) { rc = -rc; } break; } } return(rc); }
public int Compare(MatrixEntry m1, MatrixEntry m2) { if (_Sorting == null) { return(m1.HashItem.CompareTo(m2.HashItem)); } object o1 = null, o2 = null; TypeCode tc = TypeCode.Object; int rc; try { foreach (SortBy sb in _Sorting.Items) { IExpr e = sb.SortExpression.Expr; o1 = e.Evaluate(_rpt, m1.R); o2 = e.Evaluate(_rpt, m2.R); tc = e.GetTypeCode(); rc = Filter.ApplyCompare(tc, o1, o2); if (rc != 0) { return(sb.Direction == SortDirectionEnum.Ascending? rc : -rc); } } } catch (Exception e) // this really shouldn't happen { _rpt.rl.LogError(8, string.Format("Matrix Sort rows exception\r\nArguments: {0} {1}\r\nTypecode: {2}\r\n{3}\r\n{4}", o1, o2, tc.ToString(), e.Message, e.StackTrace)); return(m1.HashItem.CompareTo(m2.HashItem)); } return(0); // treat as the same }
public int Compare(Row x, Row y) { object xv = parentExpr.Evaluate(rpt, x); object yv = groupExpr.Evaluate(rpt, y); return(-Filter.ApplyCompare(_Type, yv, xv)); }
public int Compare(Row r1, Row r2) { if (r1 == r2) // why does the sort routine do this?? { return(0); } object o1 = null, o2 = null; TypeCode tc = TypeCode.Object; int rc; try { foreach (RowsSortExpression se in _SortBy) { o1 = se.expr.Evaluate(this._Rpt, r1); o2 = se.expr.Evaluate(this._Rpt, r2); tc = se.expr.GetTypeCode(); rc = Filter.ApplyCompare(tc, o1, o2); if (rc != 0) { return(se.bAscending? rc: -rc); } } } catch (Exception e) // this really shouldn't happen { _Rpt.rl.LogError(8, string.Format("Sort rows exception\r\nArguments: {0} {1}\r\nTypecode: {2}\r\n{3}\r\n{4}", o1, o2, tc.ToString(), e.Message, e.StackTrace)); } return(r1.RowNumber - r2.RowNumber); // in case of tie use original row number }
public bool EvaluateBoolean(Report rpt, Row row) { object left = _lhs.Evaluate(rpt, row); object right = _rhs.Evaluate(rpt, row); if (Filter.ApplyCompare(_lhs.GetTypeCode(), left, right) <= 0) { return(true); } else { return(false); } }
public object Evaluate(Report rpt, Row row) { bool bSave = true; IEnumerable re = this.GetDataScope(rpt, row, out bSave); if (re == null) { return(null); } Row startrow = null; foreach (Row r in re) { startrow = r; // We just want the first row break; } object v = GetValue(rpt); object current_value = _Expr.Evaluate(rpt, row); if (row == startrow) { } else { if (current_value == null) { return(v); } else if (v == null) { } else if (Filter.ApplyCompare(_tc, v, current_value) > 0) { } else { return(v); } } SetValue(rpt, current_value); return(current_value); }
public object Evaluate(Report rpt, Row row) { bool bSave = true; IEnumerable re = this.GetDataScope(rpt, row, out bSave); if (re == null) { return(null); } object v = GetValue(rpt); if (v == null) { object max_value = null; object current_value; foreach (Row r in re) { current_value = _Expr.Evaluate(rpt, r); if (current_value == null) { continue; } else if (max_value == null) { max_value = current_value; } else if (Filter.ApplyCompare(_tc, max_value, current_value) < 0) { max_value = current_value; } } v = max_value; if (bSave) { SetValue(rpt, v); } } return(v); }
private void PrepRecursiveGroup(Report rpt, TableWorkClass wc) { // Prepare for processing recursive group Grouping g = wc.RecursiveGroup; IExpr parentExpr = g.ParentGroup; GroupExpression gexpr = g.GroupExpressions.Items[0] as GroupExpression; IExpr groupExpr = gexpr.Expression; TypeCode tc = groupExpr.GetTypeCode(); List <Row> odata = new List <Row>(wc.Data.Data); // this is the old data that we'll recreate using the recursive hierarchy List <Row> newrows = new List <Row>(odata.Count); // For now we assume on a single top of tree (and it must sort first as null) // spec is incomplete: should have ability to specify starting value of tree // TODO: pull all of the rows that start with null newrows.Add(odata[0]); // add the starting row odata.RemoveAt(0); // remove olddata // we need to build the group entry stack // Build the initial one wc.Groups = new List <GroupEntry>(); GroupEntry ge = new GroupEntry(null, null, 0); ge.EndRow = odata.Count - 1; wc.Groups.Add(ge); // top group List <GroupEntry> ges = new List <GroupEntry>(); ges.Add(ge); // loop thru the rows and find their children // we place the children right after the parent // this reorders the rows in the form of the hierarchy Row r; RecursiveCompare rc = new RecursiveCompare(rpt, parentExpr, tc, groupExpr); for (int iRow = 0; iRow < newrows.Count; iRow++) // go thru the temp rows { r = newrows[iRow]; r.GroupEntry = ge = new GroupEntry(g, null, iRow); // TODO: sort for this group?? r.GroupEntry.EndRow = iRow; // pull out all the rows that match this value int iMainRow = odata.BinarySearch(r, rc); if (iMainRow < 0) { for (int i = 0; i <= r.Level + 1 && i < ges.Count; i++) { ge = ges[i] as GroupEntry; Row rr = newrows[ge.StartRow]; // start row has the base level of group if (rr.Level < r.Level) { ge.EndRow = iRow; } } continue; } // look backward for starting row; // in case of duplicates, BinarySearch can land on any of the rows object cmpvalue = groupExpr.Evaluate(rpt, r); int sRow = iMainRow - 1; while (sRow >= 0) { object v = parentExpr.Evaluate(rpt, odata[sRow]); if (Filter.ApplyCompare(tc, cmpvalue, v) != 0) { break; } sRow--; } sRow++; // adjust; since we went just prior it // look forward for ending row int eRow = iMainRow + 1; while (eRow < odata.Count) { object v = parentExpr.Evaluate(rpt, odata[eRow]); if (Filter.ApplyCompare(tc, cmpvalue, v) != 0) { break; } eRow++; } // Build a group entry for this GroupEntry ge2 = ges[r.Level] as GroupEntry; ge2.NestedGroup.Add(ge); if (r.Level + 1 >= ges.Count) // ensure we have room in the array (based on level) { ges.Add(ge); // add to the array } else { ges[r.Level + 1] = ge; // put this in the array } // add all of them in; want the same order for these rows. int offset = 1; for (int tRow = sRow; tRow < eRow; tRow++) { Row tr = odata[tRow]; tr.Level = r.Level + 1; newrows.Insert(iRow + offset, tr); offset++; } // remove from old data odata.RemoveRange(sRow, eRow - sRow); } // update the groupentries for the very last row int lastrow = newrows.Count - 1; r = newrows[lastrow]; for (int i = 0; i < r.Level + 1 && i < ges.Count; i++) { ge = ges[i] as GroupEntry; ge.EndRow = lastrow; } wc.Data.Data = newrows; // we've completely replaced the rows return; }
private void PrepGroups(Report rpt, TableWorkClass wc) { wc.RecursiveGroup = null; if (_TableGroups == null) { // no tablegroups; check to ensure details is grouped if (_Details == null || _Details.Grouping == null) { return; // no groups to prepare } } int i = 0; // 1) Build array of all GroupExpression objects List <GroupExpression> gea = new List <GroupExpression>(); // count the number of groups int countG = 0; if (_TableGroups != null) { countG = _TableGroups.Items.Count; } Grouping dg = null; Sorting ds = null; if (_Details != null && _Details.Grouping != null) { dg = _Details.Grouping; ds = _Details.Sorting; countG++; } GroupEntry[] currentGroups = new GroupEntry[countG++]; if (_TableGroups != null) { // add in the groups for the tablegroup foreach (TableGroup tg in _TableGroups.Items) { if (tg.Grouping.ParentGroup != null) { wc.RecursiveGroup = tg.Grouping; } tg.Grouping.SetIndex(rpt, i); // set the index of this group (so we can find the GroupEntry) currentGroups[i++] = new GroupEntry(tg.Grouping, tg.Sorting, 0); foreach (GroupExpression ge in tg.Grouping.GroupExpressions.Items) { gea.Add(ge); } } } if (dg != null) { // add in the groups for the details grouping if (dg.ParentGroup != null) { wc.RecursiveGroup = dg; } dg.SetIndex(rpt, i); // set the index of this group (so we can find the GroupEntry) currentGroups[i++] = new GroupEntry(dg, ds, 0); foreach (GroupExpression ge in dg.GroupExpressions.Items) { gea.Add(ge); } } if (wc.RecursiveGroup != null) { if (gea.Count != 1) // Limitiation of implementation { throw new Exception("Error: Recursive groups must be the only group definition."); } PrepRecursiveGroup(rpt, wc); // only one group and it's recursive: optimization return; } // Save the typecodes, and grouping by groupexpression; for later use TypeCode[] tcs = new TypeCode[gea.Count]; Grouping[] grp = new Grouping[gea.Count]; i = 0; foreach (GroupExpression ge in gea) { grp[i] = (Grouping)(ge.Parent.Parent); // remember the group tcs[i++] = ge.Expression.GetTypeCode(); // remember type of expression } // 2) Loop thru the data, then loop thru the GroupExpression list wc.Groups = new List <GroupEntry>(); object[] savValues = null; object[] grpValues = null; int rowCurrent = 0; foreach (Row row in wc.Data.Data) { // Get the values for all the group expressions if (grpValues == null) { grpValues = new object[gea.Count]; } i = 0; foreach (GroupExpression ge in gea) { if (((Grouping)(ge.Parent.Parent)).ParentGroup == null) { grpValues[i++] = ge.Expression.Evaluate(rpt, row); } else { grpValues[i++] = null; // Want all the parentGroup to evaluate equal } } // For first row we just primed the pump; action starts on next row if (rowCurrent == 0) // always start new group on first row { rowCurrent++; savValues = grpValues; grpValues = null; continue; } // compare the values; if change then we have a group break for (i = 0; i < savValues.Length; i++) { if (Filter.ApplyCompare(tcs[i], savValues[i], grpValues[i]) != 0) { // start a new group; and force a break on every subgroup GroupEntry saveGe = null; for (int j = grp[i].GetIndex(rpt); j < currentGroups.Length; j++) { currentGroups[j].EndRow = rowCurrent - 1; if (j == 0) { wc.Groups.Add(currentGroups[j]); // top group } else if (saveGe == null) { currentGroups[j - 1].NestedGroup.Add(currentGroups[j]); } else { saveGe.NestedGroup.Add(currentGroups[j]); } saveGe = currentGroups[j]; // retain this GroupEntry currentGroups[j] = new GroupEntry(currentGroups[j].Group, currentGroups[j].Sort, rowCurrent); } savValues = grpValues; grpValues = null; break; // break out of the value comparison loop } } rowCurrent++; } // End of all rows force break on end of rows for (i = 0; i < currentGroups.Length; i++) { currentGroups[i].EndRow = rowCurrent - 1; if (i == 0) { wc.Groups.Add(currentGroups[i]); // top group } else { currentGroups[i - 1].NestedGroup.Add(currentGroups[i]); } } return; }
private void PrepGroups(Report rpt, WorkClass wc) { if (_Grouping == null) { return; } int i = 0; // 1) Build array of all GroupExpression objects List <GroupExpression> gea = _Grouping.GroupExpressions.Items; GroupEntry[] currentGroups = new GroupEntry[1]; _Grouping.SetIndex(rpt, 0); // set the index of this group (so we can find the GroupEntry) currentGroups[0] = new GroupEntry(_Grouping, _Sorting, 0); // Save the typecodes, and grouping by groupexpression; for later use TypeCode[] tcs = new TypeCode[gea.Count]; Grouping[] grp = new Grouping[gea.Count]; i = 0; foreach (GroupExpression ge in gea) { grp[i] = (Grouping)(ge.Parent.Parent); // remember the group tcs[i++] = ge.Expression.GetTypeCode(); // remember type of expression } // 2) Loop thru the data, then loop thru the GroupExpression list wc.Groups = new List <GroupEntry>(); object[] savValues = null; object[] grpValues = null; int rowCurrent = 0; foreach (Row row in wc.Data.Data) { // Get the values for all the group expressions if (grpValues == null) { grpValues = new object[gea.Count]; } i = 0; foreach (GroupExpression ge in gea) // Could optimize to only calculate as needed in comparison loop below?? { grpValues[i++] = ge.Expression.Evaluate(rpt, row); } // For first row we just primed the pump; action starts on next row if (rowCurrent == 0) // always start new group on first row { rowCurrent++; savValues = grpValues; grpValues = null; continue; } // compare the values; if change then we have a group break for (i = 0; i < savValues.Length; i++) { if (Filter.ApplyCompare(tcs[i], savValues[i], grpValues[i]) != 0) { // start a new group; and force a break on every subgroup GroupEntry saveGe = null; for (int j = grp[i].GetIndex(rpt); j < currentGroups.Length; j++) { currentGroups[j].EndRow = rowCurrent - 1; if (j == 0) { wc.Groups.Add(currentGroups[j]); // top group } else if (saveGe == null) { currentGroups[j - 1].NestedGroup.Add(currentGroups[j]); } else { saveGe.NestedGroup.Add(currentGroups[j]); } saveGe = currentGroups[j]; // retain this GroupEntry currentGroups[j] = new GroupEntry(currentGroups[j].Group, currentGroups[j].Sort, rowCurrent); } savValues = grpValues; grpValues = null; break; // break out of the value comparison loop } } rowCurrent++; } // End of all rows force break on end of rows for (i = 0; i < currentGroups.Length; i++) { currentGroups[i].EndRow = rowCurrent - 1; if (i == 0) { wc.Groups.Add(currentGroups[i]); // top group } else { currentGroups[i - 1].NestedGroup.Add(currentGroups[i]); } } return; }