首页 > 解决方案 > 试图弄清楚为什么 for each 语句与 if 语句一起使用,但是当我将其切换到 for 循环时抛出异常

问题描述

提前抱歉,因为几年前我在 VB 的历史有限,只使用 C# 大约一个月。这是我试图为工作创建的一种邮件合并循环,以使他们的生活更轻松。我已经弄清楚了日期。我有一个 NumUpDown 控件设置 int myInt,以及一个formCount从 0 开始的 int 。当我将代码if(formCount==0),切换到

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

它现在抛出一个

“System.NullReferenceException:'对象引用未设置为对象的实例。'”

我知道可能还有另一种方法可以做我正在做的事情,即一次将连续日期添加到一个月的表格中。我将日期存储在一个数组myDate[31]中。

我正在使用numUpDwn(min 1 max 31)来获取myInt,因此我们可以选择一个月中有多少天,或者如果我们需要替换页面则只打印几天,因此我们可以打印 1 到 31 页的任何页面。

使用 if 语句,它将从模板创建第一页(.dotx)doc(var)将 doc 的内容复制到 doc2 并添加一个新页面以接收下一个内容粘贴。

我相信这是一个愚蠢的问题,有人也会有一个简单的答案。该循环应该打开模板,添加日期,复制到 doc2。关闭原件,然后重新启动,直到达到所选的页数/日期。感谢您的帮助,这是我需要完成的最后一部分,我很难过。哦,我使用了 != 因为它跳过了合并字段,但只有 1 个字段不等于任何工作。

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);


标签: for-loopforeachms-wordcopy-pastemailmerge

解决方案


我没有运行您的代码,但据我所知,即使没有 formcount 循环,在您拥有多个 MERGEFIELD 字段的情况下,此代码也可能会失败,因为您在doc处理完此类字段后立即关闭,然而 foreach 循环正在处理 doc.Fields 中的每个字段。

即使该 foreach 循环正常终止,在您正在使用的 formCount 循环的下一次迭代中doc.Activate(),但doc已关闭,因此将失败。

所以我建议要做的主要事情是考虑在什么时候需要打开哪些文档才能使流程正常工作。

一些观察(不一定与您的主要问题有关)

  • myInt 设置在哪里?
  • 是否有一个 formCount++ 循环在循环中为每个 MERGEFIELD 使用 formCount++doc真的是你的意图吗?
  • 在过滤 MAILMERGE 字段而不是匹配文本时,您最好测试 field.Type(),至少如果最终用户可以设置这些字段
  • 当您在 Word 中处理集合并且要添加或删除集合的成员时,有时必须考虑使用从集合的最后一个成员开始并返回到开头的循环。不确定在这种情况下是否需要这样做,但由于您在填写字段时可能会“删除”。选择然后键入文本,请记住这一点
  • 当您主要试图勾勒出循环的逻辑时,这可能看起来很复杂,但我通常发现在开发过程中尽早开始使用 try...catch...finally 块非常有帮助。

推荐阅读