使用Interop挂起的Excel文件挂起并且不会关闭

时间:2013-09-13 18:43:47

标签: c# asp.net excel excel-vba vba

我在ASP.NET C#中有一个网页,用Microsoft.Office.Interop.Excel类打开一个Excel文件。

excel文件具有在Workbook_BeforeClose事件上运行的VBA代码。 使用Excel打开和关闭文件时,代码运行正常,并在代码运行后提示保存更改。

但是当使用C#在网页上执行相同操作时,该页面只会无限制地加载。调试显示它在myExcelWorkbook.Close(true)行停止(等待?);

这是C#代码的样子:

using Excel = Microsoft.Office.Interop.Excel;
public string getExcelInfo(string value1, string value2, string mapPath)
{
    Excel.Application myExcelApp;
    Excel.Workbooks myExcelWorkbooks;
    Excel.Workbook myExcelWorkbook;
    object misValue = System.Reflection.Missing.Value;    
    myExcelApp = new Excel.Application();
    myExcelWorkbooks = myExcelApp.Workbooks;
    //Copy file to allow simultaneous executions
    Random rnd = new Random();
    int rand = rnd.Next(1000000);
    File.Copy(mapPath+"/App_Data/ConfigAQNX01.xlsm", mapPath+"/App_Data/ConfigAQNX01"+rand.ToString() + ".xlsm");

    //Open file, workbook and sheet
    String fileName = mapPath+"/App_Data/ConfigAQNX01" + rand.ToString() + ".xlsm";
    myExcelWorkbook = myExcelWorkbooks.Open(fileName, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue);
    Excel.Worksheet myExcelWorksheet = (Excel.Worksheet)myExcelWorkbook.ActiveSheet;

    //insert values
    myExcelWorksheet.Cells[3, 2] = value1;
    myExcelWorksheet.Cells[6, 2] = value2;

    //Save so formulaes are executed
    myExcelWorkbook.Save();
    myExcelWorksheet = (Excel.Worksheet)myExcelWorkbook.ActiveSheet;

    //read value in excel

    Excel.Range currentRange = (Excel.Range)myExcelWorksheet.Cells[7, 4];
    string Cost_Cad_Unit = currentRange.Value2.ToString();

    //Close Excel
    GC.Collect();
    GC.WaitForPendingFinalizers();
    Marshal.ReleaseComObject(currentRange);
    Marshal.ReleaseComObject(myExcelWorksheet);

    //Set SaveChange to true on close
    myExcelWorkbook.Close(true);  //This line is where processing takes forever, literraly
    Marshal.ReleaseComObject(myExcelWorkbook);
    Marshal.ReleaseComObject(myExcelWorkbooks);

    myExcelApp.Quit();                                   
    Marshal.ReleaseComObject(myExcelApp);

    currentRange = null;
    myExcelWorksheet = null;
    myExcelWorkbook = null;
    myExcelWorkbooks = null;
    myExcelApp = null;

    return Cost_Cad_Unit; 
}

是否可以设置选项以使VBA代码运行,或者知道是什么使其挂起?或者Microsoft.Office.Interop.Excel是否存在限制以运行Workbook_BeforeClose代码?

谢谢,

1 个答案:

答案 0 :(得分:0)

这是VBA代码:

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Dim FileName, CalcSheet As String
    Dim English As Boolean

    Worksheets("Drawing").Activate
    Worksheets("Drawing OE").Activate
    Worksheets("Interface").Activate

    Worksheets("Parameters").Range("Closing").Formula = "O"
    If Worksheets("Parameters").Range("CreateDrawing").Value = "N" Then Exit Sub

    If Worksheets("Interface").Range("digit_oper").Value = 4 Then
        Sheets(Array("Drawing", "Drawing OE")).Select
    Else
        Sheets(Array("Drawing")).Select
    End If

    Worksheets("Drawing").Activate
    FileName = ActiveSheet.Range("Drawingpdf").Value

    ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=FileName, _
        Quality:=xlQualityStandard, IncludeDocProperties:=False, _
        IgnorePrintAreas:=False, OpenAfterPublish:=False

    Worksheets("Calc").Activate
    FileName = ActiveSheet.Range("Calcpdf").Value

    English = Worksheets("Drawing").Range("English").Value
    If English Then CalcSheet = "Calc EN" Else CalcSheet = "Calc"

    Sheets(Array(CalcSheet)).Select
    Worksheets(CalcSheet).Activate

    ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=FileName, _
        Quality:=xlQualityStandard, IncludeDocProperties:=False, _
        IgnorePrintAreas:=False, OpenAfterPublish:=False

    Worksheets("Parameters").Range("Closing").Formula = "N"
    Worksheets("Interface").Activate

End Sub

我创建了一个新方法GenerateFiles(),将代码从Workbook_BeforeClose移动到此方法并将C#代码更改为:     ...     myExcelWorkbook.Save();     myExcelApp.Run( “GenerateFiles”);     myExcelWorkbook.Close(假);     ... 现在有效。 就好像myExcelWorkbook.Close在Workbook_BeforeClose方法没有“足够快”执行时,使用Workbook_BeforeClose创建一个无限循环......