Tutoriel pour tenir la comptabilité d'une association caritative avec Access

Claude Leloup

Cet article s'adresse à des utilisateurs d'Access qui ont déjà une expérience du logiciel (VBA notamment) et qui possèdent des notions de comptabilité.

Il s'inscrit dans le prolongement des deux tutoriels :

- Tutoriel pour gérer une association avec Access pour ce qui concerne le contexte ;

- Tenir une comptabilité avec Access pour la mise en œuvre d'une comptabilité organisée en journaux auxiliaires.

Vous y trouverez aussi quelques exemples de comptabilisation d'événements courants dans la vie d'une association.

Si vous désirez réagir, un espace de dialogue vous est proposé sur le forum : Commentez

- Titre : Tutoriel pour tenir la comptabilité d'une association caritative avec Access

- Auteur : Claude Leloup

- Parution : 27 mai 2016

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2016 Claude Leloup. 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. Contexte

- II. Le plan comptable

- III. Les différents formulaires pour saisir les événements comptables

- III-A. Les opérations au compte Banque

- III-B. Les opérations au compte Caisse

- III-C. Le facturier des achats

- III-D. Les opérations diverses

- IV. Quelques exemples de comptabilisations pour enregistrer des événements particuliers

- V. Les écritures relatives à la fin d'exercice

- VI. Commentaires sur la confection de l'état sePassif

- VII. Commentaires sur la confection de l'état eGrandLivre

- VIII. Commentaires du code VBA (module mCompta)

- VIII-A. Deux variables globales et les fonctions qui restituent leur valeur

- VIII-A-1. À quoi servent ces globales ?

- VIII-B. Deux fonctions pour demander une date ou une année

- VIII-B-1. Pour demander une date

- VIII-B-2. Pour demander une année

- VIII-C. Deux fonctions pour connaître le solde d'un compte à une date

- VIII-C-1. Solde()

- VIII-C-2. SoldePP()

- VIII-D. Une fonction qui renvoie zéro si la donnée n'existe pas

- VIII-E. La routine CreaMvts()

- VIII-F. Automatiser la clôture des comptes de résultat

- VIII-F-1. Code associé au clic du bouton

- VIII-F-2. La routine Cloture() proprement dite

- IX. Téléchargement

- X. Remerciements

I - Contexte

Il s'agit d'une association caritative qui recueille des fonds sous la forme de cotisations, de parrainages et des dons ponctuels, pour les redistribuer à des personnes âgées en grande détresse, sous forme de dons alimentaires et vestimentaires, d'accès aux soins médicaux et à l'hygiène, d'hébergement ponctuel pour des seniors sans famille et sans abri.

II - Le plan comptable

On se réfère au plan comptable des associations (loi 1901) dont la liste complète peut être consultée sur ce site : Loi1901.com.

Pour ce qui concerne les besoins de l'exemple, nous avons retenu seulement ceux-ci :

- Une case cochée dans la colonne « À l'actif » signifie que ce compte de bilan (N° 1000 à 5999) figure à l'actif, les comptes de bilan non cochés s'inscriront au passif.

- Les colonnes « OKii » servent à indiquer si le compte peut être mouvementé pour enregistrer des opérations respectivement dans les livres banque, caisse, achats et opérations diverses.

- Les quelques comptes fournisseurs individuels sont intégrés dans le plan comptable pour des raisons pratiques (leur solde individuel est donc directement accessible). Pour la confection du bilan, ils sont globalisés dans le compte 4010 Fournisseurs.

III - Les différents formulaires pour saisir les événements comptables

III-A - Les opérations au compte Banque

Encodage des opérations de banque

III-B - Les opérations au compte Caisse

Encodage des opérations de caisse

Remarque

Prélever des fonds dans la caisse pour les verser en banque se comptabilise :

- d'abord dans le journal de caisse, le jour du versement :

Virements de fonds

à Caisse

- ensuite, dans le journal de banque, quand on reçoit l'extrait de la banque :

Banque

