for-loop - 试图弄清楚为什么 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);
解决方案
我没有运行您的代码,但据我所知,即使没有 formcount 循环,在您拥有多个 MERGEFIELD 字段的情况下,此代码也可能会失败,因为您在doc
处理完此类字段后立即关闭,然而 foreach 循环正在处理 doc.Fields 中的每个字段。
即使该 foreach 循环正常终止,在您正在使用的 formCount 循环的下一次迭代中doc.Activate()
,但doc
已关闭,因此将失败。
所以我建议要做的主要事情是考虑在什么时候需要打开哪些文档才能使流程正常工作。
一些观察(不一定与您的主要问题有关)
- myInt 设置在哪里?
- 是否有一个 formCount++ 循环并在循环中为每个 MERGEFIELD 使用 formCount++
doc
真的是你的意图吗? - 在过滤 MAILMERGE 字段而不是匹配文本时,您最好测试 field.Type(),至少如果最终用户可以设置这些字段
- 当您在 Word 中处理集合并且要添加或删除集合的成员时,有时必须考虑使用从集合的最后一个成员开始并返回到开头的循环。不确定在这种情况下是否需要这样做,但由于您在填写字段时可能会“删除”。选择然后键入文本,请记住这一点
- 当您主要试图勾勒出循环的逻辑时,这可能看起来很复杂,但我通常发现在开发过程中尽早开始使用 try...catch...finally 块非常有帮助。
推荐阅读
- c++ - 使用 chilkat lib 发布请求
- symfony - Symfony Doctrine 按特定顺序排序 oneToMany
- vb.net - 如何使用 sqlbulkcopy 将数据从 dataReader 流式传输到 SQL?
- python - 如何抓取跟随另一个 html 行的特定 html 行
- java - Spring Boot SessionFactory 实例化失败但仅在容器化时
- react-native - 如何在抽屉导航器内的堆栈导航器中通过 backButton 返回
- java - java中如何处理像“@PathParam(”“)”这样的java注解?我们在哪里可以找到特定注释处理器的源代码?
- image - 使用 arsd nanovega 渲染到位图
- javascript - 将 randomID 函数从 JS 移植到 PHP
- excel - 如何获取代码以每次在新工作表中逐行重复编程操作