VBA hàm do tìm ký tự trong đoạn text (1 người xem)

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

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

Ldh1984

Thành viên chính thức
Tham gia
18/7/21
Bài viết
55
Được thích
7
Function GetID(RngData As Range, txt As String) As String
Dim arrData, v As Variant
arrData = RngData.Value
txt = " " & Replace(txt, "+", " ") & " "
For Each v In arrData
If InStr(1, txt, " " & v & " ", vbTextCompare) > 0 Then
GetID = v
Exit For
End If
Next v

End Function

- Mình có file dính kèm và đoạn Code trên, khi thực hiện phát sinh lỗi không lấy được dữ liệu như ý muốn
- Theo file các ô mình tô màu vàng thì code trên không tìm ra được các giá trị cần tìm.
- Kính mong các anh em giúp và hỗ trợ lại đoạn Code để công việc được hiệu quả hơn ạ!
- Chân thành cảm ơn.
 

File đính kèm

@thớt:
Code trên là code nguy hiểm. Tham số khai báo "txt As String" mặc định sẽ là ByRef. Bên trong hàm thay đổi txt tức là thay đổi tham số.

@tác giả bài #2:
Delimiter nên gọi tắt là Delim. Deli là tiếng gọi tắt của cửa hàng tạp hoá thức ăn nhẹ (Delicatessen).
 
HI, bác @befaint file "layNgua" bác gửi em khi tải về chạy code thì báo lỗi #VALUE! ạ? , excel báo có thể file chưa viruses, em Enable Editing lên thì code không chạy, bác chỉ cần chỉnh sao để nó hoạt động ạ.
Bài đã được tự động gộp:

@thớt:
Code trên là code nguy hiểm. Tham số khai báo "txt As String" mặc định sẽ là ByRef. Bên trong hàm thay đổi txt tức là thay đổi tham số.

@tác giả bài #2:
Delimiter nên gọi tắt là Delim. Deli là tiếng gọi tắt của cửa hàng tạp hoá thức ăn nhẹ (Delicatessen).
bác ơi, hiện code em đang dùng là code độc hại ấy ạ? vậy mà bấy lâu nay dùng mà không biết, cảm ơn bác nhiều nhé, nhờ bác giúp cho đoạn code ạ để hỗ trợ công việc ạ.
 
Lần chỉnh sửa cuối:
HI, bác @befaint file "layNgua" bác gửi em khi tải về chạy code thì báo lỗi #VALUE! ạ? , excel báo có thể file chưa viruses, em Enable Editing lên thì code không chạy, bác chỉ cần chỉnh sao để nó hoạt động ạ.
Muốn chạy code đó thì phải cài thêm .NET Framework, không phải ai cũng tự có đâu.

bác ơi, hiện code em đang dùng là code độc hại ấy ạ? vậy mà bấy lâu nay dùng mà không biết, cảm ơn bác nhiều nhé, nhờ bác giúp cho đoạn code ạ để hỗ trợ công việc ạ.
Bạn có txt As String, tương đương với ByRef txt As String, tức biến txt được truyền qua địa chỉ. Vì thế khi trong code bạn thay đổi giá trị của txt như bạn làm thì giá trị của biến txt sau khi gọi hàm sẽ thay đổi. Vd.
Mã:
Function lamgido(txt As String)
    txt = "hic hic"
    lamgido = 0
End Function

Sub test()
Dim txt As String, a
    txt = "ngay mai em di"
    MsgBox txt
    a = lamgido(txt)
    MsgBox txt
End Sub
Nếu chạy test thì giá trị txt lần 2 khác lần 1 do txt được truyền bằng địa chỉ và trong hàm lamgido nó bị thay đổi. Nếu thay bằng Function lamgido(BYVAL txt As String) thì giá trị txt sau khi gọi hàm y như trước khi gọi hàm.

Tuy nhiên do bạn truyền B3, B4, ... nên B3, B4, ... không thay đổi. Excel không cho phép. Lưu ý cho bạn để đề phòn những trường hợp như ví dụ của tôi.

Về code của bạn ...

Theo bạn thì các ô mầu vàng bị lỗi? Thế theo bạn thì chúng phải có kết quả là bao nhiêu? Vd. ô C9 mầu vàng và có giá trị RỖNG. Theo bạn thì C9 phải có bao nhiêu?

Trong B9 bạn có:

"NOP TIEN+BHXH+103+00+TA1088A+05200+dong BHXH+ NN MANG DUC TIEN HUAN NOP BHXH CONG TY TNHH HOA QUAN"