à Virements de fonds

III-C - Le facturier des achats

Les factures des fournisseurs sont numérotées et conservées dans un classeur.

Encodage des factures d'achats

Remarque : l'association qui sert d'exemple n'est pas assujettie à la TVA.

III-D - Les opérations diverses

Pour comptabiliser les événements comptables qui n'impliquent ni la banque, ni la caisse, ni un fournisseur. Par exemple, les écritures de fin d'exercice.

Encodage des opérations diverses

IV - Quelques exemples de comptabilisations pour enregistrer des événements particuliers

- Un artisan offre à l'association un lot d'objets qu'elle pourra mettre en vente lors de son marché de Noël, valeur estimée : 2000 € :

- Un donateur offre un projecteur (750 €) avec une cartouche d'encre (45 €) à l'association :

- Amortissement du projecteur reçu (par exemple en cinq ans) :

- L'association achète un ordinateur (499 €) :

- Amortissement de l'ordinateur acheté (par exemple en trois ans) :

- L'association perçoit les intérêts sur son livret bleu :

Note pour les lecteurs qui recourent aux services de Mossack Fonseca : dans votre cas, il vaut mieux ne rien comptabiliser !

V - Les écritures relatives à la fin d'exercice

À la fin de l'exercice comptable (souvent le 31/12), on va « clôturer » les comptes et établir le bilan et le compte de résultat.

On commence par établir un inventaire. En fait on va comparer
- le contenu des comptes des classes 1 à 5 qui traduisent le patrimoine de l'association
avec
- la réalité du terrain.

En pratique, on tire une balance (« provisoire ») des comptes et on « justifie les soldes » des comptes de bilan.

Dans notre exemple :

Il s'agit de la contrepartie du projecteur reçu de Christophe.

On a décidé de l'amortir en cinq ans, on comptabilise l'amortissement :

On vérifie que c'est bien le report comptabilisé au bilan précédent (31/12/14).

Ce solde représente
- le projecteur (750 que nous avons déjà réduit plus haut)
et
- l'ordinateur (499) que nous avons décidé d'amortir en trois ans.
On comptabilise l'amortissement :

On dresse l'inventaire des objets encore en stock et on valorise chaque pièce à sa valeur d'achat (par exemple sur une feuille Excel).

Supposons que la valeur totale s'élève à 1234,00 €, on comptabilise l'ajustement :

et On compare ce solde à celui (symétrique !(1)) qui figure à l'extrait bancaire.

On compte l'argent qui est effectivement dans la caisse.

Un ultime coup d'œil sur la balance (en principe « définitive ») pour détecter et corriger les erreurs d'imputation éventuelles.

Quand on est convaincu que tout est OK, on clôture les comptes de résultat de l'exercice.

Concrètement, on met leur solde à zéro par contrepartie de « 1100 Report à nouveau ».

Cette opération est automatisée :

Et viennent bilan et compte de résultat en deux clics :

De même pour les journaux auxiliaires :

et le grand-livre :

VI - Commentaires sur la confection de l'état sePassif

La source (plutôt acrobatique !) :

SELECT IIf([PlanCpte] Like "4*",4010,[Plancpte]) AS CptePassif, Sum(solde([PlanCpte],getgvLaDate())) AS Mt, First(IIf([PlanCpte]=[CptePassif],[PlanIntitule],"Fournisseurs")) AS Intitule
FROM tPlanCompta
WHERE (((tPlanCompta.[Actif])=No))
GROUP BY IIf([PlanCpte] Like "4*",4010,[Plancpte])
HAVING (((Sum(solde([PlanCpte],getgvLaDate())))>0.001));

VII - Commentaires sur la confection de l'état eGrandLivre

Nous voulons, compte par compte, afficher :

le solde en début d'exercice (en-tête de groupe PlanCpte) ;

le détail des mouvements (détail) ;

le solde en fin d'exercice (pied de groupe PlanCpte).

La source n'est pas piquée des vers :

