Créer une gestion de multipaiements avec Access

Denis Hulo

Objectif : apprendre à créer une gestion de multipaiements avec Access.

Niveau requis : débutant.

Commentez cet article : Commentez

- Titre : Créer une gestion de multipaiements avec Access

- Auteur : Denis Hulo

- Parution : 11 décembre 2017

- Public visé :

- Licence : Copyright ® 2017 Denis Hulo. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Structure générale de l'application

- III. Tables

- III-A. T_Facture

- III-B. T_DetailFacture

- III-C. T_DetailPaiement

- III-D. T_Article

- III-E. T_Client

- III-F. T_Chantier

- IV. Requêtes

- IV-A. R_Facture

- IV-B. R_DetailFacture

- IV-C. R_DetailPaiement

- IV-D. R_TotalFacture

- IV-E. R_TotalPaiement

- IV-F. R_ListeFacture

- V. Formulaires de l'application

- V-A. Formulaire F_Facture

- V-A-1. Zones de texte dans l'en-tête de formulaire

- V-A-2. Boutons de commande et liste déroulante à droite du formulaire

- V-A-2-a. Bouton de commande cmdListeFactures

- V-A-2-b. Bouton de commande cmdActualiser

- V-A-2-c. Bouton de commande CmdImprimer

- V-A-2-d. Liste déroulante CmbRechercherFacture

- V-A-3. Boutons de commande et zone de texte dans le pied du formulaire

- V-A-3-a. Bouton de commande CmdAjouter

- V-A-3-b. Bouton de commande CmdAnnuler

- V-A-3-c. Bouton de commande CmdSupprimer

- V-A-3-d. Bouton de commande CmdFermer

- V-A-3-e. Zone de texte TxtTotalTTC

- V-A-4. Onglet En-tête de facture

- V-A-4-a. Contrôle sous-formulaire SF_Client

- V-A-4-b. Contrôle sous-formulaire SF_Chantier

- V-A-5. Onglet Détail de facture

- V-A-5-a. Contrôle sous-formulaire SF_DetailFacture

- V-A-5-a-i. Liste déroulante CmbIdArticle

- V-A-5-a-ii. Zone de texte TxtTotalHT

- V-A-5-a-iii. Zone de texte TxtTotalTVA

- V-A-5-b. Zone de texte TxtTotalHT

- V-A-5-c. Zone de texte TxtTotalTVA

- V-A-6. Onglet Détail des paiements

- V-A-6-a. Contrôle sous-formulaire SF_DetailPaiement

- V-A-6-a-i. Zone de texte TxtTotalPaiement

- V-A-6-b. Zone de texte TxtTotalPaiement

- V-A-6-c. Zone de texte TxtReste

- V-B. Formulaire F_ListeFacture

- V-B-1. Boutons de commande situés dans l'en-tête

- V-B-1-a. Bouton de commande CmdAjouter

- V-B-1-b. Bouton de commande CmdClients

- V-B-1-c. Bouton de commande CmdExporter

- V-B-1-d. Bouton de commande CmdImprimer

- V-B-1-e. Bouton de commande CmdActualiser

- V-B-1-f. Bouton de commande CmdFermer

- V-B-2. Listes déroulantes et groupe d'options pour le filtrage des données

- V-B-2-a. Procédure générique RefreshListeFactures

- V-B-2-b. Liste déroulante CmbRechercherClient

- V-B-2-c. Liste déroulante CmbRechercherTelephone

- V-B-2-d. Liste déroulante CmbRechercherFacture

- V-B-2-e. Liste déroulante CmbRechercherDateFacture

- V-B-2-f. Groupe d'options OptEtatFacture

- V-B-2-g. Zone de texte TxtDateDebut

- V-B-2-h. Zone de texte TxtDateFin

- V-B-3. Contrôle sous-formulaire SF_ListeFacture

- V-B-3-a. Zone de texte txtRefFacture

- VI. État pour impression

- VI-A. État E_Facture

- VI-A-1. Contrôle sous-formulaire SE_Client

- VI-A-2. Contrôle sous-formulaire SE_DetailFacture

- VI-A-3. Zones de texte affichant les totaux en bas de page

- VII. Les bases de données à télécharger

- VIII. Remerciements

I - Introduction

Pour les factures importantes le client peut souvent effectuer plusieurs paiements étalés dans le temps. L'objectif est donc de vous aider à créer une application permettant de gérer pour chaque facture les différents paiements réalisés, et d'avoir une vision globale des factures non payées avec les montants restants.

gestion des multipaiements

Pour cela, nous présenterons la structure générale de l'application exemple et décrirons ensuite la composition de ses principaux objets et de leurs éléments, dans l'ordre de leur création. Le code proposé dans cet article est valable pour toutes les versions d'Access. Nous proposerons à ce titre, à la fin de l'article, des fichiers compatibles avec toutes les versions d'Access.

II - Structure générale de l'application

L'application comporte :

- Un formulaire de saisie/édition des factures ;

Aperçu du formulaire de saisie/édition des factures

- Un formulaire de recherche multicritère ;

Aperçu du formulaire de recherche multicritère

- Un état pour imprimer la facture :

Aperçu de l'état

Par la suite, nous allons décrire dans l'ordre les différents objets de l'application.

III - Tables

Aperçu des relations entre les tables

III-A - T_Facture

La table contenant les données relatives aux factures : référence, désignation, client…

T_Facture

Nom du champ

Type du champ

Description

IdFacture

Entier long

Identifiant de la facture ou numéro de facture (1, 2, 3..)

DateFacture

Date/heure

Date de la facture

IdClient

Entier long

Identifiant du client relié au champ IdClient de la table T_Client

IdChantier

Entier long

Identifiant du chantier relié au champ IdChantier de la table T_Chantier

DesignationFacture

Texte

Désignation de la facture

ConditionReglement

Entier long

Condition de règlement de la facture

III-B - T_DetailFacture

Elle contient les informations détaillant la facture : les produits, leur quantité, prix unitaire et montant HT.

