Capital Letters

D

David McRitchie

Of course it is difficult to send without a *valid* email address
so if you want my test workbook, email me before I forget
which Excel workbook.
 
G

Guest

Hello again,
Though I think the usual requirement would be that the first letter
and/or first letter after a period (or ? or !) would all that would
need to be changed so I would leave out the initial conversion to
lowercase, except that that was a requirement of the poster.
For which I previously indicated I would have used a separate
macro to convert everything to lowercase first if really needed
Rather than destroying existing proper nouns.

Thanks for testing David.

Actually, David, other than the fact that I hard-coded LCase() in the
function (once), my function pretty much does that. See the following:

'-------------------
Function sCase2(ByRef strIn As String) As String
Dim bArr() As Byte, i As Long, i2 As Long
If strIn = vbNullString Then Exit Function
Let bArr = StrConv(strIn, vbFromUnicode)
Select Case bArr(0)
Case 97 To 122
bArr(0) = bArr(0) - 32
End Select
For i = 1 To UBound(bArr)
Select Case bArr(i)
Case 105
If Not i = UBound(bArr) Then
Select Case bArr(i + 1)
Case 32, 33, 39, 44, 46, 58, 59, 63, 148, 160
If bArr(i - 1) = 32 Then _
bArr(i) = bArr(i) - 32
End Select
ElseIf bArr(i - 1) = 32 Then _
bArr(i) = bArr(i) - 32
End If
Case 33, 46, 58, 63
For i2 = i + 1 To UBound(bArr)
Select Case bArr(i2)
Case 97 To 122
bArr(i2) = bArr(i2) - 32
i = i2: Exit For
End Select
If bArr(i2) <> 32 And bArr(i2) <> 33 And bArr(i2) <> 46 _
And bArr(i2) <> 63 And bArr(i2) <> 160 Then
i = i2: Exit For
End If
Next
End Select
Next
sCase2 = StrConv(bArr, vbUnicode)
End Function