SELECT tPlanCompta.tPlanPK, tPlanCompta.PlanCpte, tPlanCompta.PlanIntitule,
"31/12/" & getgvAnnee()-1 AS DateDepart,
"31/12/" & getgvAnnee() AS DateFin,
solde([PlanCpte],[DateDepart]) AS SoldeOuverture,
IIf([soldeOuverture]<0,-[SoldeOuverture],0) AS SODebiteur,
IIf([soldeOuverture]>0,[SoldeOuverture],0) AS SOCrediteur,
solde([PlanCpte],[DateFin]) AS SoldeCloture,
IIf([SoldeCloture]<0,-[SoldeCloture],0) AS SCDebiteur,
IIf([SoldeCloture]>0,[SoldeCloture],0) AS SCCrediteur,
tMvts.Origine, tMvts.MvtDate,
IIf([MvtMt]<0,-[MvtMt],0) AS Debit,
IIf([MvtMt]>0,[MvtMt],0) AS Credit, tMvts.MvtLibelle
FROM tMvts INNER JOIN tPlanCompta ON tMvts.tPlanFK = tPlanCompta.tPlanPK
WHERE (((tMvts.MvtDate)>"31/12/" & getgvAnnee()-1 And (tMvts.MvtDate)<="31/12/" & getgvAnnee()))
ORDER BY tPlanCompta.PlanCpte;

On comprendra mieux avec un dessin :

On construit la date de l'exercice précédent et celle de l'exercice courant.

On utilise chacune de ces dates comme paramètre de la fonction Solde().

On ventile la colonne du solde en solde débiteur et solde créditeur.

Seuls les mouvements de l'exercice sont sélectionnés.

Les MvtMt sont ventilés en débit et crédit.

VIII - Commentaires du code VBA (module mCompta)

VIII-A - Deux variables globales et les fonctions qui restituent leur valeur

Global gvLaDate As Date
Global gvAnnee As Long

Public Static Function GetgvLadate()
GetgvLadate = gvLaDate
End Function

Public Static Function GetgvAnnee()
GetgvAnnee = gvAnnee
End Function

VIII-A-1 - À quoi servent ces globales ?

Par exemple, si l'utilisateur demande l'édition du bilan, il devra renseigner la date.
On vérifie qu'il s'agit d'une date pertinente, avant de la stocker dans la variable globale gvLaDate.

La fonction GetgvDate() permet d'en récupérer la valeur pour l'utiliser dans la requête source de l'actif :

Dans une requête, on n'a pas accès aux variables globales. Pour pallier cette lacune, on utilise une fonction qui a la même valeur.

VIII-B - Deux fonctions pour demander une date ou une année

VIII-B-1 - Pour demander une date

1. Public Function DemanderDate() As Boolean

2. On Error GoTo GestionErreurs

3. Dim LaDate As Date

4. 'Invite

5. LaDate = InputBox("À quelle date jj/mm/aaaa ?")

6. 'Vérifier la pertinence

7. If IsNull(DLookup("tMvtsPK", "tMvts", "year(MvtDate)=" & Year(LaDate))) Then

8. Err.Raise 13

9. End If

10. 'MàJ gvLaDate

11. gvLaDate = LaDate

12. DemanderDate = True

13. GestionErreurs:

14. Select Case Err.Number

15. Case 0 'Pas d'erreur

16. Exit Function

17. Case 13, 94 'Valeur incorrecte

18. MsgBox "La valeur entrée n'est pas pertinente !"

19. Exit Function

20. Case Else

21. MsgBox "Erreur dans DemanderDate N° " & Err.Number & " " & Err.Description

22. End Select

23. End Function

Commentaires du code

7 : on vérifie que la table tMvts contient au moins un mouvement pour cette période. Si ce n'est pas le cas, on force une erreur N° 13 que l'on traite à l'instruction 17 pour signaler l'anomalie à l'utilisateur.

12 : si la date est pertinente, la fonction renvoie True. Sinon, elle renvoie sa valeur initiale par défaut : False.