T_DetailFacture

Nom du champ

Type du champ

Description

IdDetailFacture

Entier long

Identifiant du détail de la facture

IdFacture

Entier long

Identifiant de la facture

IdArticle

Entier long

Identifiant de l'article relié au champ IdArticle de la table T_Article

Quantite

Numérique

Quantité d'articles facturée

PrixUnitaire

Monétaire

Prix unitaire de l'article

TauxTVA

Numérique

Taux de TVA appliqué à l'article

III-C - T_DetailPaiement

Elle contient les données détaillant les paiements de la facture : date de paiement, mode de paiement, référence, montant.

T_DetailPaiement

Nom du champ

Type du champ

Description

IdDetailPaiement

Entier long

Identifiant du détail des paiements

IdFacture

Entier long

Identifiant de la facture

MntPaiement

Monétaire

Montant du paiement

ModePaiement

Entier long

Identifiant du mode de paiement

III-D - T_Article

Elle permet d'enregistrer les données relatives aux produits.

T_Article

Nom du champ

Type du champ

Description

IdArticle

Entier long

Identifiant de l'article

RefArticle

Texte

Référence de l'article

DesignationArticle

Texte

Désignation de l'article

PrixUnitaire

Monétaire

Prix unitaire de l'article

TauxTVA

Numérique

Taux de TVA appliqué à l'article

GroupeArticle

Texte

Groupe de l'article

FamilleArticle

Texte

Famille de l'article

SousFamilleArticle

Texte

Sous-famille de l'article

III-E - T_Client

Elle contient les données relatives aux clients.

T_Client

Nom du champ

Type du champ

Description

IdClient

Entier long

Identifiant du client

NomClient

Texte

Nom du client

PrenomClient

Texte

Prénom du client

Adresse1

Texte

Adresse principale

ComplementAdresse

Texte

Complément d'adresse

CodePostal

Texte

Code postal du client

Ville

Texte

Ville du client

Telephone

Texte

Téléphone du client

Telecopie

Texte

Fax du client

Email

Texte

E-mail du client

III-F - T_Chantier

Elle permet d'enregistrer les données relatives aux chantiers.

T_Chantier

Nom du champ

Type du champ

Description

IdChantier

Entier long

Identifiant du chantier

RefChantier

Texte

Référence du chantier

NomChantier

Texte

Nom du chantier

Adresse1

Texte

Adresse principale

ComplementAdresse

Texte

Complément d'adresse

CodePostal

Texte

Code postal de la ville du chantier

Ville

Texte

Ville du chantier

Etat

Texte

État d'avancement du chantier

IV - Requêtes

Nous présenterons dans cette section les différentes requêtes et leur code SQL.

Pour accéder à l'éditeur SQL, dans Access 2010, il faut passer par le menu Affichage, puis cliquer sur Mode SQL :

Menu Mode SQL

Le code SQL des requêtes utilise la commande SELECT, pour les débutants en voici une structure simplifiée :

SELECT champ1 [, champ2 ...]
FROM source1 [, source2 ...]
WHERE conditions
ORDER BY champ1 [, champ2 ...];

- champ1 [, champ2…] : désigne les noms des champs des tables ou des requêtes à afficher, ce peut être aussi des champs calculés ;

- source1 [, source2…] : représentent les sources de données, à savoir des tables ou des requêtes séparées par des virgules ;

- conditions : des expressions conditionnelles faisant intervenir les champs des tables ou des requêtes et permettant de filtrer les données ;

Une version avec regroupement :

SELECT champ1 [, champ2 ...]
FROM source1 [, source2 ...]
WHERE conditions
GROUP BY champ1 [, champ2 ...]
HAVING conditions
ORDER BY champ1 [, champ2 ...];

Enfin, une version avec jointure :

SELECT champ1 [, champ2 ...]
FROM source1 JOIN source2 ON source1.champ1=source2.champ2
WHERE conditions
ORDER BY champ1 [, champ2 ...];

Pour plus de détails, n'hésitez pas à consulter comprendre les jointures dans Access.

IV-A - R_Facture

Source du formulaire F_Facture, elle affiche les informations sur la facture.

Aperçu de la requête R_Facture en mode création

Code SQL de la requête R_Facture

SELECT T_Facture.*, "F-" & Format([IdFacture],"0000000") AS RefFacture, , CCur(Nz(DSum("TotalLigne","R_DetailFacture","IdFacture=" & Nz([IdFacture],0)),0)) AS TotalHT, CCur(Nz(DSum("[TotalLigne]*TauxTVA","R_DetailFacture","IdFacture=" & Nz([IdFacture],0)),0)) AS TotalTVA, [TotalHT]+[TotalTVA] AS TotalTTC, CCur(Nz(DSum("MntPaiement","T_DetailPaiement","IdFacture=" & Nz([IdFacture],0)),0)) AS TotalPaiement, Nz(DSum("TotalLigne*(1+TauxTVA)","R_DetailFacture","IdFacture=" & Nz([IdFacture],0)),0)-Nz(DSum("MntPaiement","T_DetailPaiement","IdFacture=" & Nz([IdFacture],0)),0) AS Reste, [Reste]=0 AS Payee
FROM T_Facture;

Gros plan sur les champs calculés :

Champs calculés de la requête

RefFacture: "F-" & Format([IdFacture];"0000000") ' Affiche la référence de la facture
TotalHT: CMonnaie(Nz(SomDom("TotalLigne";"R_DetailFacture";"IdFacture=" & Nz([IdFacture];0));0)) ' Affiche la somme des montants d'une même facture
TotalTVA: CMonnaie(Nz(SomDom("[TotalLigne]*TauxTVA";"R_DetailFacture";"IdFacture=" & Nz([IdFacture];0));0)) ' Affiche le total de TVA pour une même facture
TotalTTC: [TotalHT]+[TotalTVA] ' Affiche le total TTC en fonction du total HT et du total de TVA
TotalPaiement: CMonnaie(Nz(SomDom("MntPaiement";"T_DetailPaiement";"IdFacture=" & Nz([IdFacture];0));0)) ' Affiche le total des paiements pour une même facture
' Calcule le solde restant à payer (TotalTTC - TotalPaiement)
Reste: Nz(SomDom("TotalLigne*(1+TauxTVA)";"R_DetailFacture";"IdFacture=" & Nz([IdFacture];0));0)-Nz(SomDom("MntPaiement";"T_DetailPaiement";"IdFacture=" & Nz([IdFacture];0));0)
Payee: [Reste]=0 ' Indique si la facture est payée (Reste=0) ou pas.

