Thuật toán đếm số từ giống nhau trong 1 hàng, 1 cột trong Excel

15.5939

Trả lời :

 Bài toán của bạn có thể phân tích ra thành 2 bài toán nhỏ hơn:

 1. Đếm số lượng từ xác định trong 1 chuỗi. Bạn có thể dùng thuật toán dò tìm tuần tự trong chuỗi để phát hiện ra các vị trí chứa từ cần tìm. Hàm SubStrCount() dưới đây sẽ hiện thực thuật toán này.

 2. Duyệt từng cell trong tập hợp cho trước (trong Excel gọi là Range, Selection), lấy nội dung chuỗi của cell đó rồi nhờ hàm SubsStrCount() đếm dùm số lượng từ cần tìm trong chuỗi. Tích lũy kết quả vào 1 biến Sum. Sau khi duyệt các cell trong tập hợp, giá trị biến Sum chính là số lượng từ cần tìm. Hàm RngStrCount() dưới đây hiện thực ý tưởng trên.

 Qui trình viết các hàm user-defined và sử dụng các hàm này trong Excel như sau:
 1. Chạy Excel, mở file Excel chứa tài liệu cần xử lý (có 1 hay nhiều Worksheet chứa các chuỗi văn bản cần đếm từ).
 2. Chọn menu Tools.Macro.Visual Basic Editor để hiển thị cửa sổ soạn code VBA.
 3. Dời chuột về phần tử gốc trong cửa sổ Project, nhấn phải chuột trên nó, chọn chức năng Insert.Module để tạo 1 module chức năng mới (tên mặc định là Module1) rồi viết các hàm chức năng cần dùng sau đây:

 Option Explicit
 '========================
 'hàm đếm chuỗi con trong chuỗi lớn
 'ContentStr là chuỗi lớn, SubStr là chuỗi con
 'Fsensitive miêu tả chế độ so sánh có phân biệt thường/HOA
 '========================
 Public Function SubStrCount(ContentStr As String, SubStr As String, FSensitive As Boolean) As Integer
 'định nghĩa các biến cần dùng
 Dim lenContent As Integer
 Dim ContentArr() As Integer
 Dim lenSubStr As Integer
 Dim SubStrArr() As Integer
 Dim wcount As Integer
 Dim MaxIdx As Integer
 Dim i As Integer
 'đổi chuỗi lớn thành dãy các mã ký tự Unicode
 lenContent = Len(ContentStr)
 ReDim ContentArr(lenContent)
 For i = 0 To lenContent - 1
 If (FSensitive) Then
 ContentArr(i) = AscW(Mid(ContentStr, i + 1, 1))
 Else
 ContentArr(i) = AscW(LCase(Mid(ContentStr, i + 1, 1)))
 End If
 Next i
 'đổi chuỗi con thành dãy các mã ký tự Unicode
 lenSubStr = Len(SubStr)
 ReDim SubStrArr(lenSubStr)
 For i = 0 To lenSubStr - 1
 If (FSensitive) Then
 SubStrArr(i) = AscW(Mid(SubStr, i + 1, 1))
 Else
 SubStrArr(i) = AscW(LCase(Mid(SubStr, i + 1, 1)))
 End If
 Next i
 wcount = 0
 MaxIdx = lenContent - lenSubStr
 'lặp tuần tự dò và đếm chuỗi
 i = 0
 Do While i <=>
 'tìm đến vị trí đầu chuỗi khả dĩ
 Do While (i <= maxidx)="" and="" (substrarr(0)=""><> ContentArr(i))
 i = i + 1
 Loop
 'nếu hết chuỗi lớn thì dừng
 If i > MaxIdx Then Exit Do
 'nếu đúng là chuỗi con thì tăng biến đếm
 If StrCompare(SubStrArr, ContentArr, i, lenSubStr) Then
 wcount = wcount + 1
 'dời vị trí dò tiếp về sau chuỗi tìm được
 i = i + lenSubStr
 Else
 'dời vị trí dò tiếp về ký tự kế tiếp
 i = i + 1
 End If
 Loop
 'trả về giá trị đếm được
 SubStrCount = wcount
 End Function
 
 'hàm so sánh 2 chuỗi
 Private Function StrCompare(x() As Integer, y() As Integer, ByVal start As Integer, ByVal count As Integer) As Boolean
 Dim i As Integer
 For i = 0 To count - 1
 If x(i) <> y(start + i) Then
 StrCompare = False
 Exit Function
 End If
 Next i
 StrCompare = True
 End Function
 
 '========================
 'hàm đếm từ trong tập hợp cell
 'rng xác định tập các cell, str là từ cần đếm
 'Fsensitive miêu tả chế độ so sánh có phân biệt thường/HOA
 '========================
 Public Function RngWordCount(rng As Range, str As String, FSensitive As Boolean) As Integer
 'Khai báo các biến cần dùng
 Dim count As Integer
 Dim i As Integer, j As Integer
 Dim content As String
 'khởi động số lượng ban đầu
 count = 0
 'duyệt xử lý từng cell trong tập hợp
 For i = 1 To rng.Rows.count
 For j = 1 To rng.Columns.count
 'xác định nội dung của cell(i,j)
 content = CStr(rng.Item(i, j))
 'đếm số từ trong cell và tích lũy vào biến count
 count = count + SubStrCount(content, str, FSensitive)
 Next j
 Next i
 'trả về số lượng đếm được
 RngWordCount = count
 End Function
 4. Chọn menu File.Close và Return to Microsoft Excel để quay về cửa sổ bảng tính Excel, dời chuột về cell chứa kết quả đếm, nhập vào công thức sau cho cell này:
 =RngWordCount(B3:N3, "từ cần đếm", False)
 Trong đó B1:N1 miêu tả tập hợp các cell trong hàng 3 từ cột B tới cột N. Lưu ý rằng chúng tôi khai báo tham số miêu tả tập hợp của hàm RngWordCount thuộc kiểu Range, nên có độ tổng quát rất cao, bạn có thể truyền tập hợp các cell theo hàng, theo cột hay 1 vùng chọn tùy ý gồm nhiều hàng, cột.
 

0--1

Liên hệ xóa tin: [email protected]