Trong C9 là công thức.
Mã:
=GetID($A$3:$A$588,B9)

Tôi đoán là trong chuỗi B9 chỉ có TA1088A là mã. Nhưng TA1088A ở tận A831 trong khi công thức của bạn chỉ xét vùng $A$3:$A$588. Đương nhiên là không tìm thấy. Nếu tìm thấy thì mới là chuyện lạ đó đây.

Các ô vàng khác tương tự . Tóm lại hãy mở rộng vùng tham chiếu trong các công thức.
 
Lần chỉnh sửa cuối:
Do dữ liệu của bạn đa dạng nên code của bạn vẫn chưa tìm hết. Vd. C384 rỗng trong khi B384 =

"CONG TY CO PHAN THUY SAN BINH DINH ; Thu khac ; Van phong BHXH Tinh Binh Dinh NOP BHXH THANG 10.2021-TZ0159Z"

tức chứa mã TZ0159Z. Nguyên nhân là do bạn chỉ thay các dấu "+" bằng dấu cách trong khi trước TZ0159Z là dấu "-". Code dùng "System.Collections.Hashtable" cũng bị "dính" chưởng này.

Nếu cột B còn "đa dạng" hơn thì phải dùng code khác.
 
HI, bác @befaint file "layNgua" bác gửi em khi tải về chạy code thì báo lỗi #VALUE! ạ? , excel báo có thể file chưa viruses, em Enable Editing lên thì code không chạy, bác chỉ cần chỉnh sao để nó hoạt động ạ.

Bạn mở file đó, chép code sang file của bạn rồi chạy xem.
Nếu .NET Framework mà không chạy thì tìm cách bật nó lên. Nên nhớ, Windows luôn luôn và luôn luôn (từ xa xưa xa lắc lơ tới giây phút này) có sẵn .NET Framework.

1638526369777.png

1638526473547.png


1638526619914.png
 
Muốn chạy code đó thì phải cài thêm .NET Framework, không phải ai cũng tự có đâu.


Bạn có txt As String, tương đương với ByRef txt As String, tức biến txt được truyền qua địa chỉ. Vì thế khi trong code bạn thay đổi giá trị của txt như bạn làm thì giá trị của biến txt sau khi gọi hàm sẽ thay đổi. Vd.
Mã:
Function lamgido(txt As String)
    txt = "hic hic"
    lamgido = 0
End Function

Sub test()
Dim txt As String, a
    txt = "ngay mai em di"
    MsgBox txt
    a = lamgido(txt)
    MsgBox txt
End Sub
Nếu chạy test thì giá trị txt lần 2 khác lần 1 do txt được truyền bằng địa chỉ và trong hàm lamgido nó bị thay đổi. Nếu thay bằng Function lamgido(BYVAL txt As String) thì giá trị txt sau khi gọi hàm y như trước khi gọi hàm.

Tuy nhiên do bạn truyền B3, B4, ... nên B3, B4, ... không thay đổi. Excel không cho phép. Lưu ý cho bạn để đề phòn những trường hợp như ví dụ của tôi.

Về code của bạn ...

Theo bạn thì các ô mầu vàng bị lỗi? Thế theo bạn thì chúng phải có kết quả là bao nhiêu? Vd. ô C9 mầu vàng và có giá trị RỖNG. Theo bạn thì C9 phải có bao nhiêu?

Trong B9 bạn có:

"NOP TIEN+BHXH+103+00+TA1088A+05200+dong BHXH+ NN MANG DUC TIEN HUAN NOP BHXH CONG TY TNHH HOA QUAN"

Trong C9 là công thức.
Mã:
=GetID($A$3:$A$588,B9)

Tôi đoán là trong chuỗi B9 chỉ có TA1088A là mã. Nhưng TA1088A ở tận A831 trong khi công thức của bạn chỉ xét vùng $A$3:$A$588. Đương nhiên là không tìm thấy. Nếu tìm thấy thì mới là chuyện lạ đó đây.

Các ô vàng khác tương tự . Tóm lại hãy mở rộng vùng tham chiếu trong các công thức.
- Bác ơi, em không để ý chổ "vùng tham chiếu trong công thức" nên có sai sót, như có một trong số đó nó chạy không được, em gửi lai file excel bác xem qua.
- với lại VBA em học kiểu copy nên có số vấn đề... mong bác giúp đỡ!
- Cho em xin một Code khác chạy để phục vụ công việc được không ạ?
Em cảm ơn!
Bài đã được tự động gộp:

