在保存现有的word文档时遇到困难

问题描述:

我想在C#中自动化word文档后,在桌面上保存现有的docx文件。我正在使用窗体来执行我的应用程序。当桌面上没有相同的文件名时,我可以保存文档。但是,当我尝试再次保存相同的文件名时,它会给我这个错误信息:在保存现有的word文档时遇到困难

当文件被另一个进程使用时,您无法保存。尝试使用新名称保存文件 。 (C:\桌面\ TempWord.docx)

我在Microsoft website我能使用另存为,如果有一个现有的文件名读它,它会自动覆盖它。

我不太确定为什么会出现这样的信息,因为当这个程序运行时我没有打开任何其他的word文档。

我不太清楚如何解决这个问题。也许我做了一件很愚蠢的,我没有看到:(


这是我的代码:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Reflection; 
using Microsoft.Office; 
using Word = Microsoft.Office.Interop.Word; 
using System.Runtime.InteropServices; 


namespace TestWordAutoWithTemplate 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void butGenerate_Click(object sender, EventArgs e) 
     { 


      //OBJECT OF MISSING "NULL VALUE" 
      Object oMissing = Missing.Value; 

      //OBJECTS OF FALSE AND TRUE 
      Object oTrue = true; 
      Object oFalse = false; 

      //CREATING OBJECTS OF WORD AND DOCUMENT 
      Word.Application oWord = new Word.Application(); 
      Word.Document oWordDoc = new Word.Document(); 

      //SETTING THE VISIBILITY TO TRUE 
      //oWord.Visible = true; 

      //THE LOCATION OF THE TEMPLATE FILE ON THE MACHINE 
      Object oTemplatePath = @"C:\Documents and Settings\YYC\Desktop\TestTemplate.dotx"; 

      //ADDING A NEW DOCUMENT FROM A TEMPLATE 
      oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing); 
      int iTotalFields = 0; 

      foreach (Word.Field myMergeField in oWordDoc.Fields) 
      { 
       iTotalFields++; 
       Word.Range rngFieldCode = myMergeField.Code; 
       String fieldText = rngFieldCode.Text; 

       // ONLY GETTING THE MAILMERGE FIELDS 
       if (fieldText.StartsWith(" MERGEFIELD")) 
       { 
        // THE TEXT COMES IN THE FORMAT OF 
        // MERGEFIELD MyFieldName \\* MERGEFORMAT 
        // THIS HAS TO BE EDITED TO GET ONLY THE FIELDNAME "MyFieldName" 
        Int32 endMerge = fieldText.IndexOf("\\"); 
        Int32 fieldNameLength = fieldText.Length - endMerge; 
        String fieldName = fieldText.Substring(11, endMerge - 11); 

        // GIVES THE FIELDNAMES AS THE USER HAD ENTERED IN .dot FILE 
        fieldName = fieldName.Trim(); 

        // **** FIELD REPLACEMENT IMPLEMENTATION GOES HERE ****// 
        // THE PROGRAMMER CAN HAVE HIS OWN IMPLEMENTATIONS HERE 
        if (fieldName == "Name") 
        { 
         myMergeField.Select(); 
         //Check whether the control text is empty 
         if (txtName.Text == "") 
         { 
          oWord.Selection.TypeText(" "); 
         } 
         else 
         { 
          oWord.Selection.TypeText(txtName.Text); 
         } 
        } 
        if (fieldName == "Address") 
        { 
         myMergeField.Select(); 
         //Check whether the control text is empty 
         if (txtAddress.Text == "") 
         { 
          oWord.Selection.TypeText(" "); 
         } 
         else 
         { 
          oWord.Selection.TypeText(txtAddress.Text); 
         } 
        } 

        if (fieldName == "Age") 
        { 
         myMergeField.Select(); 
         // check whether the control text is empty 
         if (txtAge.Text == "") 
         { 
          oWord.Selection.TypeText(" "); 
         } 
         else 
         { 
          oWord.Selection.TypeText(txtAge.Text); 
         } 
        } 

        if (fieldName == "EAddress") 
        { 
         myMergeField.Select(); 
         // check whether the control text is empty 
         if (txtEmail.Text == "") 
         { 
          oWord.Selection.TypeText(" "); 
         } 
         else 
         { 
          oWord.Selection.TypeText(txtEmail.Text); 
         } 
        } 

        if (fieldName == "Company") 
        { 
         myMergeField.Select(); 
         // Check whether the control text is empty 
         if (txtCompany.Text == "") 
         { 
          oWord.Selection.TypeText(" "); 
         } 
         else 
         { 
          oWord.Selection.TypeText(txtCompany.Text); 
         } 
        } 

        if (fieldName == "TelNo") 
        { 
         myMergeField.Select(); 
         // Check whether the control text is empty 
         if (txtTelephone.Text == "") 
         { 
          oWord.Selection.TypeText(" "); 
         } 
         else 
         { 
          oWord.Selection.TypeText(txtCompany.Text); 
         } 
        } 

        if (fieldName == "ODetails") 
        { 
         myMergeField.Select(); 
         // Check whether the control text is empty 
         if (txtOther.Text == "") 
         { 
          oWord.Selection.TypeText(" "); 
         } 
         else 
         { 
          oWord.Selection.TypeText(txtOther.Text); 
         } 
        } 

       } 
      } 

      oWord.Visible = false; 

      //Marshal.ReleaseComObject(oWordDoc.Fields); 
      //Marshal.ReleaseComObject(oWordDoc); 
      //Marshal.; 


      // If you want your document to be saved as docx 
      Object savePath = @"C:\Documents and Settings\YYC\Desktop\TempWord.doc"; 
      //oWordDoc.Save(); 
      oWordDoc.SaveAs(ref savePath 
       //, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing, 
       //ref oMissing 
       ); 



      // Close the Word document, but leave the Word application open. 
      // doc has to be cast to type _Document so that it will find the 
      // correct Close method. 
      object doNotSaveChanges = Word.WdSaveOptions.wdDoNotSaveChanges; 
      ((Word._Document)oWordDoc).Close(ref doNotSaveChanges, ref oMissing, ref oMissing); 
      oWordDoc = null; 
      // word has to be case to type _Application so that it will find 
      // the correct Quit method. 
      ((Word._Application)oWord).Quit(ref doNotSaveChanges, ref oMissing, ref oMissing); 
      oWord = null; 
      GC.Collect(); 


     } 
    } 
} 

