Private cancel As Boolean
Public Function ShowDatesDialog(startDate As Date, endDate As Date, timeInterval As String) As Boolean
Call Initialize
Me.Show
If Not cancel Then
startDate = calStartDate.Value
endDate = calEndDate.Value
Select Case True
Case optMonth: timeInterval = "m"
Case optWeek: timeInterval = "w"
Case optDay: timeInterval = "d"
End Select
End If
ShowDatesDialog = Not cancel
Unload Me
End Function
Private Sub Initialize()
calStartDate.Value = DateSerial(Year(Date) - 2, Month(Date), Day(Date))
calEndDate.Value = Date
optMonth.Value = True
End Sub
Private Function Valid() As Boolean
Dim startDate As Date, endDate As Date
Valid = True
startDate = calStartDate.Value
endDate = calEndDate.Value
If startDate >= endDate Then
Valid = False
MsgBox "The starting date should be before the ending date.", _
vbInformation, "Invalid dates"
calStartDate.SetFocus
Exit Function
ElseIf startDate < EARLIST_DATE Then
Valid = False
MsgBox " The starting date shouldn't be before 1990.", _
vbInformation, "Start date too early"
calStartDate.SetFocus
Exit Function
ElseIf endDate > Date Then
Valid = False
masgbox " The ending date shouldn't be after today's date.", _
vbInformation, "end date too late"
calEndDate.SetFocus
Exit Function
End If
End Function
Private Sub btnOK_Click()
If Valid Then Me.Hide
cancel = False
End Sub
Private Sub btnCancel_Click()
Me.Hide
cancel = True
End Sub
Private Sub UserForm_QueryClose(cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then btnCancel_Click
End Sub
回答
很多。
Initialize
和btnCancel_Click
是事件處理程序:不應該明確調用它們。他們的目的是爲了處理事件。
你是在正確的道路上,雖然 - 我看你真的已經很努力避免使用默認實例...但我懷疑你的調用代碼看起來是這樣的:
MyAwesomeForm.ShowDatesDialog startDate, endDate, timeInterval
,對嗎?
那麼這ShowDatesDialog
運行關閉窗體的默認實例,這意味着這樣的:
Me.Show
顯示的默認實例。
一個表格不應該爲自己摧毀負責(因爲它不是自己創建的) - 你做得很好Me.Hide
,但Unload Me
然後擊敗了它,因爲它使對象自毀,這意味着調用者可以永遠不要抓住對象:它們顯示形式,然後消失,並且在對象做任何事情之前對象已經消失。
表格不應該負責顯示本身:這也是來電者的工作。
揭露封裝cancel
場爲只讀屬性,並將其重命名爲cancelled
,使其不與QuerClose
處理程序的參數衝突:
Private cancelled As Boolean
Public Property Get IsCancelled() As Boolean
IsCancelled = cancelled
End Property
暴露你模型爲屬性太:
Public Property Get StartingDate() As Date
StartingDate = calStartDate.Value
End Property
Public Property Get EndingDate() As Date
EndingDate = calEndDate.Value
End Property
Public Property Get TimeInterval() As String
Select Case True
Case optMonth.Value
TimeInterval = "m"
Case optWeek.Value
TimeInterval = "w"
Case optDay.Value
TimeInterval = "d"
Case Else
TimeInterval = vbNullString
End Select
End Property
現在你的來電可以做到這一點 - 基本上你ShowDatesDialog
功能變爲調用代碼:
With New MyAwesomeForm
.Show
If Not .IsCancelled Then
Dim startDate As Date
startDate = .StartingDate
Dim endDate As Date
endDate = .EndingDate
Dim interval As String
interval = .TimeInterval
End If
End With
Valid
函數應該是一個動詞,例如, Validate
或開始帶有動詞,例如, IsValid
;因爲該功能有副作用,我更傾向於命名它Validate
而不是IsValid
,但YMMV。其壓痕嚴重需要一些愛,雖然:
If startDate >= endDate Then
Valid = False
MsgBox "The starting date should be before the ending date.", _
vbInformation, "Invalid dates"
calStartDate.SetFocus
Exit Function
ElseIf startDate < EARLIST_DATE Then
Valid = False
MsgBox " The starting date shouldn't be before 1990.", _
vbInformation, "Start date too early"
calStartDate.SetFocus
Exit Function
ElseIf endDate > Date Then
Valid = False
masgbox " The ending date shouldn't be after today's date.", _
vbInformation, "end date too late"
calEndDate.SetFocus
Exit Function
End If
注意,如果VBA讓您無需在編譯時抱怨運行這段代碼,那麼你需要在模塊的頂部指定Option Explicit
(應該是在頂部的每模塊),因爲這不可能編譯:
masgbox " The ending date shouldn't be after today's date.", _ vbInformation, "end date too late"
除非你有地方規定,當然,一個masgbox
功能。考慮通過反轉布爾邏輯來減少冗餘(布爾變量爲False
,直到它被分配給True
),提取message
變量並標題化標題,並且只在一個地方調用MsgBox
。
需要明確的是,這裏是你的窗體的代碼隱藏在我看來:
Option Explicit
Private Const EARLIEST_DATE As Date = #1990-01-01#
Private cancelled As Boolean
Public Property Get IsCancelled() As Boolean
IsCancelled = cancel
End Property
Public Property Get StartingDate() As Date
StartingDate = calStartDate.Value
End Property
Public Property Get EndingDate() As Date
EndingDate = calEndDate.Value
End Property
Public Property Get TimeInterval() As String
Select Case True
Case optMonth.Value
TimeInterval = "m"
Case optWeek.Value
TimeInterval = "w"
Case optDay.Value
TimeInterval = "d"
Case Else
TimeInterval = vbNullString
End Select
End Property
Private Sub Initialize()
calStartDate.Value = DateSerial(Year(Date) - 2, Month(Date), Day(Date))
calEndDate.Value = Date
optMonth.Value = True
End Sub
Private Sub UserForm_QueryClose(cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
cancelled = True
Me.Hide
End If
End Sub
Private Sub btnCancel_Click()
cancelled = True
Me.Hide
End Sub
Private Sub btnOk_Click()
If Validate Then Me.Hide
End Sub
Private Function Validate() As Boolean
Dim result As Boolean
Dim message As String
If StartingDate >= EndingDate Then
message = "Invalid selection. The starting date must be before the ending date.",
calStartDate.SetFocus
ElseIf StartingDate < EARLIEST_DATE Then
message = "Start date is too early. Cannot be before 1990."
calStartDate.SetFocus
ElseIf EndingDate > Date Then
message = "End date is too late. The ending date cannot be after today's date."
calEndDate.SetFocus
Else
result = True
End If
If Not result Then MsgBox message, "Validation Failed", vbExclamation
Validate = result
End Function
而且調用代碼:
Public Sub DoSomething()
With New MyAwesomeForm
.Show
If Not .IsCancelled Then
Dim startDate As Date
startDate = .StartingDate
Dim endDate As Date
endDate = .EndingDate
Dim interval As String
interval = .TimeInterval
'...do stuff...
End If
End With
End Sub
考慮處理calStartDate
和calEndDate
控制Changed
事件來執行更早的驗證,並且只有在窗體有效時才啓用按鈕OK;這樣你可以用一個整齊的小驗證/通知標籤來替換煩人的消息框。
這就是說,我不知道你的路徑/文件錯誤來自什麼,你的文章沒有任何文件做任何事情。但這應該可以幫助你至少得到你的表格。
- 1. VBA刪除用戶窗體控制對象,它是離屏
- 2. 錯誤「無法創建組件‘控件名稱’」當拖動Windows窗體用戶控件到窗體
- 3. 我的線程沒有看到窗體窗體組件
- 4. 如何在我的主窗體中顯示處理窗體
- 5. 用戶窗體運行時錯誤'424':需要的對象Excel VBA
- 6. 問題當我在我的窗體上顯示Powerpoint的c#.net
- 7. 訪問沒有窗體實例的VBA用戶窗體控件
- 8. Django窗體總是顯示錯誤「此字段是必需的」
- 9. phpMyAdmin錯誤:我在用戶帳戶中看到錯誤
- 10. VBA用戶窗體刷新
- 11. 我有一個用戶窗體的列表框,但當我顯示用戶窗體的列表框是空的,但是當我不顯示我可以看到項目
- 12. 文本框在用戶窗體當我改變ComboBox2價值
- 13. 從窗體內的用戶控件,我如何訪問父窗體的DataGridView?
- 14. 窗體:錯誤沒有顯示錯誤
- 15. Excel VBA用戶窗體顯示選中的工作表
- 16. Kohana 3.2,在窗體中顯示錯誤
- 17. Spring Framework .... wat是窗體之間的區別:錯誤路徑和窗體:lable path ...?
- 18. 無法在窗體上看到我的圖片 - asp.net
- 19. 賬戶對象中的SetDefaultAccountValues它顯示總和錯誤
- 20. Django窗體,ModelMultipleChoiceField上的顯示錯誤
- 21. Excel 2010個的用戶窗體VBA
- 22. 如何從父窗體調用用戶窗體中的方法?
- 23. 使用簡單的形式在窗體上顯示用戶
- 24. 窗體:錯誤不顯示錯誤列表,但窗體:錯誤path =「x」工程
- 25. Excel VBA用戶窗體 - 設置與用戶窗體大小相同的圖表
- 26. Django窗體:我如何顯示最初的空白窗體?
- 27. 獲取拖入Windows窗體窗體的文件的路徑
- 28. 用戶控制單擊 - Windows窗體
- 29. 在窗體外顯示彈出窗體錯誤
- 30. 在用戶窗體的文本框中的箭頭鍵,VBA
我可以想象,單擊用戶窗體時出現錯誤的唯一方法是在UserForm_Click事件或UserForm_Activate事件中存在代碼。你在這些事件中是否有代碼? –