Lập trình Userform-VBA tạo mục nhập có danh sách tìm kiếm với BSSearchEngine - Add-in A-Tools v10.1 (1 người xem)

Người dùng đang xem chủ đề này

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia
13/6/06
Bài viết
4,898
Được thích
10,366
Giới tính
Nam
Nghề nghiệp
Giáo viên, CEO tại Bluesofts
Nhập liệu nâng cao trong Add-in A-Tools cho phép tìm và lọc trên sheet. Từ phiên bản v10.1 cho phép người dùng lập trình với class BSSearchEngine để tạo cửa sổ tìm kiếm này với điều khiển - control trên Userform. Tốc độ nhanh dù hàng trăm ngàn dòng. BSSearchEngine cung cấp phong phú các thủ tục, thuộc tính, sự kiện để tùy biến giao diện và hành động.

Khi cài A-Tools bạn mở tập tin tại đường dẫn dưới đây để xem mã nguồn ví dụ đầy đủ:

(*) File mã nguồn ví dụ: "C:\A-Tools\HELP & DEMOS\A-Tools VBA Programming\BSSearchEngine - Create DropDown List on control\BSSearchEngine - DropDown List.xlsm"
(*) Bài viết gốc tại đây

Chủ đề này tôi sẽ hướng dẫn từng bước lập trình từ cơ bản đến nâng cao với BSSearchEngine để tạo tính năng tìm và lọc với control trên Userform giống như chức năng Nhập liệu nâng cao trên sheet.

Video phần 01 - Tạo mục tìm và lọc đơn giản


