0

I have a datatable similar to

Rank  Year  Value
1     1990  1234556.5676
2     2000  12313.1212 
3     2010  131242.1234

I have the following code which I wrote with the help of the following thread: How to select min and max values of a column in a datatable?

double dMaxValue = 0;
foreach (DataRow dr in dsView.Tables[0].Rows)
{
    double dValue = dr.Field<double>("Value");
    dMaxValue = Math.Max(dMaxValue, dValue);
}

This is throwing an error "Specified cast is not valid". What am I missing here and also how can I get the value of the year column once I find the MAX Value? The year needs to be returned to the calling program.

EDIT- (SOLUTION): With the help of SLacks I figured out how to accomplish the task. Firstly, I found that the data in my datatable was of type string so converted the value to double and determine the maximum value. Then used a variable to find the corresponding year.

string sYear = string.Empty;
double dMaxValue = double.MinValue;
foreach (DataRow dr in dsView.Tables[0].Rows)
{
    double dValue = Convert.ToDouble(dr.Field<string>("Value"));
    if (dValue > dMaxValue)
    {
        sYear = dr["Year"].ToString();
    }
    dMaxValue = Math.Max(dMaxValue, dValue);                            
}
return sYear;
Community
  • 1
  • 1
Sri Reddy
  • 6,832
  • 20
  • 70
  • 112

3 Answers3

2

Your Value column is probably a decimal, or perhaps a float.

You cannot cast directly from a boxed float to a double, so you need an extra cast.

It would be better to use the actual type of your field from the dataset, or to change that type to Double.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • I tried all datatypes by changing the code to `float dValue = dr.Field("Value");` and `decimal dValue = dr.Field("Value");` but no luck. Is this the right way to check? Since I don't have access to the dataset.. so I really can't edit it. How can I find the type of the column from a dataset? – Sri Reddy Jul 28 '11 at 19:59
  • 1
    @user: `dr["Value"].GetType()`, or `table.Columns["Value"].DataType` – SLaks Jul 28 '11 at 20:00
  • Thanks for your initial suggestion. I thought for a minute and found that the dataset has all column data as strings. I have resolved it using the following: `double dValue = Convert.ToDouble(dr.Field("Value"));`. But now how can I find the corresponding Year? Is there a simple solution for it? – Sri Reddy Jul 28 '11 at 20:05
  • 1
    You need to make a separate variable for the year and assign `if` the value is larger. – SLaks Jul 28 '11 at 20:33
0

How do you get the year?

You can sort the dataview:

           http://msdn.microsoft.com/en-us/library/system.data.dataview.sort.aspx

and then pluck the year from the sorted view.

Tim
  • 5,371
  • 3
  • 32
  • 41
0

Try something like this (using System.Linq and Extensions, note the let variable for the conversion):

double maxVal = 0; // supposing all your values are > 0
var maxRow = (from row in dsView.Tables[0].AsEnumerable() 
   let Val = Convert.ToDouble(row.Field<string>("Value"))
   where Val > maxVal
   select new {maxVal = Val, Year = row.Field<int>("Year")}).Last();

return maxRow.Year;
cudahead
  • 153
  • 6
  • Unfortunately, `Max` can't do that. – SLaks Jul 28 '11 at 20:26
  • @cudahead, the data in dataset is string type. So I tweaked your code to `var maxRow = (from row in dsView.Tables[0].AsEnumerable() select new { Val = Convert.ToDouble(row.Field("Value")), Year = Convert.ToDouble(row.Field("Year")) }).Max(x => x.Val);`. Firstly, this code doesn't work and I don't get Year in maxRow. Did I miss something? – Sri Reddy Jul 28 '11 at 20:32
  • I thought of a solution with a let variable. Please find my updated post above! – cudahead Jul 28 '11 at 21:13
  • cudahead, I still don't see Year or Val in maxRow. I am sure I am missing something.. – Sri Reddy Jul 29 '11 at 13:31
  • Ok, now it should work (once again updated). Note that there is no Max() used here. Please check! – cudahead Jul 29 '11 at 19:25