Sub testTime()
Debug.Print sCase2(LCase$("hello? erm, i'M only testing, eh. indeed, " & _
"i am inquisitve."))
Debug.Print sCase2(LCase$("how old?! 22 Years."))
Debug.Print sCase2(LCase$("how old?! twenty-two Years."))
Debug.Print sCase2(LCase$("hmmmm.... wOrking?!?! sam i am. yes-no? " & _
"isn't i'm isn't."))
Debug.Print sCase2(LCase$("THE DAY WAS SUNNY AND I WORE A HAT.PETER WAS
THERE"))
Debug.Print sCase2(LCase$("no WorRies, i'm ONLY testIng! yes-no?"))
Debug.Print sCase2(LCase$("mY fRiend & i"))
Debug.Print sCase2(LCase$("iiiiiiiiiiiiii"))
Debug.Print sCase2(LCase$("***T. toast %T i @"))
Debug.Print sCase2(LCase$("re: sentences."))
Debug.Print sCase2("hello? thought i'd test this for David McRitchie.
NOTHING.")
End Sub
'-------------------

Doesn't help the OP much, unless they know to use LCase$() as I have.

I'm going to leave this as a function on my end. It helps distinguish the
two different processes going on here: String parsing and Object Property
manipulation. And, it makes resuse a lot easier than cutting up the in-line
procedure. This says nothing to in-line procedures being more efficient, I'll
agree with you on this as it's true.

Peter,
Thanks for your follow up, I agree with some of your points but not entirely
<g>. You had already sold me on the idea of the Byte Array method but I
could still be a buyer of RegExp.

I'm not sure I'm all out anti RegExp, I just wanted to help Teresa out and
this made sense to me for a variety of reasons.
Despite my allowances for the references, my limited test was still not
quite comparable, Tushar's routine also and necessarily includes some string
functions.

1.6 x slower than extremely fast is still extremely fast. With small qty's
of strings
(say 1200) and called occasionally, to me, then it is inconsequential.
That's not the same as insignificant but other factors become more
important. It's a kind of Quick vs Bubble Sort choice.

As does mine. Well there are other factors. Does everyone know RegExp? Does
everyone have RegExp? What about those pesky question marks, etc... There are
more considerations.

0 X? Can SentCap return a String? I wouldn't mind testing that function in
its own right without having to rework it (I've had my share of reworking for
this thread said:
Why - I understand it well, only took a few minutes to write, and rightly or
lazily to me that's a consideration. Corrections and acronyms etc are easy
to include, even by a VBA novice later without needing to understand the
entire function (I think), albeit at some degradation in performance. In
other words easy to maintain.

Common argument. However, I tend to stay away from the 'let's program to the
lowest common denominator so that everyone gets it' point of view or
practice. We can talk about execution time, # of code lines, compatibility,
disk footprint, but I find the latter to be too relative and gray to make any
sense of, I don't know what the base is, so I don't do it.

Here's what I will say however, byte arrays aren't as scary as they may
seem. I'd recommend learning more about them and perhaps commenting your
code. Bruce McKinney's Hardcore Visual Basic might be as good a place to
start as any:

http://vb.mvps.org/hardcore/html/whatisunicode.htm
http://brucem.mystarband.net/mckinney2b.htm#12

Once you get a handle on them, you can crank them out pretty quickly, not as
quick as they execute, but my first pass at SCase() didn't take too long,
really. And you can cover a lot of ground with a fairly short function.

But, I'm agreeable to disagreeing.

Funny, I had never seen the second link above before. For international
issues (although I'd wonder if we should capitalize Is at this point), it
might make more sense to use the API calls Bruce flags for us. E.g.,

'-----------------
Private Declare Function IsCharLower Lib "user32" Alias "IsCharLowerA" ( _
ByVal cChar As Byte) As Long

Declare Function CharUpperBuffB Lib "user32" Alias "CharUpperBuffA" ( _
lpsz As Byte, _
ByVal cchLength As Long) As Long

Function sCase3(ByVal strIn As String) As String
Dim bArr() As Byte, I As Long, i2 As Long
If strIn = vbNullString Then Exit Function
Let bArr = StrConv(strIn, vbFromUnicode)
CharUpperBuffB bArr(0), 1
For I = 1 To UBound(bArr)
Select Case bArr(I)
Case 105
If Not I = UBound(bArr) Then
Select Case bArr(I + 1)
Case 32, 33, 39, 44, 46, 58, 59, 63, 148, 160
If bArr(I - 1) = 32 Then _
CharUpperBuffB bArr(I), 1
End Select
ElseIf bArr(I - 1) = 32 Or bArr(I - 1) = 160 Then _
CharUpperBuffB bArr(I), 1
End If
Case 33, 46, 58, 63
For i2 = I + 1 To UBound(bArr)
If IsCharLower(bArr(i2)) Then
CharUpperBuffB bArr(i2), 1
I = i2: Exit For
End If
If bArr(i2) <> 32 And bArr(i2) <> 33 And bArr(i2) <> 46 _
And bArr(i2) <> 63 And bArr(i2) <> 160 Then
I = i2: Exit For
End If
Next
End Select
Next
sCase3 = StrConv(bArr, vbUnicode)
End Function

Sub testTime44()
Debug.Print sCase3(LCase$("À LA CARTE")) 'Something
Debug.Print LCase$("À LA CARTE") 'Something
Debug.Print sCase3("À LA CARTE") 'Nothing
End Sub
'-----------------

The original SCase() while faster, can't handle 'à'.

Have a good evening,
Nate Oliver
 
G

Guest

Why - I understand it well, only took a few minutes to write, and rightly
or
Common argument. However, I tend to stay away from the 'let's program to the
lowest common denominator so that everyone gets it' point of view or
practice. We can talk about execution time, # of code lines, compatibility,
disk footprint, but I find the latter to be too relative and gray to make any
sense of, I don't know what the base is, so I don't do it.

Pretty serious typo, I meant former, not latter. Sorry about that.

Regards,
NPO
 
P

Peter T

Of course it is difficult to send without a *valid* email address
so if you want my test workbook, email me before I forget
which Excel workbook.

The thinly disguised address in my previous message is valid (again copied
below). Also I emailed you direct yesterday. Not sure if you received it, if
not please advise.

Regards,
Peter T

pmbthornton at gmail dot com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top