Utiliser un tableau
Résolu
conrade82
Messages postés
96
Date d'inscription
Statut
Membre
Dernière intervention
-
conrade82 Messages postés 96 Date d'inscription Statut Membre Dernière intervention -
conrade82 Messages postés 96 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
J'ai envie d'utiliser le système des tableaux. On en parle tant sur le web comme permettant d'optimiser une macro Excel que j'ai envie d'essayer. Mais je n'y comprends rien. Alors je vous présente mon souci et j'aimerai savoir si les tableaux peuvent m'être utiles.
Un des onglets de mon fichier contient 10 colonnes:
- des immatriculations en colonne A
- un model ID en colonne B
- un code alpha numérique en colonne C
- un nombre entre 1 et 12 en colonne D
- les colonnes E à J doivent être renseignées par la macro.
Un exemple:
en colonne E, j'ai une formule recherchev qui recherche les données de la colonne B dans un autre onglet et affiche un model de véhicule. Le nombre d'immatriculation est variable et peut atteindre 2000 lignes. Ainsi, afin de renseigner les colonnes E à J de mon fichier, je procède au code suivant:
A la lecture de ce code, pensez-vous que je peux me servir de tableaux pour effectuer ces calculs? Ce qu'il faut savoir c'est que je travaille sur un fichier qui pèse 110Mo, c'est une vrai fournaise. Alors je cherche les optimisations maximales pour alléger ce fichier.
Une idée pour limiter les calculs était pour moi d'utiliser les worsheetfunction.vlookup mais si je fais ça, il me faudra utiliser une boucle et je pense que ça va ralentir le temps d'exécution de la macro et vu le volume du fichier, ça va tourner plus lentement...
Si vous pensez que je peux me servir d'un tableau, merci de bien vouloir m'expliquer. Si vous voulez me diriger vers un tuto, il faudrait que ce soit plus que clair car des nombreux tuto que j'ai lu depuis quelques jours, aucun ne m'explique comment fonctionnent les tableaux ou alors je n'y ais rien compris.
Merci d'avance de votre aide.
Cordialement,
Conrade82
J'ai envie d'utiliser le système des tableaux. On en parle tant sur le web comme permettant d'optimiser une macro Excel que j'ai envie d'essayer. Mais je n'y comprends rien. Alors je vous présente mon souci et j'aimerai savoir si les tableaux peuvent m'être utiles.
Un des onglets de mon fichier contient 10 colonnes:
- des immatriculations en colonne A
- un model ID en colonne B
- un code alpha numérique en colonne C
- un nombre entre 1 et 12 en colonne D
- les colonnes E à J doivent être renseignées par la macro.
Un exemple:
en colonne E, j'ai une formule recherchev qui recherche les données de la colonne B dans un autre onglet et affiche un model de véhicule. Le nombre d'immatriculation est variable et peut atteindre 2000 lignes. Ainsi, afin de renseigner les colonnes E à J de mon fichier, je procède au code suivant:
Sub Macro1()
Dim i As Integer, Lastli As Integer
Lastli = Range("A2").End(xlDown).Row
Cells(2, 5) = "=VLOOKUP(RC2,categories!C13:C14,2,FALSE)"
Cells(2, 6) = "=VLOOKUP(RC[-1],categories!C1:C2,2,FALSE)"
Cells(2, 7) = "=VLOOKUP(RC[-2],categories!C1:C4,3,FALSE)"
Cells(2, 8) = "=VLOOKUP(RC[-3],categories!C1:C4,4,FALSE)"
Cells(2, 9) = "=VLOOKUP(RC3,Stations!C1:C26,2,FALSE)"
Cells(2, 10) = "=VLOOKUP(RC3,Stations!C1:C26,3,FALSE)"
Range(Cells(2, 5), Cells(2, 10)).Copy
With Range(Cells(2, 5), Cells(Lastli, 10))
.PasteSpecial
.Calculate
Application.CutCopyMode = False
.Copy
.PasteSpecial xlPasteValues
Application.CutCopyMode = False
End With
End Sub
A la lecture de ce code, pensez-vous que je peux me servir de tableaux pour effectuer ces calculs? Ce qu'il faut savoir c'est que je travaille sur un fichier qui pèse 110Mo, c'est une vrai fournaise. Alors je cherche les optimisations maximales pour alléger ce fichier.
Une idée pour limiter les calculs était pour moi d'utiliser les worsheetfunction.vlookup mais si je fais ça, il me faudra utiliser une boucle et je pense que ça va ralentir le temps d'exécution de la macro et vu le volume du fichier, ça va tourner plus lentement...
Si vous pensez que je peux me servir d'un tableau, merci de bien vouloir m'expliquer. Si vous voulez me diriger vers un tuto, il faudrait que ce soit plus que clair car des nombreux tuto que j'ai lu depuis quelques jours, aucun ne m'explique comment fonctionnent les tableaux ou alors je n'y ais rien compris.
Merci d'avance de votre aide.
Cordialement,
Conrade82
A voir également:
- Utiliser un tableau
- Tableau word - Guide
- Trier un tableau excel - Guide
- Tableau ascii - Guide
- Utiliser chromecast - Guide
- Imprimer un tableau excel - Guide
6 réponses
Bonjour,
110 Mo pour un fichier Excel...
Bon, commençons par le commencement.
Utilisez vous le bon logiciel pour traiter vos données?
Pour pouvoir répondre à cette question, sans voir votre appli (parce que dans l'état ça risque d'être compliqué...), il faut nous la décrire au maximum.
- qu'elles sont les données stockées dans les feuilles
- nombre de feuilles
- utilité des feuilles
- formules utilisées fréquemment (dans votre exemple vous parlez tout de même de 12 000 formules RECHERCHEV...)
- Comment traitez vous les données ? macro, formule
- Y a t'il des Tableaux Croisés Dynamiques, des images, des Mise en Forme Conditionnelles
- etc...
Enfin donnez nous un maximum d'infos sur votre application.
110 Mo pour un fichier Excel...
Bon, commençons par le commencement.
Utilisez vous le bon logiciel pour traiter vos données?
Pour pouvoir répondre à cette question, sans voir votre appli (parce que dans l'état ça risque d'être compliqué...), il faut nous la décrire au maximum.
- qu'elles sont les données stockées dans les feuilles
- nombre de feuilles
- utilité des feuilles
- formules utilisées fréquemment (dans votre exemple vous parlez tout de même de 12 000 formules RECHERCHEV...)
- Comment traitez vous les données ? macro, formule
- Y a t'il des Tableaux Croisés Dynamiques, des images, des Mise en Forme Conditionnelles
- etc...
Enfin donnez nous un maximum d'infos sur votre application.
Bonjour Franck,
110 Mo pour un fichier Excel...
C'était le volume d'origine. Grâce à une épuration de certains traitement de la macro, j'ai pu diminuer le volume à 87 Mo. ça reste lourd en effet!
Utilisez vous le bon logiciel pour traiter vos données?
J'espère que oui :-)
- qu'elles sont les données stockées dans les feuilles
Voir point suivants
- nombre de feuilles et composition:
22 Feuilles au total
* 8 feuilles de tableaux croisés dynamiques;ces 8 feuilles sont constituées de:
- 8 TCD avec des données externes Access
- 4 TCD dont les données font partie des 14 autres feuilles
Ces feuilles de TCD peuvent contenir jusqu'à trois TCD. Un exemple: j'ai un TCD qui démarre en A3 et finit en BA4311.
* 6 feuilles affichant les résultats demandées en fonction d'une certaine catégorie par recherchev vers les différents TCD. Les formules sont si longues que l'enregistreur macro ne peut pas créer le code.
* 1 feuille regroupant les boutons de macros et des données de liste déroulante
* 7 feuilles alimentant les TCD; sur ces 7 feuilles:
- 2 sont alimentéés manuellement (par copie/colle) avec des lignes variables pouvant aller jusqu'à 20000 pour l'une de des deux feuilles. Il y a du travail à faire avec ces feuilles car certaines colonnes ne sont pas nécessaires aux traitements. Je pourrais donc les supprimer.
- 1 est alimentée par macro à partir d'un autre fichier Excel issue d'une base de données Access (simple copier/coller). A optimiser également...
utilité des feuilles
en partie répondu ci-dessus. Certaines données sont si longues en ligne qu'il n'est pas possible de les regrouper dans une seule feuille. Je travaille sur office 2003. Chaque feuille est utilisée. Mais certaines données dans les feuilles peuvent effet être supprimées, je suis dessus actuellement. Supprimer les colonnes inutiles revient à corriger toutes les formules et tout le code...
formules utilisées fréquemment (dans votre exemple vous parlez tout de même de 12 000 formules RECHERCHEV...)
12000? possible en effet! les 6 feuilles qui affichent mes résultats contiennent 100 lignes chacune (lignes non vides j'entends) et près de 245 colonnes. La recherchev avec getpivotdata (donc recherchev sur un TCD) est la plus fréquemment usitée.
Comment traitez vous les données ? macro, formule
les TCD sont mis à jour par macro. Mes 2 feuilles alimentées manuellement (20000 lignes) doivent générer un résultat par recherchev qui est traité via une macro. Les 6 feuilles affichant mes résultats sont traitées par formule.
etc...
- les 6 feuilles ont des mises en forme conditionnelles, des images (je viens de me rendre compte que l'image utilisée pourrait être remplacé par un commentaire qu'on laisserait affiché en permanence)
- après que la macro ait mis à jour toutes les données, elle ouvre un autre fichier et y copie / colle les 6 feuilles. J'ai voulu utiliser le "déplacer/coller" mais vu les formules, ça prenait encore plus de temps...
pour info: le code ne pèse que 125kb
Posez vos questions si besoin.
Alors qu'en pensez-vous ?
Cordialement,
Conrade82
110 Mo pour un fichier Excel...
C'était le volume d'origine. Grâce à une épuration de certains traitement de la macro, j'ai pu diminuer le volume à 87 Mo. ça reste lourd en effet!
Utilisez vous le bon logiciel pour traiter vos données?
J'espère que oui :-)
- qu'elles sont les données stockées dans les feuilles
Voir point suivants
- nombre de feuilles et composition:
22 Feuilles au total
* 8 feuilles de tableaux croisés dynamiques;ces 8 feuilles sont constituées de:
- 8 TCD avec des données externes Access
- 4 TCD dont les données font partie des 14 autres feuilles
Ces feuilles de TCD peuvent contenir jusqu'à trois TCD. Un exemple: j'ai un TCD qui démarre en A3 et finit en BA4311.
* 6 feuilles affichant les résultats demandées en fonction d'une certaine catégorie par recherchev vers les différents TCD. Les formules sont si longues que l'enregistreur macro ne peut pas créer le code.
* 1 feuille regroupant les boutons de macros et des données de liste déroulante
* 7 feuilles alimentant les TCD; sur ces 7 feuilles:
- 2 sont alimentéés manuellement (par copie/colle) avec des lignes variables pouvant aller jusqu'à 20000 pour l'une de des deux feuilles. Il y a du travail à faire avec ces feuilles car certaines colonnes ne sont pas nécessaires aux traitements. Je pourrais donc les supprimer.
- 1 est alimentée par macro à partir d'un autre fichier Excel issue d'une base de données Access (simple copier/coller). A optimiser également...
utilité des feuilles
en partie répondu ci-dessus. Certaines données sont si longues en ligne qu'il n'est pas possible de les regrouper dans une seule feuille. Je travaille sur office 2003. Chaque feuille est utilisée. Mais certaines données dans les feuilles peuvent effet être supprimées, je suis dessus actuellement. Supprimer les colonnes inutiles revient à corriger toutes les formules et tout le code...
formules utilisées fréquemment (dans votre exemple vous parlez tout de même de 12 000 formules RECHERCHEV...)
12000? possible en effet! les 6 feuilles qui affichent mes résultats contiennent 100 lignes chacune (lignes non vides j'entends) et près de 245 colonnes. La recherchev avec getpivotdata (donc recherchev sur un TCD) est la plus fréquemment usitée.
Comment traitez vous les données ? macro, formule
les TCD sont mis à jour par macro. Mes 2 feuilles alimentées manuellement (20000 lignes) doivent générer un résultat par recherchev qui est traité via une macro. Les 6 feuilles affichant mes résultats sont traitées par formule.
etc...
- les 6 feuilles ont des mises en forme conditionnelles, des images (je viens de me rendre compte que l'image utilisée pourrait être remplacé par un commentaire qu'on laisserait affiché en permanence)
- après que la macro ait mis à jour toutes les données, elle ouvre un autre fichier et y copie / colle les 6 feuilles. J'ai voulu utiliser le "déplacer/coller" mais vu les formules, ça prenait encore plus de temps...
pour info: le code ne pèse que 125kb
Posez vos questions si besoin.
Alors qu'en pensez-vous ?
Cordialement,
Conrade82
Bonjour,
Ce que j'en penses.
8 feuilles de TCD, 6 feuilles remplies de formules (dont certaines longues comme le bras), 1 feuille regroupant les boutons ... ne sont pas nécessairement utiles. Pour moi elles ne servent pas.
Par contre,7 feuilles alimentant les TCD; sur ces 7 feuilles:
- 2 sont alimentées manuellement (par copie/colle) avec des lignes variables pouvant aller jusqu'à 20000 pour l'une de des deux feuilles. Il y a du travail à faire avec ces feuilles car certaines colonnes ne sont pas nécessaires aux traitements. Je pourrais donc les supprimer.
- 1 est alimentée par macro à partir d'un autre fichier Excel issue d'une base de données Access (simple copier/coller). A optimiser également...
Euh... ça ne fait que 3 feuilles...
En fait, dans ton classeur tu as 7 feuilles de données, et les 15 autres feuilles ne servent qu'à traiter ces données. C'est bien cela?
Fait une sauvegarde de ton classeur et ne travaille qu'avec une copie pour les essais que l'on va faire.
Depuis ta copie du classeur, déplace les 7 feuilles de données dans un nouveau classeur, les 7 dans le même bien sur. Enregistre ce nouveau classeur (ne contenant que des données bien sur) et dis nous qu'elle en est la taille.
En fait, ce que je te conseille c'est de traiter les données, uniquement par macro, uniquement lorsque tu en as besoin. Inutile de créer 12 TCD et de les conserver. Tu pourrais, par macro, créer un tableau de résultats à l'instant t.
Pour cela, l'utilisation de variables tableau (le but de ton sujet) va t'aider considérablement.
Par contre, j'espère que ce n'est pas trop urgent, car je ne reviendrais ici que lundi...
A moins qu'un autre ne prenne en charge ton sujet...
A+
Ce que j'en penses.
8 feuilles de TCD, 6 feuilles remplies de formules (dont certaines longues comme le bras), 1 feuille regroupant les boutons ... ne sont pas nécessairement utiles. Pour moi elles ne servent pas.
Par contre,7 feuilles alimentant les TCD; sur ces 7 feuilles:
- 2 sont alimentées manuellement (par copie/colle) avec des lignes variables pouvant aller jusqu'à 20000 pour l'une de des deux feuilles. Il y a du travail à faire avec ces feuilles car certaines colonnes ne sont pas nécessaires aux traitements. Je pourrais donc les supprimer.
- 1 est alimentée par macro à partir d'un autre fichier Excel issue d'une base de données Access (simple copier/coller). A optimiser également...
Euh... ça ne fait que 3 feuilles...
En fait, dans ton classeur tu as 7 feuilles de données, et les 15 autres feuilles ne servent qu'à traiter ces données. C'est bien cela?
Fait une sauvegarde de ton classeur et ne travaille qu'avec une copie pour les essais que l'on va faire.
Depuis ta copie du classeur, déplace les 7 feuilles de données dans un nouveau classeur, les 7 dans le même bien sur. Enregistre ce nouveau classeur (ne contenant que des données bien sur) et dis nous qu'elle en est la taille.
En fait, ce que je te conseille c'est de traiter les données, uniquement par macro, uniquement lorsque tu en as besoin. Inutile de créer 12 TCD et de les conserver. Tu pourrais, par macro, créer un tableau de résultats à l'instant t.
Pour cela, l'utilisation de variables tableau (le but de ton sujet) va t'aider considérablement.
Par contre, j'espère que ce n'est pas trop urgent, car je ne reviendrais ici que lundi...
A moins qu'un autre ne prenne en charge ton sujet...
A+
Euh... ça ne fait que 3 feuilles...
Mea culpa: en fait les 5 autres sont des copier/coller manuels pour le moment.
En fait, dans ton classeur tu as 7 feuilles de données, et les 15 autres feuilles ne servent qu'à traiter ces données. C'est bien cela?
7 Feuilles de données, 6 feuilles qui affichent les résultats recherchés (à moins que tu considères que ces feuilles servent également à traiter ces données...?), les 9 autres ne servent à rien si je pense comme toi :-).
Fait une sauvegarde de ton classeur et ne travaille qu'avec une copie pour les essais que l'on va faire...
C'est fait! Le nouveau fichier pèse 22 474 KB
Bon weekend et à lundi! ça peut attendre ton retour. Merci!
@+ !
Mea culpa: en fait les 5 autres sont des copier/coller manuels pour le moment.
En fait, dans ton classeur tu as 7 feuilles de données, et les 15 autres feuilles ne servent qu'à traiter ces données. C'est bien cela?
7 Feuilles de données, 6 feuilles qui affichent les résultats recherchés (à moins que tu considères que ces feuilles servent également à traiter ces données...?), les 9 autres ne servent à rien si je pense comme toi :-).
Fait une sauvegarde de ton classeur et ne travaille qu'avec une copie pour les essais que l'on va faire...
C'est fait! Le nouveau fichier pèse 22 474 KB
Bon weekend et à lundi! ça peut attendre ton retour. Merci!
@+ !
Bonjour,
Dans le classeur qui te servira de base, seules sont utiles les feuilles contenant les données.
Le reste n'est pas utile, dans le sens ou tu peux, à chaque fois que tu le souhaites, recréer ces feuilles, par macro, en un clic...
Il faudrait que tu développes : en fait les 5 autres sont des copier/coller manuels pour le moment.
Des copier/coller de quoi? pourquoi pour le moment, c'est amené à évoluer?
Il va me falloir, à un moment, avoir accès à ce classeur (celui que tu as refait, de 22 474Kb).
Pour cela, tu peux me l'envoyer par MP (clic sur mon pseudo ici même et envoyer un message), en passant d'abord par un service Web de pièce jointe. Cf ICI pour envoyer des fichiers volumineux.
Dans le classeur qui te servira de base, seules sont utiles les feuilles contenant les données.
Le reste n'est pas utile, dans le sens ou tu peux, à chaque fois que tu le souhaites, recréer ces feuilles, par macro, en un clic...
Il faudrait que tu développes : en fait les 5 autres sont des copier/coller manuels pour le moment.
Des copier/coller de quoi? pourquoi pour le moment, c'est amené à évoluer?
Il va me falloir, à un moment, avoir accès à ce classeur (celui que tu as refait, de 22 474Kb).
Pour cela, tu peux me l'envoyer par MP (clic sur mon pseudo ici même et envoyer un message), en passant d'abord par un service Web de pièce jointe. Cf ICI pour envoyer des fichiers volumineux.
Voici un exemple de ce qu'il est possible de faire à partir de ton classeur (Données cobf.xls) fermé.
Tu va donc :
- Ouvrir un nouveau classeur,
- L'enregistrer,
- Passer sous VBE,
- Copier/Coller ce code :
- Adapter le chemin d'accès complet à ton fichier Données cobf.xls
- Fermer VBE
- Lancer la macro (Alt + F8, ImporterLaTableFLOTTE, Exécuter)
Cette procédure, dans l'ordre, réalise les opérations suivantes :
1- crée une connexion avec ton classeur fermé,
2- Exécute une requête sur ce fichier
==> La requête est ici : SELECT * FROM [FLOTTE$] ce qui signifie : Sélectionner toute la feuille FLOTTE
3- Colle les données dans la feuille Feuil1
4- Stocke toutes les données dans une variable tableau
Tu va donc :
- Ouvrir un nouveau classeur,
- L'enregistrer,
- Passer sous VBE,
- Copier/Coller ce code :
Sub ImporterLaTableFLOTTE() Dim cn As ADODB.Connection Dim Rst As ADODB.Recordset Dim strQuery As String, strChemin As String, Donnees() Dim t As Single, Col As Integer, dl As Long t = Timer Set cn = New ADODB.Connection strChemin = "C:\Users\Desktop\conrade82\Données cobf.xls" With cn .Provider = "MSDASQL" .ConnectionString = "Driver={Microsoft Excel Driver (*.xls)};" & "DBQ=" & strChemin & "; ReadOnly=False;" .Open End With strQuery = "SELECT * FROM [FLOTTE$]" Set Rst = New ADODB.Recordset Set Rst = cn.Execute(strQuery) 'colle les noms des entêtes de colonne For i = 0 To Rst.Fields.Count - 1 Sheets("Feuil1").Cells(1, i + 1) = Rst.Fields(i).Name Next i 'colle toutes les valeurs Sheets("Feuil1").Range("A2").CopyFromRecordset Rst 'stocke dans une variable tableau les données contenues dans la feuille dl = Sheets("Feuil1").Range("A" & Rows.Count).End(xlUp).Row Donnees = Sheets("Feuil1").Range("A2:N" & dl).Value MsgBox "Macro réalisée en : " & Timer - t & " secondes. On retrouve : " & Donnees(3, 2) & " en cellule : B4, et : " & Donnees(12, 5) & " en cellule : E13." cn.Close Set cn = Nothing Set Rst = Nothing End Sub
- Adapter le chemin d'accès complet à ton fichier Données cobf.xls
- Fermer VBE
- Lancer la macro (Alt + F8, ImporterLaTableFLOTTE, Exécuter)
Cette procédure, dans l'ordre, réalise les opérations suivantes :
1- crée une connexion avec ton classeur fermé,
2- Exécute une requête sur ce fichier
==> La requête est ici : SELECT * FROM [FLOTTE$] ce qui signifie : Sélectionner toute la feuille FLOTTE
3- Colle les données dans la feuille Feuil1
4- Stocke toutes les données dans une variable tableau
Bonjour,
Tout d'abord, je te donne deux liens à lire attentivement :
- Les variables tableaux
et :
- L'objet dictionnary => lorsque l'on parle de doublon
Ensuite, pour afficher le nombre d'immatriculation pour le SIPP code EDMR sans faire appel à un TCD, il suffit d'utiliser, via VBA, un simple fonction excel NB.SI.
Voici la syntaxe pour le nombre d'immatriculation pour le SIPP code EDMR :
Mais, cette procédure ne va pas t'aider beaucoup. En effet, il conviendrait de trouver une fonction qui te renvoie le nombre d'immatriculation selon le code SIPP.
Pour cela, tu peux utiliser une Fonction personnalisée :
Cette fonction est appelée depuis une procédure comme ceci :
Mais... Tous ces codes ne font pas un TCD... Nous sommes bien d'accord.
Nous allons donc nous pencher sur "comment retourner le nombre d'immatriculation par code, pour chacun des codes".
Pour ceci, nous allons utiliser :
- une variable tableau => stocke les valeurs de la colonne SIPP
- un objet dictionnary => retourne la liste des codes sans doublons
Voici le code de la macro :
On a vu hier que la procédure ImporterLaTableFLOTTE, stocke, dans une variable tableau Donnees(), toutes les valeurs de la feuille "FLOTTE". Nous allons nous en servir maintenant.
Pour cela, il convient, au préalable, de déclarer la variable Donnees() en entête du Module, comme ceci :
Cela afin de pouvoir en utiliser les valeurs dans toutes les procédures de ce module...
Et donc, notre procédure TCD devient, en utilisant les valeurs de la variable tableau Donnees() :
Et voici un classeur récapitulatif de tout ça : https://www.cjoint.com/?DDDi6JmjlmU
A adapter : comme hier le nom du chemin d'accès.
Tout d'abord, je te donne deux liens à lire attentivement :
- Les variables tableaux
et :
- L'objet dictionnary => lorsque l'on parle de doublon
Ensuite, pour afficher le nombre d'immatriculation pour le SIPP code EDMR sans faire appel à un TCD, il suffit d'utiliser, via VBA, un simple fonction excel NB.SI.
Voici la syntaxe pour le nombre d'immatriculation pour le SIPP code EDMR :
Sub NbreImmatSIPP_EDMR() Dim Nb As Long Nb = WorksheetFunction.CountIf(Columns(3), "EDMR") MsgBox Nb End Sub
Mais, cette procédure ne va pas t'aider beaucoup. En effet, il conviendrait de trouver une fonction qui te renvoie le nombre d'immatriculation selon le code SIPP.
Pour cela, tu peux utiliser une Fonction personnalisée :
Function NbImmat(Code As String, NumColonne As Integer) As Long 'Cette fonction retourne le nbre d'immatriculation en fonction 'du code SIPP 'du numéro de colonne ou se trouvent les codes NbImmat = WorksheetFunction.CountIf(Columns(NumColonne), Code) End Function
Cette fonction est appelée depuis une procédure comme ceci :
Sub AppelFonctionNbImmat_CodeSIPP() 'procédure qui appelle la fonction NbImmat Dim MaVar As Long 'en lui "injectant" le code SIPP choisi et le numéro de la colonne (ici 3 pour colonne C) MaVar = NbImmat("EDMR", 3) MsgBox MaVar 'A noter : cette fonction peut tout aussi bien te retourner un nombre de véhicule immatriculé pour la direction PACA : ' MaVar = NbImmat("PACA", 6) 'ou le nbre de véhicule au statut ON : ' MaVar = NbImmat("ON", 4) End Sub
Mais... Tous ces codes ne font pas un TCD... Nous sommes bien d'accord.
Nous allons donc nous pencher sur "comment retourner le nombre d'immatriculation par code, pour chacun des codes".
Pour ceci, nous allons utiliser :
- une variable tableau => stocke les valeurs de la colonne SIPP
- un objet dictionnary => retourne la liste des codes sans doublons
Voici le code de la macro :
Sub TCD_NbImmat() 'Utilise les données contenues dans la Feuil1 'Cette procédure va : '- établir la liste des codes, sans doublons, '- compter le nombre d'occurence de chaque code '- restituer le tout sous forme d'un tableau en Feuil2 Dim ListeCodesSIPP As Object Dim Feuille As Worksheet Dim TablCodes() Dim i As Long, t As Single t = Timer Set Feuille = Sheets("Feuil1") Set ListeCodesSIPP = CreateObject("Scripting.Dictionary") '==> création de l'objet dictionnary 'On appelle la procédure ImporterLaTableFLOTTE afin de remplir la feuille avec les données Call ImporterLaTableFLOTTE 'on remplit la variable tableau TablCodes avec les données contenues colonne C : TablCodes = Feuille.Range("C2:C" & Feuille.Range("C" & Rows.Count).End(xlUp).Row) 'Boucle sur les données de la variable tableau For i = LBound(TablCodes) To UBound(TablCodes) 'On compte le nombre d'occurence de chaque code : ListeCodesSIPP(TablCodes(i, 1)) = ListeCodesSIPP(TablCodes(i, 1)) + 1 Next i 'Restitution des données : With Sheets("Feuil2") .Range("C2").Resize(ListeCodesSIPP.Count, 1) = Application.Transpose(ListeCodesSIPP.keys) .Range("D2").Resize(ListeCodesSIPP.Count, 1) = Application.Transpose(ListeCodesSIPP.items) End With MsgBox Timer - t & " secondes." End Sub
On a vu hier que la procédure ImporterLaTableFLOTTE, stocke, dans une variable tableau Donnees(), toutes les valeurs de la feuille "FLOTTE". Nous allons nous en servir maintenant.
Pour cela, il convient, au préalable, de déclarer la variable Donnees() en entête du Module, comme ceci :
Option Explicit Dim Donnees() Sub ImporterLaTableFLOTTE() Dim cn As ADODB.Connection Dim Rst As ADODB.Recordset Dim strQuery As String, strChemin As String ', Donnees() => on peut la supprimer d'ici Dim t As Single, Col As Integer, i As Long, dl As Long 't = Timer Set cn = New ADODB.Connection '... '...
Cela afin de pouvoir en utiliser les valeurs dans toutes les procédures de ce module...
Et donc, notre procédure TCD devient, en utilisant les valeurs de la variable tableau Donnees() :
Sub TCD_NbImmat_2() 'Utilise les données contenues dans la variable tableau Donnees Dim ListeCodesSIPP As Object Dim TablCodes() Dim i As Long, t As Single t = Timer Set ListeCodesSIPP = CreateObject("Scripting.Dictionary") '==> création de l'objet dictionnary 'On appelle la procédure ImporterLaTableFLOTTE afin de '- remplir la feuille avec les données, '- remplir la variable tableau Donnees() Call ImporterLaTableFLOTTE 'Boucle sur les données de la variable tableau For i = LBound(Donnees) To UBound(Donnees) 'On compte le nombre d'occurence de chaque code : ListeCodesSIPP(Donnees(i, 3)) = ListeCodesSIPP(Donnees(i, 3)) + 1 Next i 'Restitution des données : With Sheets("Feuil2") .Range("F2").Resize(ListeCodesSIPP.Count, 1) = Application.Transpose(ListeCodesSIPP.keys) .Range("G2").Resize(ListeCodesSIPP.Count, 1) = Application.Transpose(ListeCodesSIPP.items) End With MsgBox Timer - t & " secondes." End Sub
Et voici un classeur récapitulatif de tout ça : https://www.cjoint.com/?DDDi6JmjlmU
A adapter : comme hier le nom du chemin d'accès.
Bonjour,
Pour obtenir les données TCD, suis-je obligé de copier/collet les données sources dans ma nouvelle feuille? N'est-il pas possible que les données de cobf soient copiées/collées dans la variable tableau uniquement et directement? but final sera d'obtenir le total flotte par Sipp et par jour. Ce total s'obtient par addition/soustraction des données du fichier Données cobf.
Puis-je utiliser ta méthode pour importer des données issues d'Accès?
Merci de ton aide.
Pour obtenir les données TCD, suis-je obligé de copier/collet les données sources dans ma nouvelle feuille? N'est-il pas possible que les données de cobf soient copiées/collées dans la variable tableau uniquement et directement? but final sera d'obtenir le total flotte par Sipp et par jour. Ce total s'obtient par addition/soustraction des données du fichier Données cobf.
Puis-je utiliser ta méthode pour importer des données issues d'Accès?
Merci de ton aide.
Bonjour,
L'objet RecordSet est déjà une forme de tableau.
Il est cependant plus aisé de travailler avec une variable tableau.
Pour cela, rien de plus simple :
3 questions viennent alors :
- Est ce qu'avec ce code je récupère les noms des champs situés en 1ère ligne de ma base Excel?
Réponse : Non. La valeur Donnees(0, 0) renvoie la valeur située ligne 2 colonne A de ma feuille.
- Pourquoi 100000 alors que je n'ai que 20000 lignes?
La méthode GetRows renvoie le nombre de lignes disponibles si on en demande plus. Comme nous ne sommes pas censé connaitre le nombre de lignes d'enregistrements max, j'en demande plus...
- Comment sont stockées mes données?
Et bien rien de plus simple, les valeurs sont stockées comme ceci :
Donnees(NumColonne - 1, NumLigne - 2)
Comme Donnees(0, 0) renvoie la valeur contenue ligne 2 colonne A, alors :
Donnees(3, 0) => valeur contenue colonne D ligne 2
Donnees(1, 2) => valeur contenue colonne B ligne 4
etc...
Ta procédure ImporterLaTableFLOTTE devient donc :
Puis-je utiliser ta méthode pour importer des données issues d'Accès?
Bien sur! Je te recommande pour cela, la lecture du tutoriel de l'excellent caféine.
L'objet RecordSet est déjà une forme de tableau.
Il est cependant plus aisé de travailler avec une variable tableau.
Pour cela, rien de plus simple :
Donnees = Rst.GetRows(100000)
3 questions viennent alors :
- Est ce qu'avec ce code je récupère les noms des champs situés en 1ère ligne de ma base Excel?
Réponse : Non. La valeur Donnees(0, 0) renvoie la valeur située ligne 2 colonne A de ma feuille.
- Pourquoi 100000 alors que je n'ai que 20000 lignes?
La méthode GetRows renvoie le nombre de lignes disponibles si on en demande plus. Comme nous ne sommes pas censé connaitre le nombre de lignes d'enregistrements max, j'en demande plus...
- Comment sont stockées mes données?
Et bien rien de plus simple, les valeurs sont stockées comme ceci :
Donnees(NumColonne - 1, NumLigne - 2)
Comme Donnees(0, 0) renvoie la valeur contenue ligne 2 colonne A, alors :
Donnees(3, 0) => valeur contenue colonne D ligne 2
Donnees(1, 2) => valeur contenue colonne B ligne 4
etc...
Ta procédure ImporterLaTableFLOTTE devient donc :
Sub ImporterLaTableFLOTTE() Dim cn As ADODB.Connection Dim Rst As ADODB.Recordset Dim strQuery As String, strChemin As String, Donnees() Dim t As Single, Col As Integer, dl As Long t = Timer Set cn = New ADODB.Connection strChemin = "C:\Users\Desktop\conrade82\Données cobf.xls" With cn .Provider = "MSDASQL" .ConnectionString = "Driver={Microsoft Excel Driver (*.xls)};" & "DBQ=" & strChemin & "; ReadOnly=False;" .Open End With strQuery = "SELECT * FROM [FLOTTE$]" Set Rst = New ADODB.Recordset Set Rst = cn.Execute(strQuery) Donnees = Rst.GetRows(100000) MsgBox "Macro réalisée en : " & Timer - t & " secondes. On retrouve : " & Donnees(3, 2) & " en cellule : B4, et : " & Donnees(12, 5) & " en cellule : E13." cn.Close Set cn = Nothing Set Rst = Nothing End Sub
Puis-je utiliser ta méthode pour importer des données issues d'Accès?
Bien sur! Je te recommande pour cela, la lecture du tutoriel de l'excellent caféine.
Exemple d'utilisation de ta procédure ImporterLaTableFlotte en passant par une procédure d'import :
Ici on va lui demander d'importer en fonction de plusieurs paramètres :
1- le classeur,
2- la feuille,
3- le chemin d'accès (dépendant du nom du classeur)
4- le numéro de la colonne à importer
La procédure importe une colonne et la place dans la variable tableau valeurs().
Pour boucler sur la variable valeurs() :
Cordialement,
Franck
Ici on va lui demander d'importer en fonction de plusieurs paramètres :
1- le classeur,
2- la feuille,
3- le chemin d'accès (dépendant du nom du classeur)
4- le numéro de la colonne à importer
La procédure importe une colonne et la place dans la variable tableau valeurs().
Option Explicit Dim Donnees(), valeurs() Sub Import() Dim FeuilleAimporter As String, Classeur As String, Chemin As String, numChamp As Integer Classeur = "Données cobf.xls" FeuilleAimporter = "FLOTTE" Chemin = "C:\Users\conrade82\" & Classeur 'Dans ton fichier, feuille FLOTTE (par exemple), les colonnes sont définies comme ceci : 'Colonne 0 = Registration_number 'Colonne 1 = Unit_number 'Colonne 2 = SIPP_code 'Colonne 3 = Vehicle_status 'etc... 'donc complète la variable numChamp par le numéro de la colonne que tu souhaites numChamp = 2 'on efface les deux variables tableaux pour ne pas cumuler au cas ou Erase Donnees Erase valeurs 'et on importe ImporterLaTable FeuilleAimporter, Chemin, numChamp End Sub Sub ImporterLaTable(NomFeuilSource As String, strChemin As String, Colonne As Integer) Dim cn As ADODB.Connection Dim Rst As ADODB.Recordset Dim strQuery As String Dim t As Single, i As Long t = Timer Set cn = New ADODB.Connection With cn .Provider = "MSDASQL" .ConnectionString = "Driver={Microsoft Excel Driver (*.xls)};" & "DBQ=" & strChemin & "; ReadOnly=False;" .Open End With strQuery = "SELECT * FROM [" & NomFeuilSource & "$]" Set Rst = New ADODB.Recordset Set Rst = cn.Execute(strQuery) Donnees = Rst.GetRows(100000) For i = LBound(Donnees, 2) To UBound(Donnees, 2) ReDim Preserve valeurs(i) valeurs(i) = Donnees(Colonne, i) Next cn.Close Set cn = Nothing Set Rst = Nothing MsgBox "Macro réalisée en : " & Timer - t & " secondes. Importation de " & UBound(valeurs) & " données." End Sub
Pour boucler sur la variable valeurs() :
For i = LBound(valeurs) To UBound(valeurs) Debug.Print valeurs(i) Next i
Cordialement,
Franck
Salut Frank
Juste au passage
afin d'éviter d'avoir à cocher les références ADO, j'utilise cette syntaxe valable quelque soit la version MSoffice et qui mange moins de mémoire
Dim Cn as object
Dim rst as object
...
Set Cn=createobject("ADODB.connection")
Set Rst= Createobject("ADODB;Recordset")
D'autre part l'emploi de dim cn as New.
t'oblige à annuler en fin de code la connection
par cn=nothing
idem pour le recordset....
Je te laisse un extrait d'une vieille discussion sur XLD sur ce sujet ( à l' époque, j'utilisais les collections, ignorant ce qu'était dictionary)
https://www.cjoint.com/?0Edr1X3ju7j
Enfin, je ne sais pas la version XL utilisée mais à partir de XL2007, les connections ne se font plus par ODBC mais par OLEDB
amicalement
Juste au passage
afin d'éviter d'avoir à cocher les références ADO, j'utilise cette syntaxe valable quelque soit la version MSoffice et qui mange moins de mémoire
Dim Cn as object
Dim rst as object
...
Set Cn=createobject("ADODB.connection")
Set Rst= Createobject("ADODB;Recordset")
D'autre part l'emploi de dim cn as New.
t'oblige à annuler en fin de code la connection
par cn=nothing
idem pour le recordset....
Je te laisse un extrait d'une vieille discussion sur XLD sur ce sujet ( à l' époque, j'utilisais les collections, ignorant ce qu'était dictionary)
https://www.cjoint.com/?0Edr1X3ju7j
Enfin, je ne sais pas la version XL utilisée mais à partir de XL2007, les connections ne se font plus par ODBC mais par OLEDB
With Cn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" _
& Fichier & ";Extended Properties=""Excel 12.0;HDR=YES;"""
.Open
End With
amicalement
Bonjour Michel_m,
Merci de ton passage, toujours le bienvenu.
Merci encore pour la piqure de rappel. Cette discussion que tu avais eu avec Thierry, tu me l'avais déjà faite passer, mais je l'avais oublié... Of course, je ne "bosses" que rarement avec des variables Objets et encore plus rarement avec des "New" quelque chose...
Est ce valable quelque soit l'objet?
Si oui, ce rappel tombe à point nommé. Je suis sur un autre projet par ailleurs avec de grosses variables objets déclarés, jusqu'à aujourd'hui As New Machin... Sur ce projet nous observons des quantités de mémoire qui "part en vrille", avec de grosses difficultés pour les détruire... Je vais donc tenter un réajustement par ta méthode.
Merci également pour le Provider OLEDB, je ne connaissais pas cette différence.
On en apprends tous les jours.
Merci de ton passage, toujours le bienvenu.
Merci encore pour la piqure de rappel. Cette discussion que tu avais eu avec Thierry, tu me l'avais déjà faite passer, mais je l'avais oublié... Of course, je ne "bosses" que rarement avec des variables Objets et encore plus rarement avec des "New" quelque chose...
Est ce valable quelque soit l'objet?
Si oui, ce rappel tombe à point nommé. Je suis sur un autre projet par ailleurs avec de grosses variables objets déclarés, jusqu'à aujourd'hui As New Machin... Sur ce projet nous observons des quantités de mémoire qui "part en vrille", avec de grosses difficultés pour les détruire... Je vais donc tenter un réajustement par ta méthode.
Merci également pour le Provider OLEDB, je ne connaissais pas cette différence.
On en apprends tous les jours.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Bonjour conrade82,
C'est reparti?
Alors il me faut :
1- ta version d'Excel
2- Ton classeur importes des données d'Excel, d'Access. C'est tout?
Il me faut donc les noms des chemins d'accès, les noms des classeurs (ou des bases de données), des feuilles (ou des tables) et des entêtes de colonne (ou les noms des champs) que tu importes afin de pouvoir adapter "au plus près" un classeur d'import...
@Michel : si tu pouvais rester dans le coin, au moins pour la liaison avec Access. Je n'ai pas ce logiciel et donc ne pourrais pas tester efficacement ma(es) proposition(s). Merci d'avance
C'est reparti?
Alors il me faut :
1- ta version d'Excel
2- Ton classeur importes des données d'Excel, d'Access. C'est tout?
Il me faut donc les noms des chemins d'accès, les noms des classeurs (ou des bases de données), des feuilles (ou des tables) et des entêtes de colonne (ou les noms des champs) que tu importes afin de pouvoir adapter "au plus près" un classeur d'import...
@Michel : si tu pouvais rester dans le coin, au moins pour la liaison avec Access. Je n'ai pas ce logiciel et donc ne pourrais pas tester efficacement ma(es) proposition(s). Merci d'avance
Bonjour Franck,
Voici les infos:
1- Chemin d'accès à la base Access: "C:\Users\conrade82\Mec.mdb"
2- Tables / Requête:
- Requête Situation On Rent (TCD RA OPEN, TCD RA CI )
Colonnes importée = Rental Agreement Number, Original Checkout date, CO Station code, CO - Area desc, CI Station code, SIPP code, Checkin Date, CI - Area desc, Type vhls, Direction C/O, Exploitation C/O, Type 2, TYPE3 RES, Direction C/I, Exploitation C/I, Durée.
- Requête Réservations (TCD RES CO, TCD RES CI)
Colonnes importées = Reservation number, Reservation status, Date of projected C/O, Date of projected C/I, Booked Vehicle Category, Checkout station Id, Projected Checkin station Id, CO Area desc, CI Area desc, Checkout station Category, TYPE VHLS, DIRECTION C/O, EXPLOITATION C/O, TYPE2 RES, TYPE3 RES, DIRECTION C/I, EXPLOITATION C/I
Un panoplie...
Voici les infos:
1- Chemin d'accès à la base Access: "C:\Users\conrade82\Mec.mdb"
2- Tables / Requête:
- Requête Situation On Rent (TCD RA OPEN, TCD RA CI )
Colonnes importée = Rental Agreement Number, Original Checkout date, CO Station code, CO - Area desc, CI Station code, SIPP code, Checkin Date, CI - Area desc, Type vhls, Direction C/O, Exploitation C/O, Type 2, TYPE3 RES, Direction C/I, Exploitation C/I, Durée.
- Requête Réservations (TCD RES CO, TCD RES CI)
Colonnes importées = Reservation number, Reservation status, Date of projected C/O, Date of projected C/I, Booked Vehicle Category, Checkout station Id, Projected Checkin station Id, CO Area desc, CI Area desc, Checkout station Category, TYPE VHLS, DIRECTION C/O, EXPLOITATION C/O, TYPE2 RES, TYPE3 RES, DIRECTION C/I, EXPLOITATION C/I
Un panoplie...
Bonjour Franck, bonjour à tous!
Désolé Franck, je viens juste de découvrir que tu m'avais posé une question suite à ta réponse à Michel. C'est fou, j'ai lu ton message pour Michel, mais je n'ai pas vu que tu m'avais écris ensuite et j'avoue, je pensais que tu n'avais trop le temps pour m'aider pour le moment... Mea culpa.
1. Je travaille sur Office 2003
2. Mon classeur importe des données d'Excel (celles que tu as traité ci-dessus) et j'ai des TCD crées directement à partir d'Access.
je te transmets lundi les infos que tu demandes.
Merci pour toute l'aide que vous m'apportez tous.
Cordialement,
Conrade82
Désolé Franck, je viens juste de découvrir que tu m'avais posé une question suite à ta réponse à Michel. C'est fou, j'ai lu ton message pour Michel, mais je n'ai pas vu que tu m'avais écris ensuite et j'avoue, je pensais que tu n'avais trop le temps pour m'aider pour le moment... Mea culpa.
1. Je travaille sur Office 2003
2. Mon classeur importe des données d'Excel (celles que tu as traité ci-dessus) et j'ai des TCD crées directement à partir d'Access.
je te transmets lundi les infos que tu demandes.
Merci pour toute l'aide que vous m'apportez tous.
Cordialement,
Conrade82