2012-02-09 60 views
0

我想在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

回答

1

我做了一個這樣的方法,所以把這行代碼擺脫它在按鈕生成和複製下面的新方法,所以你的新代碼應該看起來像這樣

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