Home » excel » vba – Excel range Style: specifying Borders via VSTO doesn't work

vba – Excel range Style: specifying Borders via VSTO doesn't work

Posted by: admin April 23, 2020 Leave a comment

Questions:

Instead of formatting ranges by setting individual formatting properties one by one, I am trying to use Excel Styles, because it seems to be faster at formatting large numbers of cells. I define a Style once, and then apply it to Ranges like this:

var cell = worksheet.Cells[row, column];
cell.Style = "MyCustomStyle";

It works perfectly for Interior Color and Font, but I am running into weird issues when trying to work with Borders. When I try to define what borders to show on a range, and how they should be formatted, I get unpredictable results, and can’t find a way to control it.

The following method creates a Style named ListRowStyle;

private static void CreateListRowStyle(Workbook workbook)
{
    var listRowStyle = workbook.Styles.Add(ListRowStyle);

    listRowStyle.Interior.Color = ColorTranslator.ToOle(Color.LightGray);

    listRowStyle.Font.Color = ColorTranslator.ToOle(Color.DarkBlue);
    listRowStyle.Font.Bold = true;

    listRowStyle.IncludeBorder = true;
    listRowStyle.Borders.Color = ColorTranslator.ToOle(Color.Black);
    listRowStyle.Borders.LineStyle = XlLineStyle.xlContinuous;
    listRowStyle.Borders.Weight = XlBorderWeight.xlMedium;
}

This creates every single border in the range (vertical, horizontal and diagonal) – so far, so good. However, when I try to display only, say, the top and bottom borders, using the following code, problems start happening:

private static void CreateEditableListRowStyle(Workbook workbook)
{
    var editableListRowStyle = workbook.Styles.Add(EditableListRowStyle);
    editableListRowStyle.Interior.Color = ColorTranslator.ToOle(Color.Yellow);

    editableListRowStyle.Font.Color = ColorTranslator.ToOle(Color.Red);
    editableListRowStyle.Font.Bold = false;

    editableListRowStyle.IncludeBorder = true;

    editableListRowStyle.Borders[XlBordersIndex.xlEdgeLeft].LineStyle = XlLineStyle.xlLineStyleNone;
    editableListRowStyle.Borders[XlBordersIndex.xlEdgeRight].LineStyle = XlLineStyle.xlLineStyleNone;

    editableListRowStyle.Borders[XlBordersIndex.xlDiagonalDown].LineStyle = XlLineStyle.xlLineStyleNone;
    editableListRowStyle.Borders[XlBordersIndex.xlDiagonalUp].LineStyle = XlLineStyle.xlLineStyleNone;

    editableListRowStyle.Borders[XlBordersIndex.xlEdgeTop].LineStyle = XlLineStyle.xlContinuous;
    editableListRowStyle.Borders[XlBordersIndex.xlEdgeTop].Weight = XlBorderWeight.xlMedium;

    editableListRowStyle.Borders[XlBordersIndex.xlEdgeBottom].LineStyle = XlLineStyle.xlContinuous;
    editableListRowStyle.Borders[XlBordersIndex.xlEdgeBottom].Weight = XlBorderWeight.xlThin;
}

The color styling happens, but no borders show up. Things get even weirder when I modify the code to format the Left and Right border like this:

private static void CreateEditableListRowStyle(Workbook workbook)
{
    var editableListRowStyle = workbook.Styles.Add(EditableListRowStyle);
    editableListRowStyle.Interior.Color = ColorTranslator.ToOle(Color.Yellow);

    editableListRowStyle.Font.Color = ColorTranslator.ToOle(Color.Red);
    editableListRowStyle.Font.Bold = false;

    editableListRowStyle.IncludeBorder = true;

    editableListRowStyle.Borders[XlBordersIndex.xlEdgeLeft].LineStyle = XlLineStyle.xlContinuous;
    editableListRowStyle.Borders[XlBordersIndex.xlEdgeLeft].Weight = XlBorderWeight.xlMedium;

    editableListRowStyle.Borders[XlBordersIndex.xlEdgeRight].LineStyle = XlLineStyle.xlContinuous;
    editableListRowStyle.Borders[XlBordersIndex.xlEdgeRight].Weight = XlBorderWeight.xlMedium;

    editableListRowStyle.Borders[XlBordersIndex.xlDiagonalDown].LineStyle = XlLineStyle.xlLineStyleNone;
    editableListRowStyle.Borders[XlBordersIndex.xlDiagonalUp].LineStyle = XlLineStyle.xlLineStyleNone;

    editableListRowStyle.Borders[XlBordersIndex.xlEdgeTop].LineStyle = XlLineStyle.xlContinuous;
    editableListRowStyle.Borders[XlBordersIndex.xlEdgeTop].Weight = XlBorderWeight.xlMedium;

    editableListRowStyle.Borders[XlBordersIndex.xlEdgeBottom].LineStyle = XlLineStyle.xlContinuous;
    editableListRowStyle.Borders[XlBordersIndex.xlEdgeBottom].Weight = XlBorderWeight.xlThin;
}

At that point, the top and bottom borders still don’t show up; on the other hand, I get a Left border that shows up, but no Right border. Uh?

So – am I doing something wrong, or is setting Borders on a Style via VSTO just not working? Note that the following code, which is a very close translation of the VSTO/C# code in VBA, works exactly as I would expect it to.

Sub Styling()

    ActiveWorkbook.Styles.Add Name:="VbaStyle"

    With ActiveWorkbook.Styles("VbaStyle")
        .IncludeBorder = True
    End With

    ActiveWorkbook.Styles("VbaStyle").Borders(xlLeft).LineStyle = xlNone
    ActiveWorkbook.Styles("VbaStyle").Borders(xlRight).LineStyle = xlNone
    ActiveWorkbook.Styles("VbaStyle").Borders(xlDiagonalDown).LineStyle = xlNone
    ActiveWorkbook.Styles("VbaStyle").Borders(xlDiagonalUp).LineStyle = xlNone

    With ActiveWorkbook.Styles("VbaStyle").Borders(xlTop)
        .LineStyle = xlContinuous
        .Weight = xlMedium
    End With

    With ActiveWorkbook.Styles("VbaStyle").Borders(xlBottom)
        .LineStyle = xlContinuous
        .Weight = xlThin
    End With

End Sub

This is on Windows 7, Excel 2007.

How to&Answers:

Try using xlLeft, xlRight, xlTop, xlBottom instead of xlEdgeLeft, xlEdgeRight, xlEdgeTop, xlEdgeBottom

Answer:

I was trying for sometime and came across your question and got some heads-up.
Thanks for that.
Was able to create the style using the optional parameter of basedOn like below:

var activeSheet = workbook.ActiveSheet as Worksheet;
Range first = activeSheet.Range["A1"];
first.Borders.Item[XlBordersIndex.xlEdgeBottom].Color = Color.FromArgb(0, 16, 80);
first.Borders.Item[XlBordersIndex.xlEdgeBottom].Weight = XlBorderWeight.xlThick;
first.Borders.Item[XlBordersIndex.xlEdgeBottom].LineStyle = XlLineStyle.xlContinuous;
Style myStyle = o9Workbook.Styles.Add("MyStyle",first);
//reset the first to normal style
first.Style = "Normal";

Hope it helps someone!