private void RunGroups(IPresent ip, List <GroupEntry> groupEntries, TableWorkClass wc) { Report rpt = ip.Report(); GroupEntry fge = (GroupEntry)(groupEntries[0]); if (fge.Group != null) { ip.GroupingStart(fge.Group); } foreach (GroupEntry ge in groupEntries) { // set the group entry value int index; if (ge.Group != null) // groups? { ip.GroupingInstanceStart(ge.Group); ge.Group.ResetHideDuplicates(rpt); // reset duplicate checking index = ge.Group.GetIndex(rpt); // yes } else // no; must be main dataset { index = 0; } wc.Data.CurrentGroups[index] = ge; if (ge.NestedGroup.Count > 0) { RunGroupsSetGroups(rpt, wc, ge.NestedGroup); } // Handle the group header if (ge.Group != null && ge.Group.Parent != null) { TableGroup tg = ge.Group.Parent as TableGroup; if (tg != null && tg.Header != null) { // Calculate the number of table rows below this group; header, footer, details count if (ge.NestedGroup.Count > 0) { wc.GroupNestCount = RunGroupsCount(ge.NestedGroup, 0); } else { wc.GroupNestCount = (ge.EndRow - ge.StartRow + 1) * DetailsCount; } tg.Header.Run(ip, wc.Data.Data[ge.StartRow]); wc.GroupNestCount = 0; } } // Handle the nested groups if any if (ge.NestedGroup.Count > 0) { RunGroups(ip, ge.NestedGroup, wc); } // If no nested groups then handle the detail rows for the group else if (_Details != null) { if (ge.Group != null && ge.Group.Parent as TableGroup == null) { // Group defined on table; means that Detail rows only put out once per group _Details.Run(ip, wc.Data, ge.StartRow, ge.StartRow); } else { _Details.Run(ip, wc.Data, ge.StartRow, ge.EndRow); } } // Do the group footer if (ge.Group != null) { if (ge.Group.Parent != null) { TableGroup tg = ge.Group.Parent as TableGroup; // detail groups will result in null if (tg != null && tg.Footer != null) { tg.Footer.Run(ip, wc.Data.Data[ge.EndRow]); } } ip.GroupingInstanceEnd(ge.Group); } } if (fge.Group != null) { ip.GroupingEnd(fge.Group); } }