【问题标题】:Subroutine unexpectedly ends when a Workbook is closed关闭工作簿时子例程意外结束
【发布时间】:2014-11-05 14:28:55
【问题描述】:

我今天的问题是子例程的一部分,当Workbook 关闭时,它莫名其妙地中断了它的执行。
我写了以下代码:

Public Const Pi As Double = 3.14159265358979
Public Const Rad As Double = Pi / 180 
Public CalcBook As Workbook
Public FilePath As String, Files() As String
Public FreqArray() As Integer

Sub Main()

Dim ChooseFolder As Object, FilePath As String, StrFile As String
Dim i As Integer, j As Integer, k As Integer, x As Integer
Dim DirNum As Integer, HNum As Integer, VNum As Integer
Dim DirColShift As Integer, HColShift As Integer, VColShift As Integer
Dim TheStart As Date, TheEnd As Date, TotalTime As Date

Set ChooseFolder = Application.FileDialog(msoFileDialogFolderPicker)

With ChooseFolder
    .AllowMultiSelect = False
    .Title = "Please choose a folder containing .txt files"
    If .Show = -1 Then
        FilePath = .SelectedItems(1) & "\"
    Else
        Set ChooseFolder = Nothing
        Exit Sub
    End If
End With
Set ChooseFolder = Nothing

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.DisplayStatusBar = False

' Stores only files containing an AntennaName + "_T" + any number of characters + "_?_?45.xls" string
' (where "?" is a single character and "*" is any number). Checks if the number of files is correct too.

StrFile = Dir(FilePath & "*_T*_?_?45.txt")
Do While Len(StrFile) > 0
    ReDim Preserve Files(i)
    Files(i) = FilePath & StrFile
    i = i + 1
    StrFile = Dir
Loop


If Not (UBound(Files) + 1) / 6 = Int((UBound(Files) + 1) / 6) Then GoTo FileError
For i = 0 To UBound(Files)
    Select Case Right(Files(i), 9)
    Case "D_+45.txt", "D_-45.txt"
        DirNum = DirNum + 1
    Case "H_+45.txt", "H_-45.txt"
        HNum = HNum + 1
    Case "V_+45.txt", "V_-45.txt"
        VNum = VNum + 1
    End Select
Next
If Not (DirNum / 2 = Int(DirNum / 2) And HNum / 2 = Int(HNum / 2) And VNum / 2 = Int(VNum / 2) And DirNum = HNum And HNum = VNum) Then
FileError:
    MsgBox "Failed to properly load files. Looks like a wrong number of them is at dispose", vbCritical, "Check the import-files"
    Exit Sub
End If

' Imports files in Excel for better data access

Set CalcBook = Application.Workbooks.Add

' FROM HERE ON THE DATA IS PROCESSED IN ORDER TO OBTAIN AN EXCEL WORKBOOK WITH 3 SHEETS CALLED "Directivity", "Horizontal" and "Vertical".

Application.ScreenUpdating = True
Options.Show

TheStart = Now

Application.ScreenUpdating = False
If Options.OnlyEval = False Then PolarCharts
If Options.OnlyCharts = False Then Auswertung
Application.DisplayAlerts = False
CalcBook.Close savechanges:=False
Application.DisplayAlerts = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Set CalcBook = Nothing

TheEnd = Now
TotalTime = TheEnd - TheStart
MsgBox Format(TotalTime, "HH:MM:SS"), vbInformation, "Computing Time"

Unload Options

End Sub

Options 是访问PolarChartsAuswertung 的数据所需的表单。这些 Subs 被正确执行(我知道因为它们保存的数据也是正确的)。

我尝试删除 .ScreenUpdating.DisplayAlerts 命令,以及 Unload 认为它们可能会窃听某些东西,但结果并没有改变。

还要知道我要关闭的工作簿根本不包含任何代码(没有其他任何内容涉及“.Close”,因此不可能在 .Close 事件上执行某些操作)。

在我的“选项”代码下方:

Private Sub Cancel_Click()
    End
End Sub

Private Sub UserForm_Terminate()
    End
End Sub

