我在做导入导出的时候,导入导出完毕以后总是有一个Excel在后台运行。开始我以为是没执行Quit指令。但现在调试的结果发现还有可能是 Excel退出的过程中产生的一个无响应的Excel进程,阻塞系统的其他程序的运行。
    我在win98,office2000下,我把导入的Excel设置为可见,程序不关闭Excel,手工关闭Excel程序。在手工关闭Excel之间,按下Ctrl+Alt+Del,发现并没有excel在后台运行。关闭Excel以后,按下Ctrl+Alt+Del,却发现有一个Excel进程在后台运行。
并且如果不强行把这个excel进程关闭,会阻塞其他程序的运行。
    我调试的结果:
   1)只有部分的Excel文件导入以后会留下阻塞其他程序运行的Excel进程。
   2)暂时来说,用Excel程序建立的excel文档,每次导入都正常。但我的导出模块导出的程Excel文档,再导入,导入完毕以后就会留下一个阻塞其他程序运行的excel进程。
   3) 单步调试时,quit一定是执行了。把打开的Excel设置为可视,程序不关闭excel,手工关闭Excel,我的程序已经完全退出,手工关闭前按Ctrl+Alt+Del没有Excel进程在运行。但是手工退出Excel后, 按Ctrl+Alt+Del才发现时多了一个Excel进程。
    请教大家了,这是为什么会这样? 
    另外是不是我导出时,创建的Excel文件文件不对。导致他每次退出时,到无法正常退出。

