Chào các bác, hôm nay em muốn chia sẻ một kỹ thuật nhỏ mà em hay dùng để tối ưu hóa việc tạo UserForm trong VBA, đặc biệt là khi cần hiển thị danh sách dữ liệu lớn. Thay vì phải tạo từng control (như TextBox, ComboBox) một cách thủ công rồi bind dữ liệu, em thường sử dụng một Array để lưu trữ thông tin các control và tự động tạo chúng khi UserForm khởi tạo.
Cách này rất hữu ích khi bạn có một danh sách các trường cần nhập liệu mà cấu trúc tương đối giống nhau. Ví dụ, khi làm báo cáo nhân sự, bạn có thể có các trường như: Mã NV, Họ tên, Ngày sinh, Chức vụ, Phòng ban... Thay vì kéo thả từng TextBox, Label, bạn có thể định nghĩa một Array chứa tên các trường và kiểu dữ liệu tương ứng.
Cấu trúc Array có thể như sau:
Dim arrFields As Variant
arrFields = Array(
Array("txtMaNV", "Mã NV", "TextBox"),
Array("txtHoTen", "Họ tên", "TextBox"),
Array("dtpNgaySinh", "Ngày sinh", "DatePicker"), ' Giả sử có UserControl DatePicker
Array("cboChucVu", "Chức vụ", "ComboBox"),
Array("cboPhongBan", "Phòng ban", "ComboBox")
)Sau đó, trong sự kiện UserForm_Initialize, bạn sẽ lặp qua Array này để tạo và định vị các Control tương ứng. Ví dụ:
Private Sub UserForm_Initialize()
Dim i As Integer
Dim topPos As Integer
topPos = 10 ' Vị trí bắt đầu theo trục Y
For i = LBound(arrFields) To UBound(arrFields)
' Tạo Label
Dim lbl As MSForms.Label
Set lbl = Me.Controls.Add("Forms.Label.1", "lbl" & arrFields(i)(0), True)
lbl.Caption = arrFields(i)(1)
lbl.Top = topPos
lbl.Left = 20
lbl.Width = 100
' Tạo Control nhập liệu (TextBox, ComboBox...)
Dim ctrl As MSForms.Control
Set ctrl = Me.Controls.Add("Forms." & arrFields(i)(2) & ".1", arrFields(i)(0), True)
ctrl.Top = topPos
ctrl.Left = 130
ctrl.Width = 150
' Xử lý thêm cho ComboBox (nếu cần bind dữ liệu)
If arrFields(i)(2) = "ComboBox" Then
' Gọi hàm để nạp dữ liệu cho ComboBox này
Call LoadComboBoxData(ctrl, arrFields(i)(0))
End If
topPos = topPos + 30 ' Tăng vị trí cho control tiếp theo
Next i
End SubViệc này giúp code của bạn gọn gàng hơn, dễ dàng thêm bớt hoặc sửa đổi các trường thông tin mà không cần đụng vào giao diện UserForm quá nhiều. Ngoài ra, bạn có thể mở rộng thêm để tự động bind dữ liệu từ một Range hoặc Array khác vào các Control này.
Có bác nào đã áp dụng cách này chưa, hoặc có ý tưởng nào hay hơn để tối ưu hóa việc tạo UserForm không ạ?