Tách số không dùng vòng lặp (2 người xem)

Liên hệ QC

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

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,957
Sưu tầm được 1 hàm tách số khá hay, xin chia sẽ với mọi người!
Điểm đặc biệt là không dùng tí vòng lập nào!
PHP:
Function TachSo(Cell As Range) As Double
  Set Temp = CreateObject("VBScript.RegExp")
  Temp.Global = True
  Temp.Pattern = "[^0-9]"
  TachSo = Temp.Replace(Cell, "")
End Function
Các bạn có thể tham khảo và phát triển thêm tùy theo yêu cầu riêng!
 

File đính kèm

Nhờ sửa lỗi khi dùng VBScript.RegExp

Em mới học phần này, thử tự làm một ví dụ xem nhưng không hiểu tại sao dòng If Tach = "" Then Tach = 0 trong Code

PHP:
Function Tach(Text As String, Pos As Long)
    On Error GoTo NextStp
    Set Tmp = CreateObject("VBScript.RegExp")
    Tmp.Global = True
    Tmp.Pattern = "[^0-9,,]"
    Tach = Tmp.Replace(Text, "")
    Tach = Split(Tach, ",")(Pos - 1)
    If Tach = "" Then Tach = 0
    Exit Function
NextStp:
    Tach = ""
End Function
lại không có tác dụng?
 

File đính kèm

Upvote 0
Em mới học phần này, thử tự làm một ví dụ xem nhưng không hiểu tại sao dòng If Tach = "" Then Tach = 0 trong Code

PHP:
Function Tach(Text As String, Pos As Long)
    On Error GoTo NextStp
    Set Tmp = CreateObject("VBScript.RegExp")
    Tmp.Global = True
    Tmp.Pattern = "[^0-9,,]"
    Tach = Tmp.Replace(Text, "")
    Tach = Split(Tach, ",")(Pos - 1)
    If Tach = "" Then Tach = 0
    Exit Function
NextStp:
    Tach = ""
End Function
lại không có tác dụng?
Đương nhiên không tác dụng rồi, vì nếu Tach không thể "làm việc" tiếp tức là nó bị lỗi thì làm sao mà = "" để cho bạn IF gì gì đó chứ
Vậy nên, nếu bạn muốn trường hợp hợp Tach "không ra cái gì" thì Tach = 0, ta sẽ sửa thế này:
PHP:
Function Tach(Text As String, Pos As Long)
  Dim tmp
    On Error GoTo NextStp
    Set tmp = CreateObject("VBScript.RegExp")
    tmp.Global = True
    tmp.Pattern = "[^0-9,,]"
    Tach = tmp.Replace(Text, "")
    Tach = Split(Tach, ",")(Pos - 1)
    Exit Function
NextStp:
    Tach = 0
End Function
Hoặc ngắn gọn hơn
PHP:
Function Tach(Text As String, Pos As Long) As Long
  On Error Resume Next
  With CreateObject("VBScript.RegExp")
    .Global = True
    .Pattern = "[^0-9,]"
    Tach = Split(.Replace(Text, ""), ",")(Pos - 1)
  End With
End Function
Vì khai báo hàm Tach thuộc biến Long (hoặc Double) nên giá trị ban đầu của Tach đương nhiên = 0, khi code bị lỗi, do có On Error Resume Next ở trên, code sẽ đi tiếp và chẳng tách ra được cái giống gì cả, cuối cùng Tach vẫn cứ = 0 (như ban đầu)
 
Upvote 0
Em không muốn Tach = 0 nữa thì thay đổi khai báo như thế nào hả thày?
Không muốn = 0 vậy bạn muốn nó = bi nhiêu?
Muốn bằng cái gì thì thay vào dòng cuối của code này:
Mã:
Function Tach(Text As String, Pos As Long)
  Dim tmp
  On Error GoTo NextStp
  With CreateObject("VBScript.RegExp")
    .Global = True: .Pattern = "[^0-9,,]"
     Tach = Split(.Replace(Text, ""), ",")(Pos - 1)
  End With
  Exit Function
NextStp:
  [B]Tach = ""[/B]  ''<--- Muốn bằng bao nhiêu, thay vào đây
End Function
 
Upvote 0
Thưa thầy ndu96081631 , ví dụ e có chuỗi 153DT0001
e muốn tách phần số bên trái là 153 ra .
Chuỗi bên trái không nhất định là 3 ký tự thì e phải cải biên hàm post#1 như thế nào ?!$@!!
 
Upvote 0
Thưa thầy ndu96081631 , ví dụ e có chuỗi 153DT0001
e muốn tách phần số bên trái là 153 ra .
Chuỗi bên trái không nhất định là 3 ký tự thì e phải cải biên hàm post#1 như thế nào ?!$@!!

Trong VBA có hàm VAL đáp ứng được nhu cầu của bạn:
Val("153DT0001") cho kết quả = 153 ---> Tức nó sẽ tách những con số nằm bên trái ra, đến khi nào gặp ký tự không phải số thì ngưng
 
