So sánh text trong Cell

  • Thread starter Thread starter abdung
  • Ngày gửi Ngày gửi
Liên hệ QC

abdung

Thành viên mới
Tham gia
9/2/12
Bài viết
7
Được thích
2
Hi cả nhà, mình đang có 1 file excel nhiều dòng có data text trong file giống file sample. Dữ liệu ngăn cách nhau bởi dấu chấm phảy (;) Data có khoảng vài nghìn dòng.
Mình đang cần xây dựng 1 hàm /VBA để lọc ra:
" Nếu cột B và C có chứa thông tin giống nhau chỉ khác về thứ tự thì trả về kết quả True, Nếu có khác nhau thì trả về kết quả False"
Cả nhà giúp mình với nhé. VBA thì càng tốt.
 

File đính kèm

Hi cả nhà, mình đang có 1 file excel nhiều dòng có data text trong file giống file sample. Dữ liệu ngăn cách nhau bởi dấu chấm phảy (;) Data có khoảng vài nghìn dòng.
Mình đang cần xây dựng 1 hàm /VBA để lọc ra:
" Nếu cột B và C có chứa thông tin giống nhau chỉ khác về thứ tự thì trả về kết quả True, Nếu có khác nhau thì trả về kết quả False"
Cả nhà giúp mình với nhé. VBA thì càng tốt.
Các mẫu trong 1 ô chỉ là ký tự a-z không dấu thôi à ban
 
Upvote 0
Hi cả nhà, mình đang có 1 file excel nhiều dòng có data text trong file giống file sample. Dữ liệu ngăn cách nhau bởi dấu chấm phảy (;) Data có khoảng vài nghìn dòng.
Mình đang cần xây dựng 1 hàm /VBA để lọc ra:
" Nếu cột B và C có chứa thông tin giống nhau chỉ khác về thứ tự thì trả về kết quả True, Nếu có khác nhau thì trả về kết quả False"
Cả nhà giúp mình với nhé. VBA thì càng tốt.
Bạn thử cái Sub "cùi bắp" này coi sao.
PHP:
Public Sub sGpe()
Dim sArr(), dArr(), Tmp1, Tmp2, I As Long, J As Long, R As Long
sArr = Range("B2", Range("B2").End(xlDown)).Resize(, 2).Value
R = UBound(sArr)
ReDim dArr(1 To R, 1 To 1)
With CreateObject("Scripting.Dictionary")
For I = 1 To R
    dArr(I, 1) = "T"
    Tmp1 = Split(UCase(sArr(I, 1)), ";")
    Tmp2 = Split(UCase(sArr(I, 2)), ";")
    If UBound(Tmp1) <> UBound(Tmp2) Then
        dArr(I, 1) = "F"
    Else
        For J = 0 To UBound(Tmp1)
            .Item(Tmp1(J)) = ""
        Next J
        For J = 0 To UBound(Tmp2)
            If .Exists(Tmp2(J)) Then
                .Remove Tmp2(J)
            Else
                dArr(I, 1) = "F"
                Exit For
            End If
        Next J
    End If
Next I
End With
Range("E2").Resize(R) = dArr
End Sub
 
Upvote 0
Trong file mẫu, trong 1 ô có ký tự nào trùng đâu.
 
Upvote 0
Hi cả nhà, mình đang có 1 file excel nhiều dòng có data text trong file giống file sample. Dữ liệu ngăn cách nhau bởi dấu chấm phảy (;) Data có khoảng vài nghìn dòng.
Mình đang cần xây dựng 1 hàm /VBA để lọc ra:
" Nếu cột B và C có chứa thông tin giống nhau chỉ khác về thứ tự thì trả về kết quả True, Nếu có khác nhau thì trả về kết quả False"
Cả nhà giúp mình với nhé. VBA thì càng tốt.
Em góp vui 1 tẹo
 

File đính kèm