Exemple d'utilisation

Si on clique sur le bouton « Balance » du menu, le code suivant se déclenche :

1. Private Sub btBalance_Click()

2. 'Demander la date

3. If DemanderDate = True Then

4. Call CreaMvts

5. DoCmd.OpenReport "eBalance", acViewPreview

6. End If

7. End Sub

L'utilisateur reçoit cette invite :

S'il introduit par erreur « 311/2/2015 », ce message sera affiché :

VIII-B-2 - Pour demander une année

1. Public Function DemanderAnnee() As Boolean

2. On Error GoTo GestionErreurs

3. Dim lngAnnee As Long

4. 'Invite

5. lngAnnee = InputBox("Quelle année aaaa ?")

6. 'Vérif pertinence

7. If IsNull(DLookup("tMvtsPK", "tMvts", "year(MvtDate)=" & lngAnnee)) Then

8. Err.Raise 13

9. End If

10. 'MàJ gvAnnee

11. gvAnnee = lngAnnee

12. DemanderAnnee = True

13. GestionErreurs:

14. Select Case Err.Number

15. Case 0 'Pas d'erreur

16. Exit Function

17. Case 13, 94 'Valeur incorrecte

18. MsgBox "La valeur entrée n'est pas pertinente !"

19. Case Else

20. MsgBox "Erreur dans DemanderAnnee N° " & Err.Number & " " & Err.Description

21. End Select

22. End Function

Même explication, mutatis mutandis.

VIII-C - Deux fonctions pour connaître le solde d'un compte à une date

VIII-C-1 - Solde()

Le solde d'un compte, c'est la somme algébrique de ses mouvements (dans notre cas, les débits sont signés « - »).

1. Public Function solde(NumCpte As Long, ADate As Date) As Single

2. Dim lngCptePK As Long

3. 'Rechercher le tPlanPK

4. lngCptePK = DLookup("tPlanPK", "tPlanCompta", "PlanCpte =" & NumCpte)

5. 'Solde = somme des mouvements

6. solde = Nz(DSum("MvtMt", "tMvts", "MvtDate<=#" & Format(ADate, "mm/dd/yyyy") & "# AND tPlanFK =" & lngCptePK), 0)

7. End Function

Dans une fonction (et d'une manière générale dans le VBA), les dates doivent être formatées à la sauce anglaise : mois, jour, année, et encadrées de croisillons (#).

Ex. pour le 2 mars 2016 : #3/2/16#.

Explication du code

4 : on recherche l'id (tPlanPK) du N° de compte dans la table tPlan.

7 : on additionne les mouvements de ce compte. Si la somme est null (pas encore de mouvement à cette date, par exemple), la fonction renvoie « 0 ».

Exemple d'utilisation

VIII-C-2 - SoldePP()

Pour confectionner le bilan, les comptes de résultat (on dit aussi les comptes de pertes et profits =>PP) sont soldés par transfert au compte « 1100 Report à nouveau ».

La fonction SoldePP() renvoie le solde du compte juste avant cette écriture de transfert :

1. Public Function SoldePP(NumCpte As Long, Annee As Long) As Double

2. 'Solde des comptes de pertes et profits avant clôture

3. Dim lngCle As Long

4. 'Recherche le tPlanPK du compte

5. lngCle = DLookup("tPlanPK", "tPlanCompta", "PlanCpte=" & NumCpte)

6. 'Calcul du solde

7. SoldePP = Nz(DSum("MvtMt", "tMvts", "tPlanFk=" & lngCle _

8. & " AND  format(MvtDate,""yyyy"")=" & Annee _

9. & " AND MvtLibelle <> ""ClôturePP"""), 0)

10. End Function

Explication du code

4 : on recherche l'id (tPlanPK) du N° de compte dans la table tPlan.

7-9 : on additionne les mouvements de ce compte en excluant ceux qui concernent la clôture (libellé = ClôturePP. Si la somme est null (pas encore de mouvement à cette date), la fonction renvoie « 0 ».

Exemple d'utilisation

VIII-D - Une fonction qui renvoie zéro si la donnée n'existe pas

On connaît la fonction Nz(variant[, valeur-si-null]) qui renvoie une valeur (par ex. « 0 ») si la valeur donnée en premier paramètre est Null.

Ce dont on parle ici, c'est d'une fonction qui renvoie  « 0 »… si la valeur n'existe pas.

Un exemple concret pour comprendre de quoi on parle.

Prenons l'état eRecettesDepenses :

Instinctivement, on coderait la formule en jaune pour afficher le résultat.

Mais qu'advient-il si, par exemple, il n'y avait pas de dépenses ? Voici :

Écrire la formule comme ceci :

=Nz([CTNRseRecettes].[Etat]![txtTotalRecettes];0)-Nz[CTNRseDepenses].[Etat]![txtTotalDepenses];0)

ne changerait rien à l'affaire, car [CTNRseDepenses].[Etat]![txtTotalDepenses] n'a pas la valeur Null, le contrôle n'existe pas !

De là, l'idée de cette fonction :

Function AbsentToZero(anyValue As Variant) As Variant
On Error GoTo GestionErreur
AbsentToZero = Nz(anyValue, 0)
GestionErreur:
AbsentToZero = 0
End Function

Et nous exprimerons la différence comme ceci :

=AbsentToZero([CTNRseRecettes].[Etat]![txtTotalRecettes])-AbsentToZero[CTNRseDepenses].[Etat]![txtTotalDepenses])

