VBA – Incompatibilidade de Tipos (Erro em Tempo de Execução 13)

Written by

Mel Jenkins

Reviewed by

Steve Rynearson

Translated by

Daniel Caramello

Last updated on August 16, 2023

Erros de Incompatibilidade de Tipo do VBA

O Que é um Erro de Incompatibilidade de Tipo?

Um erro de incompatibilidade pode ocorrer com frequência quando você executa seu código VBA. O erro impedirá a execução completa do código e sinalizará, por meio de uma caixa de mensagem, que esse erro precisa ser resolvido.

Observe que, se você não tiver testado totalmente o código antes de distribuí-lo aos usuários, essa mensagem de erro ficará visível para eles e causará uma grande perda de confiança no aplicativo do Excel. Infelizmente, os usuários costumam fazer coisas muito peculiares em um aplicativo e, muitas vezes, são coisas que você, como desenvolvedor, nunca considerou.

Um erro de incompatibilidade de tipos ocorre porque você definiu uma variável usando a instrução Dim como um determinado tipo, por exemplo, inteiro, data, e seu código está tentando atribuir um valor à variável que não é aceitável, por exemplo, uma cadeia de texto atribuída a uma variável inteira, como neste exemplo:

Aqui está um exemplo:

vbe tipos incompativeis

Clique em Depurar e a linha de código incorreta será destacada em amarelo. Não há opção no pop-up de erro para continuar, pois esse é um erro grave e não há como o código continuar sendo executado.

Nesse caso específico, a solução é alterar a instrução Dim para um tipo de variável que funcione com o valor que você está atribuindo à variável. O código funcionará se você alterar o tipo de variável para “String” e, provavelmente, você também desejará alterar o nome da variável.

tela-depurar

No entanto, a alteração do tipo de variável exigirá a reinicialização do projeto, e você terá de executar o código novamente desde o início, o que pode ser muito incômodo se houver um procedimento longo envolvido

redefinicao projeto

Erro de Incompatibilidade Causado por Cálculo de Planilha

O exemplo acima é muito simples de como um erro de incompatibilidade pode ser produzido e, nesse caso, é facilmente solucionado.

Entretanto, a causa dos erros de incompatibilidade geralmente é muito mais profunda do que isso e não é tão óbvia quando se está tentando depurar o código.

Por exemplo, suponha que você tenha escrito um código para pegar um valor em uma determinada posição em uma planilha e que ele contenha um cálculo dependente de outras células da pasta de trabalho (B1, neste exemplo)

A planilha tem a aparência deste exemplo, com uma fórmula para localizar um caractere específico em uma cadeia de texto.

erro localizar

Do ponto de vista do usuário, a célula A1 é de formato livre e ele pode inserir qualquer valor que desejar. No entanto, a fórmula está procurando uma ocorrência do caractere “B” e, nesse caso, ele não é encontrado, de modo que a célula B1 tem um valor de erro.

O código de teste abaixo produzirá um erro de incompatibilidade porque um valor errado foi inserido na célula A1

Sub TesteIncompatibilidade()
Dim MeuNumero As Integer
MeuNumero = Sheets("Planilha1").Range("B1").Value
End Sub

O valor na célula B1 gerou um erro porque o usuário inseriu um texto na célula A1 que não está de acordo com o esperado e não contém o caractere “B”.

O código tenta atribuir o valor à variável “MeuNumero”, que foi definida para esperar um número inteiro, e, portanto, você recebe um erro de incompatibilidade.

Esse é um dos exemplos em que a verificação meticulosa do código não fornecerá a resposta. Também é necessário verificar na planilha de onde o valor está vindo para descobrir por que isso está acontecendo.

Na verdade, o problema está na planilha, e a fórmula em B1 precisa ser alterada para que os valores de erro sejam tratados. Você pode fazer isso usando a fórmula “SEERRO” para fornecer um valor padrão de 0 se o caractere de pesquisa não for encontrado.

formula corrigida

Em seguida, é possível incorporar o código para verificar se há um valor zero e exibir uma mensagem de aviso ao usuário de que o valor na célula A1 é inválido.

Sub TesteIncompatibilidade()
Dim MeuNumero As Integer
MeuNumero = Sheets("Planilha1").Range("B1").Text
If MeuNumero = 0 Then
    MsgBox "O valor da célula A1 é inválido", vbCritical
    Exit Sub
End If
End Sub

Você também pode usar a Validação de Dados (grupo Ferramentas de Dados na guia Dados da faixa de opções) na planilha para impedir que o usuário faça o que quiser e cause erros na planilha. Só permita que o usuário insira valores que não causem erros na planilha.

Você poderia escrever um código VBA com base no evento Change da planilha para verificar o que foi inserido.