解决方案 »

  1.   

    是用的CreateOleObject吗?不是的话最好用CreateOleObject,是的话在最后执行ExcelApp:=varNull。
      

  2.   

    错了,还以为是在Delphi中呢,是 Set ExcelApp=Nothing
      

  3.   

    你的程序调用excel时,没有自动关闭它。要关闭它并set it = nothing
      

  4.   

    我的到出、导入代码:'***********************************************************************************
    '*函数名称:Pf_FlexExport
    '*说明:把表的数据导出到Excel中
    '*参数说明:flexgrid,要导出的Excel表;LastCol,截至到的列,如果小于0或大于总的列数,使用默认的表的列数
    'LastRow,截至到的行,如果小于0或大于总的行数,使用默认的表的行数
    '***********************************************************************************
    Public Function Pf_FlexExport(flexgrid As MSHFlexGrid, Optional LastCol As Long = -1, _
                                  Optional LastRow As Long = -1)
    '数据输出到Excel
    Dim xlApp           As Excel.Application
    Dim xlBook          As Excel.Workbook
    Dim xlSheet         As Excel.Worksheet
    '进度条窗口
    Dim frm_ProGress    As New Frm_OthProgressBar
    '行数和列数
    Dim sv_FlexRow      As Long
    Dim sv_flexCol      As Long
    '调试变量
    Dim t1 As Long, T2 As Long
        Screen.MousePointer = vbHourglass
        On Error GoTo err_proc
        Set xlApp = New Excel.Application                     'CreateObject("Excel.Application")
        Set xlBook = xlApp.Workbooks.Add
        Set xlSheet = xlBook.Worksheets(1)
        
        '设置行数和列数
         If LastCol < 0 Or LastCol >= flexgrid.Cols Then
            sv_flexCol = flexgrid.Cols - 1
         Else
            sv_flexCol = LastCol
         End If
         
         If LastRow < 0 Or LastRow >= flexgrid.Rows Then
            sv_FlexRow = flexgrid.Rows - 1
         Else
            sv_FlexRow = LastRow
         End If
        '开始充入数据
        Dim i As Long
        Dim j As Integer
        On Error Resume Next
        frm_ProGress.Show
        frm_ProGress.ProgrValue = 0
        
        t1 = GetTickCount
        On Error Resume Next
        With flexgrid
            '设置列宽
            For j = 0 To sv_flexCol
                xlSheet.Columns(j + 1).ColumnWidth = .ColWidth(j) / UNIT / 2.5
            Next j
            For i = 0 To sv_FlexRow
                For j = 0 To sv_flexCol
                    If j + 1 Then
                        '设置单元格格式为字符
                        xlSheet.Cells(i + 1, j + 1).NumberFormat = "@"
                    End If
                    xlSheet.Cells(i + 1, j + 1).value = .TextMatrix(i, j)
    '                xlSheet.Cells(i + 1, j + 1).ColorIndex = 34
                Next j
                '改变背景颜色
                If Pr_SetZCColor = True Then
                    If Len(.TextMatrix(i, Pr_ZCCodeNum)) < numlevel(5) Then
                        xlSheet.Rows(CStr(i + 1) & ":" & CStr(i + 1)).Select
                        Selection.Interior.ColorIndex = 34
    '                   Selection.Interior.Pattern = xlSolid
                    End If
                End If
                frm_ProGress.ProgrValue = i / sv_FlexRow * 100
            Next i
         End With
        
         xlApp.Visible = True
         'xlApp.Quit
         'xlBook.Saved = True
         'xlBook.Close
         'xlApp.Quit
         Screen.MousePointer = vbDefault
         Set xlApp = Nothing
         Set xlBook = Nothing
         Set xlSheet = Nothing
         
         Unload frm_ProGress
         Set frm_ProGress = Nothing
         Exit Function
    err_proc:
    On Error Resume Next
        Screen.MousePointer = vbDefault
        
        MsgBox Err.Description
        If Not (xlApp Is Nothing) Then
            xlApp.Quit
            Set xlApp = Nothing
        End If
        If Not (frm_ProGress Is Nothing) Then
            Unload frm_ProGress
            Set frm_ProGress = Nothing
        End If
    End Function导出的代码:
    Public Sub ExcelImPort(Flex As MSHFlexGrid, fv_FileName As String, Optional fv_fixRow As Integer = 1,  Optional fv_Fixcol As Integer = 0, Optional fv_beginCol As Long = 0)
    On Error GoTo Err:
    'Excel对象
    Dim xlApp           As Excel.Application
    Dim xlBook          As Excel.Workbook
    Dim xlSheet         As Excel.Worksheet
    Dim sv_rng          As Range                 '获得excel对象的范围,返回Excel的行数和列数
    '进度条对象
    Dim frm_Prog        As New Frm_OthProgressBar'Excel的行数和列数
    Dim Ex_rows         As Long
    Dim Ex_Cols         As Long
    Dim sv_ExBeginRow   As Integer     '从excel表的哪一个列开始读取数据
    '设置Flex表的导入的行数和列数
    Dim FlexRows        As Long
    Dim flexcols        As Long
    'Flex表总共有的列数,注意:Flex表总共有的列数<>要导出的列数
    Dim EndCols         As Long
    '循环变量
    Dim i_row           As Long          'Excel行的循环变量
    Dim j_col           As Long
    Dim sv_ContiI_Row   As Boolean        '执行下一个循环变量的I_Row
    Dim sv_ContiJ_Col   As Boolean        '执行下一个循环变量的J_Col
    Dim i_flexRow      As Long           'Grid行的循环变量On Error GoTo OpenErr:
        '初始化对象
        Set xlApp = CreateObject("Excel.Application")
        'Set xlApp = New Excel.Application
        Set xlBook = xlApp.Workbooks.Open(fv_FileName)
        Set xlSheet = xlBook.Worksheets(1)
        '设置鼠标和Flex的刷新
    On Error GoTo Err:
        Screen.MousePointer = vbHourglass
        Flex.Redraw = False    '显示进度条
        frm_Prog.Show
        frm_Prog.ProgrValue = 0
        '返回Excel的行数和列数
        Set sv_rng = xlSheet.UsedRange
        Ex_rows = sv_rng.Rows.Count     '从1-Excel的最末行的名称
        Ex_Cols = sv_rng.Columns.Count    '当Excel表中有596行时,返回595行
        
        Flex.Rows = Ex_rows + fv_fixRow
        FlexRows = Flex.Rows - 1
        '如果限定导出的列数,取限定的列数和总列数之间的最小值
          flexcols = Flex.Cols - 1
         
        '限定的列数和Excel表具有的列数进行比较,取最小值
        flexcols = min(flexcols + 1, Ex_Cols)     '因为Excel表中所在的列比Flex表中大1,在循环的时候,Flex的列数是flexcols-1
        'flex表总的列数
        EndCols = Flex.Cols - 1
        
        'flexGrid开始导入的行
        i_flexRow = fv_fixRow
        '开始导入
        For i_row = 1 To FlexRows             'flex的第0行作为固定行
            For j_col = 1 To flexcols
                    Flex.TextMatrix(i_flexRow, j_col - 1) = xlSheet.Cells(i_row, j_col)   'excel是从1开始算的,
                                                                                                    'flexgrid从0开始算,循环变量是从0开始算,所以flexGrid的Col要减1
                Next
                For j_col = flexcols + 1 To EndCols + 1                Flex.TextMatrix(i_row, j_col - 1) = "" 
                Next
                '提示窗口的进度条
                frm_Prog.ProgrValue = i_flexRow / FlexRows * 100
                'FlexGrid的列的变量
                i_flexRow = i_flexRow + 1
           Next
        Unload frm_Prog
        
        'xlApp.Quit
        xlApp.ActiveWorkbook.Save
        If Not xlSheet Is Nothing Then
            Set xlSheet = Nothing
        End If
        
        If Not xlBook Is Nothing Then
            xlBook.Close
            Set xlBook = Nothing
        End If
        If Not xlApp Is Nothing Then
            xlApp.Quit   
            Set xlApp = Nothing
        End If
        
        Screen.MousePointer = vbDefault
        Flex.Redraw = TrueExit Sub
    OpenErr:
        MsgBox err.Description 
        Screen.MousePointer = vbDefault
        Exit Sub
    Err:
        MsgBox err.Description 
        Resume Next
        Flex.Redraw = True
        Screen.MousePointer = vbDefault
    End Sub
      

  5.   

    Quit和Set ExcelApp=Nothing都执行了!
      

  6.   

    你最好把那句on Error resume next先注释掉,看看哪一句会出错。代码中是执行了Quit和Set ExcelApp=Nothing。但当出错的时候,它未必会执行到。可以使用逐句调试。
      

  7.   

    我是说那个on Error goto----
      

  8.   

    看来看去,问题 可能出在Unload frm_Prog那一句,应将它放置最后即那个exit sub之前。你把窗体都卸载了,代码又是在什么地方执行的呢?
      

  9.   

    http://support.microsoft.com/default.aspx?scid=kb;EN-US;247412
      

  10.   

    Transferring data cell by cell can be a perfectly acceptable approach if the amount of data is small. You have the flexibility to place data anywhere in the workbook and can format the cells conditionally at run time. However, this approach is not recommended if you have a large amount of data to transfer to an Excel workbook. Each Range object that you acquire at run time results in an interface request so that transferring data in this manner can be slow. Additionally, Microsoft Windows 95 and Windows 98 have a 64K limitation on interface requests. If you reach or exceed this 64k limit on interface requests, the Automation server (Excel) might stop responding or you might receive errors indicating low memory.
      

  11.   

    我也编过Excel后台程序,没有这样的问题啊。
    有一点要提醒一下。你一定要用循环把所有文档关闭了,再:
    N.Quit
    Set N=Nothing
    就可以了