tangoctuan
Thành viên hoạt động
- Tham gia
- 22/4/08
- Bài viết
- 153
- Được thích
- 19
Nhờ bạn hỗ trợ bài toán này giúp mình nữa với.Làm cho bạn 2 cột giá
Dùng Sub VBA, nhấn mặt cười chạy codeNhờ mọi người giúp mình cách làm sao để xác định được trong 1 đoạn text có hay không có 1 từ/cụm từ cho trước (dữ liệu về từ/cụm từ này có thể thay đổi tùy biến)?
File ví dụ (hiện đang làm tay) như trong đính kèm.
Cám ơn cả nhà rất nhiều!
Private aBoDau(1 To 65535) As Long
Sub CheckCumTu()
Dim sArr(), Res() As Long, S
Dim eRow&, sRow&, i&, j&, n&, Str$
With Sheet1
Str = LCase(.Range("F1").Value)
eRow = .Range("B" & Rows.Count).End(xlUp).Row
If Len(Str) = 0 Or eRow < 2 Then MsgBox ("Khong co du lieu"): Exit Sub
S = Split(";" & BoDauViet(Str), ";")
sArr = .Range("B2:B" & eRow + 1).Value
End With
n = UBound(S)
For j = 1 To n
S(j) = " " & Application.Trim(S(j)) & " "
Next j
sRow = UBound(sArr) - 1
ReDim Res(1 To sRow, 1 To 1)
For i = 1 To sRow
Str = " " & BoDauViet(LCase(sArr(i, 1))) & " "
For j = 1 To n
If InStr(1, Str, S(j)) Then
Res(i, 1) = 1
Exit For
End If
Next j
Next i
Sheet1.Range("C2").Resize(sRow) = Res
End Sub
Private Function BoDauViet(ByVal Str$) As String
Dim i&, C$
If aBoDau(225) <> 97 Then
CodeKt = Array(97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 105, 105, 105, 105, 105, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 121, 121, 121, 121, 121, 100)
CodeDau = Array(225, 224, 7843, 227, 7841, 259, 7855, 7857, 7859, 7861, 7863, 226, 7845, 7847, 7849, 7851, 7853, 233, 232, 7867, 7869, 7865, 234, 7871, 7873, 7875, 7877, 7879, 237, 236, 7881, 297, 7883, 243, 242, 7887, 245, 7885, 244, 7889, 7891, 7893, 7895, 7897, 417, 7899, 7901, 7903, 7905, 7907, 250, 249, 7911, 361, 7909, 432, 7913, 7915, 7917, 7919, 7921, 253, 7923, 7927, 7929, 7925, 273)
For i = 0 To UBound(CodeKt)
aBoDau(CodeDau(i)) = CodeKt(i)
Next i
End If
For i = 1 To Len(Str)
C = Mid(Str, i, 1)
If aBoDau(AscW(LCase(C))) Then
If C = LCase(C) Then Mid(Str, i, 1) = ChrW(aBoDau(AscW(C))) Else Mid(Str, i, 1) = UCase(ChrW(aBoDau(AscW(LCase(C)))))
End If
Next i
BoDauViet = Str
End Function
Nhờ xem hộ giúp mình lại chỗ này với, có các cụm từ này mà kết quả trả về = 0.Dùng Sub VBA, nhấn mặt cười chạy code
Mã:Private aBoDau(1 To 65535) As Long Sub CheckCumTu() Dim sArr(), Res() As Long, S Dim eRow&, sRow&, i&, j&, n&, Str$ With Sheet1 Str = LCase(.Range("F1").Value) eRow = .Range("B" & Rows.Count).End(xlUp).Row If Len(Str) = 0 Or eRow < 2 Then MsgBox ("Khong co du lieu"): Exit Sub S = Split(";" & BoDauViet(Str), ";") sArr = .Range("B2:B" & eRow + 1).Value End With n = UBound(S) For j = 1 To n S(j) = " " & Application.Trim(S(j)) & " " Next j sRow = UBound(sArr) - 1 ReDim Res(1 To sRow, 1 To 1) For i = 1 To sRow Str = " " & BoDauViet(LCase(sArr(i, 1))) & " " For j = 1 To n If InStr(1, Str, S(j)) Then Res(i, 1) = 1 Exit For End If Next j Next i Sheet1.Range("C2").Resize(sRow) = Res End Sub Private Function BoDauViet(ByVal Str$) As String Dim i&, C$ If aBoDau(225) <> 97 Then CodeKt = Array(97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 105, 105, 105, 105, 105, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 121, 121, 121, 121, 121, 100) CodeDau = Array(225, 224, 7843, 227, 7841, 259, 7855, 7857, 7859, 7861, 7863, 226, 7845, 7847, 7849, 7851, 7853, 233, 232, 7867, 7869, 7865, 234, 7871, 7873, 7875, 7877, 7879, 237, 236, 7881, 297, 7883, 243, 242, 7887, 245, 7885, 244, 7889, 7891, 7893, 7895, 7897, 417, 7899, 7901, 7903, 7905, 7907, 250, 249, 7911, 361, 7909, 432, 7913, 7915, 7917, 7919, 7921, 253, 7923, 7927, 7929, 7925, 273) For i = 0 To UBound(CodeKt) aBoDau(CodeDau(i)) = CodeKt(i) Next i End If For i = 1 To Len(Str) C = Mid(Str, i, 1) If aBoDau(AscW(LCase(C))) Then If C = LCase(C) Then Mid(Str, i, 1) = ChrW(aBoDau(AscW(C))) Else Mid(Str, i, 1) = UCase(ChrW(aBoDau(AscW(LCase(C))))) End If Next i BoDauViet = Str End Function
Ý tưởng hay quá, tks bạn.Vấn đề chỉ là xác định giới hạn của một từ.
Néu code đã có thể biết dấu cách là giới hạn từ rồi thỉ chỉ cần thêm một công việc đổi tất cả các dấu chấm câu thành "dấu cách" + "dấu chấm câu" là được.
Bạn tự thêm ký tự đặc biệt vào FunctionNhờ xem hộ giúp mình lại chỗ này với, có các cụm từ này mà kết quả trả về = 0.
View attachment 226771
Bài đã được tự động gộp:
Mình hiểu vì sao rồi. Hình như code đang bắt cả dấu "." kia đặt sát thì cũng khiến cụm từ đó không được tính luôn. Nhờ bạn chỉnh giúp hộ trường hợp nếu là ký tự chữ cái/số/từ /cụm từ đặt sát thì mới ko tính có cụm từ đó, còn nếu là dấu câu đặt sát trước/sau (, ; . ! ?...) thì cụm từ đó vẫn tính đúng như bình thường.
Cảm ơn bạn.
Private aBoDau(1 To 10000) As Long
Sub CheckCumTu()
Dim sArr(), Res() As Long, S
Dim eRow&, sRow&, i&, j&, n&, Str$
With Sheet1
Str = LCase(.Range("F1").Value)
eRow = .Range("B" & Rows.Count).End(xlUp).Row
If Len(Str) = 0 Or eRow < 2 Then MsgBox ("Khong co du lieu"): Exit Sub
S = Split(";" & BoDauViet(Str), ";")
sArr = .Range("B2:B" & eRow + 1).Value
End With
n = UBound(S)
For j = 1 To n
S(j) = " " & Application.Trim(S(j)) & " "
Next j
sRow = UBound(sArr) - 1
ReDim Res(1 To sRow, 1 To 1)
For i = 1 To sRow
Str = " " & BoDauViet(LCase(sArr(i, 1))) & " "
Str = BoKyTuDacBiet(Str)
For j = 1 To n
If InStr(1, Str, S(j)) Then
Res(i, 1) = 1
Exit For
End If
Next j
Next i
Sheet1.Range("C2").Resize(sRow) = Res
End Sub
Private Function BoDauViet(ByVal Str$) As String
Dim i&, C$
If aBoDau(225) <> 97 Then
CodeKt = Array(97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 105, 105, 105, 105, 105, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 121, 121, 121, 121, 121, 100)
CodeDau = Array(225, 224, 7843, 227, 7841, 259, 7855, 7857, 7859, 7861, 7863, 226, 7845, 7847, 7849, 7851, 7853, 233, 232, 7867, 7869, 7865, 234, 7871, 7873, 7875, 7877, 7879, 237, 236, 7881, 297, 7883, 243, 242, 7887, 245, 7885, 244, 7889, 7891, 7893, 7895, 7897, 417, 7899, 7901, 7903, 7905, 7907, 250, 249, 7911, 361, 7909, 432, 7913, 7915, 7917, 7919, 7921, 253, 7923, 7927, 7929, 7925, 273)
For i = 0 To UBound(CodeKt)
aBoDau(CodeDau(i)) = CodeKt(i)
Next i
End If
For i = 1 To Len(Str)
C = Mid(Str, i, 1)
If aBoDau(AscW(LCase(C))) Then
If C = LCase(C) Then Mid(Str, i, 1) = ChrW(aBoDau(AscW(C))) Else Mid(Str, i, 1) = UCase(ChrW(aBoDau(AscW(LCase(C)))))
End If
Next i
BoDauViet = Str
End Function
Private Function BoKyTuDacBiet(ByVal Str$) As String
Dim i&, sCol&, KyTu$, C$
KyTu = ",;.:!?" 'Tu them ky tu dac biet vao trong cap nhay kep
If InStr(1, Str, Chr(10)) Then Str = Replace(Str, Chr(10), " ")
sCol = Len(KyTu)
For i = 1 To sCol
C = Mid(KyTu, i, 1) & " "
If InStr(1, Str, C) Then
Str = Replace(Str, C, " ")
End If
Next i
BoKyTuDacBiet = Str
End Function
Cách của bạn trên cũng giải quyết được về mặt kết quả rồi nhưng lại tác động vào nguồn dữ liệu gốc. Cách này của bạn Hiếu thì hoạt động độc lập và hoàn hảo luôn.Bạn tự thêm ký tự đặc biệt vào Function
Mã:Private aBoDau(1 To 10000) As Long Sub CheckCumTu() Dim sArr(), Res() As Long, S Dim eRow&, sRow&, i&, j&, n&, Str$ With Sheet1 Str = LCase(.Range("F1").Value) eRow = .Range("B" & Rows.Count).End(xlUp).Row If Len(Str) = 0 Or eRow < 2 Then MsgBox ("Khong co du lieu"): Exit Sub S = Split(";" & BoDauViet(Str), ";") sArr = .Range("B2:B" & eRow + 1).Value End With n = UBound(S) For j = 1 To n S(j) = " " & Application.Trim(S(j)) & " " Next j sRow = UBound(sArr) - 1 ReDim Res(1 To sRow, 1 To 1) For i = 1 To sRow Str = " " & BoDauViet(LCase(sArr(i, 1))) & " " Str = BoKyTuDacBiet(Str) For j = 1 To n If InStr(1, Str, S(j)) Then Res(i, 1) = 1 Exit For End If Next j Next i Sheet1.Range("C2").Resize(sRow) = Res End Sub Private Function BoDauViet(ByVal Str$) As String Dim i&, C$ If aBoDau(225) <> 97 Then CodeKt = Array(97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 105, 105, 105, 105, 105, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 121, 121, 121, 121, 121, 100) CodeDau = Array(225, 224, 7843, 227, 7841, 259, 7855, 7857, 7859, 7861, 7863, 226, 7845, 7847, 7849, 7851, 7853, 233, 232, 7867, 7869, 7865, 234, 7871, 7873, 7875, 7877, 7879, 237, 236, 7881, 297, 7883, 243, 242, 7887, 245, 7885, 244, 7889, 7891, 7893, 7895, 7897, 417, 7899, 7901, 7903, 7905, 7907, 250, 249, 7911, 361, 7909, 432, 7913, 7915, 7917, 7919, 7921, 253, 7923, 7927, 7929, 7925, 273) For i = 0 To UBound(CodeKt) aBoDau(CodeDau(i)) = CodeKt(i) Next i End If For i = 1 To Len(Str) C = Mid(Str, i, 1) If aBoDau(AscW(LCase(C))) Then If C = LCase(C) Then Mid(Str, i, 1) = ChrW(aBoDau(AscW(C))) Else Mid(Str, i, 1) = UCase(ChrW(aBoDau(AscW(LCase(C))))) End If Next i BoDauViet = Str End Function Private Function BoKyTuDacBiet(ByVal Str$) As String Dim i&, sCol&, KyTu$, C$ KyTu = ",;.:!?" 'Tu them ky tu dac biet vao trong cap nhay kep If InStr(1, Str, Chr(10)) Then Str = Replace(Str, Chr(10), " ") sCol = Len(KyTu) For i = 1 To sCol C = Mid(KyTu, i, 1) & " " If InStr(1, Str, C) Then Str = Replace(Str, C, " ") End If Next i BoKyTuDacBiet = Str End Function