VBA Exception? VBA Re-Write?

buggabooed

Board Regular
Joined
Aug 17, 2012
Messages
112
I have a VBA Script in Word that looks for the information I need (a beginning of a sentence), copies the entire sentence until it hits a ".", and then repeats for all instances. I did not create this script as I'm not that awesome ( I had help from here), and it worked great until the vendor sent in wrinkles this time around. What is happening now, is that there are instances mid-sentence of things like "1.5" and such that have a period in the middle, and it is seeing that and ending the sentence right there instead of the actual end of the sentence. Is there a way around this, like an exception, or another way to do this? I'm not real VBA saavy, or really code saavy for that matter. Any help would be appreciated. Thank you. I have the script below.

Sub ExportL2RintoExcel()
'Set reference in Tools >> References to MS Excel
Dim doc As Document
'Both Word and Excel have a "range" object
'but with completely different methods and properties
'so we need to make it obvious which we're working with
Dim WDrngAll As Word.Range
Dim WDrngFind As Word.Range
Dim WDrngText As Word.Range
Dim appXL As Excel.Application
Dim XLwkb As Excel.Workbook
Dim XLwks As Excel.Worksheet
Dim x As Long, y As Long, z As Long
'Initiate objects
Set doc = ActiveDocument
Set WDrngAll = doc.Content
x = 1
z = 0
'First, count all instances of "L2R" in the text
With WDrngAll.Find
Do While .Execute(FindText:="L2R", Forward:=True) = True
z = z + 1
Loop
End With
If MsgBox("I find " & z & " instances of L2R. Does this look right? " & _
"Click Yes to continue; click No to quit.", vbYesNo) = vbYes Then

'All is good, so let's go!
'Dim an array for our info
z = z + 2
ReDim aryExport(z, 2) As String

'In Word VBA, Find searchs a range of text for a string.
'If found, that range shrinks to encompass only that string.
'So we need to set up a series of ranges: the whole doc content,
'a portion of the content to search, and the part to put in the array.
'Could probably be a bit leaner, but this keeps me away from mistakes!

'Since we searched this and found text, we don't know what it encompasses,
'so we'll reset it
Set WDrngAll = doc.Content
'Our search range is going to be reset within our loop to stretch from
'the end of the Text range to the end of the All range. This way, the
'range keeps shrinking to encompass only from the end of where we just
'came from to the end of the document. To start, then, we need a Text
'range that is just one single point at the top of the doc.
Set WDrngText = WDrngAll.Duplicate
WDrngText.Collapse wdCollapseStart

'Start the search loop
Do
'Initiate Find range
Set WDrngFind = doc.Range(WDrngText.End, WDrngAll.End)
'Find text; TRUE if found
If WDrngFind.Find.Execute(FindText:="L2R", Forward:=True) = True Then
'Found one; WDrngFind now contains only the first found "L2R"
'so we need to stretch the range to encompass the whole word
WDrngFind.MoveEnd wdWord, 1
'Load that into the array
aryExport(x, 1) = Trim(WDrngFind.Text)
'Get the text following
'(I could just keep resetting WDrngFind, but it's too prone to
'human error that I can avoid by using another range object)
Set WDrngText = doc.Range(WDrngFind.End, WDrngFind.End)
'WDrngText is now a single point at the end of the found L2R word
'Move the end forward until we see a period
WDrngText.MoveEndUntil "."
WDrngText.MoveEnd wdCharacter, 1
'Put this text into the array
aryExport(x, 2) = Trim(WDrngText.Text)

x = x + 1

'Done here; the Find range resets at the top of the loop
Else
'L2R not found; end loop
Exit Do
End If
Loop

'At this point, we should have an array full of text elements.
'In the first positions are the L2R words. In the second positions
'are all the text blocks following those words.
'Now we write into Excel.

'Check for open Excel instance; if none, create one
On Error Resume Next
Set appXL = GetObject(, "Excel.Application")
On Error GoTo 0
If appXL Is Nothing Then _
Set appXL = CreateObject("Excel.Application")
appXL.Visible = True
'Create workbook; get first sheet
Set XLwkb = appXL.Workbooks.Add
Set XLwks = XLwkb.Worksheets("Sheet1")

'Stop display updating for faster writing
appXL.ScreenUpdating = False

'Write array elements
For y = 1 To x
XLwks.Cells(y + 1, 1) = aryExport(y, 1)
XLwks.Cells(y + 1, 2) = aryExport(y, 2)
Next y

'Reset display
appXL.ScreenUpdating = True

End If
MsgBox "Done!"
End Sub
 

Excel Facts

Whats the difference between CONCAT and CONCATENATE?
The newer CONCAT function can reference a range of cells. =CONCATENATE(A1,A2,A3,A4,A5) becomes =CONCAT(A1:A5)
Ed