Do dữ liệu của bạn đa dạng nên code của bạn vẫn chưa tìm hết. Vd. C384 rỗng trong khi B384 =

"CONG TY CO PHAN THUY SAN BINH DINH ; Thu khac ; Van phong BHXH Tinh Binh Dinh NOP BHXH THANG 10.2021-TZ0159Z"

tức chứa mã TZ0159Z. Nguyên nhân là do bạn chỉ thay các dấu "+" bằng dấu cách trong khi trước TZ0159Z là dấu "-". Code dùng "System.Collections.Hashtable" cũng bị "dính" chưởng này.

Nếu cột B còn "đa dạng" hơn thì phải dùng code khác.
dạ, đó là phần nhỏ ạ ^^ nó rất ư là đa dạng
 

File đính kèm

Bạn mở file đó, chép code sang file của bạn rồi chạy xem.
Nếu .NET Framework mà không chạy thì tìm cách bật nó lên. Nên nhớ, Windows luôn luôn và luôn luôn (từ xa xưa xa lắc lơ tới giây phút này) có sẵn .NET Framework.
Tôi dùng Windows XP Home mười mấy năm, phiên bản mua đàng hoàng. Thế mà không bao giờ tôi biết chỗ bật .NET Framework. Bạn có thể hướng dẫn tôi bật được không? Tôi không biết chủ thớt dùng phiên bản nào, nhưng một hướng dẫn cho tôi cũng có thể giúp ích chủ thớt.
Thực ra chuyện nhỏ. Nếu không biết bật, hoặc quá khó để hướng dẫn, thì luôn có thể tải về và cài đặt. Tìm và cài đặt thì có lẽ ai ai cũng biết.
 
Bạn mở file đó, chép code sang file của bạn rồi chạy xem.
Nếu .NET Framework mà không chạy thì tìm cách bật nó lên. Nên nhớ, Windows luôn luôn và luôn luôn (từ xa xưa xa lắc lơ tới giây phút này) có sẵn .NET Framework.

View attachment 269926

View attachment 269927


View attachment 269928
bản mình dùng bản lậu ^^, hèn gì.
Bài đã được tự động gộp:

Tôi dùng Windows XP Home mười mấy năm, phiên bản mua đàng hoàng. Thế mà không bao giờ tôi biết chỗ bật .NET Framework. Bạn có thể hướng dẫn tôi bật được không? Tôi không biết chủ thớt dùng phiên bản nào, nhưng một hướng dẫn cho tôi cũng có thể giúp ích chủ thớt.
Thực ra chuyện nhỏ. Nếu không biết bật, hoặc quá khó để hướng dẫn, thì luôn có thể tải về và cài đặt. Tìm và cài đặt thì có lẽ ai ai cũng biết.
Em đang cài NET Framework 4.8, hiện đang dùng 3.5, Win 11
 
Lần chỉnh sửa cuối:
bản mình dùng bản lậu ^^, hèn gì.
Bài đã được tự động gộp:


Em đang cài NET Framework 4.8, hiện đang dùng 3.5, Win 11
Chưa hiểu nguyên nhân, đã cài NET Framework 4.8 rồi mà dùng Code của @befaint vẫn không chạy được. Copy Code qua file cũng vạy không được luônScreenshot 2021-12-03 175252.pngScreenshot 2021-12-03 175345.png
Bài đã được tự động gộp:

Bạn mở file đó, chép code sang file của bạn rồi chạy xem.
Nếu .NET Framework mà không chạy thì tìm cách bật nó lên. Nên nhớ, Windows luôn luôn và luôn luôn (từ xa xưa xa lắc lơ tới giây phút này) có sẵn .NET Framework.

View attachment 269926

View attachment 269927


View attachment 269928
sao tải về chạy rồi mà vẫn không được, bản dùng hiện tại 3.5, thay bản 4.8 rồi mà như không, với lại đã chép code sang rồi nó cũng vậy. bạn có thể Copy toàn bộ Code lên đây được không ạ.
 
Lần chỉnh sửa cuối:
dạ, đó là phần nhỏ ạ ^^ nó rất ư là đa dạng
Bạn không nói rõ có những trường hợp nào nên tôi giả thiết là mã chỉ chứa chữ cái (không phân biệt hoa thường) và chữ số.

Ta thay món, dùng biểu thức chính qui nhé. Nếu là tôi thì tôi không dùng công thức mà dùng code để tính cột C thôi. Nhưng bạn thích công thức thì
Mã:
Function GetID(ByVal RngData As Range, ByVal txt As String) As String
Dim arrData, re As Object
    arrData = RngData.Value
    Set re = CreateObject("VBScript.RegExp")
    re.ignorecase = True