我也不太清楚,我没有错

编辑:我把原来的代码。

+0

您是否试过只保存? – 2012-02-09 18:23:47

+0

@ 500-InternalServerError是的,但我需要将其保存为文件名。 – yyc2001 2012-02-09 18:24:40

+0

什么是错误消息说...当你通过Microsoft.Office.Interop处置ComObjects时,你需要使用Marshal.ReleaseComObject(oWord)处理它们,例如 – MethodMan 2012-02-09 18:26:07

我做了一个这样的方法,所以把这行代码摆脱它在按钮生成和复制下面的新方法,所以你的新代码应该看起来像这样

private void butGenerate_Click(object sender, EventArgs e) 
{ 
    SaveWordTemp2WordDoc();  
} 

public void SaveWordTemp2WordDoc() 
{ 
    //OBJECT OF MISSING "NULL VALUE" 
    object oMissing = System.Reflection.Missing.Value; 
    //OBJECTS OF FALSE AND TRUE 
    Object oTrue = true; 
    Object oFalse = false; 

    //CREATING OBJECTS OF WORD AND DOCUMENT 
    Word.Application oWord = new Word.Application(); 
    Word.Document oWordDoc = new Word.Document(); 

    //SETTING THE VISIBILITY TO TRUE 
    //oWord.Visible = true; 

    //THE LOCATION OF THE TEMPLATE FILE ON THE MACHINE 
    //Change the path to a path like c:\files\docTemps\ 
    Object oTemplatePath = @"C:\Documents and Settings\YYC\Desktop\TestTemplate.dotx"; 

    //ADDING A NEW DOCUMENT FROM A TEMPLATE 
    oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing); 
    int iTotalFields = 0; 

    foreach (Word.Field myMergeField in oWordDoc.Fields) 
    { 
     iTotalFields++; 
     Word.Range rngFieldCode = myMergeField.Code; 
     String fieldText = rngFieldCode.Text; 

     // ONLY GETTING THE MAILMERGE FIELDS 
     if (fieldText.StartsWith(" MERGEFIELD")) 
     { 
      // THE TEXT COMES IN THE FORMAT OF 
      // MERGEFIELD MyFieldName \\* MERGEFORMAT 
      // THIS HAS TO BE EDITED TO GET ONLY THE FIELDNAME "MyFieldName" 
      Int32 endMerge = fieldText.IndexOf("\\"); 
      Int32 fieldNameLength = fieldText.Length - endMerge; 
      String fieldName = fieldText.Substring(11, endMerge - 11); 

      // GIVES THE FIELDNAMES AS THE USER HAD ENTERED IN .dot FILE 
      fieldName = fieldName.Trim(); 

      // **** FIELD REPLACEMENT IMPLEMENTATION GOES HERE ****// 
      // THE PROGRAMMER CAN HAVE HIS OWN IMPLEMENTATIONS HERE 
      if (fieldName == "Name") 
      { 
       myMergeField.Select(); 
       //Check whether the control text is empty 
       if (txtName.Text == "") 
       { 
        oWord.Selection.TypeText(" "); 
       } 
       else 
       { 
        oWord.Selection.TypeText(txtName.Text); 
       } 
      } 
      if (fieldName == "Address") 
      { 
       myMergeField.Select(); 
       //Check whether the control text is empty 
       if (txtAddress.Text == "") 
       { 
        oWord.Selection.TypeText(" "); 
       } 
       else 
       { 
        oWord.Selection.TypeText(txtAddress.Text); 
       } 
      } 

      if (fieldName == "Age") 
      { 
       myMergeField.Select(); 
       // check whether the control text is empty 
       if (txtAge.Text == "") 
       { 
        oWord.Selection.TypeText(" "); 
       } 
       else 
       { 
        oWord.Selection.TypeText(txtAge.Text); 
       } 
      } 

      if (fieldName == "EAddress") 
      { 
       myMergeField.Select(); 
       // check whether the control text is empty 
       if (txtEmail.Text == "") 
       { 
        oWord.Selection.TypeText(" "); 
       } 
       else 
       { 
        oWord.Selection.TypeText(txtEmail.Text); 
       } 
      } 

      if (fieldName == "Company") 
      { 
       myMergeField.Select(); 
       // Check whether the control text is empty 
       if (txtCompany.Text == "") 
       { 
        oWord.Selection.TypeText(" "); 
       } 
       else 
       { 
        oWord.Selection.TypeText(txtCompany.Text); 
       } 
      } 

      if (fieldName == "TelNo") 
      { 
       myMergeField.Select(); 
       // Check whether the control text is empty 
       if (txtTelephone.Text == "") 
       { 
        oWord.Selection.TypeText(" "); 
       } 
       else 
       { 
        oWord.Selection.TypeText(txtCompany.Text); 
       } 
      } 

      if (fieldName == "ODetails") 
      { 
       myMergeField.Select(); 
       // Check whether the control text is empty 
       if (txtOther.Text == "") 
       { 
        oWord.Selection.TypeText(" "); 
       } 
       else 
       { 
        oWord.Selection.TypeText(txtOther.Text); 
       } 
      } 

     } 
    } 

    oWord.Visible = false; 

    // If you want your document to be saved as docx 
    //Change the file Path here to a path other than your desktop 
    Object savePath = @"C:\Documents and Settings\YYC\Desktop\TempWord.doc"; 
    //oWordDoc.Save(); 
    oWordDoc.SaveAs(ref savePath, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing, 
     ref oMissing 
     ); 

    // Close the Word document, but leave the Word application open. 
    // doc has to be cast to type _Document so that it will find the 
    // correct Close method. 
    object doNotSaveChanges = Word.WdSaveOptions.wdDoNotSaveChanges; 
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oWordDoc); 
    // word has to be case to type _Application so that it will find 
    // the correct Quit method. 
    ((Word._Application)oWord).Quit(ref doNotSaveChanges, ref oMissing, ref oMissing); 
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oWord); 
} 
+0

如果代码没有突破你的ForEach,也许你会想重构foreach到一个for循环,并有一个循环设置计数 MethodMan 2012-02-10 14:20:23

+0

Oups我忘记取消注释,我把它放在.SaveAs代码中。我正在测试以查看错误是否出现在.SaveAs – yyc2001 2012-02-14 21:53:07

+0

问题已解决..? – MethodMan 2012-02-14 22:02:01