Search code examples
c#vbams-wordrgboffice-automation

C# converting a VBA macro to C# with custom RGB color


In converting a VBA macro to a plugin coded in C#, I have run into the following impasse.

The original VBA code is:

Selection.Font.Name = "Times New Roman"
Selection.Font.Size = 14
Selection.Font.Bold = True
Selection.Font.BoldBi = True
Selection.Shading.Texture = wdTextureNone
Selection.Shading.ForegroundPatternColor = wdColorAutomatic
Selection.Shading.BackgroundPatternColor = RGB(173, 216, 230)

Converted to C# with the Office.Interop namespace:

using Microsoft.Office;
using Microsoft.Office.Interop;
using Word = Microsoft.Office.Interop.Word;

Word.Document oWordDoc = new Word.Document();
var Selection = oWordDoc.ActiveWindow.Selection;

Selection.Font.Name = "Times New Roman";
Selection.Font.Size = 14;
Selection.Shading.Texture = Word.WdTextureIndex.wdTextureNone;
Selection.Shading.ForegroundPatternColor = Word.WdColor.wdColorAutomatic;
Selection.Shading.BackgroundPatternColor = Word.ColorFormat.RGB(173, 216, 230);

This code won't compile as the RGB is not a Method. I am trying to figure out how to do this with using the available methods, but no luck so far.

I would appreciate any advice on this or any description that would explain the conversion.

Update:

Actually, it looks like the following works:

Color mycolor = Color.FromArgb(173, 216, 230);
Selection.Shading.BackgroundPatternColor = (Word.WdColor)(mycolor.R + 0x100 * mycolor.G + 0x10000 * mycolor.B);

This question uses the same approach. But it still looks too complex...

Update 2:

With the suggestions below this seems to be the smoothest approach:

Selection.Shading.BackgroundPatternColor = RGB(172,216,230);

private Word.WdColor RGB(int p1, int p2, int p3)
{
    return (Word.WdColor)p1 + (0x100 * p2) + (0x10000 * p3);
}

Solution

  • The RGB function you're actually calling in your VBA code, is located in the VBA standard library, in the Information module - at least according to Rubberduck 2.0's context-sensitive status bar (disclaimer: I wrote that feature):

    Rubberduck 2.0's context-sensitive status bar

    That RGB function really does nothing more than intake 3 numbers and output a corresponding RGB hex value.

    This question asks specifically how to convert from System.Drawing.Color to a WdColor value - and the accepted answer looks pretty much exactly like your "too complex" code. Another solution would be to import Microsoft.VisualBasic and use the same Information.RGB function... but I cringe whenever I see the Microsoft.VisualBasic imported anywhere in a .NET project - it reeks of something being done wrong.

    Instead, you could make a simple extension method:

    using System.Drawing;
    using Microsoft.Interop.Word;
    
    static class ColorExtensions
    {
        public static WdColor ToWdColor(this Color color)
        {
            return (WdColor)(color.R + 0x100 * color.G + 0x10000 * color.B);
        }
    }
    

    Which turns your code to this:

    var color = Color.FromArgb(173, 216, 230).ToWdColor();