Dominando strings
Manipulação de strings é uma das tarefas mais comuns em
qualquer linguagem de programação e no VBA não é diferente. Seja
para efetuar tratamento de entradas em formulários, compor
frases que serão enviadas ao usuário, manipular registros de
arquivos ou mesmo fazer comunicação com banco de dados, saber
lidar com strings é essencial.
qualquer linguagem de programação e no VBA não é diferente. Seja
para efetuar tratamento de entradas em formulários, compor
frases que serão enviadas ao usuário, manipular registros de
arquivos ou mesmo fazer comunicação com banco de dados, saber
lidar com strings é essencial.
O VBA possui várias funções que lidam com strings. Vamos
ver algumas funções básicas que você certamente deve
conhecer:
ver algumas funções básicas que você certamente deve
conhecer:
– Len(string): Retorna o comprimento da string;
– LCase(string): Converte a string para letras minúsculas;
– UCase(string): Converte a string para letras maiúsculas;
– Str(número): Converte um número em uma string;
– Trim(string): Remove os espaços extras à esquerda e à direita da
string fornecida;
string fornecida;
– LTrim(string): Remove os espaços extras à esquerda da
string fornecida;
string fornecida;
– RTrim(string): Remove os espaços extras à direita da
string fornecida;
string fornecida;
– Left(string, quantidade): Retorna a quantidade de caracteres à esquerda da
string fornecida (também pode ser usado
Left$);
string fornecida (também pode ser usado
Left$);
– Right(string, quantidade): Retorna a quantidade de caracteres à direita da
string fornecida (também pode ser usado
Right$);
string fornecida (também pode ser usado
Right$);
– Mid(string, posição, quantidade): Retorna a quantidade de caracteres a partir da posição da
string fornecida, lembrando que a posição inicial é 1
(também pode ser usado Mid$);
string fornecida, lembrando que a posição inicial é 1
(também pode ser usado Mid$);
– Chr(valorASCII): retorna o caractere referente ao valor ASCII fornecido
(também pode ser usado Chr$). É extremamente útil para
representar caracteres que não podem ser colocados dentro de
strings, como o Enter (valor 13) e as aspas duplas
(valor 34). Permite mais flexibilidade nos textos em caixas de
mensagem (MessageBox), por exemplo.
(também pode ser usado Chr$). É extremamente útil para
representar caracteres que não podem ser colocados dentro de
strings, como o Enter (valor 13) e as aspas duplas
(valor 34). Permite mais flexibilidade nos textos em caixas de
mensagem (MessageBox), por exemplo.
Em relação às quatro últimas, temos versões com e sem o
caracter $. Qual é a diferença entre elas? Esta é uma
dúvida muito comum. A diferença é que a versão com
$ retornam uma string, enquanto as versões sem
$ retornam o formato Variant. Aparentemente essa
diferença não tem a mínima importância, mas se houver algum
valor nulo, as versões com $ retornarão uma mensagem de
erro, pois o formato string não consegue lidar com
valores nulos. Esse é um tipo de erro mais comum no Access, pois
os campos podem ter valores nulos. Como no Excel dificilmente
teremos células ou formulários retornando valores nulos, é
preferível usar sempre a versão com $, que tem um
desempenho melhor, o que faz muita diferença em processamentos
com milhares de iterações.
caracter $. Qual é a diferença entre elas? Esta é uma
dúvida muito comum. A diferença é que a versão com
$ retornam uma string, enquanto as versões sem
$ retornam o formato Variant. Aparentemente essa
diferença não tem a mínima importância, mas se houver algum
valor nulo, as versões com $ retornarão uma mensagem de
erro, pois o formato string não consegue lidar com
valores nulos. Esse é um tipo de erro mais comum no Access, pois
os campos podem ter valores nulos. Como no Excel dificilmente
teremos células ou formulários retornando valores nulos, é
preferível usar sempre a versão com $, que tem um
desempenho melhor, o que faz muita diferença em processamentos
com milhares de iterações.
Existem funções para localizar textos em strings.
InStr é a mais conhecida, mas não a única. Vejamos:
InStr é a mais conhecida, mas não a única. Vejamos:
–
InStr([posição], string, substring, [comparação]): Localiza uma substring em uma string a partir
de uma posição específica. A posição é opcional, o valor padrão
é 1 (início). Retorna a posição onde a substring começa
dentro da string, caso não seja encontrado retorna 0;
InStr([posição], string, substring, [comparação]): Localiza uma substring em uma string a partir
de uma posição específica. A posição é opcional, o valor padrão
é 1 (início). Retorna a posição onde a substring começa
dentro da string, caso não seja encontrado retorna 0;
–
InStrRev(string, substring, [posição], [comparação]): Localiza uma substring em uma string a partir
da direita. A posição é opcional, o valor padrão é -1 (final).
Retorna a posição onde a substring começa dentro da
string a partir da esquerda, caso não seja encontrado
retorna 0.
InStrRev(string, substring, [posição], [comparação]): Localiza uma substring em uma string a partir
da direita. A posição é opcional, o valor padrão é -1 (final).
Retorna a posição onde a substring começa dentro da
string a partir da esquerda, caso não seja encontrado
retorna 0.
Perceba que a ordem dos parâmetros é diferente e que a posição
retornada é sempre a partir da esquerda para a direita, mesmo no
InStrRev.
retornada é sempre a partir da esquerda para a direita, mesmo no
InStrRev.
O parâmetro opcional de comparação pode ter três valores:
vbBinaryCompare (ou 0, valor padrão),
vbTextCompare (ou 1) e
vbUseCompareOption (ou -1). O primeiro faz uma
comparação exata, ou seja, busca exatamente o que está sendo
pesquisado, enquanto o segundo efetua pesquisa por texto, não
fazendo distinção entre maiúsculas e minúsculas. O último será
explicado mais adiante. Teste os exemplos abaixo na área de
verificação imediata do Editor de VBA:
vbBinaryCompare (ou 0, valor padrão),
vbTextCompare (ou 1) e
vbUseCompareOption (ou -1). O primeiro faz uma
comparação exata, ou seja, busca exatamente o que está sendo
pesquisado, enquanto o segundo efetua pesquisa por texto, não
fazendo distinção entre maiúsculas e minúsculas. O último será
explicado mais adiante. Teste os exemplos abaixo na área de
verificação imediata do Editor de VBA:
? InStr(1, “ABC”, “a”, vbBinaryCompare)
0
? InStr(1, “ABC”, “a”, vbTextCompare)
1
O primeiro retorna 0, pois não encontrou por ser uma pesquisa
por valor exato, enquanto o segundo encontrou por ser uma
pesquisa por texto.
por valor exato, enquanto o segundo encontrou por ser uma
pesquisa por texto.
Outra função importante é Replace, que substitui texto
em strings seguindo critérios fornecidos. Sua forma é a
seguinte:
em strings seguindo critérios fornecidos. Sua forma é a
seguinte:
Replace(string, localizarsubstring, substituirsubstring,
[início], [quantidade], [comparação]): Localiza uma substring dentro de uma string, se
encontrar, substitui por uma outra substring. O parâmetro
opcional início determina a partir de que caractere deve ser
retornado (exclui os caracteres anteriores). O parâmetro
opcional quantidade determina quantas substituições serão
realizadas. Por fim, o parâmetro comparação funciona de maneira
similar ao visto em InStr e InStrRev, com a
diferença que o valor padrão é o vbUseCompareOption.
Teste os exemplos abaixo na área de verificação imediata do
Editor de VBA:
[início], [quantidade], [comparação]): Localiza uma substring dentro de uma string, se
encontrar, substitui por uma outra substring. O parâmetro
opcional início determina a partir de que caractere deve ser
retornado (exclui os caracteres anteriores). O parâmetro
opcional quantidade determina quantas substituições serão
realizadas. Por fim, o parâmetro comparação funciona de maneira
similar ao visto em InStr e InStrRev, com a
diferença que o valor padrão é o vbUseCompareOption.
Teste os exemplos abaixo na área de verificação imediata do
Editor de VBA:
? Replace(“123456789012345678901234567890”, “5”, “x”)
1234x678901234x678901234x67890
? Replace(“123456789012345678901234567890”, “5”, “x”, 3)
34x678901234x678901234x67890
? Replace(“123456789012345678901234567890”, “5”, “x”, ,2)
1234x678901234x678901234567890
? Replace(“ABCDEF”, “c”, “x”, , ,vbBinaryCompare)
ABCDEF
? Replace(“ABCDEF”, “c”, “x”, , ,vbTextCompare)
ABxDEF
Como funciona o parâmetro vbUseCompareOption? Se você já
tem alguma experiência em VBA, sabe que podemos usar o parâmetro
Option Explicit no começo do módulo para obrigar a
declaração de todas as variáveis. Da mesma forma, temos o
parâmetro Option Private Module, para impedir que as
funções codificadas no módulo sejam usadas em células do Excel.
O parâmetro Option Compare tem dois valores possíveis:
Binary ou Text.
Option Compare Binary define que as comparações serão
exatas, enquanto Option Compare Text define que as
comparações serão por texto (desconsidera distinções entre
maiúsculas e minúsculas). Quando não especificado, o valor
padrão é Binary.
tem alguma experiência em VBA, sabe que podemos usar o parâmetro
Option Explicit no começo do módulo para obrigar a
declaração de todas as variáveis. Da mesma forma, temos o
parâmetro Option Private Module, para impedir que as
funções codificadas no módulo sejam usadas em células do Excel.
O parâmetro Option Compare tem dois valores possíveis:
Binary ou Text.
Option Compare Binary define que as comparações serão
exatas, enquanto Option Compare Text define que as
comparações serão por texto (desconsidera distinções entre
maiúsculas e minúsculas). Quando não especificado, o valor
padrão é Binary.
É importante observar que, se não houver nada especificando, as
comparações serão feitas de modo binário. Se for usar
Option Compare Text, lembre-se que em InStr e
InStrRev o valor padrão é vbBinaryCompare. Na
minha opinião, é melhor sempre usar vbTextCompare quando
for necessário comparar por texto, pois deixa mais específico na
própria linha qual o tipo de comparação está sendo feita,
ajudando muito em futuras manutenções. Lembre-se também que o
código fica mais autodocumentado quando usamos as enumerações ao
invés dos valores numéricos.
comparações serão feitas de modo binário. Se for usar
Option Compare Text, lembre-se que em InStr e
InStrRev o valor padrão é vbBinaryCompare. Na
minha opinião, é melhor sempre usar vbTextCompare quando
for necessário comparar por texto, pois deixa mais específico na
própria linha qual o tipo de comparação está sendo feita,
ajudando muito em futuras manutenções. Lembre-se também que o
código fica mais autodocumentado quando usamos as enumerações ao
invés dos valores numéricos.
Existem algumas funções pouco conhecidas e menos utilizadas,
mas que é bom conhece-las porque pode ser que um dia haja a
necessidade de usar alguma delas.
mas que é bom conhece-las porque pode ser que um dia haja a
necessidade de usar alguma delas.
Asc(caracter): Retorna o valor ASCII correspondente ao caractere fornecido,
ou seja, faz o oposto da função Chr/Chr$. Se esta
função receber uma string com mais de um caractere, o
valor retornado se refere ao primeiro.
ou seja, faz o oposto da função Chr/Chr$. Se esta
função receber uma string com mais de um caractere, o
valor retornado se refere ao primeiro.
StrComp(string1, string2, [comparação]): Efetua
comparação entre duas strings e retorna um valor de
acordo com o resultado da comparação. Se ambas forem iguais,
retorna 0. Se em uma ordenação a string1 se
posicionar antes de string2, retorna -1, caso
contrário retorna 1. Se alguma das strings tiverem
valor nulo, retorna Null. O parâmetro de comparação
funciona de forma idêntica à função Replace, com valor
padrão vbUseCompareOption.
comparação entre duas strings e retorna um valor de
acordo com o resultado da comparação. Se ambas forem iguais,
retorna 0. Se em uma ordenação a string1 se
posicionar antes de string2, retorna -1, caso
contrário retorna 1. Se alguma das strings tiverem
valor nulo, retorna Null. O parâmetro de comparação
funciona de forma idêntica à função Replace, com valor
padrão vbUseCompareOption.
StrConv(string, conversão, [LCID]): Converte uma string de acordo com o parâmetro de
conversão, que pode ter os seguintes valores:
conversão, que pode ter os seguintes valores:
– vbUpperCase (ou 1): Converte para letras
maiúsculas, de forma idêntica à função UCase;
maiúsculas, de forma idêntica à função UCase;
– vbLowerCase (ou 2): Converte para letras
minúsculas, de forma idêntica à função LCase;
minúsculas, de forma idêntica à função LCase;
– vbProperCase (ou 3): Converte de modo a deixar
as iniciais das palavras em maiúsculas e o restante em
minúsculas;
as iniciais das palavras em maiúsculas e o restante em
minúsculas;
– vbUnicode (ou 64): Converte a
string para o formato Unicode;
string para o formato Unicode;
– vbFromUnicode (ou 128): Converte a
string do formato Unicode para o formato padrão do
sistema.
string do formato Unicode para o formato padrão do
sistema.
Há também os valores vbWide (ou 4) e
vbNarrow (ou 8), que convertem caracteres entre
padrões do leste asiático, e os valores vbKatakana (ou
16) e vbHiragana (ou 32), que convertem
caracteres entre padrões japoneses.
vbNarrow (ou 8), que convertem caracteres entre
padrões do leste asiático, e os valores vbKatakana (ou
16) e vbHiragana (ou 32), que convertem
caracteres entre padrões japoneses.
O parâmetro opcional LCID se refere ao código de
identificação do local. Quando não for especificado, utiliza o
código do sistema.
identificação do local. Quando não for especificado, utiliza o
código do sistema.
Split(string, [delimitador], [limite], [comparação]): Separa a string em substrings separadas pelo
delimitador. Note que o resultado deve ser armazenado em uma
variável do tipo array, cujo índice começa no valor
0. Se o parâmetro delimitador não for especificado, será
considerado o caractere de espaço. O parâmetro limite define
quantas substrings serão retornadas; se o limite for
1 retorna a string inteira, se for 2 faz a
primeira separação pelo delimitador e o restante é guardado na
segunda substring e assim por diante. Se não especificar
um valor para limite, todas as separações possíveis serão
feitas. Você pode encontrar o maior valor com a função
UBound. O parâmetro de comparação funciona da mesma
maneira da função Replace. Um exemplo para entender
melhor o funcionamento do limite:
delimitador. Note que o resultado deve ser armazenado em uma
variável do tipo array, cujo índice começa no valor
0. Se o parâmetro delimitador não for especificado, será
considerado o caractere de espaço. O parâmetro limite define
quantas substrings serão retornadas; se o limite for
1 retorna a string inteira, se for 2 faz a
primeira separação pelo delimitador e o restante é guardado na
segunda substring e assim por diante. Se não especificar
um valor para limite, todas as separações possíveis serão
feitas. Você pode encontrar o maior valor com a função
UBound. O parâmetro de comparação funciona da mesma
maneira da função Replace. Um exemplo para entender
melhor o funcionamento do limite:
X = Split(“Fulano de Tal”)
? X(0)
Fulano
? X(1)
de
? X(2)
Tal
X = Split(“Fulano de Tal”, , 2)
? X(0)
Fulano
? X(1)
de Tal
Agora a parte mais legal: aplicar os conhecimentos. Suponha que
queremos uma função que obtenha o primeiro nome de um nome
fornecido e outra função que obtenha o último nome. Caso só
tenha sido fornecido um nome, deve ser retornado o nome inteiro
em ambas funções. Podemos fazer da seguinte forma:
queremos uma função que obtenha o primeiro nome de um nome
fornecido e outra função que obtenha o último nome. Caso só
tenha sido fornecido um nome, deve ser retornado o nome inteiro
em ambas funções. Podemos fazer da seguinte forma:
Function PrimeiroNome(Nome As String) As String
Dim Espaco As Integer
Espaco = InStr(1, Nome, ” “)
If Espaco > 1 Then
PrimeiroNome =
Mid$(Nome, 1, (Espaco – 1))
Mid$(Nome, 1, (Espaco – 1))
Else
PrimeiroNome =
Nome
Nome
End If
End Function
Function UltimoNome(Nome As String) As String
Dim Espaco As Integer
Espaco = InStrRev(Nome, ” “)
If Espaco > 1 Then
UltimoNome =
Mid$(Nome, (Espaco + 1), Len(Nome))
Mid$(Nome, (Espaco + 1), Len(Nome))
Else
UltimoNome =
Nome
Nome
End If
End Function
Nessas rotinas coloquei uma variável Espaco para obter a
posição do primeiro ou último espaço, de acordo com a função.
Caso encontrado (Espaco > 1) , o retorno é gerado
usando o Mid$ (poderia ser usado o Left$ na
primeira função e o Right$ na segunda, mas nesta última
envolveria mais cálculos). Caso não encontre espaço, retorna a
string inteira.
posição do primeiro ou último espaço, de acordo com a função.
Caso encontrado (Espaco > 1) , o retorno é gerado
usando o Mid$ (poderia ser usado o Left$ na
primeira função e o Right$ na segunda, mas nesta última
envolveria mais cálculos). Caso não encontre espaço, retorna a
string inteira.
Vejamos agora as mesmas funções criadas com a função
Split:
Split:
Function PrimeiroNome(Nome As String) As String
Dim Nomes As Variant
Nomes = Split(Nome)
PrimeiroNome = Nomes(0)
End Function
Function UltimoNome(Nome As String) As String
Dim Nomes As Variant
Nomes = Split(Nome)
UltimoNome = Nomes(UBound(Nomes))
End Function
Foi criada a variável Nomes do tipo variant para receber
o array de nomes em ambas funções. A partir daí, extrai o
primeiro (com índice 0) ou o último (UBound(Nomes)
retorna o último índice do array).
o array de nomes em ambas funções. A partir daí, extrai o
primeiro (com índice 0) ou o último (UBound(Nomes)
retorna o último índice do array).
As duas versões de cada função fazem exatamente a mesma coisa,
a diferença é a quantidade de instruções utilizadas, o que
impacta no desempenho. Se o uso for ocasional, o impacto é
mínimo, mas se houver uma estrutura de repetição executando
milhares de vezes o impacto será perceptível.
a diferença é a quantidade de instruções utilizadas, o que
impacta no desempenho. Se o uso for ocasional, o impacto é
mínimo, mas se houver uma estrutura de repetição executando
milhares de vezes o impacto será perceptível.
Podemos também criar uma função PCase, para simplificar
o uso da função StrConv com parâmetro
vbProperCase:
o uso da função StrConv com parâmetro
vbProperCase:
Function PCase(Texto As String) As String
PCase = StrConv(Texto, vbProperCase)
End Function
Desta forma, você consegue uma forma mais simples e sem
parâmetros do que escrever toda aquela linha para efetuar a
conversão, funcionando da mesma forma que as funções nativas
UCase e LCase.
parâmetros do que escrever toda aquela linha para efetuar a
conversão, funcionando da mesma forma que as funções nativas
UCase e LCase.
Perceba que com o conhecimento das funções de strings é
possível simplificar muito algumas tarefas repetitivas. Você
pode até criar suas próprias funções para facilitar seu próprio
código. Use o conhecimento a seu favor: automatize tarefas e
simplifique seu código.
possível simplificar muito algumas tarefas repetitivas. Você
pode até criar suas próprias funções para facilitar seu próprio
código. Use o conhecimento a seu favor: automatize tarefas e
simplifique seu código.
Pedro Martins
Formado em Tecnologia em Eletrônica Digital, já trabalhou como
artefinalista, eletrotécnico, programador de CLP (para máquinas
industriais) e analista de sistemas em sistema bancário, programando
em COBOL.
Mexe com computadores e programação desde a segunda metade dos
anos 1980, quando teve um MSX e aprendeu a programar em BASIC. É a
favor da disseminação do conhecimento.
artefinalista, eletrotécnico, programador de CLP (para máquinas
industriais) e analista de sistemas em sistema bancário, programando
em COBOL.
Mexe com computadores e programação desde a segunda metade dos
anos 1980, quando teve um MSX e aprendeu a programar em BASIC. É a
favor da disseminação do conhecimento.
Catálogo de aulas (NOVIDADE)
Criei um catálogo de aulas para ajudar você em seus estudos. Acesse clicando na imagem abaixo ou clique aqui.