I kept on getting that error when I was trying the code, with/without modifications.

It even happened after I'd closed and re-opened Word.
 
Upvote 0
Okay - it looks like I pasted in the bit of code wrong and overwrote some important parts - like initializing the ranges!! :banghead:

Here's what it should look like (fingers are crossed!!):

Code:
Sub ExportL2RintoExcel()</SPAN>
'Set reference in Tools >> References to MS Excel</SPAN>
Dim doc As Document</SPAN>
'Both Word and Excel have a "range" object</SPAN>
'but with completely different methods and properties</SPAN>
'so we need to make it obvious which we're working with</SPAN>
Dim WDrngAll As Word.Range</SPAN>
Dim WDrngFind As Word.Range</SPAN>
Dim WDrngText As Word.Range</SPAN>
Dim appXL As Excel.Application</SPAN>
Dim XLwkb As Excel.Workbook</SPAN>
Dim XLwks As Excel.Worksheet</SPAN>
Dim x As Long, y As Long, z As Long</SPAN>
'Initiate objects</SPAN>
Set doc = ActiveDocument</SPAN>
Set WDrngAll = doc.Content</SPAN>
x = 1</SPAN>
z = 0</SPAN>
'First, count all instances of "L2R" in the text</SPAN>
With WDrngAll.Find</SPAN>
Do While .Execute(FindText:="L2R", Forward:=True) = True</SPAN>
z = z + 1</SPAN>
Loop</SPAN>
End With</SPAN>
If MsgBox("I find " & z & " instances of L2R. Does this look right? " & _</SPAN>
"Click Yes to continue; click No to quit.", vbYesNo) = vbYes Then</SPAN>
 
'All is good, so let's go!</SPAN>
'Dim an array for our info</SPAN>
z = z + 2</SPAN>
ReDim aryExport(z, 2) As String</SPAN>
 
'In Word VBA, Find searchs a range of text for a string.</SPAN>
'If found, that range shrinks to encompass only that string.</SPAN>
'So we need to set up a series of ranges: the whole doc content,</SPAN>
'a portion of the content to search, and the part to put in the array.</SPAN>
'Could probably be a bit leaner, but this keeps me away from mistakes!</SPAN>
 
'Since we searched this and found text, we don't know what it encompasses,</SPAN>
'so we'll reset it</SPAN>
Set WDrngAll = doc.Content</SPAN>
'Our search range is going to be reset within our loop to stretch from</SPAN>
'the end of the Text range to the end of the All range. This way, the</SPAN>
'range keeps shrinking to encompass only from the end of where we just</SPAN>
'came from to the end of the document. To start, then, we need a Text</SPAN>
'range that is just one single point at the top of the doc.</SPAN>
Set WDrngText = WDrngAll.Duplicate</SPAN>
WDrngText.Collapse wdCollapseStart</SPAN>
 
'Start the search loop</SPAN>
Do</SPAN>
'Initiate Find range</SPAN>
Set WDrngFind = doc.Range(WDrngText.End, WDrngAll.End)</SPAN>
'Find text; TRUE if found</SPAN>
If WDrngFind.Find.Execute(FindText:="L2R", Forward:=True) = True Then</SPAN>
'Found one; WDrngFind now contains only the first found "L2R"</SPAN>
'so we need to stretch the range to encompass the whole word</SPAN>
WDrngFind.MoveEnd wdWord, 1</SPAN>
'Load that into the array</SPAN>
aryExport(x, 1) = Trim(WDrngFind.Text)</SPAN>
'Get the text following</SPAN>
'(I could just keep resetting WDrngFind, but it's too prone to</SPAN>
'human error that I can avoid by using another range object)</SPAN>
 
