Uppercase just the first word in a textbox

chrisjames25

Registered User.
Local time
Today, 06:08
Joined
Dec 1, 2014
Messages
404
HI I have the following code to ensure that all first letters of every word in a textbox are capitalised:

Code:
Dim LResult As String

        LResult = StrConv(Me.Txt_NewTier3.Value, 3)
        Me.Txt_NewTier3.Value = LResult

Works fine until i enter someone name such as Mike O'Riley and the end result is Mike O'riley.

Is there a solution to this so that it capitalising after an ' also or perhaps just capitalise the first word in a textbox.
 
Are all the entries for this textbox names?
 
Sadly no, i just used names as an example. IN fact what i am using it for is plant species names. For example "Soleil D'Or"

Cheers
 
only thing you can do is scan the text for a quotation character and modify the next character to upper case

Code:
dim p as integer
dim c as integer
p=instr(myName,"'")
if p<>0 then ' there is a D'Or
   c=asc(mid(myName,p+1,1) 'check to see if already a capital
   if c>=97 and c<=122 then ' it is lowercase alpha, so convert to uppercase
        myname=left(myname,p) & chr(c-32) & mid(myname,P+2)
   end if
end if
 
Here is something I use in a database of mine

Call it as

ProperCased = mixed_case(textcontrol)

Eg
? mixed_case("soleil d'or")
Soleil D'Or

HTH


Code:
Option Compare Database
Option Explicit
'************** Code Start *************
'This code was originally written by Jay Holovacs.
'It is not to be altered or distributed,
'except as part of an application.
'You are free to use it in any application,
'provided the copyright notice is left unchanged.
'
'Code Courtesy of
'Jay Holovacs
'
Public Function mixed_case(str As Variant) As String
'returns modified string, first character of each word us uppercase
'all others lower case
Dim ts As String, ps As Integer, char2 As String
    If IsNull(str) Then
        mixed_case = ""
        Exit Function
    End If
    str = Trim(str) 'added 11/22/98
    If Len(str) = 0 Then
        mixed_case = ""
        Exit Function
    End If
    ts = LCase$(str)
    ps = 1
    ps = first_letter(ts, ps)
    Special_Name ts, 1 'try to fix the beginning
    Mid$(ts, 1) = UCase$(Left$(ts, 1))
    If ps = 0 Then
        mixed_case = ts
        Exit Function
    End If
    While ps <> 0
        If is_roman(ts, ps) = 0 Then 'not roman, apply the other rules
            Special_Name ts, ps
            Mid$(ts, ps) = UCase$(Mid$(ts, ps, 1)) 'capitalize the first letter
        End If
        ps = first_letter(ts, ps)
    Wend
    mixed_case = ts
End Function
Private Sub Special_Name(str As String, ps As Integer)
'expects str to be a lower case string, ps to be the
'start of name to check, returns str modified in place
'modifies the internal character (not the initial)

Dim char2 As String
char2 = Mid$(str, ps, 2) 'check for Scots Mc
If (char2 = "mc") And Len(str) > ps + 1 Then '3rd char is CAP
    Mid$(str, ps + 2) = UCase$(Mid$(str, ps + 2, 1))
End If

char2 = Mid$(str, ps, 2) 'check for ff
If (char2 = "ff") And Len(str) > ps + 1 Then 'ff form
    Mid$(str, ps, 2) = LCase$(Mid$(str, ps, 2))
End If

char2 = Mid$(str, ps + 1, 1) 'check for apostrophe as 2nd char
If (char2 = "'") Then '3rd char is CAP
    Mid$(str, ps + 2) = UCase$(Mid$(str, ps + 2, 1))
End If

Dim char3 As String
char3 = Mid$(str, ps, 3) 'check for scots Mac
If (char3 = "mac") And Len(str) > ps + 1 Then 'Mac form
    Mid$(str, ps + 3) = UCase$(Mid$(str, ps + 3, 1))
End If

Dim char4 As String
char4 = Mid$(str, ps, 4) 'check for Fitz
If (char4 = "fitz") And Len(str) > ps + 1 Then 'Fitz form
    Mid$(str, ps + 4) = UCase$(Mid$(str, ps + 4, 1))
End If

End Sub
Private Function first_letter(str As String, ps As Integer) As Integer
'ps=starting point to search (starts with character AFTER ps)
'returns next first letter, 0 if no more left
'modified 6/18/99 to handle hyphenated names
Dim p2 As Integer, p3 As Integer, s2 As String
    s2 = str
    p2 = InStr(ps, str, " ") 'points to next blank, 0 if no more
    p3 = InStr(ps, str, "-") 'points to next hyphen, 0 if no more
    If p3 <> 0 Then
        If p2 = 0 Then
            p2 = p3
        ElseIf p3 < p2 Then
            p2 = p3
        End If
    End If
    If p2 = 0 Then
        first_letter = 0
        Exit Function
    End If
    'first move to first non blank, non punctuation after blank
    While is_alpha(Mid$(str, p2)) = False
        p2 = p2 + 1
        If p2 > Len(str) Then 'we ran off the end
            first_letter = 0
            Exit Function
        End If
    Wend
    first_letter = p2
End Function
Public Function is_alpha(ch As String)
'returns true if this is alphabetic character
'false if not
    Dim c As Integer
    c = Asc(ch)
    Select Case c
        Case 65 To 90
            is_alpha = True
        Case 97 To 122
            is_alpha = True
        Case Else
            is_alpha = False
    End Select
    
End Function
Private Function is_roman(str As String, ps As Integer) As Integer
'starts at position ps, until end of word. If it appears to be
'a roman numeral, than the entire word is capped in passed back
'string, else no changes made in string
'returns 1 if changes were made, 0 if no change
Dim mx As Integer, p2 As Integer, flag As Integer, i As Integer
    mx = Len(str) 'just so we don't go off the edge
    p2 = InStr(ps, str, " ") 'see if there is another space after this word
    If p2 = 0 Then
        p2 = mx + 1
    End If
    'scan to see if any inappropriate characters in this word
    flag = 0
    For i = ps To p2 - 1
        If InStr("ivxIVX", Mid$(str, i, 1)) = 0 Then
            flag = 1
        End If
    Next i
    If flag Then
        is_roman = 0
        Exit Function 'this is not roman numeral
    End If
    Mid$(str, ps) = UCase$(Mid$(str, ps, p2 - ps))
    is_roman = 1
End Function
'************** Code End  *************
 
Mr.gasman can i hijack this.
 
Hi Gasman

Thought that looked good so I tried it on a few names but with 'mixed results':
These worked perfectly
mixed_case("bethan o'sullivan") => Bethan O'Sullivan
mixed_case("hannah mcbride") => Hannah McBride
mixed_case("hugh macdonald") => Hugh MacDonald
?mixed_case("YOLANDE BLANCO GARCIA-VALDECASAS")=> Yolande Blanco Garcia-Valdecasas

BUT these didn't
mixed_case("nancy dell'olio") => Nancy Dell'olio
mixed_case("Nancy Dell'Olio") => Nancy Dell'olio

Looks like it doesn't like apostrophes in the middle of a name
 
Mr.ridders you need to tweak it a little bit.
 
Mr.ridders you need to tweak it a little bit.

Yes I know - I was just pointing out it won't always work perfectly 'out of the box'
That's true of all functions of this type.
The problem is if you have a large number of names of varying types, it isn't always obvious in advance which will fail

And here's another awkward surname: De'ath for which there are at least 4 ways of capitalising it

This is from Wikipedia: https://en.wikipedia.org/wiki/De'Ath
De'Ath or de'Ath may refer to:

Wilfred De'ath (born 1937), a BBC producer
Charles De'Ath (born 1968), an English actor
Rod de'Ath (1950–2014), a Welsh drummer
Giles De'ath, a fictional character in Love and Death on Long Island

Good luck trying to code names like that 'correctly'
 
Last edited:
Perhaps CJ_London's approach would do it.?

Or tweak this part?
Code:
char2 = Mid$(str, ps + 1, 1) 'check for apostrophe as 2nd char
If (char2 = "'") Then '3rd char is CAP
    Mid$(str, ps + 2) = UCase$(Mid$(str, ps + 2, 1))
End If

My attempt
Code:
'char2 = Mid$(str, ps + 1, 1) 'check for apostrophe as 2nd char
'If (char2 = "'") Then '3rd char is CAP
'    Mid$(str, ps + 2) = UCase$(Mid$(str, ps + 2, 1))
'End If

' Allow for a ' anywhere and then UCASE the next character
For iLen = ps To Len(str)
    char2 = Mid$(str, iLen, 1) 'check for apostrophe
    If (char2 = "'") Then 'next char is CAP
        Mid$(str, iLen + 1) = UCase$(Mid$(str, iLen + 1, 1))
    End If
Next

? mixed_case("nancy dell'olio")
Nancy Dell'Olio

? mixed_case("wilfred de'ath")
Wilfred De'Ath

FWIW those last two de'ath's all appear to be De'Ath when I google them?, but I would apply the rule as next character after the apostrophe is uppercased.

Hi Gasman

Thought that looked good so I tried it on a few names but with 'mixed results':
These worked perfectly
mixed_case("bethan o'sullivan") => Bethan O'Sullivan
mixed_case("hannah mcbride") => Hannah McBride
mixed_case("hugh macdonald") => Hugh MacDonald
?mixed_case("YOLANDE BLANCO GARCIA-VALDECASAS")=> Yolande Blanco Garcia-Valdecasas

BUT these didn't
mixed_case("nancy dell'olio") => Nancy Dell'olio
mixed_case("Nancy Dell'Olio") => Nancy Dell'olio

Looks like it doesn't like apostrophes in the middle of a name
 
Last edited:
Perhaps CJ_London's approach would do it.?

Or tweak this part?
Code:
char2 = Mid$(str, ps + 1, 1) 'check for apostrophe as 2nd char
If (char2 = "'") Then '3rd char is CAP
    Mid$(str, ps + 2) = UCase$(Mid$(str, ps + 2, 1))
End If

The function is one of the best I've seen for this type of task.
You could certainly adapt the code so the first letter after an apostrophe is capitalised (as CJ London suggested)

However, I don't see how any function could manage every possible variation in capitalisation.
For a start the many variations on De'ath would be the 'death' of any guarantee of success.

This article lists some common myths programmers have about handling names:
https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/
I've seen another version with examples somewhere but can't remember where

Here is another similar article, this time myths about addresses - with examples this time:
https://www.mjt.me.uk/posts/falsehoods-programmers-believe-about-addresses/
 
Last edited:

Users who are viewing this thread

Back
Top Bottom