End With without With - except there is a With - Solved

User avatar
Charles Kenyon
4StarLounger
Posts: 596
Joined: 10 Jan 2016, 15:56
Location: Madison, Wisconsin

End With without With - except there is a With - Solved

Post by Charles Kenyon »

I figured it out. See following posts.
Key thing I learned was:
It seems to be an annoying thing that VB does not examine each structure individually, rather it treats them all like they were the same and simply counts the opening and closing statements for all blocks... when they do not balance, VB simply assumes the last block structure is at fault.... At least that had always been the case for me in Excel. I am not sure why in this case it did not say you had a For without Next...
I guess when you get this sort of error you should just ignore what it says specifically and just go through all your If, For, With .. etc… blocks.
Someone posted what appears to be a vba homework question on the Word forum (url below). It looked like an interesting challenge to me so I started writing a procedure. It is to look at the first and last character in each word and if the character is a vowel, to change the color of the word.
https://www.msofficeforums.com/word/45 ... post152576

When I try to run it, though, I get an "End With without With" error. But there is a with, and only one.
Here is the code:

Code: Select all

Sub VowelsTest()
    ' Charles Kenyon
    ' https://www.msofficeforums.com/word/45285-need-help-vba-assignment.html#post152576
    Dim iWordCount As Long
    Dim iSentenceCount As Long
    Dim i As Long ' counter
    Dim strChar As String
    Dim iMarker As Long
    Dim iCharacters As Long
    '
    Let iSentenceCount = ActiveDocument.Sentences.Count
    Let iWordCount = ActiveDocument.Words.Count
    For i = 1 To iWordCount
        With ActiveDocument.Words(i)
            Let iMarker = 0
            Let iCharacters = .Characters.Count
            Let strChar = .Characters(1)
            If VowelTest(strChar) = True Then iMarker = 1 ' First character is a vowel
            Let strChar = .Characters(iCharacters)
            If VowelTest(strChar) = True Then ' Last character is a vowel
                If iMarker = 1 Then  ' Both first and last are vowels
                Let iMarker = 3
            Else
                Let iMarker = 2 ' Only last character is a vowel
            End If
            Select Case iMarker
                Case 1
                    .Font.ColorIndex = wdYellow
                Case 2
                    .Font.ColorIndex = wdBlue
                Case 3
                    .Font.ColorIndex = wdGreen
            End Select
        End With
    Next i
    
End Sub

Private Function VowelTest(strChar As String) As Boolean
    ' True if strChar is a vowel in English
    VowelTest = False
    Select Case strChar
        Case "a", "A", "e", "E", "i", "I", "o", "O", "u", "U", "y", "Y"
            VowelTest = True
    End Select
End Function
BTW: That it is an assignment is a guess. I added the part to the title about that. I do not intend to provide this to the student, until we see some effort and thinking.
Last edited by Charles Kenyon on 13 Jul 2020, 21:09, edited 2 times in total.

User avatar
Charles Kenyon
4StarLounger
Posts: 596
Joined: 10 Jan 2016, 15:56
Location: Madison, Wisconsin

Re: End With without With - except there is a With

Post by Charles Kenyon »

It runs OK if I comment out

Code: Select all

'            If VowelTest(strChar) = True Then ' Last character is a vowel
'                If iMarker = 1 Then  ' Both first and last are vowels
'                Let iMarker = 3
'            Else
'                Let iMarker = 2 ' Only last character is a vowel
'            End If

User avatar
StuartR
Administrator
Posts: 12577
Joined: 16 Jan 2010, 15:49
Location: London, Europe

Re: End With without With - except there is a With

Post by StuartR »

I think you are missing an End If in the section that you quoted above.

This version works fine

Code: Select all

Option Explicit