'''Set WDrngText = doc.Range(WDrngFind.End, WDrngFind.End)
''''WDrngText is now a single point at the end of the found L2R word
''''Move the end forward until we see a period
'''WDrngText.MoveEndUntil "."
'''WDrngText.MoveEnd wdCharacter, 1
''''Put this text into the array
'''aryExport(x, 2) = Trim(WDrngText.Text)
'***************************
'This section changed 1/29/13
'
Set WDrngText = doc.Range(WDrngFind.End, WDrngAll.End)
'WDrngText stretches from the end of the L2R word to the end of the doc
'Now we find the next L2R word
If WDrngText.Find.Execute(FindText:="L2R", Forward:=True) = True Then
'Found the next L2R
'Reset WDrngText to encompass text
WDrngText.SetRange Start:=WDrngFind.End, End:=WDrngText.Start
'Put this text into the array
aryExport(x, 2) = Trim(WDrngText.Text)
Else
'No other L2R; go to end of doc
WDrngText.SetRange Start:=WDrngFind.End, End:=WDrngAll.End
'Put this text into the array
aryExport(x, 2) = Trim(WDrngText.Text)
End If
'
'***************************</SPAN></SPAN>
 
 
x = x + 1</SPAN>
 
'Done here; the Find range resets at the top of the loop</SPAN>
Else</SPAN>
'L2R not found; end loop</SPAN>
Exit Do</SPAN>
End If</SPAN>
Loop</SPAN>
 
'At this point, we should have an array full of text elements.</SPAN>
'In the first positions are the L2R words. In the second positions</SPAN>
'are all the text blocks following those words.</SPAN>
'Now we write into Excel.</SPAN>
 
'Check for open Excel instance; if none, create one</SPAN>
On Error Resume Next</SPAN>
Set appXL = GetObject(, "Excel.Application")</SPAN>
On Error GoTo 0</SPAN>
If appXL Is Nothing Then _</SPAN>
Set appXL = CreateObject("Excel.Application")</SPAN>
appXL.Visible = True</SPAN>
'Create workbook; get first sheet</SPAN>
Set XLwkb = appXL.Workbooks.Add</SPAN>
Set XLwks = XLwkb.Worksheets("Sheet1")</SPAN>
 
'Stop display updating for faster writing</SPAN>
appXL.ScreenUpdating = False</SPAN>
 
'Write array elements</SPAN>
For y = 1 To x</SPAN>
XLwks.Cells(y + 1, 1) = aryExport(y, 1)</SPAN>
XLwks.Cells(y + 1, 2) = aryExport(y, 2)</SPAN>
Next y</SPAN>
 
'Reset display</SPAN>
appXL.ScreenUpdating = True</SPAN>
 
End If</SPAN>
MsgBox "Done!"</SPAN>
End Sub</SPAN>
 
Upvote 0
I'm sorry Ed. I really appreciate your continued help, but I get the same error in the same spot. Same exact information as above in the look window. The most recent one.
 
Upvote 0
Ed

I think the problem is that the loop isn't ending.

If you look at the array when the error happens it's populated.

The code finds out how many occurences of L2R are in the document, so why not use that for the loop?
Code:
Option Explicit

Sub ExportL2RintoExcel()
'Set reference in Tools >> References to MS Excel
Dim doc As Document
    'Both Word and Excel have a "range" object
    'but with completely different methods and properties
    'so we need to make it obvious which we're working with
Dim WDrngAll As Word.Range
Dim WDrngFind As Word.Range
Dim WDrngText As Word.Range
Dim appXL As Excel.Application
Dim XLwkb As Excel.Workbook
Dim XLwks As Excel.Worksheet
Dim x As Long, y As Long, z As Long
Dim I As Long

    'Initiate objects
    Set doc = ActiveDocument
    Set WDrngAll = doc.Content
    z = (Len(WDrngAll) - Len(Replace(WDrngAll, "L2R", ""))) / 3

    x = 1

    If MsgBox("I find " & z & " instances of L2R. Does this look right? " & _
              "Click Yes to continue; click No to quit.", vbYesNo) = vbYes Then

        'All is good, so let's go!
        'Dim an array for our info
        z = z + 2
        ReDim aryExport(z, 2) As String

        'In Word VBA, Find searchs a range of text for a string.
        'If found, that range shrinks to encompass only that string.
        'So we need to set up a series of ranges: the whole doc content,
        'a portion of the content to search, and the part to put in the array.
        'Could probably be a bit leaner, but this keeps me away from mistakes!

        'Since we searched this and found text, we don't know what it encompasses,
        'so we'll reset it
        Set WDrngAll = doc.Content
        'Our search range is going to be reset within our loop to stretch from
        'the end of the Text range to the end of the All range. This way, the
        'range keeps shrinking to encompass only from the end of where we just
        'came from to the end of the document. To start, then, we need a Text
        'range that is just one single point at the top of the doc.
        Set WDrngText = WDrngAll.Duplicate
        WDrngText.Collapse wdCollapseStart

        'Start the search loop
        For I = 1 To z - 2
            'Initiate Find range
            Set WDrngFind = doc.Range(WDrngText.End, WDrngAll.End)
            'Find text; TRUE if found
            If WDrngFind.Find.Execute(FindText:="L2R", Forward:=True) = True Then
                'Found one; WDrngFind now contains only the first found "L2R"
                'so we need to stretch the range to encompass the whole word
                WDrngFind.MoveEnd wdWord, 1
                'Load that into the array
                aryExport(x, 1) = Trim(WDrngFind.Text)
                'Get the text following
                '(I could just keep resetting WDrngFind, but it's too prone to
                'human error that I can avoid by using another range object)

                '''Set WDrngText = doc.Range(WDrngFind.End, WDrngFind.End)
                ''''WDrngText is now a single point at the end of the found L2R word
                ''''Move the end forward until we see a period
                '''WDrngText.MoveEndUntil "."
                '''WDrngText.MoveEnd wdCharacter, 1
                ''''Put this text into the array
                '''aryExport(x, 2) = Trim(WDrngText.Text)
                '***************************
                'This section changed 1/29/13
                '
                Set WDrngText = doc.Range(WDrngFind.End, WDrngAll.End)
                'WDrngText stretches from the end of the L2R word to the end of the doc
                'Now we find the next L2R word
                If WDrngText.Find.Execute(FindText:="L2R", Forward:=True) = True Then
                    'Found the next L2R
                    'Reset WDrngText to encompass text
                    WDrngText.SetRange Start:=WDrngFind.End, End:=WDrngText.Start
                    'Put this text into the array
                    aryExport(x, 2) = Trim(WDrngText.Text)
                Else
                    'No other L2R; go to end of doc
                    WDrngText.SetRange Start:=WDrngFind.End, End:=WDrngAll.End
                    'Put this text into the array
                    aryExport(x, 2) = Trim(WDrngText.Text)
                End If
                '
                '***************************


                x = x + 1

                'Done here; the Find range resets at the top of the loop
            Else
                'L2R not found; end loop

            End If
        Next I


        'At this point, we should have an array full of text elements.
        'In the first positions are the L2R words. In the second positions
        'are all the text blocks following those words.
        'Now we write into Excel.

        'Check for open Excel instance; if none, create one
        On Error Resume Next
        Set appXL = GetObject(, "Excel.Application")
        On Error GoTo 0
        If appXL Is Nothing Then _
           Set appXL = CreateObject("Excel.Application")
        appXL.Visible = True
        'Create workbook; get first sheet
        Set XLwkb = appXL.Workbooks.Add
        Set XLwks = XLwkb.Worksheets("Sheet1")

        'Stop display updating for faster writing
        appXL.ScreenUpdating = False

        'Write array elements
        For y = 1 To x
            XLwks.Cells(y + 1, 1) = aryExport(y, 1)
            XLwks.Cells(y + 1, 2) = aryExport(y, 2)
        Next y

        'Reset display
        appXL.ScreenUpdating = True

    End If
    MsgBox "Done!"