IV-B - R_DetailFacture

Source des sous-formulaires SF_DetailFacture et SE_DetailFacture, elle affiche le détail de la facture.

Aperçu de la requête R_DetailFacture en mode création

Code SQL de la requête R_DetailFacture

SELECT T_DetailFacture.*, ([Quantite]*[PrixUnitaire]) AS TotalLigne
FROM T_DetailFacture;

Gros plan sur le champ calculé :

Champ calculé de la requête

TotalLigne: [Quantite]*[PrixUnitaire] ' Montant total pour la ligne du détail

IV-C - R_DetailPaiement

Source du sous-formulaire SF_DetailPaiement, elle affiche le détail des paiements.

Aperçu de la requête R_DetailPaiement en mode création

Code SQL de la requête R_DetailPaiement

SELECT "Paiement n°" & DCount("IdDetailPaiement","T_DetailPaiement","IdFacture=" & [T_DetailPaiement].[IdFacture] & " and IdDetailPaiement<" & [T_DetailPaiement].[IdDetailPaiement])+1 AS NumPaiement, T_DetailPaiement.DatePaiement, T_DetailPaiement.IdFacture, T_DetailPaiement.MntPaiement, T_DetailPaiement.ModePaiement, DSum("[ToTalLigne]*(1+[TauxTVA])","R_DetailFacture","IdFacture=" & [T_DetailPaiement].[IdFacture])-DSum("[MntPaiement]","T_DetailPaiement","IdFacture=" & [T_DetailPaiement].[IdFacture] & " and IdDetailPaiement<=" & [IdDetailPaiement]) AS Reste
FROM T_DetailPaiement;

Gros plan sur les champs calculés :

Champs calculés de la requête

NumPaiement: "Paiement n°" & CpteDom("IdDetailPaiement";"T_DetailPaiement";"IdFacture=" & [T_DetailPaiement].[IdFacture] & " and IdDetailPaiement<" & [T_DetailPaiement].[IdDetailPaiement])+1 ' N° de la ligne du paiement
' Calcule le solde restant à payer après ce paiement
Reste: SomDom("[ToTalLigne]*(1+TauxTVA)";"R_DetailFacture";"IdFacture=" & [T_DetailPaiement].[IdFacture])-SomDom("[MntPaiement]";"T_DetailPaiement";"IdFacture=" & [T_DetailPaiement].[IdFacture] & " and IdDetailPaiement<=" & [IdDetailPaiement])

IV-D - R_TotalFacture

Cette requête de regroupement calcule le total HT et TTC par facture. Basée sur la requête R_DetailFacture, elle réalise un regroupement sur le champ IdFacture et une somme sur le champ TotalLigne.

Code SQL de la requête

SELECT idFacture, Sum(ToTalLigne) AS TotalHT, CCur(Sum([ToTalLigne]*(1+[TauxTVA]))) AS TotalTTC
FROM R_DetailFacture
GROUP BY idFacture;

IV-E - R_TotalPaiement

Cette requête regroupement calcule le total des paiements par facture. Basée sur la requête R_DetailPaiement, elle réalise un regroupement sur le champ IdFacture et une somme sur le champ MntPaiement.

Code SQL de la requête

SELECT IdFacture, Sum(MntPaiement) AS TotalPaiement
FROM T_DetailPaiement
GROUP BY IdFacture;

IV-F - R_ListeFacture

Cette requête affiche le montant TTC, le total des paiements et le solde par facture. Elle relie entre elles les tables T_Facture, T_Client et T_CategorieClient, ainsi que les requêtes R_TotalFacture et R_TotalPaiement sur les champs de liaison.

Aperçu des zones de filtrage

Code SQL de la requête

SELECT T_Facture.IdFacture, "F-" & Format([T_Facture].[IdFacture],"0000000") AS RefFacture, T_Facture.DateFacture, T_Facture.IdChantier, T_Facture.IdClient, T_Client.NomClient, T_CategorieClient.CategorieClient, T_Client.Telephone AS TelephoneClient, [R_TotalFacture].TotalTTC AS MontantTTC, [R_TotalFacture].[TotalTTC]-Nz([R_TotalPaiement].[TotalPaiement],0) AS Reste, [R_TotalPaiement].TotalPaiement, ([Reste]=0) AS Payee
FROM (((T_Facture LEFT JOIN T_Client ON T_Facture.[IdClient] = T_Client.[IDClient]) LEFT JOIN T_CategorieClient ON T_Client.CategorieClient = T_CategorieClient.IdCategorieClient) LEFT JOIN R_TotalPaiement ON T_Facture.IdFacture = R_TotalPaiement.IdFacture) LEFT JOIN R_TotalFacture ON T_Facture.IdFacture = R_TotalFacture.IdFacture;

Gros plan sur les champs calculés :

Champs calculés de la requête

MontantTTC: [R_TotalFacture].[TotalTTC] ' Total TTC des factures
' Calcule le solde restant à payer pour chaque facture
Reste: [R_TotalFacture].[TotalTTC]-Nz([R_TotalPaiement].[TotalPaiement];0)
Payee: [Reste]=0 ' Indique si la facture est payée (Reste=0) ou pas.

V - Formulaires de l'application

V-A - Formulaire F_Facture

Il permet de gérer les factures et leurs paiements. Il est basé sur la requête R_Facture et comporte trois onglets :

