2011-11-16 18 views
38

Yapılandırılmamış bir metin hücresini alacak, sdi değeri olarak adlandırılan bir şey aramalı ve bulunursa, bu sayıyı döndürecek olan Excel 2010 için bir işlev yazmaya çalışıyorum. Sdi değeri sdi #### olarak görünecektir. İstediğim SDI ve onu takip sepecific numaralarını döndürmektir, böylece hücrede "Bazı metin sdi 1234 biraz daha metin" işlevi SDI 1234.VBA'da (excel) bir normal ifadeyi döndürme (excel)

dönecektir Bu benim fonksiyondur:

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 

Eğer sdi numarası yoksa, if ifadesini hiçbir zaman girmez ve boş dizeyi dutifully verir. Eğer bir sdi numarası varsa # VALUE olsun!

Neyi eksik?

Evet, VBScript etkinleştirildi. Ek olarak, VBA'da regex'i kullanmakta sıkıntı çektim ve internette yararlı bilgiler bulmak zor. İyi çevrimiçi kaynaklara linkler takdir edilecektir.

Eğer

cevap

61

Sen SDI numaradan almak için maçları erişmesi gereken ederiz. İşte bunu yapacak bir işlev (hücre başına sadece 1 SDI numarası olduğu varsayılarak).

Normal ifadeler için "sdi ve ardından bir boşluk ve bir veya daha fazla sayı" kullandım. "Sdi bir boşluk ve sıfır ya da daha fazla sayı takip ettiniz". Yaptığınız şeye geri dönmek için şablonumdaki + işaretini * değiştirebilirsiniz. Bir cep çıkarmak istediğiniz birden fazla SDI numarasını olma ihtimali varsa

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 

, burada benim REGEXEXTRACT fonksiyonudur. Sen (onları virgülle ayırmak gibi) her maç ayırmak için üçüncü parametrelerin içinde geçebilir ve el fiili işlev çağrısında modelini girin: Burada

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

geçerli:

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 

* Lütfen RegexExtract'ımdan "RE.IgnoreCase = True" aldığımı unutmayın, ancak isterseniz onu ekleyebilir veya isteğe bağlı bir 4. parametre olarak ekleyebilirsiniz.

+0

Harika cevap, fonksiyon için teşekkürler! –

+0

Teşekkür ederim Issun - fonksiyonunuz harika çalışıyor – TheoRose

+0

+1 güzel bitti Issun – brettdj