1-Dùng một Collection hoặc Dictionary để lưu tên các form đã được mở (chỉ lưu 1 lần duy nhất).
2-Dùng CallByName + UserForms.Add để tạo ra instance nếu cần.
3-Dùng VBA.UserForms để làm việc với các instance hiện có.
Triển khai
Bước 1: Thêm Module mới, đặt tên là FormManager, thêm code:
Option Explicit
' Module: FormManager
Dim openedForms As Collection
' Khởi tạo danh sách form đã mở
Sub InitFormTracking()
Set openedForms = New Collection
End Sub
' Đăng ký tên form nếu chưa có
Sub RegisterForm(formName As String)
Dim item As Variant
On Error Resume Next
For Each item In openedForms
If item = formName Then Exit Sub
Next item
openedForms.Add formName
End Sub
' Mở form và đăng ký
Sub ShowForm(formName As String)
On Error Resume Next
Dim frm As Object
Set frm = UserForms.Add(CStr(formName))
CallByName frm, "Show", VbMethod
RegisterForm formName
End Sub
' Ẩn tất cả instance form hiện có
Sub HideAllTrackedForms()
Dim frm As Object
For Each frm In VBA.UserForms
frm.Hide
Next frm
End Sub
' Hiện lại các form đã được theo dõi
Sub ShowAllTrackedForms()
Dim name As Variant
For Each name In openedForms
Dim frm As Object
Set frm = FindFormInstance(CStr(name))
If frm Is Nothing Then
Set frm = UserForms.Add(CStr(name))
End If
CallByName frm, "Show", VbMethod
Next name
End Sub
' Đóng hoàn toàn tất cả các form đã mở (Unload)
Sub UnloadAllTrackedForms()
Dim frm As Object
Dim frmName As String
For Each frm In VBA.UserForms
frmName = TypeName(frm)
' Đảm bảo chỉ đóng những form được theo dõi
If IsFormTracked(frmName) Then
Unload frm
End If
Next frm
End Sub
' Kiểm tra xem form có trong danh sách theo dõi hay không
Function IsFormTracked(formName As String) As Boolean
Dim item As Variant
For Each item In openedForms
If item = formName Then
IsFormTracked = True
Exit Function
End If
Next item
IsFormTracked = False
End Function
' Tìm instance form theo tên
Function FindFormInstance(formName As String) As Object
Dim frm As Object
For Each frm In VBA.UserForms
If TypeName(frm) = formName Then
Set FindFormInstance = frm
Exit Function
End If
Next frm
Set FindFormInstance = Nothing
End Function
' Ghi danh sách form ra file (formlist.txt)
Sub SaveFormListToFile()
Dim path As String
path = ThisWorkbook.Path & "\formlist.txt"
Dim fso As Object, file As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.CreateTextFile(path, True)
Dim item As Variant
For Each item In openedForms
file.WriteLine item
Next item
file.Close
End Sub
' Đọc danh sách form từ file
Sub LoadFormListFromFile()
Dim path As String
path = ThisWorkbook.Path & "\formlist.txt"
Dim fso As Object, file As Object
Dim line As String
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(path) Then
Set file = fso. OpenTextFile(path, 1)
Set openedForms = New Collection
Do While Not file.AtEndOfStream
line = Trim(file.ReadLine)
If Len(line) > 0 Then openedForms.Add line
Loop
file.Close
Else
MsgBox "Không tìm thấy file: " & path
End If
End Sub
' Hiển thị lại các form đang tồn tại nhưng đang bị ẩn
Sub ShowHiddenForms()
Dim frm As Object
For Each frm In VBA.UserForms
If frm.Visible = False Then
CallByName frm, "Show", VbMethod
End If
Next frm
End Sub
2-Thêm module thứ 2 để kiểm tra:
Sub FullDemo()
InitFormTracking
ShowForm "UserForm1"
ShowForm "UserForm2"
Application.Wait Now + TimeValue("00:00:01")
HideAllTrackedForms
Application.Wait Now + TimeValue("00:00:01")
ShowAllTrackedForms
Application.Wait Now + TimeValue("00:00:01")
SaveFormListToFile
' Sau này bạn có thể dùng:
' LoadFormListFromFile
' ShowAllTrackedForms
End Sub
'--------------------------------------------------
Sub DemoShowOnlyHiddenForms()
InitFormTracking
ShowForm "UserForm1"
ShowForm "UserForm2"
Application.Wait Now + TimeValue("00:00:01")
HideAllTrackedForms
Application.Wait Now + TimeValue("00:00:01")
ShowHiddenForms ' Chỉ hiện lại các form đang ẩn, không tạo mới
End Sub