- un pour l'en-tête de facture comportant les références de la facture ;

- un autre pour le détail de la facture ;

- un enfin pour le détail des paiements.

Aperçu du formulaire en mode création

V-A-1 - Zones de texte dans l'en-tête de formulaire

Zones de texte permettant d'afficher la date, la référence, le client et le montant total de la facture.

Aperçu de l'en-tête du formulaire en mode création

V-A-2 - Boutons de commande et liste déroulante à droite du formulaire

Ces boutons permettent de revenir à la liste des factures, d'actualiser ou d'imprimer la facture.

Aperçu de la partie droite du formulaire en mode création

V-A-2-a - Bouton de commande cmdListeFactures

Permet de revenir à la liste des factures.

Code sur l'événement clic

Private Sub CmdListeFactures_Click()
DoCmd.Close acForm, Me.Name ' Ferme le formulaire
DoCmd.OpenForm "F_ListeFacture" ' Ouvre le formulaire F_ListeFacture

End Sub

V-A-2-b - Bouton de commande cmdActualiser

Permet d'actualiser le formulaire.

Code sur l'événement clic

Private Sub CmdActualiser_Click()
Me.Refresh ' Actualise le formulaire

End Sub

V-A-2-c - Bouton de commande CmdImprimer

Permet d'imprimer l'état positionné sur le même enregistrement.

Code sur l'événement clic

Private Sub CmdImprimer_Click()
Me.Refresh ' Actualise le formulaire

' Imprime l'état correspondant à la facture affichée sur le formulaire
DoCmd.OpenReport "E_Facture", acViewPreview, , "IdFacture=" & Nz(Me.IdFacture, 0), acWindowNormal

End Sub

V-A-2-d - Liste déroulante CmbRechercherFacture

Permet de rechercher la facture choisie sur la liste.

Code SQL sur la propriété Contenu

SELECT T_Facture.IdFacture, "F-" & Format([IdFacture],"0000000") AS [Réf Facture], T_Client.NomClient AS Client
FROM T_Client INNER JOIN T_Facture ON T_Client.[IDClient] = T_Facture.[IdClient]
ORDER BY T_Facture.IdFacture;

Code sur l'événement après maj

Private Sub CmbRechercherFacture_AfterUpdate()
Me.Filter = "" ' Vide le filtre

With Me.RecordsetClone

.FindFirst "IdFacture=" & Nz(Me.CmbRechercherFacture, 0) ' Recherche la facture correspondant à l'identifiant saisi dans la liste

If Not (.NoMatch) Then ' Si un enregistrement a été trouvé
Me.Bookmark = .Bookmark ' On se positionne sur l'enregistrement correspondant
Else ' Sinon
MsgBox ("Facture absente !") ' On affiche un message d'alerte
Me.CmbRechercherFacture.Undo ' On annule le choix fait dans la liste
End If

End With

End Sub

V-A-3 - Boutons de commande et zone de texte dans le pied du formulaire

Ces boutons permettent d'ajouter une facture, d'annuler les changements, de supprimer la facture ou de fermer.

Aperçu du pied du formulaire en mode création

V-A-3-a - Bouton de commande CmdAjouter

Permet d'ajouter une facture dans la base en se positionnant sur un nouvel enregistrement.

Code sur l'événement clic

Private Sub CmdAjouter_Click()

If MsgBox("Souhaitez-vous créer une nouvelle facture ?", vbYesNo + vbQuestion, "Validation") = vbYes Then ' Si on confirme la demande de création de facture

If Nz(Me.TxtDateFacture) = "" Then ' Si la date de la facture n'est pas saisie
MsgBox ("Choisir une date de facture !") ' Affiche un message pour le faire
Me.TxtDateFacture.SetFocus ' Positionne le focus sur la zone de texte TxtDateFacture
Exit Sub
End If

If Nz(Me.TxtRefFacture) = "" Then ' Si la référence de la facture n'est pas saisie
MsgBox ("Saisir une référence de facture !") ' Affiche un message pour le faire
Me.TxtRefFacture.SetFocus ' Positionne le focus sur la zone de texte TxtRefFacture
Exit Sub
End If

If Nz(Me.TxtIdClient) = "" Then ' Si le client n'est pas saisi
MsgBox ("Choisir un Client !") ' Affiche un message pour le faire
Me.TxtIdClient.SetFocus ' Positionne le focus sur la zone de texte TxtIdClient
Exit Sub
End If

DoCmd.GoToRecord acDataForm, Me.Name, acNewRec ' Se positionne sur un nouvel enregistrement

End If

End Sub

V-A-3-b - Bouton de commande CmdAnnuler

Annule les modifications effectuées sur le formulaire.

Code sur l'événement clic

Private Sub CmdAnnuler_Click()
Me.Undo ' Annule les modifications apportées au formulaire
DoCmd.Close acForm, Me.Name ' Ferme le formulaire

End Sub

V-A-3-c - Bouton de commande CmdSupprimer

Supprime l'enregistrement courant du formulaire.

Macro sur l'événement clic

ExécuterCommandeMenu
Commande SupprimerEnregistrement

V-A-3-d - Bouton de commande CmdFermer

Permet de fermer le formulaire.

Code sur l'événement clic

Private Sub CmdFermer_Click()
DoCmd.Close acForm, Me.Name ' Ferme le formulaire

End Sub

V-A-3-e - Zone de texte TxtTotalTTC

Affiche dans le pied du formulaire le total de TTC de la facture en faisant référence au total HT et au taux de TVA.

formule appliquée à la propriété Source contrôle

=[TxtTotalHT]+[txtTotalTVA])

V-A-4 - Onglet En-tête de facture

Affiche le détail du client et du chantier, ainsi que la désignation de la facture accompagnée d'un commentaire.

Aperçu de l'onglet En-tête de facture

V-A-4-a - Contrôle sous-formulaire SF_Client

Affiche le détail du client sur la facture.

Aperçu du contrôle sous-formulaire SF_Client en mode création