Upvote 0
vậy nếu trường hợp một dãy ký tự có hai dãy số cách nhau bởi chữ, em muốn lấy dãy số thứ 2 thì làm như thế nào. Giả sử trường hợp đó như sau:
sdsfs-fe5675cdfdfd5675

Thì em muốn lấy kết quả là 5675

Và nâng cao hơn em muốn lấy kết quả là d5675 thì em làm như thế nào?

Em biến đổi hàm của thầy như sau:
PHP:
Function TachSo(Cell As Range) As Double
  Set Temp = CreateObject("VBScript.RegExp")
  Temp.Global = True
  Temp.Pattern = "[^0-9]"
  TachSo = Temp.Replace(Mid(Cell, InStr(Cell, Val(Cell)), 100), "")
End Function

Nhưng phát hiện ra có trường hợp lại còn chuối hơn
BATT-PACK,EB-BJ120CBE(50V),SM-J120F

Em chỉ tách dãy số cuối cùng tính từ bên trái sang thì phải làm như thế nào?
 
Lần chỉnh sửa cuối:
Upvote 0
vậy nếu trường hợp một dãy ký tự có hai dãy số cách nhau bởi chữ, em muốn lấy dãy số thứ 2 thì làm như thế nào. Giả sử trường hợp đó như sau:
sdsfs-fe5675cdfdfd5675

Thì em muốn lấy kết quả là 5675

Và nâng cao hơn em muốn lấy kết quả là d5675 thì em làm như thế nào?

Em biến đổi hàm của thầy như sau:
PHP:
Function TachSo(Cell As Range) As Double
  Set Temp = CreateObject("VBScript.RegExp")
  Temp.Global = True
  Temp.Pattern = "[^0-9]"
  TachSo = Temp.Replace(Mid(Cell, InStr(Cell, Val(Cell)), 100), "")
End Function

Nhưng phát hiện ra có trường hợp lại còn chuối hơn
BATT-PACK,EB-BJ120CBE(50V),SM-J120F

Em chỉ tách dãy số cuối cùng tính từ bên trái sang thì phải làm như thế nào?
Cụ thể bạn muốn kết quả bằng bao nhiêu? Và file đâu?
 
Upvote 0
Thầy xem file đính kèm cho em nhé, kết quả mong muốn em cũng đã làm ví dụ một vài trường hợp ở trên cùng.
Dữ liệu linh tinh quá
- Trường hợp ASSY-BRAKET_R,BG930,BLACK thì kết quả = gì?
- Trường hợp ASSY-BATT-COVER,WHITE,DUOS,J510F thì kết quả = gì?
vân vân
 
Upvote 0
Dữ liệu linh tinh quá
- Trường hợp ASSY-BRAKET_R,BG930,BLACK thì kết quả = gì?
- Trường hợp ASSY-BATT-COVER,WHITE,DUOS,J510F thì kết quả = gì?
vân vân

Vâng trường hợp 1 kết quả là G930, trường hợp 2 kết quả là J510. Quy luật em thấy như sau:
-B1: Tìm dãy số đầu tiên bắt đầu từ bên phải của chuỗi tìm kiếm. Nếu không có dãy số nào thì kết quả trả về là khoảng trống
-B2: Nếu ở B1 có dãy số đó thì lấy ký tự kề bên dãy số này (ở bên trái dãy số)
*Như trường hợp 1 ở trên thì dãy số tìm được là 930, ta lấy thêm một ký tự nữa bên trái dãy số này và đó là G, kết hợp lại cho ra kết quả là G930.
 
Lần chỉnh sửa cuối:
Upvote 0
Mục đích của bạn là tách số hay học cách dùng Regex?
Bài này dùng Regex được, nhưng theo dùng để học thì trình độ tương đối cao, ít nhất là bạn phải hiểu nguyên tắc ghi sổ (capture) của Regex. Mà theo toi thấy thì bạn chưa nắm vững. Tốt hơn hết là bạn tìm hiểu về capture trước.
Nếu chỉ muốn tách số thì dùng vòng lặp duyệt chuỗi dễ hơn nhiều.
 
Upvote 0
Mục đích của bạn là tách số hay học cách dùng Regex?
Bài này dùng Regex được, nhưng theo dùng để học thì trình độ tương đối cao, ít nhất là bạn phải hiểu nguyên tắc ghi sổ (capture) của Regex. Mà theo toi thấy thì bạn chưa nắm vững. Tốt hơn hết là bạn tìm hiểu về capture trước.
Nếu chỉ muốn tách số thì dùng vòng lặp duyệt chuỗi dễ hơn nhiều.


Mục đích của em vừa là giải quyết vấn đề này vừa là học thêm về Regex vì em thấy nó khá thú vị. Có thể em không hiểu sâu hết nhưng nhất thời có khả năng hiểu và áp dụng vào các trường hợp tương tự cho nên mong mọi người mở mang thêm kiến thức cho em :)

Ngoài ra theo chủ đề http://www.giaiphapexcel.com/diendan/threads/vbscript-regexp.76017/
Em thấy có nói về:
^: Trả về chuỗi kết quả trong trường hợp chuỗi này nằm ở vị trí đầu của chuỗi gốc
$: Trả về chuỗi kết quả trong trường hợp chuỗi này nằm ở vị trí cuối của chuỗi gốc


