【问题标题】:Hide template Word Doc while displaying executed Word Doc?在显示已执行的 Word Doc 时隐藏模板 Word Doc?
【发布时间】:2014-01-01 11:45:12
【问题描述】:

在下面的代码中,我启动了 2 个单词实例。我将一个实例设置为我的“模板”,即尚未运行的邮件合并文档的文件。另一个实例是一个空白文档,我将使用它从执行的邮件合并文档中复制/粘贴每一页,然后单独保存该文档。

我让两个 Word 实例都可见,然后打开我的“模板”和空白文档,以便使用每个实例单独保存。接下来我打开 MailMerge 操作的数据源。

执行邮件合并操作后,屏幕上会显示 3 个文档:

  1. 邮件合并的原始“模板”
  2. 我在复制/粘贴邮件合并部分时用于保存单个文件的空白文档。
  3. 标题为“Form Letters1”的已执行邮件合并文档。

我的代码处理了一个 while() 循环,并复制“Form Letters1”的每个部分并将其粘贴到我的名为“NewDocument.doc”的文档中。然后,我的 foreach() 循环在生成“NewDocument.doc”的文件名并保存之前更新数据库跟踪表。

保存“Form Letters1”中的单个部分后,我会选择新保存的文档中的所有内容并将其清除以处理“Form Letters1”中的下一个部分。

当“Form Letters1”的所有单独部分都被复制/粘贴并保存为他们自己的文档后,我用oNewWord.Visible = false;隐藏我的“NewDocument.doc”。

我的问题是,我仍然在屏幕上显示邮件合并的“模板”文档,以及“Form Letters1”执行的邮件合并文档。

我有什么办法可以隐藏模板并保持“Form Letters1”可见?我尝试在消息框出现之前设置oWord.Visible = false;,但这隐藏了“模板”和“Form Letters1”(我需要让用户查看和打印的已执行邮件合并文档)。

public void MergeSplitAndReview()
    {
        try
        {
            //MergeDocLibrary mdl = new MergeDocLibrary();
            //mdl.mergeDocument(docSource, docLoc);

            // Mail Merge Template
            Word.Application oWord = new Word.Application();
            Word.Document oWrdDoc = new Word.Document();
            // New Document Instance
            Word.Application oNewWord = new Word.Application();
            Word.Document oNewWrdDoc = new Word.Document();

            object doNotSaveChanges = Word.WdSaveOptions.wdDoNotSaveChanges;

            // Documents must be visible for code to Activate()
            oWord.Visible = true;
            oNewWord.Visible = true;

            Object oTemplatePath = docLoc;
            Object oMissing = System.Reflection.Missing.Value;

            // Open Mail Merge Template
            oWrdDoc = oWord.Documents.Open(oTemplatePath);

            // Open New Document (Empty)
            // Note: I tried programmatically starting a new word document instead of opening an exisitng "blank",
            //       bu when the copy/paste operation occurred, formatting was way off. The blank document below was
            //       generated by taking a copy of the FullMailMerge.doc, clearing it out, and saving it, thus providing
            //       a kind of formatted "template".
            string newDocument = projectDirectory + "\\NewDocument.doc";
            oNewWrdDoc = oNewWord.Documents.Open(newDocument);

            // Open Mail Merge Datasource
            oWrdDoc.MailMerge.OpenDataSource(docSource, oMissing, oMissing, oMissing,
               oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);

            // Execute Mail Merge (Opens Completed Mail Merge Documents Titled "Letters1")
            oWrdDoc.MailMerge.Execute();

            // Save the processed Mail Merge Document for Archiving
            // oWord.ActiveDocument.SaveAs2(docTempDir + "FullMailMerge.doc");

            int docCnt = oWord.ActiveDocument.Sections.Count - 1;
            int cnt = 0;
            while (cnt != docCnt)
            {
                cnt++;
                string newFilename = "";

                // Copy Desired Section from Mail Merge
                oWord.ActiveDocument.Sections[cnt].Range.Copy();
                // Set focus to the New Word Doc instance
                oNewWord.Activate();
                // Paste copied range to New Word Doc
                oNewWord.ActiveDocument.Range(0, 0).Paste();

                foreach (ListViewItem lvI in lvData.Items)
                {
                    if (lvI.Checked) // Get first checked lvI in lvData to use for generating filename
                    {
                        updateAddrChngHistory(lvI.SubItems[16].Text);

                        string fileSys = lvI.SubItems[12].Text.ToUpper();
                        string memNo = lvI.SubItems[0].Text;

                        newFilename = fileSys + "%" + memNo + "%" + "" + "%" + "" + "%" + "CORRESPONDENCE%OUTGOING - ACKNOWLEDGEMENT%" + DateTime.Now.ToString("yyyy-MM-dd-hh.mm.ss.ffffff") + ".doc";

                        lvI.Remove(); // Delete from listview the lvI used for newFilename
                        break;        // Break out of foreach loop
                    }
                }

                // Save New Word Doc
                oNewWord.ActiveDocument.SaveAs2(docTempDir + newFilename);
                // Clear New Word Doc
                oNewWord.ActiveDocument.Content.Select();
                oNewWord.Selection.TypeBackspace();
            }
            // Show only the Full Mail Merge Doc. Have user press OK when finished to close documents.
            // Set 'False' in PROD, 'True' in DEV
            // oWord.Visible = false;
            // Hides my new word instance used to save each individual section of the full Mail Merge Doc
            oNewWord.Visible = false;
            MessageBox.Show(new Form() { TopMost = true }, "Click OK when finsihed.");

            oNewWord.ActiveDocument.Close(doNotSaveChanges); // Close the Individual Record Document
            oNewWord.Quit();                                 // Close Word Instance for Individual Record
            oWord.ActiveDocument.Close(doNotSaveChanges);    // Close the Full Mail Merge Document (Currently ALSO closes the Template document)
            oWord.Quit(doNotSaveChanges);                    // Close the Mail Merge Template
            MessageBox.Show("Mail Merge Completed, Individual Documents Saved, Instances Closed.");
        }
        catch (Exception ex)
        {
            LogException(ex);
            MessageBox.Show("Source:\t" + ex.Source + "\nMessage: \t" + ex.Message + "\nData:\t" + ex.Data);
            // Close all Word processes
            Process[] processes = Process.GetProcessesByName("winword");
            foreach (var process in processes)
            {
                process.Close();
            }
        }
        finally
        {

        }
    }

【问题讨论】:

    标签: c# .net winforms interop mailmerge


    【解决方案1】:

    您应该能够使用例如以下 VBA 的等价物来显示/隐藏单个文档:

    oWord.ActiveDocument.Windows(1).Visible = false
    

    (用适当的文档对象代替 ActiveDocument)。

    【讨论】:

    • 谢谢。明天有时间我会试试这个。现在,我最终只是在处理完成后关闭所有文档,然后让一个实例运行以重新打开保存的完整邮件合并以进行显示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多