2011-11-16 36 views
38

Tôi đang cố gắng viết hàm cho excel 2010 sẽ lấy một ô văn bản không có cấu trúc, tìm kiếm một giá trị sdi và nếu tìm thấy, trả về số đó. Giá trị sdi sẽ xuất hiện dưới dạng sdi ####. Những gì tôi muốn là để trở về SDI và những con số sepecific mà theo nó, vì vậy nếu các tế bào có chứa "một số văn bản SDI 1234 một số văn bản hơn" hàm sẽ trả về SDI 1234.Trả lại kết quả regex trong VBA (excel)

Đây là chức năng của tôi:

Function SdiTest(LookIn As String) As String 
    Dim temp As String 
    Dim STA As Object 
    temp = "" 

    Set SDI = CreateObject("VBScript.RegExp") 
    SDI.IgnoreCase = True 
    SDI.Pattern = "sdi [1-9]*" 
    SDI.Global = True 

    If SDI.Test(LookIn) Then 
    temp = SDI.Execute(LookIn) 
    End If 

    SdiTest = temp 
End Function 

Nếu không có số sdi, nó sẽ không bao giờ đi vào câu lệnh if và trả về chuỗi rỗng. Nếu có số sdi tôi nhận đượC#VALUE!

Tôi đang thiếu gì?

Có, VBScript được bật. Ngoài ra, tôi thấy nó bực bội khi sử dụng regex trong VBA, và khó tìm thấy thông tin hữu ích trực tuyến. Liên kết đến các tài nguyên trực tuyến tốt sẽ được đánh giá cao.

Cảm ơn bạn

Trả lời

61

Bạn cần truy cập các kết quả phù hợp để nhận được số SDI. Đây là một hàm sẽ làm điều đó (giả sử chỉ có 1 số SDI cho mỗi ô).

Đối với regex, tôi đã sử dụng "sdi theo sau là khoảng trắng và một hoặc nhiều số". Bạn đã có "sdi theo sau bởi một không gian và số không hoặc nhiều hơn". Bạn chỉ có thể thay đổi dấu + thành * trong mẫu của tôi để quay lại những gì bạn có.

Function ExtractSDI(ByVal text As String) As String 

Dim result As String 
Dim allMatches As Object 
Dim RE As Object 
Set RE = CreateObject("vbscript.regexp") 

RE.pattern = "(sdi \d+)" 
RE.Global = True 
RE.IgnoreCase = True 
Set allMatches = RE.Execute(text) 

If allMatches.count <> 0 Then 
    result = allMatches.Item(0).submatches.Item(0) 
End If 

ExtractSDI = result 

End Function 

Nếu ô có thể có nhiều hơn một số SDI bạn muốn trích xuất, dưới đây là hàm RegexExtract của tôi. Bạn có thể vượt qua trong một paramter thứ ba để tách mỗi trận đấu (như bằng dấu phẩy tách chúng), và bạn tự nhập các mô hình trong hàm gọi thực tế:

Ex) =RegexExtract(A1, "(sdi \d+)", ", ") 

Đây là:

Function RegexExtract(ByVal text As String, _ 
         ByVal extract_what As String, _ 
         Optional seperator As String = "") As String 

Dim i As Long, j As Long 
Dim result As String 
Dim allMatches As Object 
Dim RE As Object 
Set RE = CreateObject("vbscript.regexp") 

RE.pattern = extract_what 
RE.Global = True 
Set allMatches = RE.Execute(text) 

For i = 0 To allMatches.count - 1 
    For j = 0 To allMatches.Item(i).submatches.count - 1 
     result = result & seperator & allMatches.Item(i).submatches.Item(j) 
    Next 
Next 

If Len(result) <> 0 Then 
    result = Right(result, Len(result) - Len(seperator)) 
End If 

RegexExtract = result 

End Function 

* Xin vui lòng lưu ý rằng tôi đã thực hiện "RE.IgnoreCase = True" trong RegexExtract, nhưng bạn có thể thêm nó trở lại hoặc thậm chí thêm nó dưới dạng tham số 4 tùy chọn nếu bạn muốn.

+0

Câu trả lời hay, cảm ơn chức năng! –

+0

Cảm ơn bạn Issun - chức năng của bạn hoạt động tuyệt vời – TheoRose

+0

+1 độc đáo thực hiện Issun – brettdj

Các vấn đề liên quan