¿Cuál es la mejor manera de determinar si un carácter es una letra en VB6?
-
01-07-2019 - |
Pregunta
Necesita una función que tome un carácter como parámetro y devuelva verdadero si es una letra.
Solución
Seanyboy IsCharAlphaA
respuesta está cerca.El mejor método es utilizar la versión W así:
Private Declare Function IsCharAlphaW Lib "user32" (ByVal cChar As Integer) As Long
Public Property Get IsLetter(character As String) As Boolean
IsLetter = IsCharAlphaW(AscW(character))
End Property
Por supuesto, todo esto rara vez importa ya que todos los controles de VB6 son solo ANSI
Otros consejos
Esto fue parte del código publicado por rpetrich en respuesta a un pregunta por joel spolsky.Sentí que necesitaba una publicación específica para el problema que resuelve.Realmente es brillante.
Private Function IsLetter(ByVal character As String) As Boolean
IsLetter = UCase$(character) <> LCase$(character)
End Function
Puede estar pensando para ti mismo, "¿Esto siempre funcionará?" La documentación sobre las funciones de UCase y LCase confirma que lo hará:
Función UCasa Sólo las letras minúsculas se convierten a mayúsculas; todas las letras mayúsculas y caracteres que no son letras permanecen sin cambios.
Función LCase Sólo las letras mayúsculas se convierten a minúsculas; todas las letras minúsculas y caracteres que no son letras permanecen sin cambios.
Private Function IsLetter(Char As String) As Boolean
IsLetter = UCase(Char) Like "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]"
End Function
¿Qué hay de malo en lo siguiente, que no se basa en un comportamiento de lenguaje oscuro?
Private Function IsLetter(ByVal ch As String) As Boolean
IsLetter = (ch >= "A" and ch <= "Z") or (ch >= "a" and ch <= "z")
End Function
Creo que podemos mejorar esto un poco más. rpetrichEl código funcionará, pero quizás sólo por suerte.El parámetro de la llamada API debe ser TCHAR (WCHAR aquí en realidad) y no Long.Esto también significa no tener que jugar con la conversión a Long o enmascarar con &HFFFF.Por cierto, esto es Integer y aquí también agrega una conversión implícita a Long.¿Quizás se refería a &HFFFF& en este caso?
Además de eso, podría ser mejor llamar explícitamente al contenedor UnicoWS para esta llamada API, para compatibilidad con Win9X.Es posible que sea necesario implementar UnicoWS.dll, pero al menos tenemos esa opción.Por otra parte, tal vez desde VB6 esto se redirija automáticamente, no tengo Win9X instalado para probarlo.
Option Explicit
Private Declare Function IsCharAlphaW Lib "unicows" (ByVal WChar As Integer) As Long
Private Function IsLetter(Character As String) As Boolean
IsLetter = IsCharAlphaW(AscW(Character))
End Function
Private Sub Main()
MsgBox IsLetter("^")
MsgBox IsLetter("A")
MsgBox IsLetter(ChrW$(&H34F))
MsgBox IsLetter(ChrW$(&HFEF0))
MsgBox IsLetter(ChrW$(&HFEFC))
End Sub
Mirando un poco a mi alrededor se me ocurrió lo siguiente...
Private Declare Function IsCharAlphaA Lib "user32" Alias "IsCharAlphaA" (ByVal cChar As Byte) As Long
Creo que IsCharAlphaA prueba conjuntos de caracteres ANSI y IsCharAlpha prueba ASCII.Puedo estar equivocado.
Private Function IsAlpha(ByVal vChar As String) As Boolean
Const letters$ = "abcdefghijklmnopqrstuvwxyz"
If InStr(1, letters, LCase$(vChar)) > 0 Then IsAlpha = True
End Function
Yo uso esto en VBA
Function IsLettersOnly(Value As String) As Boolean
IsLettersOnly = Len(Value) > 0 And Not UCase(Value) Like "*[!A-Z]*"
End Function
No se documenta exactamente.Y puede que sea lento.Es un truco inteligente, pero eso es todo.Me sentiría tentado a ser más obvio en mis comprobaciones.Utilice expresiones regulares o escriba una prueba más obvia.
public bool IsAlpha(String strToCheck)
{
Regex objAlphaPattern=new Regex("[^a-zA-Z]");
return !objAlphaPattern.IsMatch(strToCheck);
}
public bool IsCharAlpha(char chToCheck)
{
return ((chToCheck=>'a') and (chToCheck<='z')) or ((chToCheck=>'A') and (chToCheck<='Z'))
}