V-A-4-b - Contrôle sous-formulaire SF_Chantier

Affiche le détail du chantier sur la facture.

Aperçu du contrôle sous-formulaire SF_Chantier en mode création

V-A-5 - Onglet Détail de facture

Comprend un contrôle sous-formulaire SF_DetailFacture pour afficher le détail de la facture et des zones de texte pour les totaux de la facture.

Aperçu de l'onglet Détail de facture

V-A-5-a - Contrôle sous-formulaire SF_DetailFacture

Affiche le détail de la facture en mode feuille de données. Le sous-formulaire est relié à la requête R_DetailFacture.

V-A-5-a-i - Liste déroulante CmbIdArticle

Permet de choisir l'article à facturer et de copier son prix unitaire dans la zone de texte TxtPrixUnitaire.

Code SQL sur la propriété Contenu

SELECT [IDArticle], [DesignationArticle], PrixUnitaire, TauxTVA FROM T_Article ORDER BY [DesignationArticle];

Code sur l'événement après maj

Private Sub cmbIdArticle_AfterUpdate()
Me!TxtPrixUnitaire = Me!cmbIDArticle.Column(2) ' Copie le prix unitaire (3e colonne de la liste) dans la zone de texte TxtPrixUnitaire
Me!TxtTauxTVA = Me!cmbIDArticle.Column(3) ' Copie le taux de TVA (4e colonne de la liste) dans la zone de texte TxtTauxTVA
End Sub

V-A-5-a-ii - Zone de texte TxtTotalHT

Affiche dans le pied du sous-formulaire le total HT du détail de la facture en effectuant la somme des montants HT par ligne.

formule appliquée à la propriété Source contrôle

=Nz(Somme([TotalLigne]);0)

V-A-5-a-iii - Zone de texte TxtTotalTVA

Affiche dans le pied du sous-formulaire le total TVA du détail de la facture en effectuant la somme des produits des montants HT par le taux de TVA.

formule appliquée à la propriété Source contrôle

=Nz(Somme([TotalLigne]*TauxTVA);0)

V-A-5-b - Zone de texte TxtTotalHT

Affiche sur l'onglet le total HT du détail de la facture en faisant référence à la zone de texte TxtTotalHT située dans le pied du sous-formulaire SF_DetailFacture.

formule appliquée à la propriété Source contrôle

=Nz([SF_DetailFacture].[Formulaire]![TxtTotalHT];0)

V-A-5-c - Zone de texte TxtTotalTVA

Affiche sur l'onglet le total de TVA à ajouter au total HT.

formule appliquée à la propriété Source contrôle

=Nz([SF_DetailFacture].[Formulaire]![TxtTotalTVA];0)

V-A-6 - Onglet Détail des paiements

Comprend un contrôle sous-formulaire SF_DetailPaiement pour afficher le détail des paiements et des zones de texte pour le total des paiements et le solde de la facture.

Aperçu de l'onglet Détail des paiements

V-A-6-a - Contrôle sous-formulaire SF_DetailPaiement

Affiche le détail des paiements en mode feuille de données. Le sous-formulaire est relié à la requête R_DetailPaiement.

V-A-6-a-i - Zone de texte TxtTotalPaiement

Affiche dans le pied du sous-formulaire le total du détail des paiements en effectuant la somme des montants par ligne.

formule appliquée à la propriété Source contrôle

=Somme([MntPaiement])

V-A-6-b - Zone de texte TxtTotalPaiement

Affiche sur l'onglet le total du détail des paiements en faisant référence à la zone de texte TxtTotalPaiement située dans le pied du sous-formulaire SF_DetailPaiement.

formule appliquée à la propriété Source contrôle

=Nz([SF_DetailFacture].[Formulaire]![TxtTotalPaiement];0)

V-A-6-c - Zone de texte TxtReste

Affiche sur l'onglet le solde restant à payer en faisant référence aux zones de texte TxtTotalTTC et TxtTotalPaiement.

formule appliquée à la propriété Source contrôle

=[TxtTotalTTC]-[TxtTotalPaiement]

V-B - Formulaire F_ListeFacture

Il s'agit du formulaire de recherche multicritère, il permet d'avoir une vision globale des factures en cours et en attente de paiement, un peu comme sur un relevé de factures, et de faire des recherches par date, client…

Critères de recherche :

- Filtre des factures payées/non payées ;

- Recherche par client ;

- Recherche par téléphone ;

- Recherche par numéro de facture.

Aperçu du formulaire en mode création

V-B-1 - Boutons de commande situés dans l'en-tête

Ces boutons permettent d'ajouter une facture, d'accéder aux fiches clients, d'exporter, imprimer ou actualiser la liste des factures.

Aperçu des boutons de commande

V-B-1-a - Bouton de commande CmdAjouter

Utilisé pour ouvrir le formulaire F_Facture en mode ajout.

Procédure évènementielle sur clic

Private Sub CmdAjouter_Click()
DoCmd.OpenForm "F_Facture", , , , acFormAdd ' Ouvre le formulaire en mode ajout.

End Sub

V-B-1-b - Bouton de commande CmdClients

Permet d'ouvrir le formulaire F_Client en mode édition.

Procédure évènementielle sur clic

Private Sub CmdClients_Click()
DoCmd.OpenForm "F_Client" ' Ouvre le formulaire F_Client

End Sub

V-B-1-c - Bouton de commande CmdExporter

Permet d'exporter sous Excel la liste des factures filtrées.

Déroulé de la fonction de génération du code SQL appliqué à la requête d'exportation :

- ajout des conditions successives dans une chaîne de caractères à copier après la clause Where du code SQL ;

- constitution de la chaîne SQL avec les conditions définies précédemment ;

- renvoi de la chaîne SQL constituée.

Fonction génération SQL

'**********************************************************************************************
'***********Fonction de génération du code SQL appliqué à la requête d'exportation*************
'**********************************************************************************************
Public Function SQLListeFactures() As String
Dim leSQL As String ' Variable destinée à contenir la chaîne SQL.
Dim leWhere As String ' Variable destinée à contenir la chaîne spécifiant le critère.

