Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2010 Comptage Complexe

cathodique

XLDnaute Barbatruc
Bonjour,
Depuis une petite BD (qui s'allongera au fil du temps), je voudrais via un formulaire faire un comptage global ou par année suivant un choix dans la combobox.

Je voudrai faire un comptage dans l'ordre suivant par Espèce, par Cat. (catégorie) et par caractère. et aussi compter le nombre de décès par année (colonne F contient la date de décès).

Attention, pour caractere, ils sont en doublons car chaque NoDossier peut changer de cat. au fil du temps.

Pour info, un NoDossier n'a jamais de catégorie "Cd" en doublon. Ce qui n'est pas le cas de autres Catégories.

Je ne sais pas si j'ai bien expliqué mon objectif. En feuille Recap, j'ai mis les différents résultats escomptés.

J'ai commencé comme ci-dessous mais je me suis emmêlé les pinceaux.

VB:
Option Explicit
Dim tb
Dim Dico As Object

Sub essai1()
   Dim i As Long, d As Object, L As Byte
   Dim année
   Set d = CreateObject("scripting.dictionary")

   tb = [Table].Value
   année = 2024 ' sera remplacé par la combobox

   For i = 1 To UBound(tb)
      d(tb(i, 4)) = "" 'récupère nb espèce sans doublon
   Next i

   Dim Tr() 'debut tableau resultat
   For i = 0 To d.Count - 1
      ReDim Preserve Tr(1 To d.Count, 1 To 10)
      Tr(i + 1, 1) = année
      Tr(i + 1, 2) = d.keys()(i)
   Next i

   For i = 1 To UBound(tb)
      If Year(tb(i, 1)) = année Then
'je me noie ici

      End If
   Next i
End Sub

J'ai voulu adapter les exemples (de ma précédente discussion )de @patricktoulon , de @laurent950 ou de @dysorthographie (la plus complexe pour moi car jamais utilisé ADO).
Je voudrai en gros obtenir le modèle d'array en feuille Recap pour alimenter la listbox.

En vous remerciant par avance.
 

Pièces jointes

  • Comptage - Copie.xlsm
    44.3 KB · Affichages: 21

patricktoulon

XLDnaute Barbatruc
il n'y a pas de doublons possible
chez moi les résultat sont exacts avec l'exemple que tu nous a donné
pour vérifier j'ai testé avec l'autofilter
si ca te convient pas alors c'est la conception de ton tableau qui est a revoir
sachant par exemple que l'on compile par exemple année espece et décès
davec ton tableau il sera tout simplement impossible de faire une règle de doublons puisque l'on est sensés compiler les doublons
regarde ton tableau filtré les deux décès sont bien en 2020
comment veux tu que j'en zape un ? c'est absurde
mainenant si tu me dit qu'il faut dedoublonner la colonnes B alors là oui mais le resultat ne sera pas celui que tu présente dans ta capture c'est évident
 
Dernière édition:

cathodique

XLDnaute Barbatruc
Bonsoir @patricktoulon ,
Comme je l'ai expliqué à @dysorthographie, les résultats pour les différentes catégories semblent Bons.
Les résultats pour adoptable et non adoptable ne sont pas bons à cause des doublons.
Pour décès, il n'y en a qu'une sont la date de décès survenu en 2024 a été enregistrée à 2 reprises (même nodossier). Embétant mais on doit faire avec.
Je souhaite construire le tableau qui alimente la listbox sur un même modèle même si les données n'existent pas. Pour nous facilter, de faire des comparatifs.
comme ci dessous

toujours la même "trame".

J'ai trouvé que dans ma bd actuelle il y 12 années différentes et 3 espèces.
J'ai défini un array de 12*3 lignes et 10 colonnes [Redim Tr(1 to 12*3, 1 to 10)
Je n'ai pas encore trouvé comment remplir les 2 premières colonnes avec la même trame
2024 chat
2024 chien
2024 lapin et la même chose pour la suite des années.
Un peu tordu, mais je voudrai avoir toujours le même modèle même avec l'ajout d'une nouvelle espèce.
Quand on manque de bagage et d’expérience, on rame dur dur.

Merci beaucoup.

Bonne soirée.
 

cathodique

XLDnaute Barbatruc
Tu trouves que mon tableau est mal conçu. Mais je fonctionne avec depuis un bon moment. Pour info, ce tableau est relié à 3 autres tableaux que je peux pas joindre pour la confidentialité. Les autres tableaux n'ont aucun rapport à ma demande.
Il s'agit d'un seul décès (même NoDossier), la colonne F est dédiée à la date de décès qui se met (par code) sur les lignes du no de l'animal. Elle est comptabilisée pour l'année 2020. or je voudrais qu'elle le soit pour l'année de décès c-à-d en 2024.

J'ai plusieurs heures à filtrer et compter pour avoir des résultats justes. Tu viens de m'annoncer qu'ils sont faux. Ce dont je suis sûr à 100%, nous n'avons eu qu'un seul décès de chats.

Il se fait tard et je suis fatigué. je reviendrai demain te confirmer le nombre par année et par espèce des adoptables et non adoptables.

Bonne nuit.
 

patricktoulon

XLDnaute Barbatruc
re
je ne dis pas que ton tableau est faux
je dis que si tu veux faire une listebox avec le comptage tu ne peux pas car
il faudrait enlever les doublons de n° dossier et là le resulta que tu souhaite dans ta capture est faux
tu ne peux pas cumuler Cd ,Fa,Ch,Rt etc.. et pas cumuler la colonne Dc ça n'a pas de sens
est ce que tu comprends mieux comme ça ?
 

cathodique

XLDnaute Barbatruc
dis moi ce qui ne va pasnstp
Je m'excuse. J'ai fait une erreur dans mon userform. Il manquait la catégorie "Ad" en l'ajoutant et en corrigeant le nombre de colonnes 10 au lieu de 9. les résultats sont décalés. Mais ils semblent bons.
Juste une chose, le décès est mis en 2020 date d'enregistrement de l'animal.
si tu consultes la bd lignes 158 et 129 on voit bien que c'est le même chat no 2020087. Donc le 1 doit être mis sur la ligne 2024 , Chat, décès=1

Je t'avoue que j'ai parcouru tes codes mais je n'ai pas compris beaucoup de chose.
Merci beaucoup pour ton aide. Je m'excuse encore une fois pour ma grossière erreur. Il me manque une colonne.

Bonne soirée.
 

cathodique

XLDnaute Barbatruc
Oui, je comprends. Comme d'habitude j'expose mon problème très mal.
Je voulais d'abord créer ce fameux tableau de comptage. Pour ensuite, l'injecter dans une listbox et permettre à l'utilisateur de sélectionner les lignes qui l'intéressent pour les transférer sur une feuille excel.

Merci beaucoup pour ton aide.

Bonne soirée.

là bonne nuit pour de vrai.
 

dysorthographie

XLDnaute Accro


Ce code VBA exécute une requête SQL sur un fichier Excel via ADO (ActiveX Data Objects) pour récupérer des informations spécifiques sur des enregistrements dans une feuille Excel. Le code est principalement destiné à calculer des totaux pour différentes catégories d'enregistrements (comme "Adoptable", "Décès", etc.) par année et par espèce.

Je vais détailler chaque partie du code et documenter ce qu'elle fait.
VB:
SouSql = "Select * From [BD$]" & IIf(Where = "", "", " Where " & Where)

  • Sql : Initialise la requête SQL qui va résumer les données. Elle commence par sélectionner l'année (Années), l'espèce (Espece), et les sommes pour différentes catégories (Ad, Cd, etc.).
  • FROM (" & vbCrLf : Le vbCrLf ajoute une nouvelle ligne pour rendre le code plus lisible. La requête sélectionne les données à partir d'une sous-requête qui va être construite ensuite.

Union des Différentes Catégories​

Les sections suivantes ajoutent des sous-requêtes spécifiques pour chaque catégorie (Ad, Cd, Fa, Ch, Rt, Adoptable, NAdoptable, Décès), en utilisant UNION ALL pour combiner les résultats.

  • SouSql : Une variable qui stocke une requête SQL de base pour sélectionner toutes les colonnes de la feuille Excel nommée BD.
  • IIf(Where = "", "", " Where " & Where) : IIf est une fonction conditionnelle en VBA. Si la variable Where est vide, elle retourne une chaîne vide, sinon elle retourne une clause WHERE avec la condition spécifiée dans Where. Cela permet de filtrer les enregistrements si nécessaire.

Initialisation de l'Objet Connection ADO​

Déclaration et Construction de la Requête SQL​

Code:
With CreateObject("Adodb.connection")
  .Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=YES;"""
  • CreateObject("Adodb.connection") : Crée une nouvelle connexion ADO pour interagir avec la source de données, dans ce cas, le fichier Excel.
  • .Open : Ouvre la connexion en utilisant le fournisseur OLEDB pour accéder aux données dans le fichier Excel (ThisWorkbook.FullName), avec des propriétés étendues qui spécifient qu'il s'agit d'un fichier Excel au format 12.0 (Excel 2007 ou plus récent) et que la première ligne contient les en-têtes de colonnes (HDR=YES).

Construction de la Requête SQL Principale​

Code:
Sql = "SELECT Années, Espece, sum(Ad), sum(Cd), sum(Fa), sum(Ch), sum(Rt), sum(Adoptable), sum(NAdoptable), sum(Décès) FROM (" & vbCrLf
  • Sql : Initialise la requête SQL qui va résumer les données. Elle commence par sélectionner l'année (Années), l'espèce (Espece), et les sommes pour différentes catégories (Ad, Cd, etc.).
  • FROM (" & vbCrLf : Le vbCrLf ajoute une nouvelle ligne pour rendre le code plus lisible. La requête sélectionne les données à partir d'une sous-requête qui va être construite ensuite.

Union des Différentes Catégories​

Les sections suivantes ajoutent des sous-requêtes spécifiques pour chaque catégorie (Ad, Cd, Fa, Ch, Rt, Adoptable, NAdoptable, Décès), en utilisant UNION ALL pour combiner les résultats.
Code:
Sql = Sql & "SELECT DISTINCT NoDossier, FORMAT([Date],'yyyy') AS Années, [Espece],1 as Ad,0 as Cd,0 as Fa,0 as Ch,0 as Rt,0 as Adoptable,0 as  NAdoptable, 0 as Décès FROM (" & SouSql & ") WHERE UCASE([Cat#]) = 'AD'" & vbCrLf

  • SELECT DISTINCT : Sélectionne des enregistrements distincts pour éviter les doublons.
  • FORMAT([Date],'yyyy') AS Années : Formate la colonne Date en année (yyyy) pour regrouper les résultats par année.
  • UCASE([Cat#]) = 'AD' : Filtre les enregistrements où la colonne Cat# (convertie en majuscules) est égale à AD.
  • 1 as Ad, 0 as Cd, ... : Attribue la valeur 1 à la colonne correspondante (ici Ad) et 0 aux autres colonnes. Cela permet de compter le nombre d'occurrences pour chaque catégorie lorsqu'on fera la somme.
Les autres UNION ALL suivent le même modèle, mais filtrent pour différentes catégories (Cd, Fa, Ch, Rt, etc.).

Agrégation et Tri Final​


Code:
Sql = Sql & ") AS SubQuery GROUP BY Années, Espece Order by Années DESC"
  • SubQuery : La sous-requête qui regroupe toutes les UNION ALL précédentes.
  • GROUP BY Années, Espece : Regroupe les résultats par année et par espèce.
  • ORDER BY Années DESC : Trie les résultats par année, en ordre décroissant (de la plus récente à la plus ancienne).

Exécution de la Requête​

Code:
With .Execute(Sql)
    If .EOF Then LST = Split(Space(10)) Else LST = .getrows
End With
  • .Execute(Sql) : Exécute la requête SQL construite précédemment.
  • If .EOF : Vérifie si la requête retourne des résultats (.EOF signifie "End Of File").
  • LST = .getrows : Si des résultats sont retournés, ils sont stockés dans LST sous forme de tableau.

Résumé​

Ce code VBA permet de faire une analyse statistique sur des données contenues dans une feuille Excel, en regroupant les enregistrements par année et par espèce, et en comptant les occurrences de différentes catégories (Ad, Cd, etc.). Il utilise ADO pour interagir avec les données Excel comme s'il s'agissait d'une base de données.

L'objectif final est d'obtenir un tableau résumé contenant les totaux de chaque catégorie par année et espèce, qui peut ensuite être utilisé pour des rapports ou des analyses supplémentaires.

Annexe :

Voici un glossaire de termes SQL de base, accompagné d'explications simples qui seront utiles à une personne débutant en SQL.

1. SQL (Structured Query Language)

  • Description: SQL est un langage standardisé utilisé pour interagir avec des bases de données relationnelles. Il permet de créer, lire, mettre à jour et supprimer des données.

2. Requête (Query)

  • Description: Une requête est une instruction écrite en SQL qui permet de récupérer ou de manipuler des données dans une base de données. Les requêtes peuvent être simples (sélectionner des données) ou complexes (inclure des calculs, des filtres, etc.).

3. SELECT

  • Description: Le mot-clé SELECT est utilisé pour récupérer des données dans une base de données. C'est la commande la plus courante en SQL.
  • Exemple: SELECT * FROM Clients; — Cela sélectionne toutes les colonnes de la table Clients.

4. FROM

  • Description: Le mot-clé FROM indique la table d'où proviennent les données que l'on souhaite récupérer.
  • Exemple: SELECT Nom FROM Clients; — Cela sélectionne uniquement la colonne Nom de la table Clients.

5. WHERE

  • Description: La clause WHERE est utilisée pour filtrer les résultats d'une requête en fonction de certaines conditions.
  • Exemple: SELECT * FROM Clients WHERE Age > 30; — Cela sélectionne les clients âgés de plus de 30 ans.

6. GROUP BY

  • Description: GROUP BY permet de regrouper les lignes qui ont les mêmes valeurs dans des colonnes spécifiées, souvent en combinaison avec des fonctions d'agrégation comme SUM, COUNT, AVG.
  • Exemple: SELECT Departement, COUNT(*) FROM Employes GROUP BY Departement; — Cela compte le nombre d'employés dans chaque département.

7. ORDER BY

  • Description: ORDER BY est utilisé pour trier les résultats d'une requête en fonction d'une ou plusieurs colonnes.
  • Exemple: SELECT Nom FROM Clients ORDER BY Age DESC; — Cela sélectionne les noms des clients en les triant par âge décroissant.

8. JOIN

  • Description: Les JOIN permettent de combiner des lignes de deux ou plusieurs tables en fonction d'une colonne commune. Il existe plusieurs types de JOIN :
    • INNER JOIN : Récupère les enregistrements qui ont des valeurs correspondantes dans les deux tables.
    • LEFT JOIN : Récupère tous les enregistrements de la table de gauche, et les correspondances de la table de droite. Si aucune correspondance n'est trouvée, les résultats contiendront NULL pour les colonnes de la table de droite.
  • Exemple: SELECT Employes.Nom, Departements.Nom FROM Employes INNER JOIN Departements ON Employes.DepartementID = Departements.ID;

9. UNION

  • Description: UNION est utilisé pour combiner les résultats de deux ou plusieurs requêtes SELECT. Les colonnes sélectionnées doivent être du même type dans toutes les requêtes.
  • Exemple: SELECT Nom FROM Clients UNION SELECT Nom FROM Fournisseurs; — Cela récupère tous les noms des clients et des fournisseurs, sans doublons.

10. INSERT INTO

  • Description: INSERT INTO est utilisé pour ajouter de nouvelles lignes dans une table.
  • Exemple: INSERT INTO Clients (Nom, Age) VALUES ('Jean', 32); — Cela ajoute un nouveau client nommé Jean, âgé de 32 ans.

11. UPDATE

  • Description: UPDATE permet de modifier les données existantes dans une table.
  • Exemple: UPDATE Clients SET Age = 33 WHERE Nom = 'Jean'; — Cela met à jour l'âge de Jean à 33 ans.

12. DELETE

  • Description: DELETE est utilisé pour supprimer des enregistrements d'une table.
  • Exemple: DELETE FROM Clients WHERE Age < 18; — Cela supprime tous les clients âgés de moins de 18 ans.

13. Subquery (Sous-requête)

  • Description: Une sous-requête est une requête imbriquée dans une autre requête SQL. Elle est utilisée pour effectuer des calculs ou des sélections supplémentaires.
  • Exemple: SELECT Nom FROM Employes WHERE Salaire > (SELECT AVG(Salaire) FROM Employes); — Cela sélectionne les employés dont le salaire est supérieur à la moyenne.

14. Alias

  • Description: Un alias est un nom temporaire attribué à une table ou une colonne dans une requête pour en faciliter la lecture ou la gestion.
  • Exemple: SELECT Nom AS ClientName FROM Clients; — Cela renomme temporairement la colonne Nom en ClientName.

15. NULL

  • Description: NULL représente une valeur manquante ou inconnue dans une base de données. C'est différent de zéro ou d'une chaîne vide.
  • Exemple: SELECT * FROM Clients WHERE Adresse IS NULL; — Cela sélectionne les clients qui n'ont pas d'adresse renseignée.

16. Aggregate Functions (Fonctions d'Agrégation)

  • Description: Ce sont des fonctions utilisées pour effectuer des calculs sur un ensemble de valeurs et retourner un seul résultat.
    • SUM : Calcule la somme des valeurs.
    • COUNT : Compte le nombre de valeurs (ou de lignes).
    • AVG : Calcule la moyenne des valeurs.
    • MAX : Retourne la valeur maximale.
    • MIN : Retourne la valeur minimale.
  • Exemple: SELECT AVG(Salaire) FROM Employes; — Cela calcule le salaire moyen des employés.

17. DISTINCT

  • Description: DISTINCT est utilisé pour retourner uniquement des valeurs uniques, en éliminant les doublons.
  • Exemple: SELECT DISTINCT Departement FROM Employes; — Cela retourne la liste des départements sans répétition.
 

Pièces jointes

  • Comptage -RD.xlsm
    77.8 KB · Affichages: 5
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
Je m'excuse. J'ai fait une erreur dans mon userform. Il manquait la catégorie "Ad" en l'ajoutant et en corrigeant le nombre de colonnes 10 au lieu de 9. les résultats sont décalés. Mais ils semblent bons.
tu es sur de bien lire les réponse cathodique

robert coucou
chez moi ca plante a l'open de la connexion
 

dysorthographie

XLDnaute Accro
Bonjour Patrick,
Test avec 16.0
VB:
With CreateObject("Adodb.connection")
'    .Open "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 16.0;HDR=YES;"""

'     .Open "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=YES;"""
End With
 

dysorthographie

XLDnaute Accro
Bonjour Staple1600,
Avec plaisir, pour le code je fais confiance qu'à moi mais pour la documentation Chatgpt est mon script préféré.

Je trouve que SQL est un langage puissant. Une requête n'est rien d'autre que la description de tâches à effectuer.

Sans forcément comprendre tous les termes de la requête,on voit bien qu'il y a une requête dont l'objectif est de faire la somme des sous requête ; et des sous requête qui extraient de la base de données excel les Ad,DC,etc une ligne de requête par cat. réuni dans une même sous requête via l'instruction Union All.

On est proche du langage parlé il fallait pas de doublon je sélectionne les données de façon distinctes.
 
Dernière édition:

cathodique

XLDnaute Barbatruc
Messieurs bonjour,

Je ne vous ai pas oublié. J'étais occupé à résoudre mon problème.
Inspiré par ce qu'avait dit @dysorthographie à propos de ChatGPT que je ne connaissais même pas.
Ayant encore de difficultés à monter des fonctions paramétrées. Je me suis dis:" et pourquoi pas?".
Je me suis bien amusé. Pour certaines questions, code bon.
Pas pour tout. Quoique que moi aussi, je pose très mal mes questions.
Mais ça m'a permis, en y mettant la patte à faire fonctionner les codes proposés.

Je suis finalement parvenu à faire ce que je voulais. Mon codage manque surement de rigueur. Mais le résultat est là.
Il ne me reste que quelques trucs à coder. Comme par exemple, à la saisie de l'année filtrer dans une Textbox, la Listbox en ne gardant que les lignes de l'année et l'année N-1. Et surement un bouton pour transférer vers une feuille.

Voilà pour le partage je joins mon fichier.

Je vous remercie, j'apprends toujours quelque chose de nouveau en venant sur le forum.
 

Pièces jointes

  • Comptage - Copie (2).xlsm
    75.5 KB · Affichages: 2

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…