qui donnera ceci :

VIII-E - La routine CreaMvts()

Cette fonction recrée tous les mouvements comptables qui dérivent des encodages des quatre formulaires : fBanque, fCaisse, fAchats et fOpeDiv.

N.B. Tous les mouvements sont recréés à chaque exécution de la routine.

1. Public Sub CreaMvts()

2. DoCmd.SetWarnings False

3. 'Purge tMvts

4. DoCmd.RunSQL " DELETE * FROM tMvts;"

5. '------

6. 'Banque

7. '------

8. 'Mvts dons

9. DoCmd.OpenQuery "rMvtsBqDons"

10. 'Mvts Recettes

11. DoCmd.OpenQuery "rMvtsBqRecettes"

12. 'Mvts Dépenses

13. DoCmd.OpenQuery "rMvtsBqFrais"

15. '------

16. 'Caisse

17. '------

18. 'Mvts dons

19. DoCmd.OpenQuery "rMvtsCaDons"

20. 'Mvts Recettes

21. DoCmd.OpenQuery "rMvtsCaRecettes"

22. 'Mvts Dépenses

23. DoCmd.OpenQuery "rMvtsCaFrais"

25. '------------------------------

26. 'Contreparties Banque et Caisse

27. '------------------------------

28. DoCmd.OpenQuery "rMvtsContreparties"

30. '------

31. 'Achats

32. '------

33. DoCmd.OpenQuery "rMvtsAchatsFournisseurs"

34. DoCmd.OpenQuery "rMvtsAchatsContreParties"

36. '-------------------

37. 'Opérations diverses

38. '-------------------

39. DoCmd.OpenQuery "rMvtsOpDivDebits"

40. DoCmd.OpenQuery "rMvtsOpDivCredits"

42. DoCmd.SetWarnings True

43. End Sub

Explication du code

4 : on vidange la table tMvts pour repartir de zéro.

6-13 : on crée les mouvements contreparties du compte banque au départ des tables qui ont servi à l'encodage des événements de banque.

9 : pour les dons :

11 : pour les autres montants reçus :

13: pour les montants prélevés au compte banque :

16-23 : on crée les mouvements contreparties du compte caisse au départ des tables qui ont servi à l'encodage des événements contre espèces.

La technique est identique à celle décrite plus haut pour la banque.

À ce stade, on a créé les mouvements contreparties des comptes 5100 Banque et 5300 Caisse, on va maintenant générer les mouvements pour ces deux comptes, pour chacune des dates.