leWhere = "where true "

If (Nz(Me.OptEtatFacture, 0) = 1) Then ' Si l'option factures payées est choisie
leWhere = leWhere & " and (Payee =True) " ' On ajoute la condition "(Payee =True)".
ElseIf (Nz(Me.OptEtatFacture, 0) = 2) Then ' Si l'option factures non payées est choisie
leWhere = leWhere & " and (Payee =false) " ' On ajoute la condition "(Payee =false)".
End If

If (Nz(Me.CmbRechercherFacture) <> "") And (Me.CmbRechercherFacture <> "[Toutes]") Then ' Si différente de [Toutes]
leWhere = leWhere & " and (RefFacture like '" & Me.CmbRechercherFacture & "')" ' La référence de la facture doit être égale à celle choisie dans la liste
Else
Me.CmbRechercherFacture = "[Toutes]" ' Sinon on n'ajoute aucune condition et on met "[Toutes]" dans la liste
End If

If (Nz(Me.CmbRechercherClient) <> "") And (Me.CmbRechercherClient <> "[Tous]") Then ' si un client est choisi
leWhere = leWhere & " and (NomClient like '" & Me.CmbRechercherClient & "')" ' On l'ajoute au critère.
Else
Me.CmbRechercherClient = "[Tous]" ' Sinon, on n'ajoute aucune condition.
End If

If (Nz(Me.CmbRechercherTelephone) <> "") And (Me.CmbRechercherTelephone <> "[Tous]") Then ' si un téléphone est choisi
leWhere = leWhere & " and (TelephoneClient like '" & Me.CmbRechercherTelephone & "')" ' On l'ajoute au critère.
Else
Me.CmbRechercherTelephone = "[Tous]" ' Sinon, on n'ajoute rien.
End If

If (Nz(Me.cmbRechercherDateFacture) = "Ce mois") Then ' Si la liste contient "Ce mois"
Me!TxtDateDebut = DateSerial(Year(Date), Month(Date), 1) ' On définit la date de début au 1er jour du mois.
Me!TxtDateFin = Date ' On définit la date de fin à aujourd'hui
leWhere = leWhere & " and DateFacture between #" & Format(Nz(Me!DateDebut, "1/1/1000"), "mm/dd/yyyy") & "# and #" & Format(Nz(Me!DateFin, "1/1/3000"), "mm/dd/yyyy") & "#" ' On ajoute ces conditions au critère
ElseIf (Nz(Me.cmbRechercherDateFacture) = "Le mois dernier") Then ' Si la liste contient "Le mois dernier"
Me!TxtDateDebut = DateSerial(Year(Date), Month(Date) - 1, 1) ' On définit la date de début au 1er jour du mois passé.
Me!TxtDateFin = DateSerial(Year(Date), Month(Date), 0) ' On définit la date de fin au dernier jour du mois passé.
leWhere = leWhere & " and DateFacture between #" & Format(Me!DateDebut, "mm/dd/yyyy") & "# and #" & Format(Me!DateFin, "mm/dd/yyyy") & "#" ' On ajoute ces conditions au critère
ElseIf (Nz(Me.cmbRechercherDateFacture) = "Personnalisé&#8230;") Then ' Si la liste contient "Personnalisé&#8230;"
Me.TxtDateDebut.SetFocus
leWhere = leWhere & " and DateFacture between #" & Format(Nz(Me!DateDebut, "1/1/1000"), "mm/dd/yyyy") & "# and #" & Format(Nz(Me!DateFin, "1/1/3000"), "mm/dd/yyyy") & "#" ' On ajoute les conditions correspondant aux dates déjà présentes
Else
Me.cmbRechercherDateFacture = "[Toutes]"
End If

leSQL = "Select * From R_ListeFacture2 " & leWhere & " order by [Date Facture] Desc, [Réf Facture] Desc;" ' On constitue le code SQL avec ajout du critère complet que l'on copie dans une variable.

SQLListeFactures = leSQL ' On renvoie le contenu de la chaîne SQL.

End Function

Procédure évènementielle sur clic

Private Sub CmdExporter_Click()
Dim db As DAO.Database ' Variable faisant référence à la base de données
Dim req As DAO.QueryDef ' Variable faisant référence à la requête

Set db = CurrentDb ' Référence à la base courante
Set req = db.QueryDefs("R_Export_ListeFacture") ' Référence à la requête d'exportation

req.sql = SQLListeFactures ' Assignation du code SQL à la requête

' Libération des variables
Set req = Nothing
Set db = Nothing

' Exécution de la commande d'exportation de la requête vers Excel
DoCmd.OutputTo acOutputQuery, "R_Export_ListeFacture", "ExcelWorkbook(*.xlsx)", "", True, "", , acExportQualityPrint

End Sub

V-B-1-d - Bouton de commande CmdImprimer

Exporte sous Excel la liste des factures filtrée pour l'imprimer.

Procédure évènementielle sur clic

Private Sub CmdImprimer_Click()

If MsgBox("Les données seront imprimées dans Excel !", vbOKCancel) = vbOK Then ' Si validation
CmdExporter_Click ' On lance la procédure d'exportation qui va ouvrir la feuille Excel en vue de l'imprimer
End If

End Sub

V-B-1-e - Bouton de commande CmdActualiser

Permet d'actualiser la liste des factures.

Procédure évènementielle sur clic

Private Sub CmdActualiser_Click()
Me.SF_ListeFacture.Requery ' Rafraîchit la liste

End Sub

V-B-1-f - Bouton de commande CmdFermer

Utilisé pour fermer le formulaire F_ListeFacture.

Procédure évènementielle sur clic

Private Sub CmdFermer_Click()
DoCmd.Close acForm, Me.Name ' Ferme le formulaire

End Sub

V-B-2 - Listes déroulantes et groupe d'options pour le filtrage des données

