Utilisation des tableau

Bonjour tout le monde ;

Je viens juste de débarquer, sur le forum, et j'espère apprendre beaucoup ici avec vous.

Mon problème est le suivant : je travaille sur une BD, et j'aimerais utiliser un tableau en VBA pour la traiter. A vrai dire, j'ai été très seduit par la rapidité des calcul avec un tableau. J'ai suivi l’exemple du cours VBA, mais le rendu de ma macro n'est pas celui escompté.

Bref, je souhaite que ma macro calcul pour chaque banque le nombre de pieces saisies pour chaque mois (sur la colonne Mois).

Si vous activer la macro, vous trouverez ma pioche

J'attends vos astuces avec impatience.

Merci

19bqs.xlsm (167.69 Ko)

Bonjour

Pourquoi VBA alors que cela est faisable en TCD en quelques clics ?

C'est vrais, mais cette macro ne sera qu'un avant goût pour la suite, parce qu'il y a d'autres BDs à rajouter pour d'autres traitements.

Bonjour sofo, Bonjour 78chris

Voici un essai en VBA :

10bqs.xlsm (176.96 Ko)

Bonjour tout le monde,

ma petite contribution également

17bqs.xlsm (182.69 Ko)

Bonjour bigdaddy154,

Très belle ligne de prog, vivement que j'arrives à un niveau comme le tien , un jour j’espère .

En regardant ton code je vois que je me complique la vie

Bonjour, Salut à tous !

Sub ACTUALISER()
    Dim tabb, tBQ(1 To 16, 1 To 12), m%, Bq%, i&
    tabb = Worksheets("BD").Range("A1").CurrentRegion.Offset(, 3).Resize(, 2).Value
    For i = 2 To UBound(tabb)
        Bq = Val(Replace(tabb(i, 1), "BQ", "")): m = tabb(i, 2)
        tBQ(Bq, m) = tBQ(Bq, m) + 1
    Next i
    Worksheets("CALCUL").Range("B2").Resize(16, 12).Value = tBQ
End Sub

Un code pour remplacer le tien. Les différences (je laisse les erreurs de côté) :

  • sur la forme, le code est correctement indenté, et les variables sont toutes déclarées et en début de procédure (tu devrais essayer, cela fait partie des choses qui permettent de travailler plus vite avec le code... )
  • sur le fond, il opère effectivement avec des tableaux ! de façon économique : tableau de récupération de la partie utile de la BD, parcours de ce tableau pour servir un tableau de résultats, affectation du tableau résultats.

Cordialement.

Bonjour Forian53 et merci pour votre réponse.

ça marche très bien, sauf que je cherche le nombre total de la colonne PIECE par JOURNAL et non pas leurs sommes.

Et puis, serait-il possible de m'expliquer ses deux lignes. Votre code est très simple et lisible, sauf que là je débute en VBA

If table(i, 4) = "BQ" & j And Month(table(i, 7)) = mois Then tableau(j, mois) = tableau(j, mois) + table(i, 3)
 Sheets("Result").Range("$B$2").Resize(UBound(tableau, 1), UBound(tableau, 2)) = tableau

Mon code parait simple car je suis aussi débutant en VBA, mais il est certainement beaucoup moins performant que ceux que propose Mferrand ou Bigdaddy154

Pour ne compter que les pièces, il suffit de remplacer "table(i, 3)" par "1"

If table(i, 4) = "BQ" & j And Month(table(i, 7)) = mois Then tableau(j, mois) = tableau(j, mois) + 1
 Sheets("Result").Range("$B$2").Resize(UBound(tableau, 1), UBound(tableau, 2)) = tableau

La 1er ligne va compter le nombre d'occurence qui correspond au différent BQ par rapport au mois, il y a en tout 3 boucles :

- (i) défile les lignes de la BDD

- (m) les différents "BQ"

-(j) les mois de l'année

Bonjour MFerrand

Trop fort mon frère, le tout en à peine quelques lignes.

Faudrait que vous m'appreniez.

Bonsoir,

Faudrait que vous m'appreniez.

On va essayer de cerner la démarche pas à pas...

