Microsoft Access 2010 All Capitalize First Letter of Every WOrd (1 Viewer)

marlind

Registered User.
Local time
Today, 12:28
Joined
Oct 9, 2007
Messages
19
I am using a function I found at it works most of the time Except WHen a Name Has a suffix like your name III will change to Your Name Iii. Here is the function
Function Proper(X)
'Capitalize first letter of every word in a field.


Dim Temp$, C$, OldC$, i As Integer

If IsNull(X) Then

Exit Function

Else

Temp$ = CStr(LCase(X))

' Initialize OldC$ to a single space because first
' letter must be capitalized but has no preceding letter.

OldC$ = " "

For i = 1 To Len(Temp$)
C$ = Mid$(Temp$, i, 1)
If C$ >= "a" And C$ <= "z" And (OldC$ < "a" Or OldC$ > "z") Then
Mid$(Temp$, i, 1) = UCase$(C$)

End If
OldC$ = C$

Next i

Proper = Temp$


End If

End Function
I have attempt to break thru this and try to figure out a way to capitalize all words but III. Could be II also. I have not been able parse the suffix of the name because it could come at the 2nd third or fourth name. I hope someone can offer suggestions. I thought about case statements but not sure where I would put it. Thanks
 

marlind

Registered User.
Local time
Today, 12:28
Joined
Oct 9, 2007
Messages
19
I didn't say what the function was doing III because Iii and II will be come Ii. Thanks again.
 

MarkK

bit cruncher
Local time
Today, 12:28
Joined
Mar 17, 2004
Messages
8,187
There is also the VBA.StrConv() function that has a vbProperCase option.

Then you could make a list of exceptions and run through that list and find instances of those exceptions that exist in your target string, and replace those.

I would store the exceptions in a table, which you can then maintain fairly easily.
 

missinglinq

AWF VIP
Local time
Today, 15:28
Joined
Jun 20, 2003
Messages
6,420
Your title says "Capitalize First Letter of Every Word" but you then only talk about names; is it only names that you're trying to handle, here?

I've got a copy of a beautiful hack that that I can post. It parses names correctly, and not only handles names like Thruston Howell, III, but hyphenated names, names like O'Brien and McNamara, and a whole slew more!

Linq ;0)>
 

marlind

Registered User.
Local time
Today, 12:28
Joined
Oct 9, 2007
Messages
19
It is only the names but some people have two last names. I thought I had it solved but the user didn't like the all caps.
 

missinglinq

AWF VIP
Local time
Today, 15:28
Joined
Jun 20, 2003
Messages
6,420
Here's the hack I mentioned, from gentlemen by the name of Jay Holovacs, Dev Ashish and Arvin Meyer! You are free to use it in your applications, gratis, but please leave the copyright notice intact, as requested, and do not attempt to alter the code! Leaving the code as is a condition for the free use of the code, and I believe you'll find that there is no need to alter it.

Place these Functions in a Standard Module and name the module NameCaps:
Code:
'************** 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
'
'© 1998-2004, Dev Ashish & Arvin Meyer, All rights reserved. Optimized

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  *************

Now, to use it, place this code in a Textbox AfterUpdate event:

Code:
Private Sub TextBoxName_AfterUpdate()
  Me.TextBoxName = mixed_case(Me.TextBoxName)
End Sub

Linq ;0)>
 

marlind

Registered User.
Local time
Today, 12:28
Joined
Oct 9, 2007
Messages
19
Thank you very much missingling. Worked on this all day yesterday before I posted the question.
 

missinglinq

AWF VIP
Local time
Today, 15:28
Joined
Jun 20, 2003
Messages
6,420
Thanks should go to Holovacs, Ashish and Meyer! It truly is a beautiful hack, and took a good deal of time to develop, I expect!

Glad it helps you!

Linq ;0)>
 

tellorin

New member
Local time
Today, 15:28
Joined
Oct 7, 2015
Messages
1
This is great! Only one issue I have had with it is that it changes a name like Mackenzie into MacKenzie. Anyone have a suggestion on how to fix that?
 

Accessna

Registered User.
Local time
Today, 12:28
Joined
Oct 4, 2015
Messages
15
Posted 8 Nov 2004 from AbuHadi at Officena website.

Also I have posted a thread about resizing the TextBox which we can use same idea to get the result from MS Excel.


Code:
Function Proper(Text As Variant) As Variant
  Dim K As Integer
  Dim NewText As String
  Dim Found As Boolean

  Proper = Text
  If VarType(Text) <> vbString Then Exit Function

  Found = True
  For K = 1 To Len(Text)
    Select Case Mid(Text, K, 1)
      Case "A" To "Z", "a" To "z"
        If Found Then
          NewText = NewText & UCase(Mid(Text, K, 1))
          Found = False
        Else
          NewText = NewText & LCase(Mid(Text, K, 1))
        End If
      Case Else
        NewText = NewText & Mid(Text, K, 1)
        Found = True
    End Select
  Next K

  Proper = NewText
End Function
 

Accessna

Registered User.
Local time
Today, 12:28
Joined
Oct 4, 2015
Messages
15
You can remove or add any word you like to array A.

Code:
Function ProperII(ByVal Text As Variant) As String
  Dim A
  A = Array("II", "III", "IV", "VI", "VII", "VIII", "IX", "XI", "XII", "XIII", "XIV", "XV")
  Dim String2 As String
  Dim i   As Integer
  Dim Pos As Integer
 
  Text = " " & StrConv(Nz(Text, ""), vbProperCase) & " "
 
  For i = 0 To UBound(A)
    String2 = " " & UCase(A(i)) & " "
    Pos = 0
    Do
      Pos = InStr(Pos + 1, Text, String2)
      If Pos > 0 Then
        Text = Left(Text, Pos - 1) & String2 & Mid(Text, Pos + Len(String2))
      End If
    Loop Until Pos = 0
  Next i
 
  ProperII = Mid(Text, 2, Len(Text) - 2)
End Function
 
Last edited:

Accessna

Registered User.
Local time
Today, 12:28
Joined
Oct 4, 2015
Messages
15
One more fix for tellorin.

Code:
Function ProperIII(ByVal Text As Variant) As String
  Dim A, B
  A = Array("II", "III", "IV", "VI", "VII", "VIII", "IX", "XI", "XII", "XIII", "XIV", "XV")
  B = Array("MacKenzie", "McDonalds", "TextBox")
  Dim String2 As String
  Dim i   As Integer
  Dim Pos As Integer
  
  Text = " " & StrConv(Nz(Text, ""), vbProperCase) & " "
  
  For i = 0 To UBound(A)
    String2 = " " & UCase(A(i)) & " "
    Pos = 0
    Do
      Pos = InStr(Pos + 1, Text, String2)
      If Pos > 0 Then
        Text = Left(Text, Pos - 1) & String2 & Mid(Text, Pos + Len(String2))
      End If
    Loop Until Pos = 0
  Next I
 
  For i = 0 To UBound(B)
    String2 = " " & B(i) & " "
    Pos = 0
    Do
      Pos = InStr(Pos + 1, Text, String2)
      If Pos > 0 Then
        Text = Left(Text, Pos - 1) & String2 & Mid(Text, Pos + Len(String2))
      End If
    Loop Until Pos = 0
  Next i
  
  ProperIII = Mid(Text, 2, Len(Text) - 2)
End Function
 

Users who are viewing this thread

Top Bottom