Ces contrôles permettent de filtrer la liste des factures suivant différents critères.

Aperçu des zones de filtrage

V-B-2-a - Procédure générique RefreshListeFactures

Elle permet de filtrer la liste des factures en fonction des critères définis dans le formulaire F_ListeFacture.

Déroulé de la fonction :

- ajout des conditions successives dans une chaîne de caractères à copier après la clause Where du code SQL ;

- constitution de la chaîne SQL avec les conditions définies précédemment ;

- affectation de la chaîne SQL à la propriété RecordSource du sous-formulaire SF_ListeFacture.

Procédure RefreshListeFactures

'**********************************************************************************************
'********************Procédure de rafraîchissement de la liste des factures********************
'**********************************************************************************************
Public Sub RefreshListeFactures()
Dim leSQL As String ' Variable destinée à contenir la chaîne SQL.
Dim leWhere As String ' Variable destinée à contenir la chaîne spécifiant le critère après la clause Where.

leWhere = "where true "

If (Nz(Me.OptEtatFacture, 0) = 1) Then ' Si l'option factures payées est choisie
leWhere = leWhere & " and (Payee =True) " ' On ajoute la condition "(Payee =True)".
ElseIf (Nz(Me.OptEtatFacture, 0) = 2) Then ' Si l'option factures non payées est choisie
leWhere = leWhere & " and (Payee =false) " ' On ajoute la condition "(Payee =false)".
End If

If (Nz(Me.CmbRechercherFacture) <> "") And (Me.CmbRechercherFacture <> "[Toutes]") Then ' Si différente de [Toutes]
leWhere = leWhere & " and (RefFacture like '" & Me.CmbRechercherFacture & "')" ' La référence de la facture doit être égale à celle choisie dans la liste
Else
Me.CmbRechercherFacture = "[Toutes]" ' Sinon on n'ajoute aucune condition et on met "[Toutes]" dans la liste
End If

If (Nz(Me.CmbRechercherClient) <> "") And (Me.CmbRechercherClient <> "[Tous]") Then ' si un client est choisi
leWhere = leWhere & " and (NomClient like '" & Me.CmbRechercherClient & "')" ' On l'ajoute au critère
Else
Me.CmbRechercherClient = "[Tous]" ' Sinon, on n'ajoute aucune condition.
End If

If (Nz(Me.CmbRechercherTelephone) <> "") And (Me.CmbRechercherTelephone <> "[Tous]") Then ' si un téléphone est choisi
leWhere = leWhere & " and (TelephoneClient like '" & Me.CmbRechercherTelephone & "')" ' On l'ajoute au critère.
Else
Me.CmbRechercherTelephone = "[Tous]" ' Sinon, on n'ajoute rien.
End If

If (Nz(Me.cmbRechercherDateFacture) = "Ce mois") Then ' Si la liste contient "Ce mois"
Me!TxtDateDebut = DateSerial(Year(Date), Month(Date), 1) ' On définit la date de début au 1er jour du mois.
Me!TxtDateFin = Date ' On définit la date de fin à aujourd'hui.
leWhere = leWhere & " and DateFacture between #" & Format(Nz(Me!DateDebut, "1/1/1000"), "mm/dd/yyyy") & "# and #" & Format(Nz(Me!DateFin, "1/1/3000"), "mm/dd/yyyy") & "#" ' On ajoute ces conditions au critère
ElseIf (Nz(Me.cmbRechercherDateFacture) = "Le mois dernier") Then ' Si la liste contient "Le mois dernier"
Me!TxtDateDebut = DateSerial(Year(Date), Month(Date) - 1, 1) ' On définit la date de début au 1er jour du mois passé.
Me!TxtDateFin = DateSerial(Year(Date), Month(Date), 0) ' On définit la date de début au dernier jour du mois passé.
leWhere = leWhere & " and DateFacture between #" & Format(Me!DateDebut, "mm/dd/yyyy") & "# and #" & Format(Me!DateFin, "mm/dd/yyyy") & "#" ' On ajoute ces conditions au critère
ElseIf (Nz(Me.cmbRechercherDateFacture) = "Personnalisé…") Then ' Si la liste contient "Personnalisé…"
Me.TxtDateDebut.SetFocus
leWhere = leWhere & " and DateFacture between #" & Format(Nz(Me!DateDebut, "1/1/1000"), "mm/dd/yyyy") & "# and #" & Format(Nz(Me!DateFin, "1/1/3000"), "mm/dd/yyyy") & "#" ' On ajoute les conditions correspondant aux dates déjà présentes
Else
Me.cmbRechercherDateFacture = "[Toutes]"
End If

leSQL = "Select * From R_ListeFacture " & leWhere & " order by DateFacture Desc, IdFacture Desc;" ' On constitue le code SQL avec ajout du critère complet que l'on copie dans une variable.

Me.SF_ListeFacture.Form.RecordSource = leSQL ' On copie le contenu de la variable dans la propriété RecordSource du sous-formulaire.

End Sub

V-B-2-b - Liste déroulante CmbRechercherClient

Affiche la liste des clients liés aux factures et permet leur recherche par le nom du client.

Aperçu de la liste déroulante

Code SQL permettant l'affichage des noms des clients :

Code SQL sur la propriété Contenu

SELECT "[Tous]" as f, 1 as position
FROM T_LigneVierge
UNION
SELECT DISTINCT NomClient as f, 2 as position
FROM R_ListeFacture ORDER BY position, f;

Ce code SQL permet d'afficher le mot « [Tous] » en haut de la liste pour permettre d'afficher les factures de tous les clients. La technique employée est décrite dans la FAQ.

Code VBA pour filtrer les données sur le client choisi :

Code sur l'événement après maj

Private Sub CmbRechercherClient_AfterUpdate()
RefreshFacture ' Actualise le sous-formulaire SF_ListeFacture en fonction des filtres de recherche

End Sub

V-B-2-c - Liste déroulante CmbRechercherTelephone

Permet de rechercher une facture en fonction du téléphone du client.

