1

I've got this code to conditionally format a cell after it has been assigned to, based on the value it contains:

var avgWeeklyDeliveriesCell = (Excel.Range)_xlSheet.Cells[curDelPerfRow,
     AVG_WEEKLY_DELIVERIES_COLUMN];
avgWeeklyDeliveriesCell.Value2 = string.Format("=ROUND(AVERAGE(C{0}:I{0}), 
     2)", curDelPerfRow);
avgWeeklyDeliveriesCell.NumberFormat = "#,##0.00";    
ConditionallyHighlight(avgWeeklyDeliveriesCell.Value2,
   _xlSheet.UsedRange.Row);

private void ConditionallyHighlight(string cellVal, int rowIndex)
{
    int COL_K_INDEX = 11;
    float avgWeeklyDelivery = float.Parse(cellVal, 
        CultureInfo.InvariantCulture);
    if (avgWeeklyDelivery > delsPerWeek)
    {
        Excel.Range cellToHighlight = (Excel.Range)_xlSheet.Cells[rowIndex
            COL_K_INDEX];
        cellToHighlight.Interior.Color = OUT_OF_BOUNDS_HIGHLIGHT_COLOR;
    }
}

The problem is with cellVal; it seems to be a string, as I'm assigning the results of a String.Format() call to the cells' Value2 property, and then passing that (value2) to the method that is to conditionally format the cell.

It compiles, but at runtime it fails with an "invalid args" message. Why, and how can I fix it?

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • What's the value of `cellVal`?, what's the value of `rowIndex`? , in wich line you got the error? – Rodolfo Feb 08 '16 at 20:10

2 Answers2

2

After you setup the formula to Value2, this property will returns the evaluated value, which is a int/double in this case. So you will not need to parse the value.

Just change the parameter cellVal type to double:

private void ConditionallyHighlight(double cellVal, int rowIndex)
{
    int COL_K_INDEX = 11;
    if (cellVal > delsPerWeek)
    {
        Excel.Range cellToHighlight = (Excel.Range)_xlSheet.Cells[rowIndex,
            COL_K_INDEX];
        cellToHighlight.Interior.Color = OUT_OF_BOUNDS_HIGHLIGHT_COLOR;
    }
}
Arturo Menchaca
  • 15,783
  • 1
  • 29
  • 53
  • Your solution is better than mine as it is short and pragmatic, worth an upvote from my side. This approach is perfect if you deal with sheets you've filled yourself, where you know, what will come back (that's the case here). But: I'd rather use an approach which does not rely on data being in the right format or type... (*defensive programming*) – Shnugo Feb 08 '16 at 21:29
1

In this line you are passing in a Value2

ConditionallyHighlight(avgWeeklyDeliveriesCell.Value2, _xlSheet.UsedRange.Row);

But the Value2 is a Range-object in Excel and - maybe - not directly useable in C#.

Have a look to D Stanley's comment (Thx!) who cleard this point.

Here is a somehow related question: Casting Range.Value2 of Excel interop to string

Try to add a ".ToString()" after Value2 and be aware of the possibilities of "null". Better use float.TryParse()

string YourString = "ImpossibleValue";
float f;
if (!float.TryParse(YourString, out f)) {
    //React on the failed parsing (default value, error... 
}
//go ahead with f, which holds the correct (or defaulted) value

Here's some background: https://msdn.microsoft.com/en-us/library/office/ff193553.aspx

Community
  • 1
  • 1
Shnugo
  • 66,100
  • 9
  • 53
  • 114
  • No, `Value2` is an `object` (a `Variant` in VBA terms), not a `Range`, it will either be a single string or double value, or a 1 or 2-dimensional array of `string` or `double`. – D Stanley Feb 08 '16 at 20:42
  • @DStanley, thx for clearing this. my own wording was misleading... Yes,I know, that within C# it's not a Range-object. What I wanted to say is, that - maybe - the Value2 is not usable directly. Anyway, the OP should monitor, what values are coming there (and give some more details about the error) – Shnugo Feb 08 '16 at 20:48
  • then it would be more clear to say that `Value2` _could be_ an array - the OP is _assuming_ it's a string in the method which _might_ be the cause of the problem. – D Stanley Feb 08 '16 at 20:49