Sub VowelsTest()
    ' Charles Kenyon
    ' https://www.msofficeforums.com/word/45285-need-help-vba-assignment.html#post152576
    Dim iWordCount As Long
    Dim iSentenceCount As Long
    Dim i As Long ' counter
    Dim strChar As String
    Dim iMarker As Long
    Dim iCharacters As Long
    '
    Let iSentenceCount = ActiveDocument.Sentences.Count
    Let iWordCount = ActiveDocument.Words.Count
    For i = 1 To iWordCount
        With ActiveDocument.Words(i)
            Let iMarker = 0
            Let iCharacters = .Characters.Count
            Let strChar = .Characters(1)
            If VowelTest(strChar) = True Then iMarker = 1 ' First character is a vowel
            Let strChar = .Characters(iCharacters)
            If VowelTest(strChar) = True Then ' Last character is a vowel
                If iMarker = 1 Then  ' Both first and last are vowels
                Let iMarker = 3
            Else
                Let iMarker = 2 ' Only last character is a vowel
            End If
            End If
            Select Case iMarker
                Case 1
                    .Font.ColorIndex = wdYellow
                Case 2
                    .Font.ColorIndex = wdBlue
                Case 3
                    .Font.ColorIndex = wdGreen
            End Select
        End With
    Next i
    
End Sub

Private Function VowelTest(strChar As String) As Boolean
    ' True if strChar is a vowel in English
    VowelTest = False
    Select Case strChar
        Case "a", "A", "e", "E", "i", "I", "o", "O", "u", "U", "y", "Y"
            VowelTest = True
    End Select
End Function
StuartR


User avatar
Charles Kenyon
4StarLounger
Posts: 596
Joined: 10 Jan 2016, 15:56
Location: Madison, Wisconsin

Re: End With without With - except there is a With

Post by Charles Kenyon »

Thank you Stuart.

I figured it out before I saw your post but you are spot on.
I had two If statements and only one End If

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

Re: End With without With - except there is a With - Solved

Post by Doc.AElstein »

It seems to be an annoying thing that VB does not examine each structure individually, rather it treats them all like they were the same and simply counts the opening and closing statements for all blocks... when they do not balance, VB simply assumes the last block structure is at fault.... At least that had always been the case for me in Excel. I am not sure why in this case it did not say you had a For without Next...
I guess when you get this sort of error you should just ignore what it says specifically and just go through all your If, For, With .. etc… blocks.

Alan
P.S.
Hey Charles, you use Let , I thought I was the only one :)
( Be careful, it contributed to me being banned from one place, since it annoyed someone so much…. )
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
Charles Kenyon
4StarLounger
Posts: 596
Joined: 10 Jan 2016, 15:56
Location: Madison, Wisconsin

Re: End With without With - except there is a With - Solved

Post by Charles Kenyon »

Hi Alan,

Too bad about using Let. I've adopted using it in the last year or so simply to distinguish from Set. I'm an old Fortran programmer and like as much structure as I can get. If I get banned, their loss.

Thanks for the tip about the error message simply counting pairs. It begins to make sense!

User avatar
Guessed
2StarLounger
Posts: 102
Joined: 04 Feb 2010, 22:44
Location: Melbourne Australia

Re: End With without With - except there is a With - Solved

Post by Guessed »

Charles
I had a play to see how short the code could be. This is what I got to.

Code: Select all

Sub VowelsTest()
  Dim aWord As Range, sWord As String, sFirst As String, sLast As String
  For Each aWord In ActiveDocument.Words
    sWord = LCase(Trim(aWord))
    sFirst = Left(sWord, 1)
    sLast = Right(sWord, 1)
    If VowelTest(sFirst) Then
      If VowelTest(sLast) Then
        aWord.Font.ColorIndex = wdGreen
      Else
        aWord.Font.ColorIndex = wdYellow
      End If
    ElseIf VowelTest(sLast) Then
      aWord.Font.ColorIndex = wdBlue
    End If
  Next aWord
End Sub

