Boucle while en erreur - VB/VBA/VBS - Programmation
Marsh Posté le 15-05-2013 à 21:30:37
J'ai oublié de préciser que je travaille sur Windows Seven et Excel 2010.
Marsh Posté le 16-05-2013 à 07:47:48
Je n'ai pas trop le temps de répondre précisément, mais effectivement, ton code doit sacrément boguer...
D'abord i et j devraient être déclaré en Integer (Variant c'est bon aussi, mais Integer c'est mieux).
Ensuite tu déclares tes 2 tableaux comme étant des Worksheet mais ensuite tu les utilises comme si c'était des variables tableaux. Ca ne peut pas fonctionner !
Ensuite, tu as ta ligne
Si tablsor = (225,25) |
Pourquoi Si et pas If et il faut rajouter un Then? De plus même un
If tablsor = (225,25) Then |
ne peut fonctionner, ça ne veut rien dire...
Bon courage
Marsh Posté le 16-05-2013 à 10:31:19
otobox a écrit : Je n'ai pas trop le temps de répondre précisément, mais effectivement, ton code doit sacrément boguer... |
Pour un i qui va jusqu'à 2000, un Integer n'est pas trop "court" ? Ne faut-il pas un Long ?
Marsh Posté le 16-05-2013 à 11:05:38
Jusqu'à 2000 un Integer convient tout à fait vu qu'il va jusqu'à 32767 !
Mais vu le nombre de lignes contenues dans une feuille, mieux vaut effectivement déclarer la variable en Long
ou ne rien déclarer du tout car pas de souci avec des entiers …
Marsh Posté le 16-05-2013 à 11:06:40
Marc L a écrit : |
Ah oui, il reste un peu de marge
Merci de l'info
Marsh Posté le 16-05-2013 à 16:16:32
Merci pour toutes vos réponse j'ai rectifié.
Cela ne fonctionne toujours pas
Marsh Posté le 16-05-2013 à 18:21:21
Marc L a écrit : |
Oui, un long peut aussi faire l'affaire, mais j'ai l'habitude d'utiliser des integer pour parcourir les tables Excel, ceux ci atteignant rarement 32767 lignes...
Toujours déclarer ses variables comme elles doivent l'être :
C'est pour ça qu'en tête de module je place systématiquement :
Option Explicit |
Tzol a écrit : Fais voir ce que tu as désormais. |
Oui, ça donne quoi maintenant ?
Marsh Posté le 16-05-2013 à 19:41:59
Code :
|
Il bloque sur la ligne 34 : While tabl(i, 1) <> "" And i < 2000
avec "erreur de compilation tableau attendu"
Marsh Posté le 16-05-2013 à 20:41:39
labeo64 a écrit : Il bloque sur la ligne 34 : While tabl(i, 1) <> "" And i < 2000 |
Normal car en comparant avec sa déclaration en ligne n°12, effectivement cela ne peut pas marcher !
Un effort de réflexion, remise à plat, est nécessaire …
Marsh Posté le 16-05-2013 à 20:45:07
J'ai un peu avancé de mon coté avec ce code
Code :
|
ça ne beuggue plus du tout mais il ne me calcule que la première colonne de la feuille 1 soit les résidences
comme ça :
100 507
140 31
150 108
180 14
190 16
200 312
300 166
400 133
500 123
incremente bien dans la feuille 3 mais il ne calcule pas sur la bonne colonne qui est la C (la troisième soit le type)
pour avoir un résultat optimum, il faudrait même qu'il compare la colonne C de la feuille 1 avec la colonne A de la feuille 2 et incrémente de 1 la feuille 3 si cellule de la colonne C de la feuille 1 et cellule de la colonne A de la feuille 2 sont égales.
Je continue donc
Merci pour vos conseils qui me permette de progresser
Marsh Posté le 16-05-2013 à 21:00:59
Marc L a écrit : |
Merci Marc.
Tu as raison des fois j'y suis tellement concentré des heures que je ne vois même plus mon code.
Pour avoir mis un IF en français, fallait le faire quand même, peut être ma blondeur enfantine qui a laissé quelques séquelles
Marsh Posté le 17-05-2013 à 07:55:15
Ben disons que l'éditeur a certainement dû hurler avec les erreurs de syntaxe. C'est étonnant que tu n'aies pas vu ces erreurs...
Ensuite, il y a le débogueur (touches F5 et surtout F8 pour faire du pas à pas) couplé à la fenêtre des variables qui sont bien utiles pour détecter les erreurs de logique.
Tu es sur la bonne voie me semble t-il, ton dernier code est beaucoup mieux que l'avant dernier.
Je n'ai pas saisi toutes les subtilités de ce que tu veux faire, donc je ne peux pas trop te dire pourquoi tu n'as pas le résultat attendu.
Bon courage
Marsh Posté le 17-05-2013 à 10:14:06
Cela me rassure car moi aussi j'ai du mal à visualiser, et ce, depuis le premier message,
car entre le résultat attendu et les feuilles 1 & 2, quid de la logique …
Sans explication précise, je ne cherche même pas …
Exemples :
- incrémente de 1 la feuille 3 : impossible ‼ Une cellule oui, mais laquelle ?
- si cellule de la colonne C de la feuille 1 et cellule de la colonne A de la feuille 2 sont égales :
là quoique plus clair, cela manque de précision sur le n° de ligne ...
Feuil1.C9 doit correspondre uniquement à Feuil2.A9 ? Ou à n'importe quelle cellule de la colonne A de Feuil2 ?
En dehors de l'effort de réflexion, il en faut un aussi quant à la présentation de la problématique devant être claire et exhaustive.
Car sinon, comme je l'ai récemment écrit, ayant prêté ma boule de cristal, je ne fais plus d'effort divinatoire ‼
Marsh Posté le 17-05-2013 à 11:07:34
Bonjour,
J'essaie d'être plus claire avec moi-même. J'ai conscience que le problème bien exposé c'est une partie du programme déjà faite.
Tableau 1 de la feuille 1
Quartier ESI Type Nom Résidence
0100 0100.15.18.1004 T4
0100 0100.12.02.0403 T2/3 RESIDENCE ALIZE 1
0100 0100.12.04.0203 T2/3 RESIDENCE ALIZE 1
0140 0140.01.01.0202 T3
0140 0140.01.01.0203 T4
0140 0140.01.01.0204 T4
0140 0140.01.01.0301 T2
0140 0140.01.01.0302 T3
0150 0150.01.01.0201 T6
0150 0150.01.01.0202 ST
Tableau 2 feuille2
type
I3
D1
D5
I6
T7
T2
D6
CHAM
I4
T6
I5
GG
D3
T2/3
I2
T4
T1
T1BIS
D4
1B
T3
T5
ST
Résultat attendu en feuille 3
Num Res Nom Res F1 F2 F2/3 F3 F4 etc
0100 Res X nombre nombre nombre etc etc
En fait, le programme doit balayer le premier tableau (entier) de la feuille1 (ce qu’il fait)
S’il trouve une valeur dans la 3ème colonne qui correspond au une valeur du tableau de la feuille 2 colonne 1 qui correspond par exemple a F1 etc
Alors il doit incrémenter de 1 la valeur F1 par rapport au nom de la résidence du tableau en feuille 1
Le but final étant de savoir combien nous avons de F1, F2, etc.. dans une résidence.
Je persevère pour obtenir dans un premier temps le nombre de F1, F2 etc en vertical.
Marsh Posté le 17-05-2013 à 12:17:13
Et là dans l'exemple de la feuille 2 il n'y a aucun F1 ...
S'il s'agit juste de totaliser un titre d'une colonne de la feuille 3 présent dans la première colonne de la feuille 2,
pas besoin de macro pour cela car une simple formule directement dans une cellule suffit !
Pour le choix de la formule, tout dépend de ta version d'Excel … ► 2010 : NB.SI.ENS
Par contre cela reste flou car je ne vois pas de lien entre la feuille 2 et le n° de résidence de la feuille 1 car,
tel que présenté, le total dans la feuille 3 à partir de la colonne 3 (F1, F2) sera le même pour chacune des lignes ‼
Tu peux utiliser l'icône Fixed pour bien présenter tes colonnes.
Marsh Posté le 17-05-2013 à 12:36:00
Merci pour ta réponse.
point 1 : autant pour moi c'est T1, T2 etc qui représente les types de logement...
point 2 oui c'est cela mais comme il faut le faire par rapport au n° et a la résidence alors on doit filtrer sur le tableau 1
point 3 : la feuille 1 représente une extraction sql de notre base oracle des logements, le numéro représente un lot (ça peut s’apparenter a un quartier), la feuille 2 est une autre extraction mais avec restriction sur ma requete, j'ai ramené que les logements qui correspondent a des habitations en excluant garage, cave etc... (qui sont présent dans le tableau 1 dans la colonne type.
A la fin, je veut le nombre de type de logement de type 1.2.3.2/3.4.5 etc par résidence.
Le numéro et le nom de la résidence doivent aussi s'afficher dans le tableau.
J'espère que cette fois je me suis faite comprendre.
Marsh Posté le 17-05-2013 à 12:45:58
labeo64 a écrit : je veux le nombre de type de logement de type 1.2.3.2/3.4.5 etc par résidence. |
Marc L a écrit : je ne vois pas de lien entre la feuille 2 et le n° de résidence de la feuille 1 |
S'il n'y a pas de n° de résidence dans la feuille 2, comment différencier les types pour le total en feuille 3 alors ?‼
Marsh Posté le 17-05-2013 à 14:50:58
Note logiciel est un peu spécial.
Chaque lot est representé par le numéro ESI
Les 4 premiers caractères représentent la résidence suivie d’un point (100. = ousse des bois) c'est la premiere colonne de ma feuille 1.
Les deux caractères suivant représentent le N° de bâtiment suivi d’un point. (100.03 = résidence du parc)
Les deux caractères suivant représentent le N° de rue suivi d’un point.
Les quatre caractères suivant représentent le N° de logement qui se décomposent en deux parties, étage + N° dans l’étage.
Comme je le disais avant je peux le faire apparaitre puisque les tableaux sont issus de mes requetes SQL
Pour le point, je comptais faire la comparaison sur les types qui eux sont communs a la feuille 1 et 2.
Ce code VBA est pour mon boulot.
C'est un peu nouveau alors je me mélange un peu les pinceaux.
Mon supérieur ne veut pas une formule (trop facile) mais bien du code VBA.
Ce n'est pas une mauvaise chose car cela me fait progresser.
Marsh Posté le 17-05-2013 à 15:04:22
Oui mais peu importe le langage de programmation, c'est avant tout un souci de pure logique …
N'obtenant toujours pas de réponse quant au problème soulevé concernant la deuxième feuille,
passant peut-être à côté de quelque chose (parfois on peut être enfermé dans ses propres arcanes internes …),
j'attends de voir les déductions d'autres intervenants compétents comme par exemple otobox …
Marsh Posté le 17-05-2013 à 15:09:23
Précision : même une fois l'horizon dégagé, ma solution ne consistera pas à faire bêtement une usine à gaz en VBA,
tout du moins à vouloir réinventer la roue au risque qu'elle fusse carrée,
j'utiliserai quand même en VBA les fonctions de calcul internes aux feuilles d'Excel
car elles sont beaucoup plus puissantes qu'une quelconque procédure VBA ‼
Marsh Posté le 17-05-2013 à 17:21:52
Bonsoir,
je suis le fil depuis son début, je crois comprendre que la feuille 2 contient la liste des différents types rencontrés dans l'ensemble des résidences.
Labeo64 voudrait, semble-t-il, voir cette liste recopiée sur la feuille 3, en ligne 1, à partir de la colonne 3 et classée (?) par ordre alphabétique croissant. Puis, elle voudrait, par résidence, la somme de chacun des types qu'on y trouve (0,n).
Reste aussi à lever l'ambigüité "quartier" "résidence"
Cordialement
Marsh Posté le 17-05-2013 à 19:33:51
Si le Senior arrive, on va pouvoir s'en sortir
J'ai toujours un peu de mal à comprendre, mais si c'est ce que dit seniorpapou est correct, labeo64 devrait pouvoir passer par un tableau dynamique croisé, sans avoir à coder du vba.
Edit : OK, je viens de voir que le vba est imposé
Marsh Posté le 17-05-2013 à 19:54:18
Merci Séniorpapou pour l'expression vraisemblablement plus distincte de ma problématique.
Comme je l'expliquais avant, otobox, ceci est un test de mon collègue pour tester mes connaissances en programmation (que j'eu mais j'ai bien peur de n'avoir pratiquer depuis très très longtemps).
Je ne sais donc encore pas si cela va être bloquant pour mon futur emploi, d'ou l'importance et l'implication que j'y mets.
Je ne désespère pas de trouver la solution et votre aide m'est très précieuse.
Marsh Posté le 17-05-2013 à 21:39:25
Bonsoir otobox, je faisais juste un court passage, parce que labeo64 m'a remis en mémoire les demandes d'un utilisateur qui savait très bien ce qu'il voulait, mais qu'il fallait presser comme un citron pour obtenir l'expression exacte de sa pensée. Bonne chance à labeo64.
Cordialement
Marsh Posté le 18-05-2013 à 08:13:23
Ce qui se conçoit bien s'énonce clairement - Et les mots pour le dire arrivent aisément (Boileau) Ça fonctionne aussi pour la programmation, comme quoi ce poète du XVIIe siècle était en avance sur son temps
Alors je reprends: l'idée est de récapituler le nombre de type de logements par résidence, chaque ligne du tableau étant une résidence. Avec en plus, l'idée de ne pas répertorier tous les types logements, mais seulement ceux qui sont identifiés dans la feuille 2. C'est ça ?
Si c'est ça, comment ça se passe quand il n'y a pas de nom de résidence ? Car dans le tableau que tu donnes :
|
Il n'y a pas de nom de résidence à chaque ligne... Alors, faut-il récapituler par n° de quartier ? Ou alors extraire le code de la résidence dans le n° ESI ? En gros, quelle est la clé unique (dans le sens BDD) définissant la résidence ?
Edit : après relecture de tes précédents messages, je vois que ce qui défini une résidence sont les 2 premières séries de chiffres du n°ESI, soit :
|
Il faudrait donc compter le nombre de type de logement en recherchant sur cette partie du numéro... OK ?
C'est important pour la suite, car pour des raisons pratiques de programmation, ainsi que pour la rapidité d'exécution de la procédure, il faut commencer -à mon avis- par trier le tableau d'entrée par numéros uniques de résidences, histoire d'éviter de parcourir plusieurs fois la liste.
Edit2 : je vois dans ce que tu as écrit avant que en fait, tu regroupes par n° de quartier...
labeo64 a écrit :
|
Marsh Posté le 18-05-2013 à 21:05:46
Merci seniorpapou et merci a otobox
le numéro important est celui de la feuille 1 dans la première colonne et peut importe s'il est associé a un nom ou pas.
Je travaille a faire une comparaison de ma colonne c en feuille 1 et ma colonne A en feuille 2
Mais cela n'est peut être la marche a suivre
Peut importe en tout les cas ce sera instructif.
Marsh Posté le 18-05-2013 à 22:10:03
OK, c'est donc un regroupement sur la première colonne.
J'ai une solution "clé en main" qui fonctionne. Je te la donne ou je te laisse chercher ?
Marsh Posté le 18-05-2013 à 22:45:32
otobox a écrit : OK, c'est donc un regroupement sur la première colonne. |
Merci pour ta proposition,
Même si tu me la donnes, je chercherais quand même, je suis du style acharnée.
Marsh Posté le 19-05-2013 à 08:54:56
Dans la solution que je te propose, je ne passe pas par des tableaux vba (ça bouffe de la mémoire), mais je travaille directement sur les cellules.
Je commence par préparer les données pour les traiter ensuite :
Déclaration des différentes feuilles Excel en tant qu'objet.
Création d'une nouvelle feuille où seront écrits les résulats. Si la feuille de résultat existe, elle est supprimée avant de la refaire.
Création d'un objet type "Dictionnary" pour faciliter l'incrémentation du nombre d'appartement dans la bonne colonne :
Dans ta solution, d'après ce que j'ai compris tu voulais faire ceci :
|
Dans la solution que je te propose, j'utilise un Dictionnary pour associer un type d'appartement à un n° de colonne. Ainsi, pas besoin de faire une boucle à chaque fois pour trouver dans quelle colonne on doit incrémenter le nombre d'appartement.
Exemple :
'J'apprends au dictionnaire le n° de la colonne pour différente type d'appartement : |
Plus simple, non ?
Je fais aussi un tri dans le tableau principal pour être sûr que les résidences soient regroupées. Ainsi, quand je parcours le tableau principal ça fait ceci :
- lecture du nom de la résidence dans le tableau principal |
Si les résidences n'étaient pas triées au préalable, je risquerais d'avoir des doublons dans les résultats en utilisant cette méthode.
J'ai organisé le programme entre une procédure principale "labeo64" qui appelle différentes fonctions et sous-routines. Ainsi, tu pourras voir plus facilement les différentes étapes, entre la préparation des données, leur traitement et leur mise en forme finale.
/!\TIP : Pour copier le code sans les n° de lignes, fais d'abord un double clic dans le cadre blanc pour les effacer
Code :
|
Bon courage
Marsh Posté le 21-05-2013 à 12:08:31
otobox a écrit : je ne passe pas par des tableaux vba (ça bouffe de la mémoire), mais je travaille directement sur les cellules. |
Et pourtant travailler sur une variable tableau est tellement plus rapide que de parcourir les cellules …
Sinon tu t'es bien amusé pour ton code !
De mon côté, dans l'hypothèse d'une structure logique de la feuille n°2 vu la demande,
je n'envisageais pas plus d'une douzaine de ligne de code afin d'alimenter la feuille n°3 …
Marsh Posté le 21-05-2013 à 19:19:42
La procédure servant à trier les données fait moins de 50 lignes, avec la déclaration des variables et les commentaires.
Quelle est ta solution ?
Marsh Posté le 22-05-2013 à 00:33:01
En fait je n'ai rien écrit vu que j'attendais une réponse, mais dans une certaine logique de clef commune entre les feuilles 1 & 2,
j'envisageais (c'est un peu comme j'imaginais, non ?) une procédure assez simple pour alimenter la feuille 3,
en somme une ébauche virtuelle cérébrale, donc rien de concret vu le manque de données objectives …
En fait c'était juste pour te dire que tu t'étais bien défoncé !
Pour un sujet récent sur un autre forum (et posté ici aussi) concernant un exercice cette fois bien présenté par une étudiante,
suite aux palabres d'intervenants quant à ce qu'ils devaient mettre en œuvre,
j'ai annoncé qu'il ne fallait pas plus d'une cinquantaine de lignes de code pour réaliser le programme.
Puis leurs solutions de 100 lignes et plus ont été postées dont une à plus de 200 et une autre à quasiment 300 lignes !
J'ai aussi réalisé puis publié mon code résolvant l'énoncé et tenant bien en une cinquantaine de lignes …
Comme quoi à un problème peuvent correspondre diverses solutions, selon des critères propres à chacun !
Marsh Posté le 22-05-2013 à 16:58:13
Bonjour,
Veuillez m'excuser pour le silence mais j'ai beaucoup travaillé et pas qu'en VBA.
Mais voici le résultat attendu par mon collègue (qu'on a composé tout les deux du coup!)
Code :
|
et Voici a quoi ressemble le résultat :
Res Nom 1B CHAM D1 D3 D4 D5 D6 GG I2 I3 I4 I5 I6 ST T1 T1BIS T2 T2/3
100 CHAM 29
140 5
150 10
180
190 RES. LE PARC DES SAULES
200 24
300 148 17
400 BAT B 92 26 6
500 34
ça c'est un peu décalé mais cela vous donne une idée.
Je suis en train de répondre a une autre demande du même genre...
Merci a tous, vos remarques sont très constructives et nous permette de progresser.
Marsh Posté le 22-05-2013 à 19:04:16
Autres remarques constructives quant au dernier code :
Exemple des lignes n°16 & 17 pouvant s'écrire en une seule : tabl = Sheets("Feuil1" ).Range("A2:D5000" )
La variable tableau déclarée en ligne n°14 est donc de type Variant (par défaut sans précision du type)
et donc chaque indice ne contient rien par défaut et en VBA rien veut aussi dire zéro ...
Dans le cas où cette variable ne doit contenir que des nombres, mieux vaut alors la déclarer avec le type adéquat (Long, Double, …)
et dès lors suite à cette déclaration la valeur par défaut est déjà à zéro …
Autant réécrire directement les lignes n°58 à 60 en une seule : Range("C3" ).Value = tbtyp(1, 1)
En résumé, travailler directement sur les objets est bien plus efficace !
Sinon je n'ai pas décrypté la logique de la procédure pour voir si elle peut être améliorée
(à l'origine j'envisageais une seule boucle combinée à la véloce méthode Find) …
Marsh Posté le 15-05-2013 à 21:07:20
Je travaille actuellement dans une boite ou la majeure partie de mon travail est la conception de requête SQL couplée avec Excel.
Aujourd'hui, je bloque sur le code VBA, les deux fichiers dont je me sers sont des extractions d'une base Oracle en Sql, je recherche sur les deux feuilles suivantes issues du même classeur : Feuille 1
Résidence ESI Type nom résidence
0100 0100.03.01.0402 T5 RESIDENCE DU PARC
0100 0100.03.03.0001 T2 RESIDENCE DU PARC
0100 0100.03.03.0002 T2 RESIDENCE DU PARC
0100 0100.03.03.0003 T5 RESIDENCE DU PARC
0100 0100.03.03.0101 T5 RESIDENCE DU PARC
0100 0100.03.03.0102 T6 RESIDENCE DU PARC
Feuille 2
TYPE
T2
T4
T1
T6
T3
T4
T1
T1BIS
Le résultat devrait donner a peut près ça :
Résidence nom résidence T1 T2 T3 T4
0300 1
0400 BAT B 7
0100 RESIDENCE DU PARC 10
0400 BAT B 1
0100 RESIDENCE DU PARC 2
0400 BAT B 1
200 4
0100 RESIDENCE DU PARC 2
0300 1
Voici mon code (qui beugge a toute les lignes), la boucle doit incrémenter de 1 mes cellules TYPE de la feuille 3.
Merci par avance.
Message édité par labeo64 le 15-05-2013 à 21:27:54