7

I've been trying to figure out how to insert 2 different formats into the same paragraph using interop.word in c# like this:

hello planet earth here's what I want to do

Alexis Pigeon
  • 7,423
  • 11
  • 39
  • 44
David Lopez
  • 141
  • 1
  • 3
  • 4

6 Answers6

5

Assuming you have your document defined as oDoc, the following code should get you the desired result:

Word.Paragraph oPara = oDoc.Content.Paragraphs.Add(ref oMissing);
oPara.Range.Text = "hello planet earth here's what I want to do";
object oStart = oPara.Range.Start + 13;
object oEnd = oPara.Range.Start + 18;

Word.Range rBold = oDoc.Range(ref oStart, ref oEnd);
rBold.Bold = 1;
Dennis
  • 51
  • 1
  • 2
  • +1 because it looks like it'll work, but there must be a way to do switch style then add characters rather than having to apply styles after-the-fact. – Rup Jul 18 '11 at 23:52
4

I had to modify Dennis' answer a little to get it to work for me.

What I'm doing it totally automated, so I have to only work with variables.

private void InsertMultiFormatParagraph(string text, int size, int spaceAfter = 10) {
    var para = docWord.Content.Paragraphs.Add(ref objMissing);

    para.Range.Text        = text;
    // Explicitly set this to "not bold"
    para.Range.Font.Bold   = 0;
    para.Range.Font.Size   = size;
    para.Format.SpaceAfter = spaceAfter;

    var start = para.Range.Start;
    var end   = para.Range.Start + text.IndexOf(":");

    var rngBold = docWord.Range(ref objStart, ref objEnd);
    rngBold.Bold = 1;

    para.Range.InsertParagraphAfter();
}

The main difference that made me want to make this post was that the Paragraph should be inserted AFTER the font is changed. My initial thought was to insert it after setting the SpaceAfter property, but then the objStart and objEnd values were tossing "OutOfRange" Exceptions. It was a little counter-intuitive, so I wanted to make sure everyone knew.

krillgar
  • 12,596
  • 6
  • 50
  • 86
  • "I can't comment on his answer yet" IMO if you're proposing new code or a non-trivial modification then a new answer is the right way to do it anyway. I suspect there's true / false constants to use for the `.Bold` values though. – Rup Apr 10 '12 at 10:44
  • I was thinking the same thing as well, except Bold (as well as Italic, Underline, etc) are all Properties of DataType int. 1 would be "true", 0 is "false". It defaults to -1, so there is a third "unset" option. Like everything with Office Interops, it's kind of counter-intuitive to how you would expect it to work. All the legacy code makes it a little hard to work with for newcomers (like myself). – krillgar Apr 10 '12 at 16:45
3

The following code seemed to work the best for me when formatting a particular selection within a paragraph. Using Word's built in "find" function to make a selection, then formatting only the selected text. This approach would only work well if the text to select is a unique string within the selection. But for most situations I have run across, this seems to work.

        oWord.Selection.Find.Text = Variable_Containing_Text_to_Select; // sets the variable for find and select
        oWord.Selection.Find.Execute(); // Executes find and select
        oWord.Selection.Font.Bold = 1; // Modifies selection
        oWord.Selection.Collapse();  // Clears selection

Hope this helps someone!

joshman1019
  • 129
  • 1
  • 8
  • 1
    Thanks! this helped me. Just wanted to add in case someone else sees this, once you run oWord.Selection.Find.Execute(); you then need to run oWord.Selection.Collapse(); before running another Selection.Find. This will clear the first selection. – Kevin Moore Jul 17 '20 at 19:25
  • That’s great advice. Thanks! – joshman1019 Jul 17 '20 at 19:27
  • I have modified my answer to include your recommendation since it seems like this may be a common need. – joshman1019 Jul 17 '20 at 19:31
1

I know this post is old, but it came out in almost all my searches. The answer below is in case someone, like me, wants to do this for more than one word in a sentence. In this case, I loop through a string array of variables that contain strings and change that text to bold--modifing @joshman1019

string[] makeBold = new string[4] {a, b, c, d};

foreach (string s in makeBold)
{
   wApp.Selection.Find.Text = s; //changes with each iteration
   wApp.Selection.Find.Execute(); 
   wApp.Selection.Font.Bold = 1;
   wApp.Selection.Collapse(); //used to 'clear' the selection
   wApp.Selection.Find.ClearFormatting();
}

So, each string represented by the variable will be bold. So if a = "hello world", then Hello World is made bold in the Word doc. Hope it saves someone some time.

Chris
  • 934
  • 1
  • 17
  • 38
0

I know this is an old thread, but I thought I'd post here anyway for those that come across it via Google (like I did). I got most of the way to a solution with krillgar's approach, but I had trouble because some of my text contains newlines. Accordingly, this modification worked best for me:

private void WriteText(string text)
    {
        var para = doc.Content.Paragraphs.Add();
        var start = para.Range.Start;
        var end = para.Range.Start + text.IndexOf(":");
        para.Range.Text = text;
        para.Range.Font.Bold = 0;
        para.Range.InsertParagraphAfter();

        if(text.Contains(":")){
            var rngBold = doc.Range(start, end);
            rngBold.Bold = 1;
        }
    }

The key difference is that I calculate start and end earlier in the function. I can't quite put my finger on it, but I think if your new text has newlines in it, the later calculation of start/end messes something up.

And obviously my solution is intended for text with the format:

Label: Data

where Label is to be bolded.

Vincent
  • 33
  • 5
0

Consider usage of Range.Collapse eventually with Microsoft.Office.Interop.Word.WdCollapseDirection.wdCollapseEnd as parameter. That would allow next text to have formatting different than previous text (and next text formatting will not affect formatting of previous one).

Failed Scientist
  • 1,977
  • 3
  • 29
  • 48
Peter
  • 11
  • 3