• Thứ Hai, 18/02/2008 08:13 (GMT+7)

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

    Lượt xem 15358
    Đánh giá

    Câu hỏi :
    Cho biết thuật toán VB hoặc công thức biểu thị cách đếm số từ giống nhau trong 1 hàng, 1 cột trong Excel và ghi tần suất xuất hiện sang ô bên cạnh tại đầu mỗi hàng hoặc cột.


    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 <= MaxIdx
     '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.
     

    Ý kiến phản hồi và bình luận      Gởi ý kiến của bạn ?
    Chuyên mục: Cơ sở dữ liệu