28 : création des mouvements aux comptes Banque et Caisse :

31-34 : création des mouvements relatifs aux factures d'achat.

33 : mouvements aux comptes individuels des fournisseurs :

34 : mouvements dans les comptes contreparties :

34-40 : création des mouvements des opérations diverses.

39 : les débits :

40 : les crédits :

VIII-F - Automatiser la clôture des comptes de résultat

En fait, automatiser le remplissage du formulaire fOpeDiv pour comptabiliser l'écriture qui solde les comptes de résultat par transfert à « 1100 Report à nouveau ».

Dans le déroulement des travaux de clôture, il n'est pas rare de devoir recommencer plusieurs fois cette opération de transfert.

On croit que c'est terminé, on clôture… et on se rend compte qu'on a oublié de comptabiliser une opération importante.

Le mécanisme mis en place dans la routine CloturePP() permet de recommencer autant de fois que nécessaire : l'écriture précédente éventuelle est d'abord détricotée.

VIII-F-1 - Code associé au clic du bouton

Private Sub BtCloturePP_Click()
If DemanderAnnee = True Then
Call CloturePP(gvAnnee)
DoCmd.OpenForm "fOpeDiv"
End If
End Sub

Explication du code

2 : on invite l'utilisateur à entrer une année.

VIII-F-2 - La routine Cloture() proprement dite

Public Sub CloturePP(Annee As Long)

Dim lngCle As Long
Dim strSQL As String
Dim dblContrePartie As Double
Dim qdf As DAO.QueryDef

'------------------------------------------------------
'Éliminer les comptabilisations précédentes éventuelles
'------------------------------------------------------
DoCmd.SetWarnings False
'1° rechercher la clé de l'enregistrement dans tOpDiv
lngCle = Nz(DLookup("tOpeDivPk", "tOpeDiv", "tOpeDivDate=#" & "12/31/" & Annee & "#" _
& "AND tOpeDivLibelle=""ClôturePP"""), 0)
'S'il existe on supprime ses débits crédits, sinon on crée un nouvel enregistrement
If lngCle <> 0 Then
'Supprimer les débits et crédits anciens
DoCmd.RunSQL "DELETE * FROM tOpeDivDebits WHERE tOpeDivFK=" & lngCle & ";"
DoCmd.RunSQL "DELETE * FROM tOpeDivCredits WHERE tOpeDivFK=" & lngCle & ";"
Else
Set qdf = CurrentDb.QueryDefs("rClotPPOpeDiv")
qdf.Parameters("LaDate") = "31/12/" & Annee
qdf.Execute
End If

'----------------
'Recréer les mvts
'----------------
Call CreaMvts
DoCmd.SetWarnings False

'--------------------------------------------------------------------
'Garnir tOpeDivDebits et tOpeDivCredits pour solder les comptes de PP
'--------------------------------------------------------------------
lngCle = DLookup("tOpeDivPk", "tOpeDiv", "tOpeDivDate=#" & "12/31/" & Annee & "#" _
& "AND tOpeDivLibelle=""ClôturePP""")
'Débits pour solder les comptes créditeurs
Set qdf = CurrentDb.QueryDefs("rClotPPRaZCrediteurs")
qdf.Parameters("[LaDate]") = "31/12/" & Annee
qdf.Parameters("[CleOpeDiv]") = lngCle
qdf.Execute

'Crédits pour solder les comptes débiteurs
Set qdf = CurrentDb.QueryDefs("rClotPPRaZdebiteurs")
qdf.Parameters("[LaDate]") = "31/12/" & Annee
qdf.Parameters("[CleOpeDiv]") = lngCle
qdf.Execute

