![](/img/trans.png)
[英]Why does VBA Workbook.Close Statement Fail Inside Workbook_BeforeClose, If Close is Triggered Programmatically?
[英]Why does Workbook.Close trigger the UserForm_Terminate? - VBA
以下代碼存在一些問題,這讓我很生氣。 當Excel Workbook
自動關閉時,我似乎無法找到代碼突然結束的原因。
代碼從Excel工作簿執行,其工作方式如下:
以下全部代碼:
Public WbLOP As Workbook, WsLop As Worksheet
Public AbtToEval As String
Sub Std_Ausw()
Dim OpenDialog As Object, FileName As String
Dim Ws As Worksheet
Dim Termin As Date
Dim TargetWb As Workbook, TargetWs As Worksheet
Dim i As Integer, j As Integer, k As Integer, w As Integer
Dim ZielCol As Integer, ZielNEWCol As Integer, PEPStatusCol As Integer, StatusAICol As Integer
Dim ActivityRow As Integer
' Asks user input file to read from
Set OpenDialog = Application.FileDialog(msoFileDialogFilePicker)
With OpenDialog
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "Excel Files", "*.xls, *.xlsx, *.xlsm"
If .Show Then
FileName = .SelectedItems(1)
Else
Set OpenDialog = Nothing
Exit Sub
End If
End With
Set OpenDialog = Nothing
' Checks if the worksheet "LOP" is contained in the file
Set WbLOP = Application.Workbooks.Open(FileName)
For Each Ws In WbLOP.Worksheets
If UCase(Ws.Name) = "LOP" Then
Set WsLop = Ws
Exit For
End If
Next
On Error Resume Next
If WsLop.Name = "" Then
WbLOP.Close savechanges:=False
Set WbLOP = Nothing
MsgBox "Fail"
Exit Sub
End If
On Error GoTo 0
' Shows a Userform to let user decide the name of the AbtToEval
Ausw.Show
我在這里粘貼UserForm的代碼:
Private Sub Cancel_Click()
End
End Sub
Private Sub UserForm_Terminate()
End
End Sub
Private Sub UserForm_Initialize()
Dim Abt() As String
Dim i As Integer, j As Integer, k As Integer
' Searches for the PD-Abt column
i = 1
Do Until LCase(WsLop.Cells(8, i)) = "pd-abt"
i = i + 1
Loop
' Copies the unique Abt in an array
j = 10
ReDim Abt(0)
Abt(0) = UCase(WsLop.Cells(j, i))
Do Until IsEmpty(WsLop.Cells(j, 1))
For k = 0 To UBound(Abt)
If Abt(k) = UCase(WsLop.Cells(j, i)) Then
Exit For
Else
If k = UBound(Abt) Then
ReDim Preserve Abt(UBound(Abt) + 1)
Abt(UBound(Abt)) = UCase(WsLop.Cells(j, i))
End If
End If
Next
j = j + 1
Loop
' Initializes the combo-box with the Abt names
For i = 0 To UBound(Abt)
Me.AbtBox.AddItem Abt(i)
Next
Me.AbtBox.ListIndex = 0
End Sub
Private Sub OK_Click()
AbtToEval = Me.AbtBox.List(Me.AbtBox.ListIndex)
Me.Hide
End Sub
這里主要的Sub恢復了
' Opens a new workbook and copies the table from the template
Application.DisplayAlerts = False
Set TargetWb = Application.Workbooks.Add
Do Until TargetWb.Sheets.Count = 1
TargetWb.Sheets(TargetWb.Sheets.Count).Delete
Loop
Set TargetWs = TargetWb.Sheets(1)
ThisWorkbook.Worksheets("Template").Range("A1:J3").Copy Destination:=TargetWs.Range("A1")
Application.DisplayAlerts = True
TargetWs.Range("A2") = AbtToEval
' Sets a standard limit of 4 weeks from today
Termin = DateAdd("ww", 4, Date)
' Searches for the Ziel-Datum columns
i = 1
Do Until InStr(1, LCase(WsLop.Cells(8, i)), "ziel-datum") <> 0
i = i + 1
Loop
If InStr(1, LCase(WsLop.Cells(8, i)), "neu") <> 0 Then
ZielNEWCol = i
i = i + 1
Do Until InStr(1, LCase(WsLop.Cells(8, i)), "ziel-datum") <> 0
i = i + 1
Loop
ZielCol = i
Else
ZielCol = i
i = i + 1
Do Until InStr(1, LCase(WsLop.Cells(8, i)), "ziel-datum") <> 0
i = i + 1
Loop
ZielNEWCol = i
End If
' Searches for the status columns
i = 1
Do Until InStr(1, LCase(WsLop.Cells(8, i)), "pep status") <> 0
i = i + 1
Loop
PEPStatusCol = i
i = 1
Do Until InStr(1, LCase(WsLop.Cells(8, i)), "status ai") <> 0
i = i + 1
Loop
StatusAICol = i
' Searches for the activities to do
i = 0
j = 0
Do Until IsEmpty(WsLop.Cells(9 + i, 1))
If Not WsLop.Cells(9 + i, PEPStatusCol) = "akt" Then GoTo Go_Forth
If WsLop.Cells(9 + i, StatusAICol) = "ges" Then GoTo Go_Forth
If IsEmpty(WsLop.Cells(9 + i, ZielNEWCol)) Then
If CDate(WsLop.Cells(9 + i, ZielCol)) > Termin Then
GoTo Go_Forth
Else
ActivityRow = 9 + i
End If
Else
If CDate(WsLop.Cells(9 + i, ZielNEWCol)) > Termin Then
GoTo Go_Forth
Else
ActivityRow = 9 + i
End If
End If
ThisWorkbook.Worksheets("Template").Range("A4:J4").Copy Destination:=TargetWs.Cells(4 + j, 1)
For w = 1 To 10
k = 1
Do Until TargetWs.Cells(3, w) = WsLop.Cells(8, k)
k = k + 1
Loop
TargetWs.Cells(4 + j, w) = WsLop.Cells(ActivityRow, k)
Next
j = j + 1
Go_Forth:
i = i + 1
Loop
' If TargetSheet is empty then shows only a message
If IsEmpty(TargetWs.Cells(4, 1)) Then
Application.DisplayAlerts = False
TargetWb.Close savechanges:=False
Application.DisplayAlerts = True
MsgBox "We have no bananas before " & Format(Termin, "dd.mm.yyyy") & " for the " & AbtToEval & "!", vbInformation, AbtToEval & " out of bananas"
Else
' If the activity is in the past, it is marked in red
i = 4
Do Until IsEmpty(TargetWs.Cells(i, 1))
If IsEmpty(TargetWs.Cells(i, 2)) Then
If CDate(TargetWs.Cells(i, 1)) <= Date Then TargetWs.Range(Cells(i, 1).Address(0, 0), Cells(i, 10).Address(0, 0)).Font.ColorIndex = 3
Else
If CDate(TargetWs.Cells(i, 2)) <= Date Then TargetWs.Range(Cells(i, 1).Address(0, 0), Cells(i, 10).Address(0, 0)).Font.ColorIndex = 3
End If
i = i + 1
Loop
' Fixes the visual and adds filters
TargetWs.Range("A4").Select
ActiveWindow.FreezePanes = True
TargetWs.Range("A3:J3").AutoFilter
TargetWs.Cells.EntireColumn.AutoFit
End If
' Ending
Set TargetWs = Nothing
Set TargetWb = Nothing
Set WsLop = Nothing
WbLOP.Close savechanges:=False
Set WbLOP = Nothing
End Sub
我設法在UserForm_Terminate
事件中找到一個解決方法, if WbLOP Is Nothing Then End
,正如一些評論/答案中所指出的那樣,是由Workbook.Close
事件觸發的,但顯然我執行了關閉TargetWb
的代碼, 什么都沒發生。
該事件基本上與WbLOP.Close
相關聯,我仍然不明白為什么。
由於您尚未發布完整代碼 - 在調試模式下運行代碼。 在要仔細查看正在發生的事情的位置添加斷點。 使用F5運行(它將在下一個斷點處停止或運行直到結束)和F8用於步進模式(移至下一行)。 使用監視表來檢查變量或整個IF contiodions的值,以確定代碼何時應該分支或執行特定的操作。
調試模式:
在這種情況下,它有可能像過去的問題嗎?
根據MSDN :
卸載對象時會觸發Terminate事件。 第一個工作簿關閉工作正常,因為表單尚未加載。 如果表單是執行工作簿關閉時該工作簿的對象,則卸載表單並觸發UserForm_Terminate,從而導致END - 代碼停止執行。
顯然,這將在每個表格的封閉上執行(甚至隱藏它)
Private Sub userform_terminate()
'Code
End Sub
您應該使用它來檢測用戶何時通過x按鈕關閉它:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then ' =0 or = vbFormControlMenu
'Code
End If
End Sub
然后它將僅在用戶關閉表單時執行,但不在表單卸載時執行,因此將userform_terminate
替換為上述替代方案,它應該可以正常工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.