Sorry in advance, as I have only been working with C# for about a month with limited history in VB years ago. It's a Mail merge kind of loop that I am trying to create for work to make their life easier. I have the dates figured out. I have a NumUpDown control setting the int myInt, and a formCount int starting at 0. The code worked fine when I used if(formCount==0), when I switched it to

for(formCount=0;formCount<myInt;formCount++)

it now throws a

"System.NullReferenceException: 'Object reference not set to an instance of an object.'"

I know there is probably another way to do what I am working on which is to just add sequential dates to forms a month at a time. I have the dates stored in an array myDate[31].

I am using the numUpDwn(min 1 max 31) to get myInt so we can select how many days in the month, or only print a couple days if we need to replace pages, so we can print anywhere from 1 to 31 pages.

With the if statement it would create the first page from the template (.dotx) to doc(var) copy the contents of doc to doc2 and add a new page to receive the next content paste.

I am sure this is a silly question, that someone will have a simple answer too. The loop is supposed to open the template, add the date, copy to doc2. close the original, and restart until it reached the number of pages/dates selected. Thanks for any help, this is the last section I need to finish and I am stumped. Oh, and I used the != because it was skipping the merge field, but with only 1 field not equal to anything worked.

private void BtnPrint_Click(object sender, EventArgs e)
       {
           var app = new Microsoft.Office.Interop.Word.Application();
           var doc = new Microsoft.Office.Interop.Word.Document();
           var doc2 = new Microsoft.Office.Interop.Word.Document();
           //app.Visible = true;
           doc = null;
           doc2.PageSetup.Orientation = WdOrientation.wdOrientLandscape;
           doc2.PageSetup.TopMargin = app.InchesToPoints(0.6f);
           doc2.PageSetup.BottomMargin = app.InchesToPoints(0.17f);
           doc2.PageSetup.LeftMargin = app.InchesToPoints(0.5f);
           doc2.PageSetup.RightMargin = app.InchesToPoints(0.5f);
           String fileSave;
           fileSave = ("OTSU" + "_" + myDate[0].Month + "_" + myDate[0].Year + ".docx");
           
           
           int formCount;
           //formCount = 0;
           var filepath = System.Windows.Forms.Application.StartupPath + outfile;
           doc = app.Documents.Add(filepath);
           
           doc2.Activate();
           //OBJECT OF MISSING "NULL VALUE"
           Object oMissing = System.Reflection.Missing.Value;
           for (formCount = 0; formCount<myInt;formCount++)
           {
               doc.Activate();

               foreach (Microsoft.Office.Interop.Word.Field field in doc.Fields)
               {

                   Range rngFieldCode = field.Code;
                   String fieldText = rngFieldCode.Text;
                   // ONLY GETTING THE MAILMERGE FIELDS
                   if (fieldText.StartsWith(" MERGEFIELD"))
                   {
                       Int32 endMerge = fieldText.IndexOf("\\");
                       Int32 fieldNameLength = fieldText.Length - endMerge;
                       String fieldName = fieldText.Substring(11);
                       // GIVES THE FIELDNAMES AS THE USER HAD ENTERED IN .dotx FILE
                       fieldName = fieldName.Trim();
                       if (fieldName != "M_2nd__3rd")
                       {
                           field.Select();
                           app.Selection.TypeText(myDate[formCount].ToShortDateString());
                       }
                       formCount++;
                       Microsoft.Office.Interop.Word.Range dRange = doc.Content;
                       dRange.Copy();
                       
                       doc2.Range(doc2.Content.End - 1, doc2.Content.End - 1).PasteSpecial(DataType: Microsoft.Office.Interop.Word.WdPasteOptions.wdKeepSourceFormatting);
                       doc2.Range(doc2.Content.End - 1, doc2.Content.End - 1).InsertBreak(Microsoft.Office.Interop.Word.WdBreakType.wdPageBreak);
                       Clipboard.Clear();
                       doc.Close(WdSaveOptions.wdDoNotSaveChanges);
                   }

               }
           }
           doc2.SaveAs2("OTSU" + myDate[0].Month + "_" + myDate[0].Year + ".docx");
           app.Documents.Open("OTSU" + myDate[0].Month + "_" + myDate[0].Year + ".docx");
           doc.Close(WdSaveOptions.wdDoNotSaveChanges);
           doc2.Close(WdSaveOptions.wdDoNotSaveChanges);


2

There are 2 best solutions below

0
On BEST ANSWER

I did find a solution for now. Since there is only one MERGFIELD, instead of trying to open doc, insert date, copy to new doc2, close doc, repeat I found I can open, insert date, copy to new doc2, undo edit on doc and repeat. At least it works for now, and I can get back to the books and learn some more while I map out the big project I have planned. I am sure I will be on here a bit with more questions. Without @slightly-snarky asking the questions he did, I wouldn't have thought of this so I have to give them credit for the answer. I did have to put the doc.Undo(); at the top of the loop and it will only work with one field. But its a start.

     private void BtnPrint_Click(object sender, EventArgs e)
    {
        var app = new Microsoft.Office.Interop.Word.Application();
        String fileSave;
        fileSave = ("OTSU" + "_" + myDate[0].Month + "_" + myDate[0].Year + ".docx");
        int formCount;
        formCount = 0;
        var filepath = System.Windows.Forms.Application.StartupPath + outfile;
        var doc = new Microsoft.Office.Interop.Word.Document();
        doc = app.Documents.Add(filepath);
        app.Visible = true;
        doc.Activate();
        var doc2 = new Microsoft.Office.Interop.Word.Document();
        doc2.PageSetup.Orientation = WdOrientation.wdOrientLandscape;
        doc2.PageSetup.TopMargin = app.InchesToPoints(0.6f);
        doc2.PageSetup.BottomMargin = app.InchesToPoints(0.17f);
        doc2.PageSetup.LeftMargin = app.InchesToPoints(0.5f);
        doc2.PageSetup.RightMargin = app.InchesToPoints(0.5f);

        doc2.Activate();
        //OBJECT OF MISSING "NULL VALUE"
        Object oMissing = System.Reflection.Missing.Value;
        for (formCount = 0; formCount < myInt; formCount++)
        {
            doc.Undo();
            foreach (Microsoft.Office.Interop.Word.Field field in doc.Fields)
            {
                Range rngFieldCode = field.Code;
                String fieldText = rngFieldCode.Text;
                // ONLY GETTING THE MAILMERGE FIELDS
                if (fieldText.StartsWith(" MERGEFIELD"))
                {
                    Int32 endMerge = fieldText.IndexOf("\\");
                    Int32 fieldNameLength = fieldText.Length - endMerge;
                    String fieldName = fieldText.Substring(11);
                    // GIVES THE FIELDNAMES AS THE USER HAD ENTERED IN .dotx FILE
                    fieldName = fieldName.Trim();
                    if (fieldName != "M_2nd__3rd")
                    {
                        field.Select();
                        app.Selection.TypeText(myDate[formCount].ToShortDateString());
                    }
                    Microsoft.Office.Interop.Word.Range dRange = doc.Content;
                    dRange.Copy();
                    doc2.Range(doc2.Content.End - 1, doc2.Content.End - 1).PasteSpecial(DataType: Microsoft.Office.Interop.Word.WdPasteOptions.wdKeepSourceFormatting);
                    doc2.Range(doc2.Content.End - 1, doc2.Content.End - 1).InsertBreak(Microsoft.Office.Interop.Word.WdBreakType.wdPageBreak);
                    Clipboard.Clear();
                }
            }
        }
        doc2.SaveAs2("OTSU" + myDate[0].Month + "_" + myDate[0].Year + ".docx");
        doc.Close(WdSaveOptions.wdDoNotSaveChanges);
        doc2.Close(WdSaveOptions.wdDoNotSaveChanges);
        app.Documents.Open("OTSU" + myDate[0].Month + "_" + myDate[0].Year + ".docx");
    }
}

}

4
On

I haven’t run your code, but as far as I can see, this code would probably fail even without the formcount loop in the situation where you have more than one MERGEFIELD field because you close doc As soon as you have processed such a field, and yet the foreach loop is processing each Field in doc.Fields.

Even if that foreach loop terminates gracefully, in the next iteration of the formCount loop you are using doc.Activate(), but doc has closed so that will fail.

So I suggest that the main thing to do is consider which documents need to be open at which point for the process to work.

Some observations (not necessarily to do with your primary question)

  • where is myInt set?
  • is having a formCount++ loop and using formCount++ within the loop for every MERGEFIELD in doc Really your intention?
  • you might be better off testing field.Type() when filtering MAILMERGE fields rather than matching the text, at least if such fields can be set up by end users
  • when you process collections in Word and you are either adding or deleting members of the collection, you sometimes have to consider using a loop that starts with last member of the collection and works back towards the beginning. Not sure you need to do that in this case but since you may be “deleting” when you do your field.Select then Typetext, please bear that in mind
  • It may seem like a complication when you are mainly trying to sketch out the logic of your loops, but I generally find it very helpful to start using try...catch...finally blocks sooner rather than later during development.