Theo cách em hiểu thì là ^ nghĩa là tìm chuỗi đầu tiên còn $ sẽ tìm chuỗi vị trí cuối cùng
Nhưng em sửa lại của thầy Ndu như sau:

PHP:
Function TachSo(Cell As Range) As Double
  Set Temp = CreateObject("VBScript.RegExp")
  Temp.Global = True
  Temp.Pattern = "[$0-9]"
  TachSo = Temp.Replace(Cell, "")
End Function

thì kết quả là Value. Cái RegExp này nhọc nhằn đây.
 
Lần chỉnh sửa cuối:
Upvote 0
Có thú vị hay không thì cách giải của bạn trật đường rồi.
Với yêu cầu như bài #51 thì nên đi tìm hiểu về hàm Test, hàm Execute và kiểu trả về của hàm Execute.
 
Upvote 0
Có thú vị hay không thì cách giải của bạn trật đường rồi.
Với yêu cầu như bài #51 thì nên đi tìm hiểu về hàm Test, hàm Execute và kiểu trả về của hàm Execute.

Em thử tìm kiếm về hàm Excute nhưng thấy ít thông tin quá.

Với code này:
PHP:
Function TachSo(Cell As Range) As Double
  Set Temp = CreateObject("VBScript.RegExp")
  Temp.Global = True
  Temp.Pattern = "[^0-9]"
  TachSo = Temp.Replace(Mid(Cell, InStr(Cell, Val(Cell)), 100), "")
End Function

Nếu trong chuỗi có hai dãy số thì code bỏ qua không lấy dãy số thứ nhất rồi và chỉ lấy dãy số thứ hai. Nếu có ba dãy số trở lên thì nó bỏ qua dãy số đầu và lấy hai dãy số tiếp theo tính từ trái sang phải của chuỗi đó. Nếu không được thì chắc em dùng tạm cái này trong khi chờ có phương án tối ưu tốt hơn vậy.
 
Lần chỉnh sửa cuối:
Upvote 0
Học Regex mà bỏ qua Execute thì cũng như học bơi mà không bơi sải, chỉ bơi ếch.

rx.Pattern = "[A-Za-z][0-9]+"
If rx.Test(str) Then ' str là chuỗi cần tách
TachChuoi = rx.Execute(str)(rx.Execute(str).Count-1)
Else
TachChuoi = "Khong có để tách" ' nếu là hàm ngừoi dùng thì set nó bằng error ở đây
End If

TachChuoi("ASSY-BATT-COVER,J123F,WHITE,DUOS,J510F") = "J510"
Đúng theo yêu cầu bài #51
 
Upvote 0
Học Regex mà bỏ qua Execute thì cũng như học bơi mà không bơi sải, chỉ bơi ếch.

rx.Pattern = "[A-Za-z][0-9]+"
If rx.Test(str) Then ' str là chuỗi cần tách
TachChuoi = rx.Execute(str)(rx.Execute(str).Count-1)
Else
TachChuoi = "Khong có để tách" ' nếu là hàm ngừoi dùng thì set nó bằng error ở đây
End If

TachChuoi("ASSY-BATT-COVER,J123F,WHITE,DUOS,J510F") = "J510"
Đúng theo yêu cầu bài #51

Cảm ơn anh, không phải bỏ qua Execute mà là tìm tài liệu về cái này không thấy có trong diễn đàn, thông tin trên mạng cũng rất ít. Em ghi từ khóa là Execute vba excel mà kết quả chẳng thấy.
 
Upvote 0
Cảm ơn anh, không phải bỏ qua Execute mà là tìm tài liệu về cái này không thấy có trong diễn đàn, thông tin trên mạng cũng rất ít. Em ghi từ khóa là Execute vba excel mà kết quả chẳng thấy.
https://www.princeton.edu/~mlovett/reference/Regular-Expressions.pdf
https://people.cs.clemson.edu/~goddard/texts/theoryOfComputation/2.pdf

http://regexr.com/

https://docs.microsoft.com/en-us/do...s/regular-expression-language-quick-reference
 
Lần chỉnh sửa cuối:
Upvote 0
Sưu tầm được 1 hàm tách số khá hay, xin chia sẽ với mọi người!
Điểm đặc biệt là không dùng tí vòng lập nào!
PHP:
Function TachSo(Cell As Range) As Double
  Set Temp = CreateObject("VBScript.RegExp")
  Temp.Global = True
  Temp.Pattern = "[^0-9]"
  TachSo = Temp.Replace(Cell, "")
End Function
Các bạn có thể tham khảo và phát triển thêm tùy theo yêu cầu riêng!

Bác ơi, sao em dùng hàm của bác thì chỉ lọc được 15 số trong chuỗi, từ số 16 trở đi thì nó thành số 0. VD: lọc abc0123456789012345xyz thì thành 123456789012345 là đúng nhưng nếu là abc01234567890123456789xyz thì thành 1234567890123460000.
 
Upvote 0
Web KT

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

Back
Top Bottom