Além disso, bloqueie e proteja a planilha com senha, para que os dados inválidos não possam ser inseridos.

Erro de Incompatibilidade Causado por Valores de Células Inseridos

Os erros de incompatibilidade podem ser causados no seu código pela inserção de valores normais de uma planilha (sem erro), mas onde o usuário inseriu um valor inesperado, por exemplo, um valor de texto quando você esperava um número. O usuário pode ter decidido inserir uma linha em um intervalo de números para que possa colocar uma nota em uma célula explicando algo sobre o número. Afinal de contas, o usuário não tem ideia de como o seu código funciona e que ele acabou de desequilibrar tudo ao inserir a nota.

erro valores inseridos

O código de exemplo abaixo cria uma matriz simples chamada “MeuNumero” definida com valores inteiros.

Em seguida, o código itera por um intervalo de células de A1 a A7, atribuindo os valores das células à matriz, usando uma variável “Cont” para indexar cada valor

Quando o código atinge o valor de texto, um erro de incompatibilidade é causado e tudo é interrompido.

Ao clicar em “Depurar” na janela pop-up de erro, você verá a linha de código que apresenta o problema destacada em amarelo. Ao passar o cursor sobre qualquer instância da variável “Cont” no código, você poderá ver o valor de “Cont” em que o código falhou, que, nesse caso, é 5.

Observando a planilha, você verá que a quinta célula tem o valor de texto e isso fez com que o código falhasse.

vbe erro valor inserido

Você poderia alterar seu código inserindo uma condição que verifique primeiro se há um valor numérico antes de adicionar o valor da célula à matriz.

Sub TesteIncompatibilidade()
Dim MeuNumero(10) As Integer, Cont As Integer
Cont = 1
Do
   If Cont = 11 Then Exit Do
   If IsNumeric(Sheets("Planilha1").Cells(Cont, 1).Value) Then
       MeuNumero(Cont) = Sheets("Planilha1").Cells(Cont, 1).Value
   Else
       MeuNumero(Cont) = 0
   End If
   Cont = Cont + 1
Loop
End Sub

O código usa a função ‘IsNumeric’ para testar se o valor é realmente um número e, se for, ele o insere na matriz. Se não for um número, ele insere o valor zero.

Isso garante que o índice da matriz seja mantido alinhado com os números das linhas das células na planilha.

Você também pode adicionar um código que copie o valor original do erro e os detalhes do local em uma planilha de “Erros” para que o usuário possa ver o que fez de errado quando o código for executado.

O teste numérico usa o código completo para a célula, bem como o código para atribuir o valor à matriz. Você poderia argumentar que isso deveria ser atribuído a uma variável para não ficar repetindo o mesmo código, mas o problema é que você precisaria definir a variável como uma “Variant”, o que não é a melhor coisa a fazer.

Você também precisa de validação de dados na planilha e proteger a planilha com senha. Isso evitará que o usuário insira linhas e dados inesperados.

Erro de Incompatibilidade Causado pela Chamada de uma Função ou Subrotina Usando Parâmetros

Quando uma função é chamada, você geralmente passa parâmetros para a função usando tipos de dados já definidos pela função. A função pode ser uma função já definida no VBA ou pode ser uma função definida pelo usuário que você mesmo criou. Às vezes, uma subrotina também pode exigir parâmetros.

Se você não seguir as convenções de como os parâmetros são passados para a função, receberá um erro de incompatibilidade.

Sub ChamarFuncao()
Dim Ret As Integer
Ret = MinhaFuncao(3, "teste")
End Sub

Function MinhaFuncao(N As Integer, T As String) As String
MinhaFuncao = T
End Function

Há várias possibilidades aqui para obter um erro de incompatibilidade.

A variável de retorno (Ret) é definida como um número inteiro, mas a função retorna uma string. Assim que você executar o código, ele falhará porque a função retorna uma cadeia de caracteres, e isso não pode ser inserido em uma variável inteira. É interessante notar que a execução do Depurar nesse código não detecta esse erro.

Se você colocar aspas ao redor do primeiro parâmetro que está sendo passado (3), ele será interpretado como uma cadeia de caracteres, o que não corresponde à definição do primeiro parâmetro na função (inteiro).

Se você transformar o segundo parâmetro na chamada de função em um valor numérico, ele falhará com uma incompatibilidade porque o segundo parâmetro na cadeia de caracteres é definido como uma cadeia de caracteres (texto).

Erro de Incompatibilidade Causado pelo Uso Incorreto de Funções de Conversão no VBA

Há várias funções de conversão que podem ser usadas no VBA para converter valores em vários tipos de dados. Um exemplo é “CInt”, que converte uma cadeia de caracteres contendo um número em um valor inteiro.

Se a cadeia de caracteres a ser convertida contiver caracteres alfa, você receberá um erro de incompatibilidade, mesmo que a primeira parte da cadeia de caracteres contenha caracteres numéricos e o restante sejam caracteres alfa, por exemplo, “123abc”.

Prevenção Geral de Erros de Incompatibilidade

Vimos nos exemplos acima várias maneiras de lidar com possíveis erros de incompatibilidade em seu código, mas há várias outras maneiras, embora elas possam não ser as melhores opções:

Defina Suas Variáveis Como Tipo Variant

Um tipo variant é o tipo de variável padrão no VBA. Se você não usar uma instrução Dim para uma variável e simplesmente começar a usá-la em seu código, ela receberá automaticamente o tipo Variant.

Uma variável Variant aceitará qualquer tipo de dado, seja ele um número inteiro, um número inteiro longo, um número de precisão dupla, um booleano ou um valor de texto. Isso parece uma ideia maravilhosa, e você se pergunta por que todo mundo não define todas as suas variáveis como variant.

No entanto, o tipo de dados variant tem várias desvantagens. Em primeiro lugar, ele ocupa muito mais memória do que outros tipos de dados. Se você definir uma matriz muito grande como variant, ela consumirá uma quantidade enorme de memória quando o código VBA estiver em execução, o que pode facilmente causar problemas de desempenho.

Em segundo lugar, o desempenho é mais lento em geral do que se você estiver usando tipos de dados específicos. Por exemplo, se você estiver fazendo cálculos complexos usando números de ponto decimal flutuante, os cálculos serão consideravelmente mais lentos se você armazenar os números como variantes, em vez de números de precisão dupla.

O uso do tipo variant é considerado uma programação desleixada, a menos que haja uma necessidade absoluta.

 

 

Usar o Comando OnError para Tratar de Erros

O comando OnError pode ser incluído no seu código para lidar com a captura de erros, de modo que, se ocorrer um erro, o usuário veja uma mensagem significativa em vez do pop-up de erro padrão do VBA

Sub ArmadilhaDeErros()
Dim MeuNumero As Integer
On Error GoTo Err_Gerenciador
MeuNumero = "test"
Err_Gerenciador:
MsgBox "O erro " & Err.Description & " ocorreu."
End Sub

Isso evita efetivamente que o erro interrompa a execução normal do seu código e permite que o usuário se recupere de forma limpa da situação de erro.

A rotina Err_Gerenciador pode mostrar mais informações sobre o erro e quem deve ser contatado para solucioná-lo.

Do ponto de vista da programação, quando você está usando uma rotina de tratamento de erros, é muito difícil localizar a linha de código em que o erro está. Se você estiver percorrendo o código usando a tecla F8, assim que a linha de código incorreta for executada, ela saltará para a rotina de tratamento de erros e você não poderá verificar onde está ocorrendo o erro.

Uma maneira de contornar isso é configurar uma constante global que seja True ou False (booleana) e usá-la para ativar ou desativar a rotina de tratamento de erros usando uma instrução “If”. Quando você quiser testar o erro, basta definir a constante global como False e o manipulador de erros não funcionará mais.

Global Const ErrGerenciamento = False
Sub ArmadilhaDeErros()
Dim MeuNumero As Integer
If ErrGerenciamento = True Then On Error GoTo Err_Gerenciador
MeuNumero = "test"
Err_Gerenciador:
MsgBox "O erro " & Err.Description & " ocorreu."
End Sub

O único problema com isso é que permite que o usuário se recupere do erro, mas o restante do código dentro da sub rotina não é executado, o que pode ter enormes repercussões mais tarde no aplicativo.

Usando o exemplo anterior de looping em um intervalo de células, o código chegaria à célula A5 e encontraria o erro de incompatibilidade. O usuário veria uma caixa de mensagem com informações sobre o erro, mas nada a partir dessa célula no intervalo seria processado.

Usar o Comando OnError para Suprimir Erros

Isso usa o comando “On Error Resume Next”. É muito perigoso incluir esse comando em seu código, pois ele impede que erros subsequentes sejam exibidos. Isso significa basicamente que, enquanto o código estiver sendo executado, se ocorrer um erro em uma linha de código, a execução passará para a próxima linha disponível sem executar a linha de erro e continuará normalmente.

Isso pode resolver uma situação de erro em potencial, mas ainda afetará todos os erros futuros no código. Você pode pensar que seu código está livre de erros, mas, na verdade, não está e partes do seu código não estão fazendo o que você acha que deveriam estar fazendo.

Há situações em que é necessário usar esse comando, por exemplo, se você estiver excluindo um arquivo usando o comando “Kill” (se o arquivo não estiver presente, haverá um erro), mas a captura de erros deve sempre ser ativada novamente imediatamente após a ocorrência do possível erro usando:

