Problème de syntaxe erreur
Bonjour tout le monde,
Je suis bloqué pour faire une macro dont j'ai mis le fichier en PJ.
En fait je voudrais que la macro :
- compare le texte de la cellule (k,2) avec N/A
- si c'est égal alors effacement de la ligne k sinon rien
- enfin lorsque la boucle est finie, la macro delete toutes les lignes dont la 1ère case de la colonne 1 est vide
Cependant j'ai deux problèmes sur la 1ére partie de la macro :
J'ai le message :
Erreur d’exécution 1004
Erreur définie par l’application ou par l’objet
lorsque j'écris :
If Cells(k, 2).Value = Cells(20,20).Value Then 'cellule(20,20) contenant =+NA()
Rows("k:k").Selectj'ai le message d'erreur au niveau de rows("k;k")
Ensuite si j'écris :
If Cells(k, 2).Value = “#N/A”.Value Then
Rows("k:k").Selectj'ai le message
Erreur d’exécution 13
Incompatibilité de type
Quelqu'un peut-il m'expliquer ces messages d'erreur s'il vous plait ?
Pb de syntaxe ?
est-ce bien équivalent de mettre "#N/A" et Cells(k,5).Value qui contient =+NA() ?
D'avance merci pour votre aide !
Bonjour,
utilise la Fonction EstNA(..) ,
et pour ce qui est de ton Cells("k:k").Select ... supprime la ligne l'instruction Select est rarement utile...
Bonjour,
Sub deleteNA()
Dim k As Integer, n As Integer
Application.ScreenUpdating = False
With ActiveSheet
n = .Cells(.Rows.Count, 2).End(xlUp).Row
For k = n To 1 Step -1
If IsError(.Cells(k, 2)) Then
If .Cells(k, 2) = CVErr(xlErrNA) Then .Rows(k).Delete
End If
Next k
End With
End Subne pas confondre syntaxe Excel et syntaxe VBA....
Cordialement.
- Messages
- 1'119
- Excel
- 2013 FR
- Inscrit
- 18/09/2015
- Emploi
- Développeur Bureautique Indépendant (Excel)
Bonjoiur clemoo, pierre.jy, MFerrand
Presque à peu près presque pareil que MFerrand, mais avec un peu de retard
Sub EffacerNA()
Dim ligDeb, ligFin, ligAct
ligDeb = 1 ' La LIGne de DEBut de liste est en 1 // à modifier selon ton cas
ligFin = Cells(ligDeb, 1).End(xlDown).Row ' Rechercher la derniere ligne non vide (LIGne de FIN)
ligFin = IIf(ligFin = Rows.Count, 0, ligFin) ' Si on arrive sur la derniere ligne possible
' Affecter 0 LIGne de FIN comme ça la boucle ne s'execute pas
' Le traitement comme ICI !!
' Boucler sur toutes les lignes (de LIGne de FIN à LIGne de DEBut
' PS/
' la boucle tourne à l'envers de la fin vers le début parce que sinon on ne trouve pas toutes les lignes
' à cause des effacements - les lignes remontent et peuvent donc être oubliées !!
For ligAct = ligFin To ligDeb Step -1
' Si la cellule de la LIGne ACTuelle en colonne 2 est #N/A
If WorksheetFunction.IsNA(Cells(ligAct, 2)) Then
' Juste pour voir le déroulement des opérations // à supprimer par la suite !!!
MsgBox "Cellule " & ligAct & " =#N/A"
' Effacer (Delete) la totalité de la ligne (EntireRow) de la cellule de la LIGne ACTuelle
Cells(ligAct, 1).EntireRow.Delete
End If
Next
End Submais en version commentée spécial débutants, novices et autres du même genre
Bonsoir,
La plus part des formules Excel sont utilisable en VBA... pour EstNa c'est : isNa ..!
- Messages
- 1'119
- Excel
- 2013 FR
- Inscrit
- 18/09/2015
- Emploi
- Développeur Bureautique Indépendant (Excel)
Bonjour pierre.jy
En attendant que notre ami nous dise quelle solution il adopte...
pierre.jy a écrit :La plus part des formules Excel sont utilisable en VBA... pour EstNa c'est : isNa ..!
Tu veux dire que au lieu de If WorksheetFunction.IsNA(Cells(ligAct, 2)) je peux écrire If IsNa(... Directement ?
Bonsoir à tous,
Il est vrai que la plupart des fonctions Excel sont disponible en VBA... avec la méthode WorksheetFunction (et en utilisant une syntaxe VBA).
Elles peuvent s'avérer dans certains cas plus pratique, voire plus efficace, notamment lorsqu'il n'existe pas de fonction VBA équivalente.
S'il existe de nombreuses fonctions Excel et aussi de nombreuses fonctions VBA, si certaines se recoupent, des fonctions Excel n'ont pas d'équivalent VBA et des fonctions VBA n'ont pas d'équivalent Excel...
Au cas particulier, la difficulté de test reposait sur les distinctions de type de donnée. Une valeur d'erreur est un type de donnée qui n'est ni du texte ni une valeur numérique et peut donc déclencher une incompatibilité de type (VBA ne convertissant pas dans ce cas).
N'ayant jamais noté que les fonctions Excel sous VBA étaient plus rapides que les fonctions VBA proprement dites, je privilégie pour ma part ces dernières dès lors qu'il y en a d'utilisables, ce qui était le cas ici.
J'ai donc utilisé un double test, analogue à un test avec IsNumeric précédant une comparaison numérique (qui déclencherait une erreur quand on n'est pas en présences de nombres), avec IsError (fonction VBA) et CVErr (fonction VBA renvoyant des valeurs d'erreurs Excel).
Pour le reste de mon code, si j'ai procédé à suppression de lignes successives aux tests, c'est plus pour des raisons didactiques (et aussi montrer que l'on n'avait pas besoin de deux procédures pour ce résultat). Mais la méthode de clemoo consistant à opérer la suppression en bloc est tout à fait utilisable (et dans la même procédure) et devrait apporter un léger gain de rapidité (léger seulement parce que le parcours en boucle n'est pas non plus dans ce cas sans interaction en écriture avec la feuille Excel...)
Cordialement.
Bonjour à tous,
Tout d'abord merci pour vos réponses et pour vos codes qui fonctionnent parfaitement !
J'ai adapté mon code avec quelques lignes de vos codes (en utilisant celui de MFerrand ^^ désolé andrea73) et ça fonctionne merci !
Sub deleteNA()
Dim k As Integer, i As Integer
i = 0
For k = 1 To 10
If IsError(Cells(k, 2)) Then
If Cells(k, 2) = CVErr(xlErrNA) Then Rows(k).delete
Rows(k).Select 'sélection de la ligne k
Selection.ClearContents 'effacement de la ligne k
i = i + 1
Else
End If
Next k
Range("A1:A10").SpecialCells(xlCellTypeBlanks).EntireRow.delete
MsgBox "Nb de lignes supprimées :" & i
End SubMFerrand, je n'ai pas compris pas la phrase "Pour le reste de mon code, si j'ai procédé à suppression de lignes successives aux tests, c'est plus pour des raisons didactiques (et aussi montrer que l'on n'avait pas besoin de deux procédures pour ce résultat)" C'est-à-dire supprimer après chaque test ?
Je ne savais pas que le #N/A n'était ni du texte ni une valeur, merci pour l'info.
J'ai voulu rajouter un compteur pour connaitre le nb de lignes supprimées, cependant je me demande s'il est bien placé, en effet lorsque 3 lignes sont supprimées le message m'indique 2...
De plus, tant que je n'ai pas fermé la box, le rond bleu de chargement tourne ... savez-vous pourquoi ?
Je suis débutant en VBA, à quoi cela sert-il d'écrire .Cells ?
Le Application.ScreenUpdating = False sert à gagner du temps ?
Désolé avec toutes mes questions,
Merci d'avance !
Bonsoir,
Si la phrase que tu ne sembles pas avoir compris soulignait que le choix de suppression globale dans ta 2e procédure était judicieux, bien que je ne l'ai pas repris, tous tes choix ne sont pas aussi judicieux...
Détaillons :
- Chaque fois que tu tapes un Select dans une procédure (ou un Activate ou équivalent), dis-toi que c'est la même chose que si au volant de ta voiture dans une ligne droite entièrement dégagée tu te mettais à presser le frein...
Pierre-jy te l'avais déjà signalé je crois... Pour chaque action nécessaire, tu en fais en plus, inutiles, qui n'ont pour effet que ralentir l'exécution.
- Quand tu écris Range ou Cells, VBA va interpréter qu'il s'agit d'une plage et qu'il doit chercher la feuille active pour la trouver car elle n'est pas qualifiée, rechercher qu'il accomplit à chaque fois... Si tu fais précéder en amont d'une instruction With ActiveSheet, VBA met cette feuille en mémoire et il sait que toute expression précédée d'un point réfère à cette feuille : quand il rencontre .Range ou .Cells il ne cherche plus de quelle feuille il s'agit. Encore un gain de temps.
- Ton maintien de Delete alors qu'en même temps tu la sélectionnes pour l'effacer crée une situation contradictoire : si la ligne est supprimée elle ne peut plus faire l'objet d'une autre action, ou c'est une autre ligne qui est alors affectée...
- Lorsqu'on supprime en utilisant une boucle, on parcours toujours la boucle à l'envers, en partant de la fin pour finir au début, car la suppression de ligne modifie la position des lignes qui suivent.
- On peut encore ajouter qu'initialiser une variable Integer à 0 est peu utile, sa valeur étant 0 tant que tu ne lui en a pas donnée une autre. De même un Else sans instruction est une instruction superflue.
- Par ailleurs, ta variable i compte le nombre de valeurs d'erreurs trouvées. Vu ton code dans la boucle, je ne me prononcerai pas sur le résultat sans test...
Cordialement.
Avec un petit changement dans la macro
Sub deleteNA()
Dim k As Long
For k = 2 To Cells(Rows.Count, 2).End(xlUp).Row
If Cells(k, 2).Text = "#N/A" Then
Cells(k, 2) = ""
End If
Next
End Sub