Upvote 0
Các bạn đăng ký kênh để theo dõi các bài học VBA nhé.
Mã:
Public Function sosanh(s1 As String, s2 As String) As Boolean
    Dim arr() As String
    
    Dim brr() As String
    Dim i As Integer
    Dim j As Integer
    Dim sen As Boolean
    
    
    
    sosanh = False
    If Len(s1) <> Len(s2) Then Exit Function
    arr = Split(s1, ";")
    brr = Split(s2, ";")
    If UBound(arr) <> UBound(brr) Then Exit Function
    
    For i = LBound(arr) To UBound(arr) Step 1
        sen = False
        For j = LBound(brr) To UBound(brr) Step 1
            If CStr(arr(i)) = CStr(brr(j)) Then
                sen = True
                Exit For
            End If
        Next j
        If sen = False Then
            Exit Function
        End If
    Next i
    
    For i = LBound(brr) To UBound(brr) Step 1
        sen = False
        For j = LBound(arr) To UBound(arr) Step 1
            If CStr(brr(i)) = CStr(arr(j)) Then
                sen = True
                Exit For
            End If
        Next j
        If sen = False Then
            Exit Function
       
        End If
    Next i
    sosanh = True
    
End Function
 
Upvote 0
Đúng rồi. Các dữ liệu a, b, c... Trong ô chỉ xuất hiện 1 lần thôi ạ. Mình ko có máy tính online nên chưa check đc. Mai sẽ check ạ. Cảm ơn cả nhà nhiều.
 
Upvote 0
Các bạn đăng ký kênh để theo dõi các bài học VBA nhé.

Public Function sosanh(s1 As String, s2 As String) As Boolean
Dim arr() As String

Dim brr() As String
Dim i As Integer
Dim j As Integer
Dim sen As Boolean

sosanh = False
If Len(s1) <> Len(s2) Then Exit Function
arr = Split(s1, ";")
brr = Split(s2, ";")
If UBound(arr) <> UBound(brr) Then Exit Function

For i = LBound(arr) To UBound(arr) Step 1
sen = False
For j = LBound(brr) To UBound(brr) Step 1
If CStr(arr(i)) = CStr(brr(j)) Then
sen = True
Exit For
End If
Next j
If sen = False Then
Exit Function
End If
Next i

For i = LBound(brr) To UBound(brr) Step 1
sen = False
For j = LBound(arr) To UBound(arr) Step 1
If CStr(brr(i)) = CStr(arr(j)) Then
sen = True
Exit For
End If
Next j
If sen = False Then
Exit Function

End If
Next i
sosanh = True

End Function
Theo bạn, hai chuỗi a;b;b;b và a;a;b;b; giống nhau hay khác nhau?
 
Upvote 0
Các bạn đăng ký kênh để theo dõi các bài học VBA nhé.
Mã:
Public Function sosanh(s1 As String, s2 As String) As Boolean
    Dim arr() As String
   
    Dim brr() As String
    Dim i As Integer
    Dim j As Integer
    Dim sen As Boolean
   
   
   
    sosanh = False
    If Len(s1) <> Len(s2) Then Exit Function
    arr = Split(s1, ";")
    brr = Split(s2, ";")
    If UBound(arr) <> UBound(brr) Then Exit Function
   
    For i = LBound(arr) To UBound(arr) Step 1
        sen = False
        For j = LBound(brr) To UBound(brr) Step 1
            If CStr(arr(i)) = CStr(brr(j)) Then
                sen = True
                Exit For
            End If
        Next j
        If sen = False Then
            Exit Function
        End If
    Next i
   
    For i = LBound(brr) To UBound(brr) Step 1
        sen = False
        For j = LBound(arr) To UBound(arr) Step 1
            If CStr(brr(i)) = CStr(arr(j)) Then
                sen = True
                Exit For
            End If
        Next j
        If sen = False Then
            Exit Function
      
        End If
    Next i
    sosanh = True
   
End Function
Dùng 1 vòng lặp thôi được không bạn.
 
Upvote 0
Bạn thử cái Sub "cùi bắp" này coi sao.
PHP:
Public Sub sGpe()
Dim sArr(), dArr(), Tmp1, Tmp2, I As Long, J As Long, R As Long
sArr = Range("B2", Range("B2").End(xlDown)).Resize(, 2).Value
R = UBound(sArr)
ReDim dArr(1 To R, 1 To 1)
With CreateObject("Scripting.Dictionary")
For I = 1 To R
    dArr(I, 1) = "T"
    Tmp1 = Split(UCase(sArr(I, 1)), ";")
    Tmp2 = Split(UCase(sArr(I, 2)), ";")
    If UBound(Tmp1) <> UBound(Tmp2) Then
        dArr(I, 1) = "F"
    Else
        For J = 0 To UBound(Tmp1)
            .Item(Tmp1(J)) = ""
        Next J
        For J = 0 To UBound(Tmp2)
            If .Exists(Tmp2(J)) Then
                .Remove Tmp2(J)
            Else
                dArr(I, 1) = "F"
                Exit For
            End If
        Next J
    End If
