Longueur de la variable String [VBA]
Résolu
JPKOF
-
JPKOF -
JPKOF -
Bonjour à tous,
Je vous expose mon problème :
Dans une feuille de calcul que je reçois chaque semaine, il y a certaines lignes pour lesquelles la valeur de la case (i , 1) est nulle (ou vide).
Je voudrai supprimer toutes ces lignes.
J'ai bien trouvé une solution avec un :
Oui ça marche mais c'est trés trés long. Mon fichier faisant entre 60 000 et 65 000 lignes j'ai donc cherché une autre solution un peu plus compliquée (mais qui ne marche pas ... encore :p ) et surtout plus rapide dans l'éxécution :
L'idée est donc de stocker tous les numéros de lignes à supprimer pour pouvoir tout supprimer en une seule étape à la fin.
Cependant, lorsque je fais tourner la macro, ça plante justement à la ligne
Et lorsque je regarde le contenu de ma variable zonasup à ce moment la (via un espion) je tombe sur
Le point positif c'est que le contenu de la variable est écrit de la façon que je voulais, le point négatif c'est que cette variable ne semble stocker que 250 caractères (j'ai testé de copier coller dans une cellule excel et j'ai fait un NBCAR(...))
Le problème vient-il de la taille maximale de la variable string ?
J'espère avoir été suffisamment clair, peut être un peu trop pour quelque chose qui ne reste peut être, au fond, qu'un petit problème de string :)
Je vous expose mon problème :
Dans une feuille de calcul que je reçois chaque semaine, il y a certaines lignes pour lesquelles la valeur de la case (i , 1) est nulle (ou vide).
Je voudrai supprimer toutes ces lignes.
J'ai bien trouvé une solution avec un :
nblig = Range("a65535").End(xlUp).Row For i = 2 To nblig If Cells(i, 1) = 0 Or Cells(i, 1) = "" Then Cells(i, 1).Delete Shift:=xlUp End If Next i
Oui ça marche mais c'est trés trés long. Mon fichier faisant entre 60 000 et 65 000 lignes j'ai donc cherché une autre solution un peu plus compliquée (mais qui ne marche pas ... encore :p ) et surtout plus rapide dans l'éxécution :
Dim zonasup as string nblig = Range("a65535").End(xlUp).Row zonasup = "" For i = 2 To nblig If Cells(i, 1) = 0 Or Cells(i, 1) = "" Then If zonasup ="" then zonasup = i & ":" & i else: zonasup = zonasup & "," & i &":" & i end if End If Next i range(zonasup).Delete Shift:=xlUp
L'idée est donc de stocker tous les numéros de lignes à supprimer pour pouvoir tout supprimer en une seule étape à la fin.
Cependant, lorsque je fais tourner la macro, ça plante justement à la ligne
range(zonasup).Delete Shift:=xlUp
Et lorsque je regarde le contenu de ma variable zonasup à ce moment la (via un espion) je tombe sur
"86:86,87:87,88:88,89:89,90:90,91:91,92:92,93:93,94:94,95:95,96:96,97:97,230:230,231:231,232:232,233:233,234:234,235:235,236:236,237:237,238:238,239:239,240:240,241:241,327:327,328:328,329:329,330:330,331:331,332:332,333:333,334:334,336:336,337:337,33
Le point positif c'est que le contenu de la variable est écrit de la façon que je voulais, le point négatif c'est que cette variable ne semble stocker que 250 caractères (j'ai testé de copier coller dans une cellule excel et j'ai fait un NBCAR(...))
Le problème vient-il de la taille maximale de la variable string ?
J'espère avoir été suffisamment clair, peut être un peu trop pour quelque chose qui ne reste peut être, au fond, qu'un petit problème de string :)
A voir également:
- Longueur de la variable String [VBA]
- Incompatibilité de type vba ✓ - Forum Programmation
- Vba range avec variable ✓ - Forum VB / VBA
- Vba concatenate string and integer ✓ - Forum VB / VBA
- Range avec une Variable ✓ - Forum VB / VBA
- Cannot access offset of type string on string - Forum PHP
3 réponses
Bonjour,
Tu peux rester sur ta 1ère solution et ajouter devant :
Application.ScreenUpdating = False
à rétablir à = True après
Et si tes cellules sont vraiment vides (pas de formule) tu peux le faire sans boucle avec :
Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
eric
Tu peux rester sur ta 1ère solution et ajouter devant :
Application.ScreenUpdating = False
à rétablir à = True après
Et si tes cellules sont vraiment vides (pas de formule) tu peux le faire sans boucle avec :
Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
eric
Bonjour,
Sur 65000 lignes je ne garantis pas mais essaies:
range("A1:A65536").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
t'enlève les celules vides (pas celles avec des 0)
je regarde pour un autre truc et te dis...
Combien as tu de colonnes dans ton tableau ?
d'ores et déjà yu gagnerais un temps important avec cette ligne en début de macro:
application.screenupdating=false
Michel
Sur 65000 lignes je ne garantis pas mais essaies:
range("A1:A65536").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
t'enlève les celules vides (pas celles avec des 0)
je regarde pour un autre truc et te dis...
Combien as tu de colonnes dans ton tableau ?
d'ores et déjà yu gagnerais un temps important avec cette ligne en début de macro:
application.screenupdating=false
Michel
Bilan : ça marche trés bien,
Cependant, quitte à apprendre quelque chose aujourd'hui j'aurai quelques questions :
Quelle est la différence entre
et
Que comprends VBA lorsqu'on appelle les varaibles
Pourquoi stocker les valeurs dans la variable tablo en inversant les lignes et les colonnes ?
Par ailleurs, la macro marche mais des lignes vides apparaissent dorénavant en première position. Est ce normal ?
Cependant, quitte à apprendre quelque chose aujourd'hui j'aurai quelques questions :
Quelle est la différence entre
derlig = Cells(Cells.Rows.Count, 1).End(xlUp).Row
et
derlig = Range("f65535").End(xlUp).Row
Que comprends VBA lorsqu'on appelle les varaibles
DIM tablo, valeur
Pourquoi stocker les valeurs dans la variable tablo en inversant les lignes et les colonnes ?
Par ailleurs, la macro marche mais des lignes vides apparaissent dorénavant en première position. Est ce normal ?
1/ les 2 formules sont valables. mais comme XL2007 a plus d'un million de lignes, la 1° formule marche sur les versions 2007 et inférieure (comme tu travailles sur 65000 lignes on aurait pu écrire
Range("A65536")..).
2/ Dim tablo, valeur ==> variant
je connaissais pas le type des données en colonne A: toi,si, donc tu peux complèter.
pour le tablo je laisse toujours en variant car le type des données est variable;dans le 1° paramêtre(8,0) 1° rang peut -être en string, le 2° en single le 3° en date...
3/ je ne sais pas combien de lignes va avoir le tableau puisqu'à chaque condition remplie j'augmente 1 ligne au nombre de lignes par redim preserve tablo (8,cpr_t)...... cpr_t=cpr_t+1
Or on peut faire cela que sur le dernier paramêtre, d'où l'inversion lignes colonnes, d'où ensuite l'utilisation de la fonction Excel "transpose"
4/ lignes vides: sur ma maquette le n'ai pas ce problème. attention si tu as fait des adaptations à la réalité de ton classeur, des oublis ou maladresses (on sait tous faire) font des trucs tout drôles ou il ya le résultat d'une formule qui renverrait "" et peut-être que...
Les variables- tableaux sont indispensables lorsque tu as des tableaux géants comme les tiens car on quitte les feuilles XL (va et vient ecran, mémoire, processeur, mémoire, ecran) pour travaille en mémoire ram et peut ^tre en L2
Si ca t'intéresse, tu as un tuto très pédagogique écrit pas mon vieux copain Silkyroad sur Developpez.Com
https://silkyroad.developpez.com/vba/tableaux/
enfin, tu ne peux peut-être pas faire autrement mais Microsoft déconseille les databases XL de plus de 15000 lignes
http://office.microsoft.com/fr-ch/excel-help/utilisation-d-access-ou-d-excel-pour-gerer-vos-donnees-HA001042918.aspx
mais bof!
Voilà, je vais quand m^me regarder pour les lignes et je te fais signe si il y a un bug... sinon, bonne soirée et content pour toi si t'es débarrassé de ce problème
Cordialement
Range("A65536")..).
2/ Dim tablo, valeur ==> variant
je connaissais pas le type des données en colonne A: toi,si, donc tu peux complèter.
pour le tablo je laisse toujours en variant car le type des données est variable;dans le 1° paramêtre(8,0) 1° rang peut -être en string, le 2° en single le 3° en date...
3/ je ne sais pas combien de lignes va avoir le tableau puisqu'à chaque condition remplie j'augmente 1 ligne au nombre de lignes par redim preserve tablo (8,cpr_t)...... cpr_t=cpr_t+1
Or on peut faire cela que sur le dernier paramêtre, d'où l'inversion lignes colonnes, d'où ensuite l'utilisation de la fonction Excel "transpose"
4/ lignes vides: sur ma maquette le n'ai pas ce problème. attention si tu as fait des adaptations à la réalité de ton classeur, des oublis ou maladresses (on sait tous faire) font des trucs tout drôles ou il ya le résultat d'une formule qui renverrait "" et peut-être que...
Les variables- tableaux sont indispensables lorsque tu as des tableaux géants comme les tiens car on quitte les feuilles XL (va et vient ecran, mémoire, processeur, mémoire, ecran) pour travaille en mémoire ram et peut ^tre en L2
Si ca t'intéresse, tu as un tuto très pédagogique écrit pas mon vieux copain Silkyroad sur Developpez.Com
https://silkyroad.developpez.com/vba/tableaux/
enfin, tu ne peux peut-être pas faire autrement mais Microsoft déconseille les databases XL de plus de 15000 lignes
http://office.microsoft.com/fr-ch/excel-help/utilisation-d-access-ou-d-excel-pour-gerer-vos-donnees-HA001042918.aspx
mais bof!
Voilà, je vais quand m^me regarder pour les lignes et je te fais signe si il y a un bug... sinon, bonne soirée et content pour toi si t'es débarrassé de ce problème
Cordialement
Merci beaucoup pour toutes ces informations.
J'ai vraiment cherché comment apparaissaient ces lignes vides.
A défaut de pouvoir prévenir, j'ai réussi a guérir en utilisant la formule que vous m'aviez donné en début de post, à savoir :
DU coup le résultat obtenu est celui attendu dans un temps record (en ajoutant votre code à la suite du mien j'obtiens une macro qui tourne en moins de 30 sec).
Merci à tout les deux pour votre aide et à la prochaine
J'ai vraiment cherché comment apparaissaient ces lignes vides.
A défaut de pouvoir prévenir, j'ai réussi a guérir en utilisant la formule que vous m'aviez donné en début de post, à savoir :
Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
DU coup le résultat obtenu est celui attendu dans un temps record (en ajoutant votre code à la suite du mien j'obtiens une macro qui tourne en moins de 30 sec).
Merci à tout les deux pour votre aide et à la prochaine
Concernant les cellules "vraiment vides" : elles le sont vraiment et la fonction que tu me proposes marche donc bien.
Cependant la cellule avec formule pour lesquelles la veleur de la formule est nulle affichent "0"
je test une formule équivalent avec xlCellTypeNull mais ça ne marche pas :)
Merci pour ton aide
Je n'avais pas rafraichi, salut michel, on est bien phase... :-)
xlCellTypeNull c'était bien tenté... ;-)
Après avoir supprimé les vides avec xlCellTypeBlanks je te propose d'utiliser le filtre automatique pour accelerer le traitement :
Cells.AutoFilter Field:=1, Criteria1:="0"
Rows("2:65536").Delete Shift:=xlUp
Selection.AutoFilter Field:=1
Je te laisse tester le gain sur un grand fichier, à toi de dire...
eric
Donc, en guise d'apéro
temps pour 7500 lignes DonT 4100 vides ou 0: environ 0,9 secondes (512 mo de ram)
principe; je récolte les lignes non vides ou 0 dans un tableau-array et je restitue en supprimeant auparavant les données originelles
Eric ta solution est astucieuse mais est ce que ca masque sans détruire les lignes vides (suis faché betement avec les filtres) ?
Ca affiche les 0 et supprime ces lignes, les vides sont traités auparavant avec xlCellTypeBlanks .
J'ai testé sur 59400 lignes, tu es plus rapide (11s au lieu de 23s) mais il reste les 0 chez toi (???).
Il doit manquer qcq chose...
eric