Quelle est la meilleure façon de déterminer si un personnage est une lettre dans VB6?
-
01-07-2019 - |
Question
Besoin d'une fonction qui prend un caractère en tant que paramètre et renvoie true s'il s'agit d'une lettre.
La solution
Le IsCharAlphaA de Seanyboy
réponse est proche. La meilleure méthode consiste à utiliser la version W comme suit:
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
Bien sûr, tout cela compte rarement, car tous les contrôles de VB6 sont uniquement ANSI
Autres conseils
Cela faisait partie du code envoyé par rpetrich en réponse à un question de Joel Spolsky . J'ai senti qu'il fallait un poste spécifique au problème à résoudre. C'est vraiment brillant.
Private Function IsLetter(ByVal character As String) As Boolean
IsLetter = UCase$(character) <> LCase$(character)
End Function
Vous pensez peut-être à vous-même, "Cela fonctionnera-t-il toujours?" La documentation sur les fonctions UCase et LCase confirme que:
Fonction UCase seules les lettres minuscules sont converties en majuscules; toutes les lettres majuscules et les caractères non lettres restent inchangés .
Fonction LCase seules les lettres majuscules sont converties en minuscules; toutes les lettres minuscules et les caractères non lettres restent inchangés .
Private Function IsLetter(Char As String) As Boolean
IsLetter = UCase(Char) Like "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]"
End Function
Quel est le problème avec ce qui suit, qui ne repose pas sur un comportement de langage obscur?
Private Function IsLetter(ByVal ch As String) As Boolean
IsLetter = (ch >= "A" and ch <= "Z") or (ch >= "a" and ch <= "z")
End Function
Je pense que nous pouvons améliorer cela un peu plus. Le code de rpetrich fonctionnera, mais peut-être que par chance. Le paramètre de l'appel API doit être un TCHAR (WCHAR ici en fait) et non un long. Cela signifie également qu’il ne faut pas jouer avec la conversion en Long ou le masquage avec & HFFFF. Ceci est d'ailleurs Integer et ajoute une conversion implicite à Long ici aussi. Peut-être pensait-il & HFFFF & amp; dans ce cas?
De plus, il serait peut-être préférable d'appeler explicitement l'encapsuleur UnicoWS pour cet appel d'API, pour la compatibilité Win9X. UnicoWS.dll devra peut-être être déployé, mais au moins, nous aurons cette option. Là encore, peut-être que depuis VB6, cela est redirigé automatiquement, Win9X n’est pas installé pour le tester.
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
En regardant autour de vous, vous trouverez ce qui suit ...
Private Declare Function IsCharAlphaA Lib "user32" Alias "IsCharAlphaA" (ByVal cChar As Byte) As Long
Je crois que IsCharAlphaA teste les jeux de caractères ANSI et IsCharAlpha teste ASCII. J'ai peut-être tort.
Private Function IsAlpha(ByVal vChar As String) As Boolean
Const letters$ = "abcdefghijklmnopqrstuvwxyz"
If InStr(1, letters, LCase$(vChar)) > 0 Then IsAlpha = True
End Function
J'utilise ceci dans VBA
Function IsLettersOnly(Value As String) As Boolean
IsLettersOnly = Len(Value) > 0 And Not UCase(Value) Like "*[!A-Z]*"
End Function
Cela ne se documente pas exactement. Et ça peut être lent. C'est un hack intelligent, mais c'est tout. Je serais tenté d'être plus évident dans ma vérification. Utilisez regex ou écrivez un test plus évident.
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'))
}