De façon générale, plus on travaille hors Excel et plus l'éxécution du code sera rapide. Donc le principe à essayer de suivre lorsque l'on doit traiter des données et produire le résultat de ce traitement consiste à prélever les données concernées sur la feuille Excel où elles se trouvent, travailler ces données pour parvenir le plus près possible du résultat final cherché, et affecter ce résultat à la feuille cible destinée à les accueillir.

Et en effet, c'est en travaillant avec des tableaux VBA que l'on peut suivre un tel déroulement (chaque fois que c'est possible, bien sûr). 1er tableau (source) : les données à traiter, constitué par les colonnes D et E de la base de données.

Le système le plus simple pour récupérer des données source sous forme de tableau consiste à cerner la plage contenant les données que l'on veut récupérer et à affecter cette plage (c'est à dire ses valeurs) à une variable de type Variant. Le résultat est toujours un tableau à 2 dimensions de base 1. On parcourra donc les lignes de ce tableau à partir de 1 ou 2 (si ligne d'en-tête), quel qu'ait été l'emplacement initial des données...

Si on le peut, la définition de la plage à prélever en utilisant la propriété CurrentRegion de l'objet Range se révèlera à la fois rapide et n'exigeant qu'un code réduit. Sinon on utilisera d'autres moyens de dimensionnement (End(xlUp), etc.)

    tabb = Worksheets("BD").Range("A1").CurrentRegion.Offset(, 3).Resize(, 2).Value

On cible la région courante à partir de A1, qui va renvoyer une plage A1:M2494, plage que l'on décale de 3 colonnes et que l'on redimensionne à 2 colonnes. Soit D1:E2494 la plage affectée à tabb.

On pourrait se contenter de l'affectation de la plage par CurrentRegion, sans redimensionnement, en travaillant ensuite sur les colonnes 4 et 5 du tableau, mais on a intérêt à réduire autant qu'on le peut le tableau aux données utiles, plus réduit il sera parcouru plus rapidement...

On a besoin d'un tableau résultat pour recueillir le résultat du traitement : si son dimensionnement est variable, on déclarera un tableau dynamique, qu'on redimensionnera ensuite, éventuellement au fur et à mesure que des données à recueillir apparaîtront. Si sa taille est prédéfinissable on pourra le dimensionner à la déclaration, et également le typer.

Le tableaux résultat est prédéfini de façon fixe à 16 lignes (nb de banques) et 12 colonnes (mois). Le nombre de mois n'a pas de raison de varier, mais le nombre de banques pourrait. Il y a divers moyens d'opérer avec des éléments variables selon la configuration. Mais tant que ce tableau est fixe, on peut définir ses dimensions au départ, 1 à 16 et 1 à 12, pour assurer la concordance des indices avec les coordonnées qui seront recueillies.

Noter que le tableau a été dimensionné lors de la déclaration, mais non typé. Or, il aurait pu être typé en Integer. Ne l'étant pas, ses éléments sont de type Variant. Quelle différence cela introduit-il ?

La valeur par défaut d'une variable de type Variant est Empty (vide), alors que la valeur par défaut d'une variable Integer sera 0. Ainsi les banques-mois dépourvues de données, dans lesquelles aucun résultat n'a été consigné, afficheront 0 si le tableau est typé en Integer (ou autre type numérique) mais n'afficheront rien s'il est non typé.

Dans un tableau de ce type, je trouve plus lisible de ne pas afficher les 0, mais si l'on souhaite le faire, on voit qu'il suffit tout simplement de typer le tableau de résultat en Integer ou Long...

La suite demain... !

MFerrand, vite, des sels ! tu as écrit « plus on travaille hors d'Excel » et jmd vient d's'évanouir !

ça va aller, jmd, les secours sont là : (j'espère qu'il va pas nous faire une AVC = Allergie à VBA Caractérisée)

dhany

Bonjour MFerrand

Très bonne explication, et vivement pour la suite.

Je l'attend avec impatience.

Merci pour cette belle initiative

Bonjour à tous !

La suite - Nous allons travailler sur un tableau dont chaque ligne nous fournit 2 informations : la banque et le mois. 2 informations à traduire en coordonnées dans le tableau résultat : pour chaque ligne du tableau source prélevé, on établira des coordonnées d'emplacement dans le tableau résultat, afin d'incrémenter la valeur existant à cet emplacement (+1).

Le mois indique directement la colonne du tableau-résultat, on l'obtient donc directement par la valeur de la 2e colonne du tableau source.

Pour la banque, elle est désignée par la mention "BQ" suivie d'un numéro d'ordre, lequel numéro d'ordre nous fournira la ligne du tableau résultat. On l'extrait donc de la valeur de la 1re colonne du tableau-source.

Mais les banques pourraient être désignées autrement... auquel cas il conviendrait d'avoir un autre repère. Supposons qu'elles soient listées dans la première colonne du tableau résultat sur feuille : on récupèrera cette liste en tableau VBA de façon à s'en servir pour déterminer le rang de chaque banque (donc la ligne dans le tableau-résultat) du tableau source.

Si elles ne sont pas listées, il conviendra de le faire par extraction d'une liste unique de banque dans la base de données.

Ce qu'il faut bien voir, c'est qu'on est dans une configuration où les résultats se consignent dans un tableau pré-défini, ils consistent en un recensement d'évènements (ou d'autres éléments) selon 2 conditions (qui ? et quand ?). Donc on tire du tableau source les coordonnées du tableau résultat, emplacement que l'on va servir par incrémentation (ou ajout d'une valeur extraite de la source).

On se ramène donc toujours à : parcours du tableau source (de 2 ici à UBound(tabb)), à chaque ligne détermination des coordonnées de l'emplacement du tableau résultat sur lequel intervenir, intervention.

Un autre cas de figure fréquent est le listage d'éléments de la source répondant à des conditions : dans ce cas le tableau résultat n'est pas prédéfini, on parcourt toujours la source et sur chaque ligne on teste les conditions, si elles sont réunies on incrémente notre tableau-résultat (dont le nombre de colonne sera généralement fixe, ce qui conduit à inverser lignes et colonnes, et rétablir l'ordre par une transposition à la fin).

Une fois le traitement achevé, on affecte le résultat.

Le principe : on dimensionne la plage-cible à la taille du tableau et on fait Plage.Value = Tablo.

Dans le cas d'un tableau résultat où l'on a été conduit à inverser lignes et colonnes : Plage.Value = WorksheetFunction.Transpose(Tablo).

On ne peut pas considérer avoir fait le tour de la question, on sera amené à rencontrer de nombreux autres cas, mais essayons de nous en tenir à quelques points essentiels en matière de travail avec des tableau VBA :

  • on a toujours intérêt à extraire en tableau VBA des données sources sur lesquelle on doit travailler, et c'est l'affectation des données d'une plage-source à une variable de type Variant qui donnera le résultat le plus aisément utilisable
  • on a également intérêt, dès lors qu'on le peut à constituer le résultat du traitement en tableau VBA, que l'on pourra globalement affecter à la fin ; le plus souvent, on déclarera un tableau dynamique que l'on dimensionnera par la suite (soit en une fois si on est en mesure de le faire, soit au fur et à mesure), mais il n'est pas exclu que l'on puisse connaître et prédimensionner un tel tableau ; de même si l'utilisation d'un Variant pour produire un tableau de résultat n'est pas le cas général il peut se produire dans le cas où le résultat consiste à compléter un tableau préexistant (on prélève, on complète et réaffecte) ; une plus grande variété donc, liée à la diversité des résultats que l'on cherchera à obtenir.

Cordialement.

Salutations MFerrand

J'ai lu la suite, mais j'avoue que j'ai du mal à tout intégrer. Ce qui est sûr c'est je tout relire a tête reposée et on verra.

Sinon, un petit conseil sûr comment je pourrais progresser?

Cordialement

A partir d'une base acquise avec des Cours, c'est la pratique qui fait progresser.

Et il est utile de revenir sur les chapitres de cours qui concernent telle ou telle partie du projet que l'on a en cours, (ou les approfondir au moyens de tutos spécialisés), il y a toujours des éléments à apprendre.

Bonne continuation.

J'y tâcherai MFerrand

Merci

Bonjour MFerrand, c'est encore moi

Si cette ligne Bq = Val(Replace(tabb(i, 1), "BQ", "")): m = tabb(i, 2) désigne bien une plage comme je le suppose (présence de :), comment vous aviez pu l'affecter (cette plage) en paramètre au tableau tBQ comme suit:

tBQ(Bq, m) = tBQ(Bq, m) + 1 ?

Ah !!! Erreur d'interprétation de ta part.

Le signe deux-points intervient dans la définition habituelle d'une adresse de plage de cellule.

Ainsi : A1:B3 va permettre de préciser l 'adresse d'une plage dans la feuille ou elle se trouve.

Mais lorsqu'elle est utilisée en VBA, cette adresse est une donnée de type String, tu écriras ....Range("A1:B3") (et Range(A1:B3) provoquerait une erreur...)

Tu peux éviter les guillemets, en écrivant ActiveSheet.[A1:B3], soit en mettant l'adresse entre crochets, ce qui se nomme notation compacte, et correspond selon les explications de Microsoft à un appel de la méthode Evaluate qui va résoudre la signification de l'expression mise entre crochets.

Mais tu noteras que l'on ne se trouve pas dans un tel contexte, et le signe deux-point peut avoir d'autres utilisations.

Tu as certainement déjà rencontré des lignes se terminant par un caractère underscore (trait de soulignement).

Par exemple :

    tabb = Worksheets("BD").Range("A1").CurrentRegion _
     .Offset(, 3).Resize(, 2).Value

Ici, tu as écrit 2 lignes, mais le caractère underscore ( _ ) précédé d'une espace indique une continuité de ligne de code, donc qu'à la ligne suivante c'est la même ligne de code qui se poursuit. On a donc 2 lignes physiques mais une seule ligne de code.

Inversement, on peut écrire plusieurs lignes de code sur la même ligne physique, mais dans ce cas il faut un indicateur qui permette de les distinguer, et c'est justement le caractère deux-points ( : ) qui constitue le séparateur de lignes de code lorsqu'elles sont écrites sur une même ligne physique.

La ligne que tu cites peut donc s'écrire :

    Bq = Val(Replace(tabb(i, 1), "BQ", ""))
    m = tabb(i, 2)

Bq et m sont des variables Integer et ces deux lignes constituent leur initialisation par extraction du tableau-source. m (le mois) est directement une valeur dans le tableau-source et fournit la colonne du tableau-résultat ; Bq (numéro d'ordre de la banque) est extrait de la valeur correspondant dans le tableau-source qui y figure sous la forme "BQ" suivi de ce numéro d'ordre, on l'extrait en remplaçant "BQ" par rien dans l'expression et en convertissant l'expression modifiée avec la fonction Val.

NB- On pouvait convertir aussi bien avec CInt par exemple, mais Val présente ici quelques avantages : Val transforme en nombre toute chaîne de texte en prenant en compte les caractères numériques rencontrés, jusqu'à ce qu'il rencontre un caractère non numérique, ainsi Val("a13b") renverra 0, Val ("13b") renverra 13, alors que CInt renverrait une erreur dans les deux cas. Donc si par exemple se terminait par un autre caractère, une espace éventuellement, cela n'empêcherait pas Val de renvoyer le numéro.

[Val peut également renvoyer un nombre décimal, mais il ne reconnaît que le point comme séparateur décimal.]

Bq et m indiquant la ligne et la colonne du tableau résultat, leur utilisation tBQ(Bq, m) comme indices est directe car la déclaration de tBQ a fait en sorte d'aligner les indices du tableau VBA sur la plage cible des résultats (en adressage relatif dans la plage...)

Cordialement.

Merci MFerrand

C'est bien plus clair pour moi ainsi.

Sinon, y aurait moyen de lire dans un classeur, à la fois, partagé et fermé?

Cordialement

Rechercher des sujets similaires à "utilisation tableau"