Cách 1: Dùng Dialog sheet để thiết kế giao diện UserForm rồi ẩn sheet này đi
Bạn thiết kế UserForm bằng sheet DiaLog.
Trình tự như sau:
Trên giao diện Excel bạn click chuột phải vào sheet và chọn Insert.
Chọn loại Dialog như hình ở dưới và ấn OK.
Việc thiết kế UserForm kiểu này rất dễ dàng. Bạn có thể lấy các đối tượng ở:
Vào thẻ Developer => Insert. Tại đây bạn có thể lấy các đối tượng cơ bản như hình dưới:
Để hiển thị, trên Module1 bạn viết code như sau:
Như vậy bài toán làm thế nào để ẩn được UserForm bây giờ quay về bài toán ẩn sheet.
Code trên Thisworbook, ta cần can thiệp vào sự kiện Workbook Open:
Hãy xem giao diện dưới đây, chúng ta hoàn toàn không thấy sự có mặt của UserForm.
Tôi đã rất ngạc nhiên trong lần tham khảo code của người khác, không hiểu vấn đề, tại sao giao diện userform khi chạy chương trình thì có. Mà khi đi tìm thiết kế userform thì không tìm thấy ở đâu. Nhờ có cựu admin vothanhthu tìm hiểu mà vấn đề này đã được lý giải.
Các bạn có thể kết hợp với ẩn Module, mã hóa unviewable bằng
Như vậy, ngay cả khi giải mã unviewable, bước tiếp theo người ta ngạc nhiên sẽ là không nhìn thấy thiết kế UserForm của bạn ở đâu.
Sự việc sẽ còn thú vị hơn, nếu như bạn không tạo ra sheet Dialog thủ công như hướng dẫn ở trên. Mà thay vào đó bạn tạo sheet Dialog bằng code.
Ví dụ bạn copy code sau cho vào Module 2 và chạy thủ tục CustomButtonsDialog:
Kết quả là có một giao diện userform hiện ra:
Nguồn code trên:
Về trình tự từng bước để tạo ra Dialog sheet bằng code như trên, chúng ta sẽ cùng bàn luận thêm.
Cách 2: Viết UserForm bằng code.
Cũng tương tự như ví dụ ở trên, không phải là tạo Dialog sheet bằng code, chúng ta tạo trực tiếp UserForm bằng code.
Hãy dán code trên vào Module 3.
Hãy chạy thủ tục CreateUserForm ở code trên.
Trước khi chạy code:
Không có UserForm nào đúng không?
Kết quả hiển thị ra như sau:
Tôi đóng UserForm trên. Kiểm tra trong VBE:
UserForm1 đã được tạo ra, thật đáng kinh ngạc. Chúng ta có thể cải tiến một chút trong code trên. Đó là kiểm tra xem file đã có UserForm nào tên là UserForm1 hay chưa, nếu có thì xóa đi, nếu chưa có thì mới thêm vào.
Và khi UserForm1 được Unload (đóng) thì nên chạy thủ tục xóa UserForm1. Như vậy thiết kế UserForm của bạn sẽ thể hiện hoàn toàn trên code, điều này sẽ gây khó khăn rất lớn cho người khác muốn học hỏi thiết kế UserForm của bạn.
Nguồn code trên tôi tham khảo
Lời kết:
Quan điểm của diễn đàn là chia sẻ kiến thức trên tinh thần học thuật. Topic này không cổ vũ các bạn giấu code.
Trên tinh thần học thuật, tôi muốn chúng ta đi theo hai hướng:
Bạn thiết kế UserForm bằng sheet DiaLog.
Bạn cần đăng nhập để thấy đính kèm
Trình tự như sau:
Trên giao diện Excel bạn click chuột phải vào sheet và chọn Insert.
Bạn cần đăng nhập để thấy đính kèm
Bạn cần đăng nhập để thấy đính kèm
Việc thiết kế UserForm kiểu này rất dễ dàng. Bạn có thể lấy các đối tượng ở:
Vào thẻ Developer => Insert. Tại đây bạn có thể lấy các đối tượng cơ bản như hình dưới:
Bạn cần đăng nhập để thấy đính kèm
Để hiển thị, trên Module1 bạn viết code như sau:
Mã:
Sub test()
ThisWorkbook.DialogSheets("Dialog1").Show
End Sub
Code trên Thisworbook, ta cần can thiệp vào sự kiện Workbook Open:
Mã:
Private Sub Workbook_Open()
ThisWorkbook.DialogSheets("Dialog1").Visible = 2 'very Hiden'
End Sub
Bạn cần đăng nhập để thấy đính kèm
Tôi đã rất ngạc nhiên trong lần tham khảo code của người khác, không hiểu vấn đề, tại sao giao diện userform khi chạy chương trình thì có. Mà khi đi tìm thiết kế userform thì không tìm thấy ở đâu. Nhờ có cựu admin vothanhthu tìm hiểu mà vấn đề này đã được lý giải.
Các bạn có thể kết hợp với ẩn Module, mã hóa unviewable bằng
Bạn cần đăng nhập để thấy link
của vothanhthu.Như vậy, ngay cả khi giải mã unviewable, bước tiếp theo người ta ngạc nhiên sẽ là không nhìn thấy thiết kế UserForm của bạn ở đâu.
Sự việc sẽ còn thú vị hơn, nếu như bạn không tạo ra sheet Dialog thủ công như hướng dẫn ở trên. Mà thay vào đó bạn tạo sheet Dialog bằng code.
Ví dụ bạn copy code sau cho vào Module 2 và chạy thủ tục CustomButtonsDialog:
Mã:
Option Explicit
Public dlgPrint As DialogSheet
Public blnPrint As Boolean
Sub CustomButtonsDialog()
'Define variables.
blnPrint = True
Dim ButtonDialog As String
ButtonDialog = "CustomButtons"
'Turn off ScreenUpdating.
Application.ScreenUpdating = False
'Delete previous dialog sheet if by chance it exists.
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.DialogSheets(ButtonDialog).Delete
Err.Clear
Application.DisplayAlerts = True
'Add the custom dialog sheet.
Set dlgPrint = ActiveWorkbook.DialogSheets.Add
'Open a With structure for the dialog sheet.
With dlgPrint
'Name the dialog sheet and hide it.
.Name = ButtonDialog
.Visible = xlSheetHidden
'Size the dialog sheet's dialog frame.
With .DialogFrame
.Height = 130
.Width = 204
.Caption = "Orientation preferences."
End With
'Hide the two default buttons of OK and Cancel.
'Custom buttons will be created and used instead.
.Buttons("Button 2").Visible = False
.Buttons("Button 3").Visible = False
'Add a label at the top of the dialog frame.
.Labels.Add 80, 50, 180, 18
.Labels(1).Caption = "What's your printing preference?"
'Add 3 buttons, Distance from Left and Top; Width and Height.
'Custom Button #1 (index button #3)
.Buttons.Add 84, 84, 80, 18
With .Buttons(3)
.Caption = "Print Portrait"
.OnAction = "myCustomButton"
End With
'Custom Button #2 (index button #4)
.Buttons.Add 180, 84, 80, 18
With .Buttons(4)
.Caption = "Print Landscape"
.OnAction = "myCustomButton"
End With
'Custom Button #3 (index button #5)
.Buttons.Add 84, 116, 176, 18
With .Buttons(5)
.Caption = "Forget it -- I don't want to print anything."
.OnAction = "myCustomButton"
End With
'Turn ScreenUpdating on again.
Application.ScreenUpdating = True
'The X Cancel button was clicked on the title bar.
If .Show = False Then
MsgBox "You clicked the ''X'' close button.", 64, "Print cancelled."
blnPrint = False
End If
'Close the dialog sheet's With structure.
End With
'Delete the dialog frame.
Run "DeleteDialog"
End Sub
Private Sub myCustomButton()
'Hide the custom dialog sheet.
dlgPrint.Hide
'Use a Case structure to run the macro corresponding to the
'index of the custom button that was clicked.
Select Case dlgPrint.Buttons(Application.Caller).Index
'Portrait.
Case 3: ActiveSheet.PageSetup.Orientation = xlPortrait
'Landscape.
Case 4: ActiveSheet.PageSetup.Orientation = xlLandscape
'Cancel (the "Forget it"-captioned button).
Case 5: blnPrint = False
MsgBox "No problem -- nothing will print.", 64, "Print cancelled."
End Select
End Sub
Private Sub DeleteDialog()
'Delete a previous dialog sheet if by chance it exists.
With Application
.ScreenUpdating = False
.DisplayAlerts = False
On Error Resume Next
DialogSheets("CustomButtons").Delete
Err.Clear
.DisplayAlerts = True
.ScreenUpdating = True
End With
End Sub
Bạn cần đăng nhập để thấy đính kèm
Bạn cần đăng nhập để thấy link
Về trình tự từng bước để tạo ra Dialog sheet bằng code như trên, chúng ta sẽ cùng bàn luận thêm.
Cách 2: Viết UserForm bằng code.
Cũng tương tự như ví dụ ở trên, không phải là tạo Dialog sheet bằng code, chúng ta tạo trực tiếp UserForm bằng code.
Hãy dán code trên vào Module 3.
Mã:
Sub CreateUserForm()
Dim myForm As Object
Dim NewFrame As MSForms.Frame
Dim NewButton As MSForms.CommandButton
'Dim NewComboBox As MSForms.ComboBox
Dim NewListBox As MSForms.ListBox
'Dim NewTextBox As MSForms.TextBox
'Dim NewLabel As MSForms.Label
'Dim NewOptionButton As MSForms.OptionButton
'Dim NewCheckBox As MSForms.CheckBox
Dim X As Integer
Dim Line As Integer
'This is to stop screen flashing while creating form
Application.VBE.MainWindow.Visible = False
Set myForm = ThisWorkbook.VBProject.VBComponents.Add(3)
'Create the User Form
With myForm
.Properties("Caption") = "New Form"
.Properties("Width") = 300
.Properties("Height") = 270
End With
'Create ListBox
Set NewListBox = myForm.designer.Controls.Add("Forms.listbox.1")
With NewListBox
.Name = "lst_1"
.Top = 10
.Left = 10
.Width = 150
.Height = 230
.Font.Size = 8
.Font.Name = "Tahoma"
.BorderStyle = fmBorderStyleOpaque
.SpecialEffect = fmSpecialEffectSunken
End With
'Create CommandButton Create
Set NewButton = myForm.designer.Controls.Add("Forms.commandbutton.1")
With NewButton
.Name = "cmd_1"
.Caption = "clickMe"
.Accelerator = "M"
.Top = 10
.Left = 200
.Width = 66
.Height = 20
.Font.Size = 8
.Font.Name = "Tahoma"
.BackStyle = fmBackStyleOpaque
End With
'add code for listBox
lstBoxData = "Data 1,Data 2,Data 3,Data 4"
myForm.codemodule.insertlines 1, "Private Sub UserForm_Initialize()"
myForm.codemodule.insertlines 2, " me.lst_1.addItem ""Data 1"" "
myForm.codemodule.insertlines 3, " me.lst_1.addItem ""Data 2"" "
myForm.codemodule.insertlines 4, " me.lst_1.addItem ""Data 3"" "
myForm.codemodule.insertlines 5, "End Sub"
'add code for Comand Button
myForm.codemodule.insertlines 6, "Private Sub cmd_1_Click()"
myForm.codemodule.insertlines 7, " If me.lst_1.text <>"""" Then"
myForm.codemodule.insertlines 8, " msgbox (""You selected item: "" & me.lst_1.text )"
myForm.codemodule.insertlines 9, " End If"
myForm.codemodule.insertlines 10, "End Sub"
'Show the form
VBA.UserForms.Add(myForm.Name).Show
'Delete the form (Optional)
'ThisWorkbook.VBProject.VBComponents.Remove myForm
End Sub
Trước khi chạy code:
Bạn cần đăng nhập để thấy đính kèm
Kết quả hiển thị ra như sau:
Bạn cần đăng nhập để thấy đính kèm
Bạn cần đăng nhập để thấy đính kèm
Bạn cần đăng nhập để thấy đính kèm
Và khi UserForm1 được Unload (đóng) thì nên chạy thủ tục xóa UserForm1. Như vậy thiết kế UserForm của bạn sẽ thể hiện hoàn toàn trên code, điều này sẽ gây khó khăn rất lớn cho người khác muốn học hỏi thiết kế UserForm của bạn.
Nguồn code trên tôi tham khảo
Bạn cần đăng nhập để thấy link
.Lời kết:
Quan điểm của diễn đàn là chia sẻ kiến thức trên tinh thần học thuật. Topic này không cổ vũ các bạn giấu code.
Trên tinh thần học thuật, tôi muốn chúng ta đi theo hai hướng:
- Tổng kết thành kiến thức, tạo Dialog sheet bằng code và các ví dụ.
- Tổng kết thành kiến thức, tạo UserForm bằng code và các ví dụ.