第二次打开文件时Excel崩溃

时间:2017-03-14 15:46:42

标签: excel vba excel-vba crash

更新2(17/21/17)

我发现只有在删除模块中的一个(或全部)导入工作表时,才会在点击“提交”按钮后尝试打开Excel工作簿。 (该过程会在重新提交之前删除旧工作表以清除工作簿以重新开始)。对于手动测试,我点击提交按钮,删除任何导入的工作表,然后尝试打开任何 excel文件,然后崩溃。我还确保在删除工作表时删除所有已解散的命名范围。我还在一个只导入空白表的文件上对此进行了测试。然后我删除它,并能够打开工作簿就好了。我想避免创建我的模块(因为它是一种拖累)。

原始问题

我有一个Excel工作簿工具,可以在处理完一些信息后打开其他Excel工作簿并从这些工作簿中导入工作表。

总共有5个模块工作簿。在较高的层次上,这些工作簿是相同的 - 表单结构,通用代码结构等。有不同的公式,一些命名的范围是不同的等等。

在主工具中,可以重新运行从不同工作簿中提取信息的代码。它基本上重置原始工作簿,然后再次运行代码。这是在不关闭原始工作簿的情况下完成的。 (用户可以刷新Web服务数据并重新运行该工具)。

我面临的问题是,当我重新运行两个模块工作簿的过程时,Excel会在重新运行期间崩溃,此时代码会尝试打开模块工作簿。其他3个模块工作簿运行良好。我可以运行并重新运行并重新运行......其他2次每次都会崩溃。

我已经对文件进行了大量研究,看看为什么会发生这种情况,但还没有找到原因。进程运行后,主工作簿中没有任何链接,没有数据连接,没有错误的链接等。

另外,有趣的是我存储在UAT环境文件夹中的文件一直运行良好。生产文件夹中的文件失败。我甚至将文件直接从UAT环境文件夹复制到生产环境文件夹,但仍然失败。我还排除了文件夹级别的权限和安全性。

我也可以在第一次提交代码后手动打开文件。

我意识到这可能略微超出了SO的范围并且有点模糊,但是希望有人可能有类似的经历并且可以解释一些。

更新

相关代码如下。基于@Ralph的评论,我通过添加行Set wbLOB = Nothing强制进行内存擦除,但不幸的是,问题仍然存在。

Function LoadLOB(sLOB As String, sXMLFile As String) As Boolean

Dim sLOBFile As String
sLOBFile = wsReference.Range("ModuleFolder").Value2 & sLOB & "\" & sLOB & ".xlsb"

Dim wbLOB As Workbook
Set wbLOB = Workbooks.Open(sLOBFile) '--> 2nd run crashes on this line.

If TieXMLToExcel(wbLOB, sXMLFile, sLOB) Then

    MapXMLFieldsToExcelCells wbLOB, sLOB

    Select Case sLOB

        Case Is = "Property"
            SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tCommonLocationProperty", "Location_ID"
            SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tLocationByCoverageTypeProperty", "Location_ID"
        Case Is = "GeneralLiability": SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tClassCodesByLocationGeneralLiability", "Location_ID"
        Case Is = "CommercialAuto": SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tVehicleSummaryCommercialAuto", "AuVehicleNo"
        Case Is = "Crime": SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tCommonLocationCrime", "Location_ID"

    End Select

    Application.Run wbLOB.Name & "!PrepareSheetForMasterFile", ThisWorkbook

    wbLOB.Close False

    LoadLOB = True

End If

Set wbLOB = Nothing

End Function

2 个答案:

答案 0 :(得分:2)

我怀疑这是答案,但我认为这是一个更好的论坛,可以交换我在这个问题上的想法。我做的是我抓住了一些Windows API来检查该文件是否打开,然后再尝试打开它。我还添加了一个关闭文件的方法,并使SaveChanges参数更加明确。我还在那里添加了一些DoEvents,以防有些东西等待完成。

希望这是其他想法的起点。我希望其中一些有帮助。

'Determine whether a file is already open or not
#If VBA7 And Win64 Then
    Private Declare PtrSafe Function lOpen Lib "kernel32" Alias "_lopen" (ByVal lpPathName As String, ByVal iReadWrite As Long) As Long
    Private Declare PtrSafe Function lClose Lib "kernel32" Alias "_lclose" (ByVal hFile As Long) As Long
#Else
    Private Declare Function lOpen Lib "kernel32" Alias "_lopen" (ByVal lpPathName As String, ByVal iReadWrite As Long) As Long
    Private Declare Function lClose Lib "kernel32" Alias "_lclose" (ByVal hFile As Long) As Long
#End If

Function LoadLOB(ByVal sLOB As String, _
                 ByVal sXMLFile As String) As Boolean

    Dim sLOBFile As String
    Dim wbLOB    As Workbook
    sLOBFile = wsReference.Range("ModuleFolder").Value2 & sLOB & "\" & sLOB & ".xlsb"

    'Make sure the file is closed before processing
    If Not isFileOpen(sLOBFile) Then
        Set wbLOB = Workbooks.Open(sLOBFile, 0, False)
    Else
        'Close it if it is open
        closeWB sLOBFile
        Set wbLOB = Workbooks.Open(sLOBFile, 0, False)
    End If

    If TieXMLToExcel(wbLOB, sXMLFile, sLOB) Then

        MapXMLFieldsToExcelCells wbLOB, sLOB

        Select Case sLOB

            Case Is = "Property"
                SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tCommonLocationProperty", "Location_ID"
                SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tLocationByCoverageTypeProperty", "Location_ID"
            Case Is = "GeneralLiability": SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tClassCodesByLocationGeneralLiability", "Location_ID"
            Case Is = "CommercialAuto": SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tVehicleSummaryCommercialAuto", "AuVehicleNo"
            Case Is = "Crime": SortTableByAscendingColumn wbLOB, "xml" & sLOB, "tCommonLocationCrime", "Location_ID"

        End Select

        Application.Run wbLOB.Name & "!PrepareSheetForMasterFile", ThisWorkbook
        DoEvents
        wbLOB.Close SaveChanges:=False
        LoadLOB = True
    End If

    Set wbLOB = Nothing
End Function

Sub closeWB(ByVal FilePath As String)
    Dim wb  As Workbook

    For Each wb In Application.Workbooks
        If wb.FullName = FilePath Then
            wb.Close SaveChanges:=False
            Set wb = Nothing
            DoEvents
            Exit For
        End If
    Next

End Sub

Function isFileOpen(ByVal FileName As String) As Boolean
    Dim FileNumb As Long: FileNumb = -1
    Dim lastErr  As Long

    FileNumb = lOpen(FileName, &H10)

    'Determine if we can open the file
    If FileNumb = -1 Then
        lastErr = Err.LastDllError
    Else
        lClose (FileNumb)
    End If

    ' Check if there is a sharing violation and report back status
    isFileOpen = (FileNumb = -1) And (lastErr = 32)
End Function

答案 1 :(得分:1)

不确定这个答案会有多大帮助,但我从头开始重新创建模块文件,它们适用于所有环境。很可能是文件中的一个小腐败,我找不到。