简体   繁体   中英

Selecting grouped max and min in a Epplus worksheet with Linq

I have an Epplus Excel Worksheet that looks like this.

在此输入图像描述

I want to group by the Group column (in column A), and then select the max and the min. Something in my group by clause isn't quite right and I'm getting an error: Cannot apply indexing with [] to ExcelRangeBase .

var maxMinGrouped = from cells in _dataSheet.Cells["A:H"]
                    group cells by cells["A:A"].Value into g //pull "Group" column into group
                    select new
                    {
                        Group = cells["A:A"].Value,
                        MaxDailyIndex = g.Max(c => c.Value),
                        MinDailyIndex = g.Min(c => c.Value)
                    };

The SQL I'm trying to achieve.

SELECT Group
    ,MAX(Col_E) AS MaxDailyIndex
    ,MIN(Col_E) AS MinDailyIndex
FROM Worksheet
GROUP BY Group

Remember that the cells collection is a 2x2 matrix so you will need to group cells into rows before you can group into groups of row. I am way rusty on the query notation of linq but here is how to do it using the dot notation:

[TestMethod]
public void Grouped_Row_Test()
{
    //http://stackoverflow.com/questions/30466257/selecting-grouped-max-and-min-in-a-epplus-worksheet-with-linq

    var existingFile = new FileInfo(@"c:\temp\Grouped.xlsx");
    using (var pck = new ExcelPackage(existingFile))
    {
        var _dataSheet = pck.Workbook.Worksheets.First();

        //Group cells by row
        var rowcellgroups = _dataSheet
            .Cells["A:H"]
            .GroupBy(c => c.Start.Row);

        //Now group rows the column A; Skip the first row since it has the header
        var groups = rowcellgroups
            .Skip(1)
            .GroupBy(rcg => rcg.First().Value);

        //Reproject the groups for the min/max values; Column E = 5
        var maxMinGrouped = groups
            .Select(g => new
            {
                Group = g.Key,
                MaxDailyIndex = g.Select(o => o.First(rc => rc.Start.Column == 5)).Max(rc => rc.Value),
                MinDailyIndex = g.Select(o => o.First(rc => rc.Start.Column == 5)).Min(rc => rc.Value)
            });

        maxMinGrouped
            .ToList()
            .ForEach(mmg => Console.WriteLine("{{Group: \"{0}\", Min={1}, Max={2}}}", mmg.Group, mmg.MinDailyIndex, mmg.MaxDailyIndex));
    }
}

Which gives this in the console after I threw in some random data to your excel table:

{Group: "3", Min=0, Max=88}
{Group: "4", Min=6, Max=99}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM