VBA - Incompatibilité de type (erreur d'exécution 13)

Qu'est-ce qu'une erreur de non-concordance de type ?

Une erreur de non-concordance peut souvent se produire lorsque vous exécutez votre code VBA. L'erreur arrêtera l'exécution complète de votre code et signalera au moyen d'une boîte de message que cette erreur doit être corrigée

Notez que si vous n'avez pas complètement testé votre code avant distribution aux utilisateurs, ce message d'erreur sera visible par les utilisateurs, et entraînera une grosse perte de confiance dans votre application Excel. Malheureusement, les utilisateurs font souvent des choses très particulières à une application et sont souvent des choses que vous, en tant que développeur, n'avez jamais envisagées.

Une erreur de non-concordance de type se produit parce que vous avez défini une variable en utilisant l'instruction Dim comme un certain type, par ex. entier, date et votre code essaie d'attribuer une valeur à la variable qui n'est pas acceptable, par ex. chaîne de texte affectée à une variable entière comme dans cet exemple :

Voici un exemple:

Cliquez sur Déboguer et la ligne de code incriminée sera surlignée en jaune. Il n'y a pas d'option dans la fenêtre contextuelle d'erreur pour continuer, car il s'agit d'une erreur majeure et il n'y a aucun moyen que le code puisse s'exécuter plus loin.

Dans ce cas particulier, la solution consiste à remplacer l'instruction Dim par un type de variable qui fonctionne avec la valeur que vous attribuez à la variable. Le code fonctionnera si vous changez le type de variable en 'String', et vous voudrez probablement aussi changer le nom de la variable.

Cependant, changer le type de variable nécessitera une réinitialisation de votre projet, et vous devrez réexécuter votre code depuis le début, ce qui peut être très ennuyeux si une longue procédure est impliquée

Erreur de non-concordance causée par le calcul de la feuille de calcul

L'exemple ci-dessus est un exemple très simple de la façon dont une erreur de non-concordance peut être produite et, dans ce cas, elle est facilement corrigée

Cependant, la cause des erreurs de non-concordance est généralement bien plus profonde que cela et n'est pas si évidente lorsque vous essayez de déboguer votre code.

Par exemple, supposons que vous ayez écrit du code pour récupérer une valeur à une certaine position sur une feuille de calcul et qu'il contienne un calcul dépendant d'autres cellules du classeur (B1 dans cet exemple)

La feuille de calcul ressemble à cet exemple, avec une formule pour trouver un caractère particulier dans une chaîne de texte

Du point de vue de l'utilisateur, la cellule A1 est au format libre et il peut entrer la valeur qu'il souhaite. Cependant, la formule recherche une occurrence du caractère « B », et dans ce cas, il n'est pas trouvé, la cellule B1 a donc une valeur d'erreur.

Le code de test ci-dessous produira une erreur de non-concordance car une valeur erronée a été entrée dans la cellule A1

1234 Incompatibilité de sous-test()Dim MyNumber en tant qu'entierMonNuméro = Feuilles("Feuille1").Plage("B1").ValeurFin du sous-marin

La valeur de la cellule B1 a produit une erreur car l'utilisateur a entré du texte dans la cellule A1 qui n'est pas conforme à ce qui était attendu et qui ne contient pas le caractère « B »

Le code essaie d'attribuer la valeur à la variable 'MyNumber' qui a été définie pour s'attendre à un entier, et vous obtenez donc une erreur de non-concordance.

C'est l'un de ces exemples où une vérification méticuleuse de votre code ne fournira pas la réponse. Vous devez également regarder sur la feuille de calcul d'où vient la valeur afin de savoir pourquoi cela se produit.

Le problème est en fait sur la feuille de calcul et la formule de B1 doit être modifiée pour que les valeurs d'erreur soient traitées. Vous pouvez le faire en utilisant la formule 'IFERROR' pour fournir une valeur par défaut de 0 si le caractère de recherche n'est pas trouvé

Vous pouvez ensuite incorporer du code pour vérifier la valeur zéro et afficher un message d'avertissement à l'intention de l'utilisateur indiquant que la valeur de la cellule A1 n'est pas valide.

12345678 Incompatibilité de sous-test()Dim MyNumber en tant qu'entierMonNuméro = Feuilles("Feuille1").Plage("B1").TexteSi MonNuméro = 0 AlorsMsgBox "La valeur de la cellule A1 n'est pas valide", vbCriticalQuitter le sousFin siFin du sous-marin

Vous pouvez également utiliser la validation des données (groupe Outils de données sur l'onglet Données du ruban) sur la feuille de calcul pour empêcher l'utilisateur de faire ce qu'il veut et de provoquer des erreurs de feuille de calcul en premier lieu. Autorisez-les uniquement à saisir des valeurs qui ne provoqueront pas d'erreurs de feuille de calcul.

Vous pouvez écrire du code VBA en fonction de l'événement Change dans la feuille de calcul pour vérifier ce qui a été entré.

Le verrouillage et le mot de passe protègent également la feuille de calcul, de sorte que les données invalides ne puissent pas être saisies

Erreur de non-concordance causée par les valeurs de cellule saisies

Des erreurs de non-concordance peuvent être causées dans votre code en introduisant des valeurs normales à partir d'une feuille de calcul (sans erreur), mais lorsque l'utilisateur a entré une valeur inattendue, par ex. une valeur de texte alors que vous attendiez un nombre. Ils peuvent avoir décidé d'insérer une ligne dans une plage de nombres afin de pouvoir mettre une note dans une cellule expliquant quelque chose à propos du nombre. Après tout, l'utilisateur n'a aucune idée du fonctionnement de votre code et du fait qu'il vient de tout chambouler en entrant sa note.

L'exemple de code ci-dessous crée un tableau simple appelé 'MyNumber' défini avec des valeurs entières

Le code parcourt ensuite une plage de cellules de A1 à A7, en attribuant les valeurs de cellule dans le tableau, en utilisant une variable « Coun » pour indexer chaque valeur

Lorsque le code atteint la valeur du texte, une erreur de non-concordance est provoquée par cela et tout s'arrête

En cliquant sur « Debug » dans la fenêtre d'erreur, vous verrez la ligne de code qui a le problème surligné en jaune. En passant votre curseur sur n'importe quelle instance de la variable "Coun" dans le code, vous pourrez voir la valeur de "Coun" là où le code a échoué, qui dans ce cas est de 5

En regardant sur la feuille de calcul, vous verrez que les 5e la cellule vers le bas a la valeur de texte et cela a provoqué l'échec du code

Vous pouvez modifier votre code en mettant en place une condition qui vérifie d'abord une valeur numérique avant d'ajouter la valeur de la cellule dans le tableau

12345678910111213 Sub TestMismatch()Dim MyNumber(10) en tant qu'entier, compter en tant qu'entierPays = 1FaireSi Coun = 11 Then Exit DoSi IsNumeric(Sheets("sheet1").Cells(Coun, 1).Value) ThenMonNuméro(Coun) = Sheets("sheet1").Cells(Coun, 1).ValueAutreMonNuméro(Pays) = 0Fin siPays = Pays + 1BoucleFin du sous-marin

Le code utilise la fonction 'IsNumeric' pour tester si la valeur est réellement un nombre, et si c'est le cas, il l'entre dans le tableau. S'il ne s'agit pas d'un nombre, il entre la valeur zéro.

Cela garantit que l'index du tableau est maintenu en ligne avec les numéros de ligne de cellule dans la feuille de calcul.

Vous pouvez également ajouter du code qui copie la valeur d'erreur d'origine et les détails de l'emplacement dans une feuille de calcul « Erreurs » afin que l'utilisateur puisse voir ce qu'il a mal fait lorsque votre code est exécuté.

Le test numérique utilise le code complet de la cellule ainsi que le code pour affecter la valeur dans le tableau. Vous pourriez argumenter que cela devrait être affecté à une variable afin de ne pas répéter le même code, mais le problème est que vous auriez besoin de définir la variable comme une "Variante", ce qui n'est pas la meilleure chose à faire.

Vous avez également besoin de la validation des données sur la feuille de calcul et de protéger par mot de passe la feuille de calcul. Cela empêchera l'utilisateur d'insérer des lignes et de saisir des données inattendues.

Erreur de non-concordance causée par l'appel d'une fonction ou d'une sous-routine à l'aide de paramètres

Lorsqu'une fonction est appelée, vous transmettez généralement des paramètres à la fonction en utilisant des types de données déjà définis par la fonction. La fonction peut être une fonction déjà définie dans VBA, ou il peut s'agir d'une fonction définie par l'utilisateur que vous avez créée vous-même. Une sous-routine peut aussi parfois nécessiter des paramètres

Si vous ne respectez pas les conventions de transmission des paramètres à la fonction, vous obtiendrez une erreur de non-concordance

12345678 Sous CallFunction()Dim Ret en tant qu'entierRet = MaFonction(3, "test")Fin du sous-marinFonction MyFunction(N comme entier, T comme chaîne) comme chaîneMaFonction = TFonction de fin

Il y a plusieurs possibilités ici pour obtenir une erreur de non-concordance

La variable de retour (Ret) est définie comme un entier, mais la fonction renvoie une chaîne. Dès que vous exécutez le code, il échouera car la fonction renvoie une chaîne et celle-ci ne peut pas entrer dans une variable entière. Fait intéressant, l'exécution de Debug sur ce code ne détecte pas cette erreur.

Si vous mettez des guillemets autour du premier paramètre passé (3), il est interprété comme une chaîne, qui ne correspond pas à la définition du premier paramètre de la fonction (entier)

Si vous transformez le deuxième paramètre de l'appel de fonction en une valeur numérique, il échouera avec une incompatibilité car le deuxième paramètre de la chaîne est défini comme une chaîne (texte)

Erreur de non-concordance causée par l'utilisation incorrecte des fonctions de conversion dans VBA

Il existe un certain nombre de fonctions de conversion que vous pouvez utiliser dans VBA pour convertir des valeurs en différents types de données. Un exemple est « CInt » qui convertit une chaîne contenant un nombre en une valeur entière.

Si la chaîne à convertir contient des caractères alpha, vous obtiendrez une erreur de non-concordance, même si la première partie de la chaîne contient des caractères numériques et le reste est constitué de caractères alpha, par ex. '123abc'

Prévention générale des erreurs de non-concordance

Nous avons vu dans les exemples ci-dessus plusieurs manières de traiter les erreurs potentielles de non-concordance dans votre code, mais il existe un certain nombre d'autres manières, bien qu'elles ne soient peut-être pas les meilleures options :

Définissez vos variables en tant que type de variante

Un type de variante est le type de variable par défaut dans VBA. Si vous n'utilisez pas d'instruction Dim pour une variable et commencez simplement à l'utiliser dans votre code, le type de Variant lui est automatiquement attribué.

Une variable Variant accepte tout type de données, qu'il s'agisse d'un entier, d'un entier long, d'un nombre double précision, d'un booléen ou d'une valeur de texte. Cela semble être une idée merveilleuse, et vous vous demandez pourquoi tout le monde ne définit pas toutes ses variables sur variant.

Cependant, le type de données variant présente plusieurs inconvénients. Premièrement, il prend beaucoup plus de mémoire que les autres types de données. Si vous définissez un très grand tableau en tant que variante, il engloutira une énorme quantité de mémoire lors de l'exécution du code VBA et pourrait facilement entraîner des problèmes de performances.

Deuxièmement, ses performances sont généralement plus lentes que si vous utilisez des types de données spécifiques. Par exemple, si vous effectuez des calculs complexes à l'aide de nombres à virgule flottante, les calculs seront considérablement plus lents si vous stockez les nombres sous forme de variantes, plutôt que de nombres à double précision.

L'utilisation du type variant est considérée comme une programmation bâclée, à moins que cela ne soit absolument nécessaire.

Utilisez la commande OnError pour gérer les erreurs

La commande OnError peut être incluse dans votre code pour gérer le piégeage des erreurs, de sorte que si une erreur se produit, l'utilisateur voit un message significatif au lieu de la fenêtre contextuelle d'erreur VBA standard.

1234567 Sous ErrorTrap()Dim MyNumber en tant qu'entierEn cas d'erreur GoTo Err_HandlerMonNuméro = "tester"Err_Handler :MsgBox " L'erreur " & Err.Description & " s'est produite "Fin du sous-marin

Cela empêche efficacement l'erreur d'arrêter le bon fonctionnement de votre code et permet à l'utilisateur de récupérer proprement de la situation d'erreur.

La routine Err_Handler peut afficher des informations supplémentaires sur l'erreur et qui contacter à ce sujet.

Du point de vue de la programmation, lorsque vous utilisez une routine de gestion des erreurs, il est assez difficile de localiser la ligne de code sur laquelle se trouve l'erreur. Si vous parcourez le code à l'aide de F8, dès que la ligne de code incriminée est exécutée, elle passe à la routine de gestion des erreurs et vous ne pouvez pas vérifier où elle ne va pas.

Un moyen de contourner cela est de configurer une constante globale qui est True ou False (booléen) et de l'utiliser pour activer ou désactiver la routine de gestion des erreurs à l'aide d'une instruction « If ». Lorsque vous souhaitez tester l'erreur, tout ce que vous avez à faire est de définir la constante globale sur False et le gestionnaire d'erreurs ne fonctionnera plus.

1 Global Const ErrHandling = False
1234567 Sous ErrorTrap()Dim MyNumber en tant qu'entierSi ErrHandling = True Then On Error GoTo Err_HandlerMonNuméro = "tester"Err_Handler :MsgBox " L'erreur " & Err.Description & " s'est produite "Fin du sous-marin

Le seul problème avec ceci est que cela permet à l'utilisateur de récupérer de l'erreur, mais le reste du code dans la sous-routine ne s'exécute pas, ce qui peut avoir d'énormes répercussions plus tard dans l'application

En utilisant l'exemple précédent de boucle à travers une plage de cellules, le code arriverait à la cellule A5 et frapperait l'erreur incompatible. L'utilisateur verrait une boîte de message donnant des informations sur l'erreur, mais rien à partir de cette cellule de la plage ne serait traité.

Utilisez la commande OnError pour supprimer les erreurs

Cela utilise la commande « On Error Resume Next ». Ceci est très dangereux à inclure dans votre code car cela empêche l'affichage d'erreurs ultérieures. Cela signifie essentiellement que pendant l'exécution de votre code, si une erreur se produit dans une ligne de code, l'exécution se déplacera simplement à la prochaine ligne disponible sans exécuter la ligne d'erreur, et se poursuivra normalement.

Cela peut résoudre une situation d'erreur potentielle, mais cela affectera toujours chaque erreur future dans le code. Vous pouvez alors penser que votre code est exempt de bogues, mais en fait ce n'est pas le cas et certaines parties de votre code ne font pas ce que vous pensez qu'il devrait faire.

Il y a des situations où il est nécessaire d'utiliser cette commande, comme si vous supprimez un fichier à l'aide de la commande 'Kill' (si le fichier n'est pas présent, il y aura une erreur), mais la capture d'erreur doit toujours être rétablie immédiatement après l'endroit où l'erreur potentielle pourrait se produire en utilisant :

1 En cas d'erreur Aller à 0

Dans l'exemple précédent de boucle à travers une plage de cellules, en utilisant 'On Error Resume Next', cela permettrait à la boucle de continuer, mais la cellule provoquant l'erreur ne serait pas transférée dans le tableau, et l'élément de tableau pour cet index particulier tiendrait une valeur nulle.

Conversion des données en un type de données pour correspondre à la déclaration

Vous pouvez utiliser les fonctions VBA pour modifier le type de données des données entrantes afin qu'il corresponde au type de données de la variable de réception.

Vous pouvez le faire lorsque vous passez des paramètres aux fonctions. Par exemple, si vous avez un nombre contenu dans une variable de chaîne et que vous souhaitez le transmettre sous forme de nombre à une fonction, vous pouvez utiliser CInt

Il existe un certain nombre de ces fonctions de conversion qui peuvent être utilisées, mais voici les principales :

CInt - convertit une chaîne qui a une valeur numérique (inférieure à + ou - 32 768) en une valeur entière. Sachez que cela tronque tous les points décimaux

CLng - Convertit une chaîne qui a une grande valeur numérique en un entier long. Les points décimaux sont tronqués.

CDbl - Convertit une chaîne contenant un nombre à virgule flottante en un nombre à double précision. Comprend des points décimaux

CDate - Convertit une chaîne contenant une date en une variable de date. Dépend en partie des paramètres du Panneau de configuration Windows et de vos paramètres régionaux sur la façon dont la date est interprétée

CStr - Convertit une valeur numérique ou de date en une chaîne

Lors de la conversion d'une chaîne en un nombre ou une date, la chaîne ne doit contenir rien d'autre que des nombres ou une date. Si des caractères alpha sont présents, cela produira une erreur de non-concordance. Voici un exemple qui produira une erreur de non-concordance :

123 Sous-test()MsgBox CInt("123abc")Fin du sous-marin

Tester les variables dans votre code

Vous pouvez tester une variable pour savoir de quel type de données il s'agit avant de l'affecter à une variable d'un type particulier.

Par exemple, vous pouvez vérifier une chaîne pour voir si elle est numérique en utilisant la fonction 'IsNumeric' dans VBA

1 MsgBox IsNumeric("123test")

Ce code renverra False car bien que la chaîne commence par des caractères numériques, elle contient également du texte et échoue donc au test.

1 MsgBox IsNumeric("123")

Ce code retournera True car ce sont tous des caractères numériques

Il existe un certain nombre de fonctions dans VBA pour tester différents types de données, mais voici les principales :

IsNumeric - teste si une expression est un nombre ou non

IsDate - teste si une expression est une date ou non

IsNull - teste si une expression est nulle ou non. Une valeur nulle ne peut être placée que dans un objet variant, sinon vous obtiendrez une erreur « Utilisation invalide de Null ». Une boîte de message renvoie une valeur nulle si vous l'utilisez pour poser une question, la variable de retour doit donc être une variante. Gardez à l'esprit que tout calcul utilisant une valeur nulle renverra toujours le résultat de null.

IsArray - teste si l'expression représente un tableau ou non

IsEmpty - teste si l'expression est vide ou non. Notez que vide n'est pas la même chose que null. Une variable est vide lorsqu'elle est définie pour la première fois mais ce n'est pas une valeur nulle

Étonnamment, il n'y a pas de fonction pour IsText ou IsString, ce qui serait vraiment utile

Objets et erreurs de non-concordance

Si vous utilisez des objets tels qu'une plage ou une feuille, vous obtiendrez une erreur de non-concordance au moment de la compilation, pas au moment de l'exécution, ce qui vous avertira que votre code ne fonctionnera pas.

123456 Sous-plage de test()Dim MyRange As Range, I As LongDéfinir MyRange = Range("A1:A2")je = 10x = UtiliserMaPlage(I)Fin du sous-marin
12 Fonction UseMyRange(R As Range)Fonction de fin

Ce code a une fonction appelée « UseMyRange » et un paramètre transmis en tant qu'objet de plage. Cependant, le paramètre transmis est un entier long qui ne correspond pas au type de données.

Lorsque vous exécutez du code VBA, il est immédiatement compilé et vous verrez ce message d'erreur :

Le paramètre incriminé sera mis en évidence avec un fond bleu

Généralement, si vous faites des erreurs dans le code VBA en utilisant des objets, vous verrez ce message d'erreur, plutôt qu'un message de non-concordance de type :

Vous contribuerez au développement du site, partager la page avec vos amis

wave wave wave wave wave