Next I
End With
Range("E2").Resize(R) = dArr
End Sub
Em chưa test được.Nhưng em nhìn code thì co khi nào nó không xoá được hết key trong dic.để lại vòng lặp sau lại chạy không anh.
 
Upvote 0
Dùng 1 vòng lặp thôi được không bạn.
Trả lời: Có thể bỏ được một vòng lặp.
Theo giả thiết bài toán thì có thể bỏ bớt một vòng kiểm tra ngược lại.
Đúng rồi. Các dữ liệu a, b, c... Trong ô chỉ xuất hiện 1 lần thôi ạ. Mình ko có máy tính online nên chưa check đc. Mai sẽ check ạ. Cảm ơn cả nhà nhiều.
Theo bạn, hai chuỗi a;b;b;b và a;a;b;b; giống nhau hay khác nhau?
theo giả thiết bài toán thì các phần tử chỉ xuất hiện 1 lần do đó có thể hiểu hai chuỗi a;b;b;b và a;a;b;b là giống nhau. Cái này tùy thuộc vào mục đích của tác giả thôi. chuỗi ký tự xuất hiện những phần tử nào mà không quan tâm phần tử xuất hiện bao nhiêu lần (thực tế thì theo tác giả, các phần tử chỉ xuất hiện 1 lần).

Nếu quan tâm số lần xuất hiện của phần tử thì cần phải giải lại, tuy nhiên lần này không cần quan tâm tới điều đó.
Để đáp ứng băn khoăn của mọi người, mong muốn lời giải cho một bài toán chặt hơn, mình đưa ra giải pháp như sau:
Mã:
Public Function sosanh(s1 As String, s2 As String) As Boolean
    Dim arr() As String
    
    Dim brr() As String
    Dim i As Integer
    Dim j As Integer
    Dim sen As Boolean
    
    
    
    sosanh = False
    If Len(s1) <> Len(s2) Then Exit Function
    arr = Split(s1, ";")
    brr = Split(s2, ";")
    If UBound(arr) <> UBound(brr) Then Exit Function
    
    For i = LBound(arr) To UBound(arr) Step 1
        sen = False
        If timsolanxuathien(CStr(arr(i)), brr) = timsolanxuathien(CStr(arr(i)), arr) Then
            sen = True
        End If
        If sen = False Then
            Exit Function
        End If
    Next i
    
   
    sosanh = True
    
End Function
Function timsolanxuathien(s As String, sarr As Variant) As Integer
    Dim i   As Integer
    Dim cnt As Integer
    cnt = 0
    For i = LBound(sarr) To UBound(sarr) Step 1
        If CStr(sarr(i)) = s Then
            cnt = cnt + 1
        End If
    Next i
    timsolanxuathien = cnt
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Trả lời: Có thể bỏ được một vòng lặp.
Theo giả thiết bài toán thì có thể bỏ bớt một vòng kiểm tra ngược lại.


theo giả thiết bài toán thì các phần tử chỉ xuất hiện 1 lần do đó có thể hiểu hai chuỗi a;b;b;b và a;a;b;b là giống nhau. Cái này tùy thuộc vào mục đích của tác giả thôi. chuỗi ký tự xuất hiện những phần tử nào mà không quan tâm phần tử xuất hiện bao nhiêu lần (thực tế thì theo tác giả, các phần tử chỉ xuất hiện 1 lần).

Nếu quan tâm số lần xuất hiện của phần tử thì cần phải giải lại, tuy nhiên lần này không cần quan tâm tới điều đó.
Ý mình nói là không để 2 vòng lặp lồng nhau ấy.
 
Upvote 0
Ý mình nói là không để 2 vòng lặp lồng nhau ấy.
Mình đã trả lời trong bài viết này.
Bạn xem code và xem video giúp mình nhé.
 
Upvote 0
Trả lời: Có thể bỏ được một vòng lặp.
Theo giả thiết bài toán thì có thể bỏ bớt một vòng kiểm tra ngược lại.