On Error Goto 0

No exemplo anterior de looping em um intervalo de células, usando “On Error Resume Next”, isso permitiria que o loop continuasse, mas a célula que causou o erro não seria transferida para a matriz e o elemento da matriz para esse índice específico conteria um valor nulo.

Conversão dos Dados em um Tipo de Dados que Corresponda à Declaração

Você pode usar as funções do VBA para alterar o tipo de dados de entrada para que ele corresponda ao tipo de dados da variável de recebimento.

Isso pode ser feito ao passar parâmetros para as funções. Por exemplo, se você tiver um número mantido em uma variável de cadeia de caracteres e quiser passá-lo como um número para uma função, poderá usar CInt.

Há várias dessas funções de conversão que podem ser usadas, mas aqui estão as principais:

CInt – converte uma cadeia de caracteres que tem um valor numérico (abaixo + ou – 32.768) em um valor inteiro. Esteja ciente de que isso trunca todos os pontos decimais.

CLng – Converte uma cadeia de caracteres com um valor numérico grande em um número inteiro longo. Os pontos decimais são truncados.

CDbl – Converte uma cadeia de caracteres que contém um número de ponto decimal flutuante em um número de precisão dupla. Inclui casas decimais.

CDate – Converte uma cadeia de caracteres que contém uma data em uma variável de data. Depende parcialmente das configurações do Painel de Controle do Windows e da sua localidade sobre como a data é interpretada.

CStr – Converte um valor numérico ou de data em uma cadeia de caracteres.

Ao converter de uma cadeia de caracteres para um número ou uma data, a cadeia não deve conter nada além de números ou uma data. Se houver caracteres alfa, isso produzirá um erro de incompatibilidade. Aqui está um exemplo que produzirá um erro de incompatibilidade:

Sub Teste()
MsgBox CInt("123abc")
End Sub

Teste de Variáveis em Seu Código

Você pode testar uma variável para descobrir que tipo de dados ela é antes de atribuí-la a uma variável de um tipo específico.

Por exemplo, você pode verificar se uma string é numérica usando a função “IsNumeric” no VBA

MsgBox IsNumeric("123test")

Esse código retornará False porque, embora a cadeia de caracteres comece com caracteres numéricos, ela também contém texto e, portanto, não passa no teste.

MsgBox IsNumeric("123")

Esse código retornará True porque todos os caracteres são numéricos

Há várias funções no VBA para testar vários tipos de dados, mas essas são as principais:

IsNumeric – testa se uma expressão é um número ou não.

IsDate – testa se uma expressão é uma data ou não.

IsNull – testa se uma expressão é nula ou não. Um valor nulo só pode ser colocado em um objeto variante; caso contrário, você receberá o erro “Uso Inválido de Nulo”. Uma caixa de mensagem retorna um valor nulo se você a estiver usando para fazer uma pergunta, portanto, a variável de retorno deve ser uma variant. Lembre-se de que qualquer cálculo que use um valor nulo sempre retornará o resultado nulo.

IsArray – testa se a expressão representa uma matriz ou não.

IsEmpty – testa se a expressão está vazia ou não. Observe que vazio não é o mesmo que nulo. Uma variável está vazia quando é definida pela primeira vez, mas não é um valor nulo.

Surpreendentemente, não há nenhuma função para IsText ou IsString, o que seria muito útil.

Objetos e Erros de Incompatibilidade

Se estiver usando objetos, como um intervalo ou uma planilha, você receberá um erro de incompatibilidade no momento da compilação, e não no momento da execução, o que lhe dará o devido aviso de que seu código não funcionará.

Sub TesteIntervalo()
Dim MyIntervalo As Range, I As Long
Set MyIntervalo = Range("A1:A2")
I = 10
x = UsarMeuIntervalo(I)
End Sub
Function UsarMeuIntervalo(R As Range)
End Function

Esse código tem uma função chamada ‘UsarMeuIntervalo’ e um parâmetro passado como um objeto de intervalo. Entretanto, o parâmetro que está sendo passado é um Long Integer, que não corresponde ao tipo de dados.

Quando você executa o código VBA, ele é imediatamente compilado e você verá essa mensagem de erro:

erro compilacao byref

O parâmetro incorreto será destacado com um fundo azul

Em geral, se você cometer erros no código VBA usando objetos, verá essa mensagem de erro, em vez de uma mensagem de incompatibilidade de tipo:

erro objeto nao definido

vba-free-addin

Exemplos de Add-ins de Códigos VBA

Acesse facilmente todos os exemplos de código que se encontram em nosso site.

Simply navigate to the menu, click, and the code will be inserted directly into your module. .xlam add-in.

(Nenhuma instalação necessária!)

Baixe de Graça

Retornar aos Exemplos de Códigos VBA