Private Function VowelTest(strChar As String) As Boolean
  VowelTest = InStr("aeiou", strChar) > 0    ' True if strChar is a lowercase vowel in English
End Function
I must say I'm intrigued that 'y' would appear in your vowel list - what you Americans have done to the mother tongue is treasonous :grin:
Andrew Lockton
Melbourne Australia

User avatar
Charles Kenyon
4StarLounger
Posts: 596
Joined: 10 Jan 2016, 15:56
Location: Madison, Wisconsin

Re: End With without With - except there is a With - Solved

Post by Charles Kenyon »

Nice! :cheers:

"The United States and Great Britain are two countries separated by a common language."
Last edited by Charles Kenyon on 29 Jul 2020, 15:34, edited 1 time in total.

User avatar
Charles Kenyon
4StarLounger
Posts: 596
Joined: 10 Jan 2016, 15:56
Location: Madison, Wisconsin

Re: End With without With - except there is a With - Solved

Post by Charles Kenyon »

I am surprised that Trim works on a range. Is this true of all string functions? The result is a string and not a range. :scratch:

This runs very quickly compared to my original code. :flee:
I ran a timer and your code took about 4.3 seconds, mine: 1358 seconds! :clapping:

I added pages of text to test timing. The document with both sets of code is in Dropbox. https://www.dropbox.com/s/ngdv836l6shi0 ... .docm?dl=0

I added comments for my own use.

Code: Select all

'==============================================================================
' Andrew Lockton - Eileen's Lounge
' https://eileenslounge.com/viewtopic.php?f=26&t=34959&p=272199#p272199
Sub VowelsTest2()
    ' DECLARE VARIABLES
  Dim aWord As Range, sWord As String, sFirst As String, sLast As String
  '
  For Each aWord In ActiveDocument.Words    ' Loop through words in document
    sWord = LCase(Trim(aWord))              ' Only lowercase tested using this
    sFirst = Left(sWord, 1)                 ' First letter of word
    sLast = Right(sWord, 1)                 ' Last letter of word
    If VowelTest2(sFirst) Then              ' Test first letter
      If VowelTest2(sLast) Then             ' Test last letter
        aWord.Font.ColorIndex = wdGreen     ' Both vowels - turn word green - note test was on sWord, change is to aWord
      Else
        aWord.Font.ColorIndex = wdYellow    ' Only first is vowel turn word yellow
      End If
    ElseIf VowelTest2(sLast) Then           ' First is not vowel - test last
      aWord.Font.ColorIndex = wdBlue        ' Only last is vowel turn word blue
    End If
  Next aWord                                ' End looping of words
End Sub

Private Function VowelTest2(strChar As String) As Boolean
  VowelTest2 = InStr("aeiou", strChar) > 0    ' True if strChar is a lowercase vowel in English
End Function
'==============================================================================[code]
Last edited by Charles Kenyon on 29 Jul 2020, 16:49, edited 5 times in total.

User avatar
HansV
Administrator
Posts: 78235
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: End With without With - except there is a With - Solved

Post by HansV »

Andrew is very good at Word VBA!
Best wishes,
Hans

User avatar
Jay Freedman
Microsoft MVP
Posts: 1312
Joined: 24 May 2013, 15:33
Location: Warminster, PA

Re: End With without With - except there is a With - Solved

Post by Jay Freedman »

Charles Kenyon wrote:
29 Jul 2020, 15:33
I am surprised that Trim works on a range. Is this true of all string functions? The result is a string and not a range. :scratch:
That works because the .Text property is the "default property" of a Range object. VBA coerces the reference to aWord into aWord.Text because the Trim function requires a String argument. You can see similar behavior if you execute Debug.Print aWord.

User avatar
Charles Kenyon
4StarLounger
Posts: 596
Joined: 10 Jan 2016, 15:56
Location: Madison, Wisconsin

Re: End With without With - except there is a With - Solved

Post by Charles Kenyon »

:cheers: Thank you for the clarification, Jay.