Vba excel: "" = pas vide?!

cs_Liro Messages postés 159 Date d'inscription jeudi 7 septembre 2006 Statut Membre Dernière intervention 30 septembre 2011 - 23 juil. 2007 à 17:11
Molenn Messages postés 797 Date d'inscription mardi 7 juin 2005 Statut Membre Dernière intervention 23 février 2011 - 25 juil. 2007 à 20:18
Bonjour,

J'ai dans un fichier excel un formule du type sur toute la colonne:
SI(B11;2;"")
C'est à dire que selon le contenu de B1 cette cellule peut prendre la valeur 2 ou "".
J'ai toujours cru que "" c'était RIEN, or il semblerait que se ne soit pas le cas et ça me pose quelques problèmes, je m'explique.

Dans une macro j'ai l'instruction suivante:
 
    Range("B1").Select
    
Selection.End(xlDown).Select

Le but étant de trouvé la dernière cellule contenant quelque chose (afin de supprimer les x lignes suivantes, car dans d'autres colonnes elles contiennent des infos que je souhaite supprimer).
Or les cellules correspondante à la formule citée plus haut sont considérée comme n'étant pas vide et trompe ma macro.

Es-ce qu'il existe une solution?
Merci par avance

Ludo

10 réponses

Molenn Messages postés 797 Date d'inscription mardi 7 juin 2005 Statut Membre Dernière intervention 23 février 2011 7
23 juil. 2007 à 17:56
Effectivement, Excel ne considère pas ta cellule comme vide puisqu'elle contient une Formule.

La première chose qui me vient à l'esprit, c'est de faire une boucle.
Avec ce que tu as déjà mis dans ta macro, tu as le numéro de la dernière ligne de ton tableau. En remontant à partir de là, tu regardes toutes les cellules 1 par 1 jusqu'à ce que tu en trouves une non vide, un truc du style :

Soit 10 la dernière ligne de ton tableau, et la colonne B celle que tu contrôles

For i = 10 to 1 step -1
      if cells(i,2).value <> "" then
            'i est le numéro de la dernière ligne non vide
            exit for
      end if
Next i

Sinon, tu as une solution avec des formules Excel, mais ça nécessite une colonne de plus, que tu peux toujours masquer.
Je considère ta colonne B la colonne à contrôler.
Tu rajoutes une colonne C dans la quelle sur chaque ligne, tu rajoutes la formule suivante :
SI(B1"";"";CELLULE("ligne";B1))
Sur chaque ligne, tu auras donc, si la colonne B de la ligne considérée n'est pas vide, le numéro de la ligne écrit dans la colonne C.

Exemple du résultat : 
N° ligne                  B                     C
1                           Toto                  1
2
3
4                           Tata                   4
5                           Tutu                   5

Il te suffit de mettre dans une cellule hors de ton tableau la formule suivante en A1 par ex :
A1: =MAX(C:C)
Cette cellule t'affichera en permanence la dernière ligne non vide de ton tableau.

Tu pourras donc utiliser cette info directement dans ta macro en remplaçant ton bout de code par Range("A1").value

A toi de voir ce que tu préfères.

Molenn
0
cs_Liro Messages postés 159 Date d'inscription jeudi 7 septembre 2006 Statut Membre Dernière intervention 30 septembre 2011
23 juil. 2007 à 19:00
Merci Molenn pour tes conseils.

"Effectivement, Excel ne considère pas ta cellule comme vide puisqu'elle contient une Formule."

J'ai oublié de préciser qu'avant d'éffectuer cette opération dans ma macro j'ai fait un copié/collage spécial, valeurs.
Dans ce cas la cellule devrait être considérée comme vide, non?

Je ne peux pas modifier mon fichier en ajoutant des formules.
Dans le morceau de code que tu donne il y a également une expression du type <>"" comme dans ma formule.
Celà ne va-t-il pas poser problèmes?

Merci
Liro
0
cs_MPi Messages postés 3877 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 17 août 2018 23
24 juil. 2007 à 01:03
Es-tu certain qu'il n'y a pas d'espace entre les 2 guillemets de ta formule ?
SI(B11;2; "" )
est différent de
=SI(B1=1;2;" ")

Autrement, les cellules devraient être considérées comme vide lors du copier/coller en valeur

MPi
0
Molenn Messages postés 797 Date d'inscription mardi 7 juin 2005 Statut Membre Dernière intervention 23 février 2011 7
24 juil. 2007 à 10:04
Rhaaaa, ça n'a pas pris mon message ! Je le sais pourtant, toujours faire un copier coller avant d'appuyer sur Ajouter !

Je disais juste donc :

Pour MPi, Liro a raison, suite à son message, j'ai fait un simple test :
A1: ="" copié sur plusieurs lignes
Puis copier coller valeur de la colonne A sur la colonne B

Et bien, en utilisant les raccourcis clavier (ctrl+flèches) dans la colonne B, on se rend compte que la plage est bien là. Idem avec un ctrl+*, toute la plage est sélectionnée.

Je ne vois pas trop comment faire. Pour retrouver un fonctionnement normal, faut juste faire Suppr sur la cellule (soit un ClearContents).

Liro, normalement, la boucle que je t'ai indiqué doit fonctionner, il n'y a pas de raison.

Molenn
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Liro Messages postés 159 Date d'inscription jeudi 7 septembre 2006 Statut Membre Dernière intervention 30 septembre 2011
24 juil. 2007 à 20:46
Merci Molenn mais dans ta boucle je dois connaîttre le nombre de cellule or je ne la connais pas! :(
Liro
0
Molenn Messages postés 797 Date d'inscription mardi 7 juin 2005 Statut Membre Dernière intervention 23 février 2011 7
24 juil. 2007 à 22:47
Ben si, tu le connais. Ton bout de code :
Range("B1").Select
Selection.End(xlDown).Select
te donne la dernière ligne de la boucle (au lieu de faire .select, tu fais .row)
Selection.End(xlDown).row

Je reprends ton exemple, qui partait de la cellule B1 :

For i = range("B1").End(xlDown).row to 1 step -1 'Boucle allant de la dernière ligne jusqu'à la première
      if cells(i,2).value <> "" then
            'i est le numéro de la dernière ligne non vide
            exit for
            else
            'Code de suppression de la ligne
            rows(i).delete
      end if
Next i

Molenn
0
mortalino Messages postés 6786 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 décembre 2011 18
24 juil. 2007 à 23:18
Bien mais pas bon Molenn sur un point :

For i = range("B1").End(xlDown).row to 1 step -1

range("B1").End(xlDown).row  doit être dans une variable avant, car à chaque passage dans For i, pour lui attribuer la valeur, il va calculer quelle est la dernière cellule utilisée.
Le mieux, c'est de faire :

        Dim DerLigne As Long
DerLigne =  range("B1").End(xlDown).row

For i = DerLigne to 1 step -1

Sur 65 536 lignes (et je ne compte pas le million de lignes dans Excel 2007), c'est certainement qques secondes de gagnées 

@++

<hr size="2" width="100%" />( Nouveau forum : Exclusivement Office & VBA
0
Molenn Messages postés 797 Date d'inscription mardi 7 juin 2005 Statut Membre Dernière intervention 23 février 2011 7
25 juil. 2007 à 08:04
??
Le End(xlDown) n'est calculé qu'une seule fois, à l'initialisation de la boucle. Au défilement de la boucle, on ne rapasse jamais sur la ligne For i.

Petit test avec le code suivant :

Private Sub CommandButton1_Click()
   
    For i = test(Range("C1")) To 1 Step -1 'Boucle allant de la dernière ligne jusqu'à la première
      If Cells(i, 3).Value <> "" Then
            'i est le numéro de la dernière ligne non vide
            Exit For
            Else
            'Code de suppression de la ligne
            Rows(i).Delete
      End If
    Next i


End Sub
Private Function test(toto As Range) As Integer
   
    test = toto.End(xlDown).Row
   
End Function

En mode pas à pas, je ne suis jamais retourné dans ma fonction test.

Donc, à moins que j'ai mal compris ce que tu voulais dire (et je m'en excuse d'avance ^^)

Molenn
0
mortalino Messages postés 6786 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 décembre 2011 18
25 juil. 2007 à 15:04
Oui, tu as absolument raison, j'étais persuadé que le test se refaisait systématiquement au passage de la boucle. Désolé, puisses-tu me pardonner

@++

<hr size="2" width="100%" />( Nouveau forum : Exclusivement Office & VBA
0
Molenn Messages postés 797 Date d'inscription mardi 7 juin 2005 Statut Membre Dernière intervention 23 février 2011 7
25 juil. 2007 à 20:18
Jamais ! Mouahahahahahaha
0
Rejoignez-nous