Aperçu de la liste déroulante

Code SQL permettant l'affichage des téléphones des clients :

Code SQL sur la propriété Contenu

SELECT "[Tous]" as f, 1 as position
FROM T_LigneVierge
UNION SELECT DISTINCT TelephoneClient as f, 2 as position
FROM R_ListeFacture where Not IsNull(TelephoneClient) ORDER BY position, f;

Procédure VBA permettant de filtrer les données sur le téléphone du client :

Code sur l'événement après maj

Private Sub CmbRechercherTelephone_AfterUpdate()
RefreshFacture ' Actualise le sous-formulaire SF_ListeFacture en fonction des filtres de recherche

End Sub

V-B-2-d - Liste déroulante CmbRechercherFacture

Permet de rechercher une facture avec sa référence.

Aperçu de la liste déroulante

Code SQL permettant l'affichage des références des factures :

Code SQL sur la propriété Contenu

SELECT "[Toutes]" as f, 1 as position
FROM T_LigneVierge
UNION
SELECT DISTINCT RefFacture as f, 2 as position
FROM R_ListeFacture where Not IsNull(RefFacture) ORDER BY position, f;

Procédure VBA permettant de filtrer les données en fonction de la référence choisie :

Code sur l'événement après maj

Private Sub CmbRechercherFacture_AfterUpdate()
RefreshFacture ' Actualise le sous-formulaire SF_ListeFacture en fonction des filtres de recherche

End Sub

V-B-2-e - Liste déroulante CmbRechercherDateFacture

Permet de rechercher une facture en fonction d'une période (Ce mois, Le mois dernier…).

On affiche dans la liste les différents choix de périodes pour le filtrage ([Tous], Ce mois, Le mois dernier…)

Aperçu de la liste déroulante

Code SQL permettant l'affichage des périodes utilisées pour le filtrage :

Code SQL sur la propriété Contenu

SELECT ParamDate
FROM T_ParamDates
ORDER BY IdParamDate;

Procédure VBA permettant de filtrer les données en fonction de la période choisie :

Code sur l'événement après maj

Private Sub CmbRechercherFacture_AfterUpdate()
RefreshFacture ' Actualise le sous-formulaire SF_ListeFacture en fonction des filtres de recherche

End Sub

V-B-2-f - Groupe d'options OptEtatFacture

Permet de filtrer les factures payées ou non payées.

Aperçu du groupe d'options

Procédure VBA pour filtrer les données en fonction du choix effectué :

Code sur l'événement après maj

Private Sub OptEtatFacture_AfterUpdate()
RefreshFacture ' Actualise le sous-formulaire SF_ListeFacture en fonction des filtres de recherche
End Sub

V-B-2-g - Zone de texte TxtDateDebut

Permet de choisir la date du début de la période de recherche des factures.

Procédure VBA pour filtrer les données en fonction de la date saisie :

Code sur l'événement après maj

Private Sub TxtDateDebut_AfterUpdate()
RefreshFacture ' Actualise le sous-formulaire SF_ListeFacture en fonction des filtres de recherche
End Sub

V-B-2-h - Zone de texte TxtDateFin

Permet de choisir la date de fin de la période de recherche des factures.

Procédure VBA pour filtrer les données en fonction de la date saisie :

Code sur l'événement après maj

Private Sub TxtDateFin_AfterUpdate()
RefreshFacture ' Actualise le sous-formulaire SF_ListeFacture en fonction des filtres de recherche
End Sub

V-B-3 - Contrôle sous-formulaire SF_ListeFacture

Il est basé sur la requête R_ListeFacture et est mis à jour au moyen de la procédure MajListeFacture.

Aperçu du contrôle sous-formulaire

Il affiche les champs principaux de la requête R_ListeFacture.

V-B-3-a - Zone de texte txtRefFacture

La procédure exécutée sur l'événement double-clic de cette zone de texte permet d'ouvrir le formulaire F_Facture sur le bon enregistrement.

Code sur l'événement double-clic

Private Sub txtRefFacture_DblClick(Cancel As Integer)
DoCmd.OpenForm "F_Facture", , , "IdFacture=" & Nz(Me.IdFacture, 0), , , "C" ' Ouvre le formulaire F_Facture sur l'enregistrement correspondant.

End Sub

C'est le même principe pour les autres zones de texte du sous-formulaire.

VI - État pour impression

VI-A - État E_Facture

Il est destiné à imprimer la facture depuis le formulaire F_Facture.

Aperçu de l'état en mode création (1)

Aperçu de l'état en mode création (2)

VI-A-1 - Contrôle sous-formulaire SE_Client

Il affiche les données relatives au client avec une liaison sur les champs IDClient.

Aperçu du sous-formulaire SE_Client

VI-A-2 - Contrôle sous-formulaire SE_DetailFacture

Il affiche le détail de la facture avec une liaison sur les champs IDFacture. Le sous-formulaire est relié à la requête R_DetailFacture.

Aperçu du sous-formulaire SE_DetailFacture

VI-A-3 - Zones de texte affichant les totaux en bas de page

Elles servent à afficher les totaux HT, TVA et TTC de la facture, mais aussi le total des paiements et du solde.

Aperçu des totaux en bas de page

Zones de texte affichant les totaux

Nom de la zone de texte

Champ de la requête R_Facture

Description

TxtTotalHT

TotalHT

Affiche le total HT de la facture

TxtTotalTVA

TotalTVA

Affiche le total de la TVA

TxtTotalTTC

TotalTTC

Affiche le total TTC de la facture

TxtTotalPaiement

TotalPaiement

Affiche le total des paiements sur la facture

TxtReste

Reste

Affiche le solde de la facture

VII - Les bases de données à télécharger

Les bases jointes sont aux formats mdb et accdb.

VIII - Remerciements

Je tiens à remercier Laurent Ott, chrtophe et tee_grandbois pour m'avoir conseillé dans la réalisation de cet article, ainsi que Claude Leloup et winjerome pour leur relecture.