I'm not sure what's the source of your problem's with Ivan's code. It works reasonably well for me (a few glitches with Sentence case, but that may be happening because of merged cells).
Anyhow, I wrote most of this a while ago, but went back and tried to shore up some weaknesses. It does not ask which case you want, but rather it toggles through U-->L-->P. It does this on a cell-by-cell basis. It will also work for some drawing objects and chart objects.
Hope you find it useful:
<font face=Courier New><SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯</SPAN>
<SPAN style="color:#00007F">Sub</SPAN> ChangeCase()
<SPAN style="color:#007F00">'_______________</SPAN>
<SPAN style="color:#007F00">' Toggles case on items in selection. Selection can be</SPAN>
<SPAN style="color:#007F00">' cells, certain drawing objects and certain chart objects.</SPAN>
<SPAN style="color:#007F00">' written by Greg Truby</SPAN>
<SPAN style="color:#00007F">If</SPAN> TypeName(Selection) <> "Range" <SPAN style="color:#00007F">Then</SPAN> <SPAN style="color:#00007F">GoTo</SPAN> OtherItemSelected
<SPAN style="color:#00007F">Dim</SPAN> strMsg <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> r <SPAN style="color:#00007F">As</SPAN> Range, r1 <SPAN style="color:#00007F">As</SPAN> Range, r2 <SPAN style="color:#00007F">As</SPAN> Range
<SPAN style="color:#00007F">On</SPAN> <SPAN style="color:#00007F">Error</SPAN> <SPAN style="color:#00007F">Resume</SPAN> <SPAN style="color:#00007F">Next</SPAN>
<SPAN style="color:#00007F">Set</SPAN> r1 = Selection.SpecialCells(xlCellTypeConstants, XlSpecialCellsValue.xlTextValues)
<SPAN style="color:#00007F">If</SPAN> r1 <SPAN style="color:#00007F">Is</SPAN> <SPAN style="color:#00007F">Nothing</SPAN> <SPAN style="color:#00007F">Then</SPAN>
<SPAN style="color:#00007F">If</SPAN> ActiveSheet.ProtectContents <SPAN style="color:#00007F">Then</SPAN>
strMsg = "This macro will fail if the worksheet is protected."
<SPAN style="color:#00007F">Else</SPAN>
strMsg = "No text cells in selection. Only numbers, dates &/or formulas"
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN>
MsgBox strMsg, vbExclamation, "No Text Cells"
<SPAN style="color:#00007F">Exit</SPAN> <SPAN style="color:#00007F">Sub</SPAN>
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">Set</SPAN> r = Selection
<SPAN style="color:#007F00">' UndoLoad r</SPAN>
<SPAN style="color:#00007F">For</SPAN> <SPAN style="color:#00007F">Each</SPAN> r1 <SPAN style="color:#00007F">In</SPAN> r.Cells
<SPAN style="color:#00007F">Set</SPAN> r2 = r1.SpecialCells(xlCellTypeConstants, XlSpecialCellsValue.xlTextValues)
<SPAN style="color:#00007F">If</SPAN> <SPAN style="color:#00007F">Not</SPAN> r2 <SPAN style="color:#00007F">Is</SPAN> <SPAN style="color:#00007F">Nothing</SPAN> <SPAN style="color:#00007F">Then</SPAN>
<SPAN style="color:#00007F">If</SPAN> <SPAN style="color:#00007F">Not</SPAN> Intersect(r1, r2) <SPAN style="color:#00007F">Is</SPAN> <SPAN style="color:#00007F">Nothing</SPAN> <SPAN style="color:#00007F">Then</SPAN>
<SPAN style="color:#00007F">If</SPAN> r2.Count > r1.Count <SPAN style="color:#00007F">Then</SPAN> <SPAN style="color:#00007F">Set</SPAN> r2 = r1
r2.Value = ChangeTextCase(r2.Value)
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">Next</SPAN> r1
<SPAN style="color:#007F00">' Application.OnUndo "Undo ChangeCase", "UndoRestore"</SPAN>
<SPAN style="color:#00007F">Exit</SPAN> <SPAN style="color:#00007F">Sub</SPAN>
OtherItemSelected:
<SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯</SPAN>
<SPAN style="color:#00007F">On</SPAN> <SPAN style="color:#00007F">Error</SPAN> <SPAN style="color:#00007F">GoTo</SPAN> ErrorHandler
<SPAN style="color:#00007F">Dim</SPAN> varObject <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN>
<SPAN style="color:#00007F">If</SPAN> TypeName(Selection) = "DrawingObjects" <SPAN style="color:#00007F">Then</SPAN>
<SPAN style="color:#00007F">For</SPAN> <SPAN style="color:#00007F">Each</SPAN> varObject <SPAN style="color:#00007F">In</SPAN> Selection
CaseForShapes varObject
<SPAN style="color:#00007F">Next</SPAN> varObject
<SPAN style="color:#00007F">Else</SPAN>
CaseForShapes Selection
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN>
<SPAN style="color:#00007F">Exit</SPAN> <SPAN style="color:#00007F">Sub</SPAN>
ErrorHandler:
<SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯</SPAN>
Beep
MsgBox "Could not execute macro." & vbCrLf & vbCrLf & _
"Check to see if the Worksheet or Workbook has Protection turned on.", _
vbCritical, "Error"
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN>
<SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯</SPAN>
<SPAN style="color:#00007F">Sub</SPAN> CaseForShapes(varObject <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN>)
<SPAN style="color:#007F00">'______________________________________</SPAN>
<SPAN style="color:#00007F">Dim</SPAN> strText <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN>
<SPAN style="color:#00007F">Select</SPAN> <SPAN style="color:#00007F">Case</SPAN> TypeName(varObject)
<SPAN style="color:#00007F">Case</SPAN> "Rectangle", "Oval"
strText = varObject.Characters.Text
strText = ChangeTextCase(strText)
varObject.Characters.Text = strText
<SPAN style="color:#00007F">Case</SPAN> "TextBox", "ChartTitle", "AxisTitle"
strText = varObject.Text
strText = ChangeTextCase(strText)
varObject.Text = strText
<SPAN style="color:#00007F">Case</SPAN> <SPAN style="color:#00007F">Else</SPAN>
Beep
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Select</SPAN>
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN>
<SPAN style="color:#007F00">'¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯</SPAN>
<SPAN style="color:#00007F">Function</SPAN> ChangeTextCase(<SPAN style="color:#00007F">ByVal</SPAN> strText <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN>) <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN>
<SPAN style="color:#007F00">'_________________________________________________________</SPAN>
<SPAN style="color:#00007F">If</SPAN> strText = UCase(strText) <SPAN style="color:#00007F">Then</SPAN>
strText = LCase(strText)
<SPAN style="color:#00007F">ElseIf</SPAN> strText = LCase(strText) <SPAN style="color:#00007F">Then</SPAN>
strText = StrConv(strText, vbProperCase)
<SPAN style="color:#00007F">Else</SPAN>
strText = UCase(strText)
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN>
ChangeTextCase = strText
<SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Function</SPAN></FONT>
Oh yeah, I commented out a couple of lines that refer to making the case change Undo-able.
Regards,