'    re.Global = True
    For Each v In arrData
        re.Pattern = "\b" & v & "\b"
        If re.test(txt) Then
            GetID = v
            Exit For
        End If
    Next v
    Set re = Nothing
End Function
 
Bạn không nói rõ có những trường hợp nào nên tôi giả thiết là mã chỉ chứa chữ cái (không phân biệt hoa thường) và chữ số.

Ta thay món, dùng biểu thức chính qui nhé. Nếu là tôi thì tôi không dùng công thức mà dùng code để tính cột C thôi. Nhưng bạn thích công thức thì
Mã:
Function GetID(ByVal RngData As Range, ByVal txt As String) As String
Dim arrData, re As Object
    arrData = RngData.Value
    Set re = CreateObject("VBScript.RegExp")
    re.ignorecase = True
'    re.Global = True
    For Each v In arrData
        re.Pattern = "\b" & v & "\b"
        If re.test(txt) Then
            GetID = v
            Exit For
        End If
    Next v
    Set re = Nothing
End Function
Bác có thể cho số đt để trao đổi tí không ạ
 
(Không có và phải cài đặt) khác hoàn toàn với (luôn có sẵn và chưa bật lên).

Nhắc lại, Windows luôn có sẵn .NET Framework.
Chưa bật lên thì gõ Google: cách bật .NET Framework trên Windows.
Rồi làm theo hướng dẫn tìm được là được rồi.
 
Ok, mình đã làm và thành công ^^
 
Trong Windows XP Home có mà tìm lòi mắt cũng không thấy. Cứ nghĩ ai cũng có Windows mới, office mới như mình. Còn đầy người dùng Windows phiên bản thấp, Excel 2007 hoặc còn thấp hơn kìa.
Mà nếu đã dùng System.Collections.Hashtable thì nên nói một câu ngắn là cần "bật" / "cài" .NET Framework. Không phải ai cũng hiểu nguyên nhân khi code không chạy như mong muốn - chứng cứ là chủ thớt đây. Giúp người khác thì nên giúp trọn vẹn, đừng mặc định là người ta giỏi như mình.

Tôi dừng ở đây, dù bất cứ gì sảy ra tiếp theo.
Bài đã được tự động gộp:

Ok, mình đã làm và thành công ^^
Bạn đã làm như thế nào? Bạn có thể bật mí không? Ý tôi nói về code ấy. Còn về .NET Framework thì tôi không quan tâm. Mấy chục năm nay tôi vẫn tự xoay xở được mà có cần ai khai sáng đâu.
 
Mình luôn giúp người khác tận tình nhưng cứ có câu hỏi hay yêu cầu nào thì người ta lờ đi. Nhiều khi viết cho người ta code, chỉ yêu cầu người ta test kỹ rồi báo cáo kết quả (vd. chạy nhanh hay chậm), nhưng người ta chỉ lấy rồi âm thầm rời đi. Rất rất nhiều lần người ta lờ mình rồi ...
 
Lần chỉnh sửa cuối:
Mình luôn giúp người khác tận tình nhưng cứ có câu hỏi hay yêu cầu nào thì người ta lờ đi. Nhiều khi viết cho người ta code, chỉ yêu cầu người ta test kỹ rồi báo cáo kết quả (vd. chạy nhanh hay chậm), nhưng người ta chỉ lấy rồi âm thầm rời đi. Rất rất nhiều lần người ta lờ mình rồi ...
Không phải đâu chú ạ.Thực ra khi được mọi người giúp rồi. Vui. Có khi ra ngoài test.Test thấy được rồi là quên mất phải phần báo cáo lại. Kiểu Ho-Ren-So bị khuyết. Chỉ chừng nào có lỗi thì mới quay lại. Đôi khi làm người giúp thấy bị hụt hẫng.
 
mình hiện tại đang rất cần xử lý chia dữ liệu từ file tổng ra các file riêng lẻ, rồi lại filter trong các file nhỏ đó để làm bc. Ngày 4 lần, mỗi lần hơn nghìn dữ liệu, giờ làm như kiểu đãi thóc hàng ngày. Bạn giúp mình với, mình muốn đổ lữ liệu vào file tổng rồi sẽ nhảy vào các file nhỏ mà lọc trùng case luôn, trong các file nhỏ cũng sẽ lọc và nhảy snag các sheet. Mình cảm ơn ạ
 
Web KT

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

Back
Top Bottom