Dòng lệnh tối thiểu để tạo cửa sổ tìm và lọc với control (các code trong chủ đề này là ngôn ngữ VBA, dùng định dạng C# để hình thức đẹp hơn)

+ Bước 1: Nhúng thư viện AddinATools.dll

Trong cửa sổ lập trình VBA, chọn Project bạn muốn lập trình, vào menu Tools -> References... tick chọn "AddinATools.dll"

VBA-references.png

+ Bước 2: Tạo Userform và chèn một control TextBox

Control phục vụ để nhập liệu là TextBox. Bạn có thể sử dụng các control ComboBox, BSEdit hoặc control nào cho phép nhập liệu.

BSSearchEngine-Userform1.png

Nhấp đúp chuột vào Userform - Vào chế độ soạn thảo code trong Userform. Copy đoạn code dưới đây dán vào.

C#:
Private WithEvents SE_MAHH As BSSearchEngine

Private Sub UserForm_Initialize()
    Set SE_MAHH = New BSSearchEngine 'Khởi tạo
    SE_MAHH.Create txtMAHH, Range("DMHH") 'Nhập thông tin cho BSSearchEngine
    SE_MAHH.BoundColumn = 1 'Ngầm định là 1 - Chỉ ra vị trí cột giá trị lấy về control
    'EditControl: TextBox, ComboBox, BSEdit, Handle to Edit
    'DataSource: Excel Range (high speed!)
    '            Array2D
    '            ADODB.Recordset
End Sub

'Sự kiện nhận giá trị chọn từ danh sách. Lấy giá trị trong mảng điền vào các control khác.
Private Sub SE_MAHH_OnAfterUpdate(RowIndex As Variant, Values As Variant, ByVal Text As String)
    lblTenHH.Caption = Values(1, 2) 'Tên hàng
    txtDVT.Text = Values(1, 4) 'Đơn vị tính
End Sub

Giải thích mã nguồn

+ BSSearchEngine: là class thực hiện tìm và lọc dữ liệu khi thay đổi dữ liệu trên control nhập liệu.

C#:
Sub BSSearchEngine.Create(EditControl, DataSource, [DataHasHeaderRow As Boolean = True], [ShowHeader As Boolean = True])

là thủ tục kết nối control nhập liệu và dữ liệu nguồn:
EditControl: có thể là: Handle of the editor control; BSAC.BSEdit Control; MSForms.TextBox, MSForms.ComboBox
DataSource: có thể là Excel Range, Array2D, ADODB.Recordset
DataHasHeaderRow: ngầm định là True, chỉ ra dữ liệu nguồn có dòng tiêu đề.
ShowHeader: ngầm định là True, chỉ ra cửa sổ tìm kiếm hiển thị dòng tiêu đề không.

Trong mã nguồn:
SE_MAHH.Create txtMAHH, Range("DMHH")
control txtMAHH sẽ được kích hoạt cửa sổ tìm kiếm và lọc, dữ liệu nguồn tại vùng NAME "DMHH" - Range("DMHH")

+ BSSearchEngine.BoundColumn: là số nguyên, ngầm định là 1 chỉ ra vị trí cột trong dữ liệu nguồn giá trị được lấy về control nhập liệu.

Muốn tương tác lệnh trong khi thực hiện các hành động thì phải lập trình sự kiện cho BSSearchEngine.
Sự kiện OnAfterUpdate() chạy ngay sau khi giá trị được cập nhật vào control. Cấu trúc sự kiện là

C#:
Sub OnAfterUpdate(RowIndex, Values, Text As String)

+ RowIndex: là mảng 1D chứa tạo độ các dòng được chọn.
+ Values: là mảng 2D chứa giá trị đã chọn từ danh sách.
+ Text: là chuỗi được nhập vào control.


Nếu bạn muốn chọn và nhận về sự kiện này nhiều dòng thì phải khai báo thuộc tính MultiInputColumns.
+ BSSearchEngine.MultiInputColumns = True cho phép chọn và nhận về nhiều dòng giá trị.

Kết quả khi chạy

nhaplieunangcao-vba.png

Bài viết tiếp theo tôi sẽ thêm ví dụ và giải thích thêm...
 
Lần chỉnh sửa cuối:
Bài chia sẻ này tôi hướng dẫn các bạn thay đổi màu sắc của từng dòng trong cửa sổ tìm và lọc của Nhập Liệu Nâng Cao trên Userform.

Để thay đổi màu trên nhập liệu nâng cao chúng ta dùng các thuộc tính, RowColor1, RowColor2:
BSSearchEngine.RowColor1: nhận màu dòng lẻ, giá trị là chuỗi hexa color hoặc kiểu Long trả về bởi hàm RGB.
BSSearchEngine.RowColor2: nhận màu dòng chẵn, giá trị là chuỗi hexa color hoặc kiểu Long trả về bởi hàm RGB.

Mã nguồn VBA như sau:
C#:
Option Explicit
Private WithEvents SE_DATA As BSSearchEngine

Private Sub UserForm_Initialize()
    Set SE_DATA = New BSSearchEngine
    SE_DATA.Create txtSearch, Range("KHO")
    SE_DATA.BoundColumn = 12 'Lay cot ROW
    SE_DATA.RowColor1 = RGB(250, 210, 198) ' or "#FAD2C6" 'Màu dòng lẻ
    SE_DATA.RowColor2 = "#F7B49F" ' Or RGB(247, 180, 159) 'Màu dòng chẵn
End Sub

'Sự kiện bắt khi giá trị nhập vào control, lấy tọa độ dòng để mở lại phiếu, chứng từ.
Private Sub SE_DATA_OnAfterUpdate(RowIndex As Variant, Values As Variant, ByVal Text As String)
    If Text <> "" Then
        If IsNumeric(Text) Then
            LoatDuLieu Text 'Tai phieu tu sheet "KHO"
        End If
    End If
End Sub


BSSearchEngine-RowColor.png

Bài viết còn tiếp ...
 
Hay thế anh ơi
Hiện tại e vẫn đang dùng User Form mà trước anh NDU có làm, để nhập nhanh hoặc tìm kiếm từ Sheets

1778983713980.png
 
Hay thế anh ơi
Hiện tại e vẫn đang dùng User Form mà trước anh NDU có làm, để nhập nhanh hoặc tìm kiếm từ Sheets

View attachment 311665

Hi em. Có gì dùng đó quan trọng đáp ứng đạt yêu cầu công việc của em là được. BSSearchEngine chính là thư viện tạo ra Nhập Liệu Nâng cao của A-Tools từ cách đây 10 năm bây giờ mới tạo interface trong thư viện để cho phép lập trình VBA hoặc các ngôn ngữ lập trình khác đấy. Khi nào rảnh, có hứng em thử trải nghệm với BSSearchEngine với dữ liệu nguồn khoảng 1.000.000 dòng (một triệu dòng) xem tốc độ thế nào nhé :D .
 
Bài viết này tôi hướng dẫn dùng ADO để lấy dữ liệu bằng câu lệnh SQL

Với giải pháp này bạn có thể lấy dữ liệu từ bên ngoài như SQL Server, MySQL, Oracle, Access, Excel,.... chỉ cần bạn nắm được cấu trúc của ConnectionString. Sau đây là các bước làm và những lưu ý.

+ Bước 1: Trong VBA, vào menu Tools -> References... chọn "Microsoft ActiveX Data Object..." Bạn chọn version nào cũng được.

vba-references-png.311661


+ Bước 2: Mở Userform dán đoạn code dưới đây:

C#:
Private cnn As ADODB.Connection
Private rst As ADODB.Recordset
Private SE_DMHH As BSSearchEngine

Private Sub UserForm_Initialize()
    Dim ExcelFile As String
    ExcelFile = ThisWorkbook.FullName
    'Setup Recordset - DataSource:
    Set cnn = New ADODB.Connection
        cnn.ConnectionString = _
        "Provider=Microsoft.ACE.OLEDB.12.0;" & _
        "Data Source=" & ExcelFile & ";" & _
        "Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"""
    cnn.Open
    'Set rst = cnn.Execute("SELECT * FROM DMHH") 'CAUTION: DO NOT USE THIS!
    Set rst = New ADODB.Recordset
    'rst.CursorLocation = adUseClient
    rst.Open "SELECT * FROM DMHH", cnn, adOpenStatic 'fine!
    '----------------------------
    'Setup Search Engine:
    Set SE_DMHH = New BSSearchEngine
    SE_DMHH.Create TextBox1, rst
    '--------------------
End Sub

'Giải phóng bộ nhớ khi đóng Userform
Private Sub UserForm_Terminate()
    If Not rst Is Nothing Then
        rst.Close
    End If
    If Not cnn Is Nothing Then
        cnn.Close
    End If
    Set rst = Nothing
    Set cnn = Nothing
End Sub

Bây giờ chạy Userform ta được màn hình như sau:

BSSearchEngine-Recordset.png

Lưu ý: việc chạy SQL để lất về Recordset ta có thể dùng lệnh
C#:
Set rst = cnn.Execute("SELECT * FROM DMHH")

Nếu bạn chỉ lấy dữ liệu một lần rồi đóng thì hoàn toàn được nhưng Recordset dùng cho BSSearchEngine được đọc đi đọc lại nhiều lần nên lệnh trên không tương thích. Bạn cần tạo Recordset như ví dụ đã nêu, tức phải là

C#:
rst.Open "SELECT * FROM DMHH", cnn, adOpenStatic


Bài viết sau tôi sẽ trình bày kỹ hơn sự khác nhau khi dùng DataSource là Excel Range, Array2D, Recordset.
 
Lần chỉnh sửa cuối:

Bài viết mới nhất

Back
Top Bottom