Private Sub Ok_Click()

    If Me.OnlyCharts = False Then

        ReDim SubFreq(4)

        If Not (Me.Start1.ListIndex = -1 And Me.Stop1.ListIndex = -1) Then SubFreq(0) = Me.Start1.List(Me.Start1.ListIndex) & "-" & Me.Stop1.List(Me.Stop1.ListIndex)
        If Not (Me.Start2.ListIndex = -1 And Me.Stop2.ListIndex = -1) Then SubFreq(1) = Me.Start2.List(Me.Start2.ListIndex) & "-" & Me.Stop2.List(Me.Stop2.ListIndex)
        If Not (Me.Start3.ListIndex = -1 And Me.Stop3.ListIndex = -1) Then SubFreq(2) = Me.Start3.List(Me.Start3.ListIndex) & "-" & Me.Stop3.List(Me.Stop3.ListIndex)
        If Not (Me.Start4.ListIndex = -1 And Me.Stop4.ListIndex = -1) Then SubFreq(3) = Me.Start4.List(Me.Start4.ListIndex) & "-" & Me.Stop4.List(Me.Stop4.ListIndex)
        If Not (Me.Start5.ListIndex = -1 And Me.Stop5.ListIndex = -1) Then SubFreq(4) = Me.Start5.List(Me.Start5.ListIndex) & "-" & Me.Stop5.List(Me.Stop5.ListIndex)

        If (Me.Start1 = "" And Me.Start2 = "" And Me.Start3 = "" And Me.Start4 = "" And Me.Start5 = "" And Me.Stop1 = "" And Me.Stop2 = "" And Me.Stop3 = "" And Me.Stop4 = "" And Me.Stop5 = "") _
        Or Me.Start1.Value > Me.Stop1.Value Or Me.Start2.Value > Me.Stop2.Value Or Me.Start3.Value > Me.Stop3.Value Or Me.Start4.Value > Me.Stop4.Value Or Me.Start5.Value > Me.Stop5.Value _
        Or (Me.Start1.ListIndex = -1 And Me.Stop1.ListIndex >= 0) Or (Me.Start2.ListIndex = -1 And Me.Stop2.ListIndex >= 0) Or (Me.Start3.ListIndex = -1 And Me.Stop3.ListIndex >= 0) Or (Me.Start4.ListIndex = -1 And Me.Stop4.ListIndex >= 0) Or (Me.Start5.ListIndex = -1 And Me.Stop5.ListIndex >= 0) _
        Or (Me.Start1.ListIndex >= 0 And Me.Stop1.ListIndex = -1) Or (Me.Start2.ListIndex >= 0 And Me.Stop2.ListIndex = -1) Or (Me.Start3.ListIndex >= 0 And Me.Stop3.ListIndex = -1) Or (Me.Start4.ListIndex >= 0 And Me.Stop4.ListIndex = -1) Or (Me.Start5.ListIndex >= 0 And Me.Stop5.ListIndex = -1) Then
            MsgBox("Please select correctly the frequency ranges - Maybe Start > Stop, one of those was not properly inserted, or the fields are blank", vbExclamation, "Frequency choice error")
            GoTo hell
        End If

        For i = 0 To 4
            If Not SubFreq(i) = "" Then j = j + 1
        Next i
        j = j - 1
        ReDim Preserve SubFreq(j)

    End If

    Me.Hide

hell:
End Sub

Private Sub UserForm_Initialize()

Dim i As Byte

    Me.StartMeas = Date
    Me.StopMeas = Date

    Me.Worker.AddItem "lol"
    Me.Worker.AddItem "rofl"
    Me.Worker.ListIndex = 0

    For i = LBound(FreqArray) To UBound(FreqArray)
        Me.Start1.AddItem FreqArray(i)
        Me.Start2.AddItem FreqArray(i)
        Me.Start3.AddItem FreqArray(i)
        Me.Start4.AddItem FreqArray(i)
        Me.Start5.AddItem FreqArray(i)
        Me.Stop1.AddItem FreqArray(i)
        Me.Stop2.AddItem FreqArray(i)
        Me.Stop3.AddItem FreqArray(i)
        Me.Stop4.AddItem FreqArray(i)
        Me.Stop5.AddItem FreqArray(i)
    Next i

    Me.Start1.ListIndex = 0
    Me.Stop1.ListIndex = Me.Stop1.ListCount - 1

End Sub

显然,当我Close CalcBook 时,它会从 Ends 所有代码的选项中触发 UserForm_Terminate 事件!我该如何避免这种情况?

【问题讨论】:

    标签: vba excel subroutine userform


    【解决方案1】:

    只需删除语句End,因为End 会导致代码执行突然结束。

    我在CancelTerminate 事件处理程序中看到了End如果你在其他地方有它,请删除它

    如果您需要退出某个方法,请使用Exit Sub

    为什么:因为End 就是这样工作的。阅读例如这篇文章:http://www.vbforums.com/showthread.php?511766-Classic-VB-Why-is-using-the-End-statement-(or-VB-s-quot-stop-quot-button)-a-bad-idea

    如果您需要停止执行代码,请使用If-condition 甚至Exit Sub,但避免使用End

    【讨论】:

    • 唯一的事情是:如果“选项”处理 Cancel_Click 或 UserForm_Terminate,我无法阻止“Main”执行。问题本身出在 UserForm_Terminate 中,因为当我关闭而不保存工作簿时,会调用“UserForm_Terminate”(我不知道为什么)。如果单击用户窗体上的 X,我确实需要结束所有代码
    • 在您发布的代码中,我在“主要”中没有看到任何“停止”?并且在处理程序“单击”和“终止”中没有代码“结束”或?当您调用“卸载选项”时,应调用“终止”。我没有看到“CalcBook”和“Options”表单之间有任何关系,或者有任何关系。所以我也很困惑。
    • 不知何故代码永远不会到达Unload Options,有趣的是CalcBook中绝对没有代码!所以 on 事件卸载触发器不可能是错误
    • @Noldor130884,向Options 添加一个名为Result 的公共变量。如果Options 被取消,则让Result = False 否则将其设置为True。检查MainResult 的值是否已取消。那你就不需要End了。
    【解决方案2】:

    试试

    Workbooks("CalcBook").Close savechanges:=False
    

    我怀疑屏幕上的错误警报和错误指示都被抑制了

    【讨论】:

    • 无法工作:没有名称为“CalcBook”的工作簿。我之前将 Calcbook 设置为特定的新工作簿。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 2022-01-04
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多