'-----------------------------------
'Contrepartie Résultat de l'exercice
'-----------------------------------
dblContrePartie = Nz(DSum("OpeDivDebitMt", "tOpeDivDebits", "tOpeDivFK =" & lngCle), 0) _
- Nz(DSum("OpeDivCreditMt", "tOpeDivCredits", "tOpeDivFK =" & lngCle), 0)
If dblContrePartie > 0 Then
'Bénéfice => créditer Report à Nouveau
Set qdf = CurrentDb.QueryDefs("rClotPPReportBenef")
qdf.Parameters("[ReportANouveau]") = dblContrePartie
qdf.Parameters("[CleOpeDiv]") = lngCle
qdf.Execute
Else
'Perte : => débiter Report à Nouveau
dblContrePartie = dblContrePartie * -1
Set qdf = CurrentDb.QueryDefs("rClotPPReportPerte")
qdf.Parameters("[ReportANouveau]") = dblContrePartie
qdf.Parameters("[CleOpeDiv]") = lngCle
qdf.Execute
End If

'-----------
'Libérer qdf
'-----------
Set qdf = Nothing
End Sub

Commentaires du code

9-24 : on annule l'écriture éventuelle déjà comptabilisée pour cette clôture.

13-14 : on recherche dans tOpeDiv la clé de cette précédente écriture éventuelle.

17-19 : s'il y a déjà eu une écriture de clôture cette année, on en supprime les débits et crédits.

21-23 : sinon, on crée un nouvel enregistrement dans tOpeDiv. On exécute la requête paramétrée rClotPPOpeDiv :

PARAMETERS [LaDate] DateTime;
INSERT INTO tOpeDiv ( tOpeDivDate, tOpeDivLibelle )
SELECT [LaDate] AS [Date], "ClôturePP" AS libelle;

27-30 : on recrée les mouvements avant clôture.

33-67 : on construit une nouvelle écriture de clôture.

37-41 : on débite les comptes de résultat actuellement créditeurs pour les solder. Pour ce faire, on exécute la requête rClotPPRazCrediteurs :

PARAMETERS [LaDate] DateTime, [CleOpeDiv] Long;
INSERT INTO tOpeDivDebits ( tPlanFK, OpeDivDebitMT, tOpeDivFK )
SELECT tPlanCompta.tPlanPK, solde([PlanCpte],[LaDate]) AS Mvt, [CleOpeDiv] AS Cle
FROM tPlanCompta
WHERE (((solde([PlanCpte],[LaDate]))>0.001) And ((tPlanCompta.PlanCpte)>=6000 And (tPlanCompta.PlanCpte)<=7999))
ORDER BY tPlanCompta.PlanCpte;

43-47 : on procède de manière semblable pour solder les comptes de résultat actuellement débiteurs.

50-67 : « 1100 Report à nouveau » est la contrepartie de ces débits et crédits de remise à zéro des comptes de résultat.

52-53 : on calcule le résultat. Si la somme des débits de mise à zéro est supérieure à celle des crédits, nous sommes en bénéfice, sinon en perte.

56-59 : dans le cas d'un bénéfice, on exécute la requête rCloPPReportBenef :

PARAMETERS [ReportANouveau] IEEEDouble, [CleOpeDiv] Long;
INSERT INTO tOpeDivCredits ( OpeDivCreditMT, tOpeDivFK, tPlanFK )
SELECT [ReportANouveau] AS benef, [CleOpeDiv] AS Cle, 2 AS NumCpte;

62-67 : idem mutatis mutandis s'il s'agit d'une perte.

IX - Téléchargement

La base de données se trouve ici. Vous devez décompresser l'archive dans un répertoire quelconque qui inclura le sous-dossier Images.

X - Remerciements

Ma gratitude à Joseph de l'association vidica qui a eu la patience de m'expliquer en détail le fonctionnement de son association.

Merci aux utilisateurs de cette application de me signaler les erreurs et lacunes éventuelles.

Merci aussi à Christophe LOUVET, Denis Hulo (User), Pierre Fauconnier et Winjerome pour leurs remarques.

Merci à Jacques Thery pour sa correction orthographique.

(1)À un crédit inscrit à l'extrait reçu de la banque correspond un débit dans notre comptabilité, d'où la symétrie des soldes.