0

My current code to do this works when all instances of the string in the document are accompanied by the associated numeral. However, where some instances of "dog" arent followed by "102", but some are, the code fails to return "102", i.e. doesn't pick up the reference numeral, instead concluding that no numeral can be found. Here is my code:

Sub FindRefNumeral()
Dim targetString As String
Dim foundRange As Range
Dim numeral As String

' Get user input
targetString = InputBox("Feature:")

' Search the document
Set foundRange = ActiveDocument.Content
With foundRange.Find
    .text = targetString & " [0-9]{1,3}" & "[A-Za-z]*"
    .MatchWildcards = True
    If .Execute Then
        ' Extract the numeral
        numeral = Split(foundRange.text, " ")(UBound(Split(foundRange.text, " ")))
        MsgBox "Reference numeral: " & numeral
    Else
        MsgBox "No reference numeral found."
    End If
End With
End Sub

I want the macro to scan the document for any instances of that string (i.e., "dog") associated with a reference numeral, and outputs in a text box the reference numeral associated with the string, i.e., "102". I also want the macro to be robust to erroneous numerals in the document, i.e. if both "dog 102" and "dog 103" are present, I'd like the macro to output the numeral that most commonly follows the string - since this is probably the correct one.

(Only if no numeral is associated with that string, i.e., no instances of the requested string are found preceding a reference numeral, do I want the output text box to display "no numeral".)

This seems like it should be an easy fix, presumably involving looping through all instances of the string in the document, functionality which the code doesn't have yet. Any ideas?

4
  • Any reason you append "[A-Za-z]*" to your search term?
    – FunThomas
    Commented May 22 at 13:22
  • Yes - to catch reference numerals which have a letter in, e.g., of the type "107a", "107b", etc.
    – cjrc
    Commented May 22 at 14:17
  • Okay, so in that case your code works for me. Do you have any instances where the keyword ("dog") and the digits (plus letter) are not separated by exactly one space?
    – FunThomas
    Commented May 22 at 14:24
  • The problem is in documents where not every instance of "dog" is followed by a numeral, I think? I'm using it on a long document with lots of instances of strings, and not every occurrence of each string is followed by its associated numeral. The macro spits out "No reference numeral".
    – cjrc
    Commented May 22 at 14:28

1 Answer 1

0

I guess the problem is the "[A-Za-z]*"-part of your search term. The find implementation of word is not using regular expressions, and [A-Za-z]* will not look for on look for zero or one character, but for exactly one. Therefore, dog 123a will be found, while dog 456 will not.

I have rewritten your routine to a function for testing:

Function FindRefNumeral(range As range, targetstring As String) As String
    With range.Find
        .Text = targetstring & " [0-9]{1;3}" & "[A-Za-z]*"
        .MatchWildcards = True
        .Wrap = wdFindContinue
        Dim okay As Boolean
        okay = .Execute
        If okay Then
            Dim tokens() As String
            tokens = Split(range.Text, " ")
            FindRefNumeral = tokens(UBound(tokens))
        End If
    End With
End Function

My test routine looked like this:

Sub test()
    Debug.Print FindRefNumeral(ActiveDocument.Content, "dog")
    Debug.Print FindRefNumeral(ActiveDocument.Content, "cat")
End Sub

And I was using the wonderful text

Header
No dog and no cat
Hello dog 999 how are you?
My cat 23a is great
Some more data, another cat and a tiny dog.

The result was

dog: 
cat: 23a

So the number for dog was not found.

Now I don't know if there is any clever way in Word to look for zero or one character - using {0,1} failed ("Invalid search term"). So I decided to first look for a number with character, and if this fails, look for a number "without" character:

Function FindRefNumeral(range As range, targetstring As String) As String
    With range.Find
        .Text = targetstring & " [0-9]{1;3}" & "[A-Za-z]*"
        .MatchWildcards = True
        .Wrap = wdFindContinue
        Dim okay As Boolean
        okay = .Execute
        If Not okay Then
            .Text = targetstring & " [0-9]{1;3}"
            okay = .Execute
        End If
        If okay Then
            Dim tokens() As String
            tokens = Split(range.Text, " ")
            FindRefNumeral = tokens(UBound(tokens))
        End If
    End With
End Function

And now the result is as expected:

dog: 999
cat: 23a

Update Your wish for a Sub is pretty easy, just ask the user for the input string, call the function and dump the result.

Sub AskAndFindRefNumeral()
    ' Get user input
    Dim targetString As String
    targetString = InputBox("Feature:")
    If targetString = "" Then Exit Sub

    ' Call function to find the text
    Dim textFound As String
    textFound = FindRefNumeral(ActiveDocument.Content, targetString)

    ' Tell it to the user
    if textFound = "" Then
        MsgBox "No reference numeral found."
    Else
        MsgBox "Reference numeral: " & textFound 
    End If
End Sub
2
  • Thanks for this - I'm having trouble getting it in the form I'm after though, with a user input defining the target string and a message box outputting the result. Could you help me massage this into Sub form as my code initially was? Much appreciated
    – cjrc
    Commented Jun 26 at 15:57
  • Have a look to my update.
    – FunThomas
    Commented Jun 26 at 17:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.