End Sub
 
Upvote 0
That's a good possibility. I haven't tested this, as I don't *cough cough* have a dummy sample doc to run it against.

You said:
x has a value of 2662
z has a value of 2663

That looks to me like it's erroring on the very last loop attempt.
At that point, it's supposed to not find another L2R and extend the range to the end of the doc.
Apparently, one of the ranges has disappeared and can't be used as a refernce point.

Try this:
Put Stop right after Else here:
Code:
                If WDrngText.Find.Execute(FindText:="L2R", Forward:=True) = True Then</SPAN></SPAN>
                    'Found the next L2R</SPAN></SPAN>
                    'Reset WDrngText to encompass text</SPAN></SPAN>
                    WDrngText.SetRange Start:=WDrngFind.End, End:=WDrngText.Start</SPAN></SPAN>
                    'Put this text into the array</SPAN></SPAN>
                    aryExport(x, 2) = Trim(WDrngText.Text)</SPAN></SPAN>
                Else</SPAN></SPAN>
                Stop ''<<<< Right Here
                    'No other L2R; go to end of doc</SPAN></SPAN>
                    WDrngText.SetRange Start:=WDrngFind.End, End:=WDrngAll.End</SPAN></SPAN>
                    'Put this text into the array</SPAN></SPAN>
                    aryExport(x, 2) = Trim(WDrngText.Text)</SPAN></SPAN>
                End If</SPAN></SPAN>

When you hit that Stop, check the Locals and see what happened to the ranges.
 
Upvote 0
Ok, tried it and here are the results:

x is now 2661
y is 0
z is 2663

Does that help? When I was running it before I started this thread, it always came up with 2661. Even when it scans it now it says 2661 on the message box that prompts to continue. So I wasn't understanding the 2662 before and the 2663 for any of this.
 
Upvote 0
Norie I'm sorry. I didn't realize it was different, I just thought you were referencing Ed's.

I ran it and it did work. Thank you very much. I get some of the junk data on the end, from as simple as a "1." to a "xxxxx On-board Segment Requirement Specification 11/12/2012 Rev. 2.7 CONFIDENTIAL AND PROPRIETARY INFORMATION 338 10." since that is in the between L2R's at times. I suspect I may be flat stuck on that piece though. I wish I were stuck - if I have to be - with just the "1." or a "12", but that long tag on at the end is what is gonna get me. Otherwise I would just to a right or a mid in excel and be close enough dropping of the "1." and such.
 
Upvote 0

Forum statistics

Threads
1,223,905
Messages
6,175,297
Members
452,633
Latest member
DougMo

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top