Qual é a melhor maneira de determinar se um personagem é uma carta no VB6?
-
01-07-2019 - |
Pergunta
Precisa de uma função que pegue um personagem como um parâmetro e retorne verdadeiro se for uma letra.
Solução
Seanyboy's IsCharAlphaA
responda está perto. O melhor método é usar a versão W como assim:
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
Obviamente, tudo isso raramente importa, pois todos os controles do VB6 são apenas ANSI
Outras dicas
Isso fazia parte do código postado por Rpetrich em resposta a um pergunta por Joel Spolsky. Eu senti que precisava de uma postagem específica para o problema que resolve. É realmente brilhante.
Private Function IsLetter(ByVal character As String) As Boolean
IsLetter = UCase$(character) <> LCase$(character)
End Function
Você pode estar pensando: "Isso sempre funcionará?" A documentação sobre as funções UCase e Lcase confirma que será:
Função ucase Somente letras minúsculas são convertidas em maiúsculas; Todas.
Função lcase Somente letras maiúsculas são convertidas em minúsculas; Todas as letras minúsculas e caracteres não -letras permanecem inalterados.
Private Function IsLetter(Char As String) As Boolean
IsLetter = UCase(Char) Like "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]"
End Function
O que há de errado com o seguinte, que não depende do comportamento obscuro da linguagem?
Private Function IsLetter(ByVal ch As String) As Boolean
IsLetter = (ch >= "A" and ch <= "Z") or (ch >= "a" and ch <= "z")
End Function
Eu acredito que podemos melhorar um pouco mais sobre isso. RpetrichO código de São funcionará, mas talvez apenas por sorte. O parâmetro da chamada da API deve ser um TCHAR (na verdade) e não muito tempo. Isso também significa que não há brincadeiras de conversão a um longo ou mascarado com o & hffff. A propósito, isso é inteiro e adiciona uma conversão implícita a Long aqui também. Talvez ele quis dizer e hffff e neste caso?
Além disso, pode ser melhor chamar explicitamente o wrapper Unicows para esta chamada de API, para compatibilidade com Win9x. O Unicows.dll pode precisar ser implantado, mas pelo menos ganhamos essa opção. Então, novamente, talvez do VB6, isso seja redirecionado automaticamente, não tenho o Win9X instalado para testá -lo.
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
Olhando em volta um pouco surgiu com o seguinte ...
Private Declare Function IsCharAlphaA Lib "user32" Alias "IsCharAlphaA" (ByVal cChar As Byte) As Long
Acredito que o ischaralphaa testa conjuntos de caracteres ANSI e testes de ischaralpha ASCII. Eu posso estar errado.
Private Function IsAlpha(ByVal vChar As String) As Boolean
Const letters$ = "abcdefghijklmnopqrstuvwxyz"
If InStr(1, letters, LCase$(vChar)) > 0 Then IsAlpha = True
End Function
Eu uso isso em vba
Function IsLettersOnly(Value As String) As Boolean
IsLettersOnly = Len(Value) > 0 And Not UCase(Value) Like "*[!A-Z]*"
End Function
Não se documenta exatamente. E pode ser lento. É um hack inteligente, mas é tudo o que é. Eu ficaria tentado a ser mais óbvio na minha verificação. Use Regex ou escreva um teste mais óbvio.
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'))
}