theo giả thiết bài toán thì các phần tử chỉ xuất hiện 1 lần do đó có thể hiểu hai chuỗi a;b;b;b và a;a;b;b là giống nhau. Cái này tùy thuộc vào mục đích của tác giả thôi. chuỗi ký tự xuất hiện những phần tử nào mà không quan tâm phần tử xuất hiện bao nhiêu lần (thực tế thì theo tác giả, các phần tử chỉ xuất hiện 1 lần).

Nếu quan tâm số lần xuất hiện của phần tử thì cần phải giải lại, tuy nhiên lần này không cần quan tâm tới điều đó.
Để đáp ứng băn khoăn của mọi người, mong muốn lời giải cho một bài toán chặt hơn, mình đưa ra giải pháp như sau:
Mã:
Public Function sosanh(s1 As String, s2 As String) As Boolean
    Dim arr() As String
   
    Dim brr() As String
    Dim i As Integer
    Dim j As Integer
    Dim sen As Boolean
   
   
   
    sosanh = False
    If Len(s1) <> Len(s2) Then Exit Function
    arr = Split(s1, ";")
    brr = Split(s2, ";")
    If UBound(arr) <> UBound(brr) Then Exit Function
   
    For i = LBound(arr) To UBound(arr) Step 1
        sen = False
        If timsolanxuathien(CStr(arr(i)), brr) = timsolanxuathien(CStr(arr(i)), arr) Then
            sen = True
        End If
        If sen = False Then
            Exit Function
        End If
    Next i
   
  
    sosanh = True
   
End Function
Function timsolanxuathien(s As String, sarr As Variant) As Integer
    Dim i   As Integer
    Dim cnt As Integer
    cnt = 0
    For i = LBound(sarr) To UBound(sarr) Step 1
        If CStr(sarr(i)) = s Then
            cnt = cnt + 1
        End If
    Next i
    timsolanxuathien = cnt
End Function
Code còn có thể rút gọn hơn 1/2 và tốc độ nhanh hơn nhiều, nếu bỏ các biến không cần thiết như "Sen", chỉ dùng 1 vòng For và 1 Function, chỉ dùng 1 hàm Split ...
 
Upvote 0
Mình đã trả lời trong bài viết này.
Bạn xem code và xem video giúp mình nhé.
Đây vẫn là dùng 2 Function nó vẫn chạy 2 vòng lặp.
Bạn xem cái này có đúng không nhé.
Mã:
Function linhtinh(ByVal s1 As String, ByVal s2 As String) As String
         Dim T, s
             If Len(s1) <> Len(s2) Then linhtinh = "FALSE": Exit Function
             s = ";" & s2 & ";"
             For Each T In Split(s1, ";")
                  If InStr(1, s, ";" & T & ";") = 0 Then
                     linhtinh = "False"
                     Exit Function
                  End If
             Next
             linhtinh = "TRUE"
End Function
 
Upvote 0
Đây vẫn là dùng 2 Function nó vẫn chạy 2 vòng lặp.
Bạn xem cái này có đúng không nhé.
Mã:
Function linhtinh(ByVal s1 As String, ByVal s2 As String) As String
         Dim T, s
             If Len(s1) <> Len(s2) Then linhtinh = "FALSE": Exit Function
             s = ";" & s2 & ";"
             For Each T In Split(s1, ";")
                  If InStr(1, s, ";" & T & ";") = 0 Then
                     linhtinh = "False"
                     Exit Function
                  End If
             Next
             linhtinh = "TRUE"
End Function
Cảm ơn bạn đã chia sẻ code.
Đối với bài toán gốc thì lời giải của bạn đúng.
Đối với bài toán chặt hơn, quan tâm tới số lần xuất hiện của phần tử thì lời giải trên không còn dùng được.
 
Upvote 0
Mã:
Public Function SoSanh(s1 As String, s2 As String) As Boolean
Dim v As Variant
If Len(s1) <> Len(s2) Then
    SoSanh = False
    Exit Function
End If
s2 = ";" & s2 & ";"
For Each v In Split(s1, ";")
  s2 = Replace(s2, ";" & v & ";", ";", 1, 1)
Next
    SoSanh = CBool(s2 = ";")
End Function
 
Upvote 0
Web KT

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

Back
Top Bottom