Automatiser la génération des écritures d’achat intragroupe et les intégrer dans un système comptable

La programmation informatique est une source inépuisable de gains de productivité. Appliquée aux métiers de la comptabilité et de la finance, les programmes limitent, entre autres, le temps passé à la saisie d’écritures pour recentrer le travail des équipes comptables sur des tâches de contrôle et d’analyse. Ce sujet est régulièrement à l’honneur sur ce blog. En voici un exemple supplémentaire, s’il était encore nécessaire d’en donner : l’automatisation de la comptabilisation des écritures d’achat intragroupe à l’aide d’un programme en VBA.

Dans cet exemple, une société centralise une partie des achats (regroupement d’achats à prix négociés…) pour le compte de ses filiales. Ces achats représentent un volume mensuel d’une centaine de factures. Ces achats sont ensuite refacturés à prix coûtant aux filiales en fonction de leur quote-part de consommation. Les opérations de saisie comptable d’achats par la société centralisatrice et de refacturation puis de comptabilisation d’achats chez les filiales mobilisent beaucoup de ressources (temps des comptables passé à saisir des données à de multiples reprises) pour une valeur ajoutée nulle.

Trame de saisie des achats

Fonctionnalités du programme

Le programme dont le code-source est reproduit ci-après se propose d’automatiser les tâches de comptabilisation des achats. Pour ce faire, la saisie des factures d’achat est synthétisée dans une feuille de travail Excel. Les données à saisir (cellules en jaune) sont d’une part, le détail des factures d’achat (date, numéro de facture, montant HT…), les comptes généraux (nature de charge, TVA, centralisateur tiers), le code tiers et d’autre part, la ventilation des achats à refacturer par filiale. Ensuite, à partir de cette feuille de calcul, une macro rédigée en VBA génère les fichiers d’écritures d’achat à intégrer dans la comptabilité de la holding et de ses filiales. Ne reste alors plus qu’à émettre les factures entre la holding et ses filiales dans le système de gestion commerciale.

Fichier d’import généré pour la centralisatrice :

Achats chez la mère

Fichier d’import généré pour l’une des filiales :

Achats chez l'utilisatrice

Prérequis à l’importation des écritures dans le logiciel de comptabilité

Il est nécessaire de créer un journal d’achat spécifique (ici, ACHI pour achats comptabilisés par importation de données) dans la comptabilité de toutes les sociétés parties prenantes afin de faciliter les opérations de contrôle d’intégration de données (rapprochement entre les données Excel et les données intégrées dans le journal d’achat). En effet, dès lors que des données sont intégrées dans un système comptable, il est hautement conseillé de créer des journaux spécifiques pour chacune des interfaces (il en est ainsi par exemple pour les écritures importées depuis la paye, la gestion commerciale, le logiciel de gestion des immobilisations…).

L’intégration de données dans un système comptable (ici SAGE 100 Comptabilité i7) nécessite la création d’un format d’importation des écritures comptables (menu Fichier / format Import/Export paramétrable…). Deux éléments sont à paramétrer : les champs de données et le format du fichier.

Concernant les champs de données, il s’agit de champs classiques décrivant des écritures comptables : date d’écritures, compte général, libellé d’écriture…

Définition des champs à importer dans SAGE 100 Comptabilité i7

Définition des champs à importer dans SAGE 100 Comptabilité i7

Concernant le format de fichier (ici un format délimité CSV), le délimiteur de champ est le point-virgule et la décimale est matérialisée par la virgule (conventions usuellement retenues en France).

Définition du format de fichier à importer dans SAGE 100 Comptabilité i7

Définition du format de fichier à importer dans SAGE 100 Comptabilité i7

L’uniformisation du plan comptable des différentes sociétés facilite grandement la programmation de la génération des fichiers d’écritures comptables (en évitant l’usage de tables de correspondance).

Importation des écritures comptables dans SAGE 100

Entrer successivement dans chacune des comptabilités concernées et à partir du menu Fichier / Importer un fichier au format paramétrable, sélectionner le format de fichier nouvellement créé et importer les fichiers créés par le programme VBA. La dernière étape consiste à consulter le journal d’importation pour s’assurer que SAGE 100 n’a pas rencontré de difficulté puis à s’assurer de l’exhaustivité des données importées (rapprocher les totaux débit / crédit du journal ACHI avec la totalisations du fichier importé).

Conclusion

En plus d’assurer des gains de productivité, ce programme fiabilise la comptabilisation des flux intragroupes (montants et dates de comptabilisation) limitant de ce fait les écarts de solde lors de la réconciliation des intercompagnies.

Cet exemple d’automatisation de process comptable est duplicable à l’envi dès lors que des opérations intragroupe sont concernées : mouvements sur comptes courants entre société mère et filiales, facturations de prestations…

La dématérialisation des flux documentaires (EDI factures, lecture OCR de factures “papier”, lecture de factures PDF signées numériquement, envoi de factures vers le portail public CHORUS…) et le développement de l’intelligence artificielle vont radicalement faire progresser ces gains de productivité dans les années à venir.

Code-source du programme écrit en VBA :

'Module de génération des écritures d'achats MMOT à refacturer aux filiales
'V1.0, 12/2017
'Programmé par Benoît RIVIERE

Option Explicit

Option Base 1

Const Adresse_Mois = "B3"
Const Adresse_Année = "B4"
Const Adresse_Période = "B5"
Const Adresse_DateRefact = "C7"
Const Adresse_DateEchRefact = "E7"
Const Adresse_TxTVARefact = "B9"
Const Adresse_EntitéRefact = "B10"
Const Adresse_CodeJalAch = "B12"
Const Plage_ListeCodeTiersRefact = "N5:R12"
Const Plage_ListeFactures = "D17:O5000"

Dim Mois As String
Dim Année As String
Dim Période As String
Dim DateRefact As String
Dim DateEchRefact As String
Dim TxTVARefact As String
Dim EntitéRefact As String
Dim CodeJalAch As String
Dim Table_ListeCodeTiersRefact As Variant
Dim Table_ListeFactures As Variant

Dim Table_EcrituresAExporter() As Variant
Const Champ_EcrituresAExporter_Jal = 1
Const Champ_EcrituresAExporter_Date = 2
Const Champ_EcrituresAExporter_CpteGal = 3
Const Champ_EcrituresAExporter_CodeTiers = 4
Const Champ_EcrituresAExporter_LibEcrit = 5
Const Champ_EcrituresAExporter_Mt = 6
Const Champ_EcrituresAExporter_Réf = 7
Const Champ_EcrituresAExporter_NumPièce = 8
Const Champ_EcrituresAExporter_NumFre = 9
Const Champ_EcrituresAExporter_DateEch = 10

Dim Chemin As String

Dim i As Integer
Dim j As Integer
Dim k As Integer

Dim NumEntitéEnCours As Integer
Dim EntitéEnCours As String
Dim TotalHT As Double

Sub Traitements()
    With ActiveWorkbook
        Chemin = .Path
        With .Sheets(1)
            Mois = .Range(Adresse_Mois).Value
            Année = .Range(Adresse_Année).Value
            Période = .Range(Adresse_Période).Value
            DateRefact = .Range(Adresse_DateRefact).Value
            DateEchRefact = .Range(Adresse_DateEchRefact).Value
            TxTVARefact = .Range(Adresse_TxTVARefact).Value
            EntitéRefact = .Range(Adresse_EntitéRefact).Value
            CodeJalAch = .Range(Adresse_CodeJalAch).Value
            Table_ListeCodeTiersRefact = .Range(Plage_ListeCodeTiersRefact).Value
            Table_ListeFactures = .Range(Plage_ListeFactures).Value
        End With
    End With
    
    For NumEntitéEnCours = 1 To UBound(Table_ListeCodeTiersRefact) + 1
        'RAZ total HT
        TotalHT = 0
        'Code entité en cours de traitement
        Select Case NumEntitéEnCours
            Case UBound(Table_ListeCodeTiersRefact) + 1:
                EntitéEnCours = EntitéRefact
            Case Else:
                EntitéEnCours = Table_ListeCodeTiersRefact(NumEntitéEnCours, 1)
        End Select
        'Collecte des lignes d'écritures concernant l'entité en cours de traitement
        ReDim Table_EcrituresAExporter(UBound(Table_ListeFactures, 1), 10)
        i = 1
        k = 1
        Do
            If (Table_ListeFactures(i, 1) = EntitéEnCours) And (Table_ListeFactures(i, 8) <> 0) Then 'uniquement si mt <>0
                For j = 1 To 10
                    Table_EcrituresAExporter(k, j) = Table_ListeFactures(i, j + 2)
                Next j
                TotalHT = TotalHT + Table_ListeFactures(i, 8)
                'Si EntitéEnCours est une filiale refacturée -> certains champs sont personnalisés
                If EntitéEnCours <> EntitéRefact Then
                    Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Jal) = CodeJalAch
                    Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Date) = DateRefact
                    Table_EcrituresAExporter(k, Champ_EcrituresAExporter_CodeTiers) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 2)
                    Table_EcrituresAExporter(k, Champ_EcrituresAExporter_LibEcrit) = EntitéRefact & "/QP " & Table_EcrituresAExporter(k, Champ_EcrituresAExporter_LibEcrit)
                    Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Réf) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 3)
                    Table_EcrituresAExporter(k, Champ_EcrituresAExporter_NumPièce) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 3)
                    Table_EcrituresAExporter(k, Champ_EcrituresAExporter_NumFre) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 3)
                End If
                k = k + 1
            End If
            i = i + 1
        Loop Until i > UBound(Table_ListeFactures)
        'Génération du fichier d'import uniquement si des lignes ont été collectées
        If TotalHT <> 0 Then
            'Ajout des lignes TVA et TTC pour les entités à refacturer
            If EntitéEnCours <> EntitéRefact Then
                'TVA
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Jal) = CodeJalAch
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Date) = DateRefact
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_CpteGal) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 5)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_CodeTiers) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 2)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_LibEcrit) = EntitéRefact & "/REFACT QP FRAIS " & Mois & "/" & Année
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Mt) = TotalHT * TxTVARefact
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Réf) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 3)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_NumPièce) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 3)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_NumFre) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 3)
                'DETTE FOURNISSEUR
                k = k + 1
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Jal) = CodeJalAch
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Date) = DateRefact
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_CpteGal) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 4)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_CodeTiers) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 2)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_LibEcrit) = EntitéRefact & "/REFACT QP FRAIS " & Mois & "/" & Année
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Mt) = -TotalHT * (1 + TxTVARefact)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_Réf) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 3)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_NumPièce) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 3)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_NumFre) = Table_ListeCodeTiersRefact(NumEntitéEnCours, 3)
                Table_EcrituresAExporter(k, Champ_EcrituresAExporter_DateEch) = DateEchRefact
            End If
            'Génération du fichier d'import
            Workbooks.Add
            With ActiveSheet
                .Range("A1:J" & UBound(Table_EcrituresAExporter, 1)).Value = Table_EcrituresAExporter
                Application.DisplayAlerts = False
                .SaveAs Chemin & "\" & EntitéEnCours & " - Ecritures à importer " & Mois & "-" & Année, FileFormat:=xlCSV, CreateBackup:=False, Local:=True
                ActiveWorkbook.Close
                Application.DisplayAlerts = True
            End With
        End If
    Next NumEntitéEnCours
End Sub

Quelques explications sur le code-source :

La compréhension du fonctionnement de ce programme nécessite de connaître quelques notions de base de la programmation (découverte du langage Basic, manipulation de données et variables tableau…).

.SaveAs Chemin & "\" & EntitéEnCours & " - Ecritures à importer " & Mois & "-" & Année, FileFormat:=xlCSV, CreateBackup:=False, Local:=True

Celle ligne enregistre les écritures au format CSV (Comma Separated Value). Ce lien renvoie vers un article qui décrit les différentes étapes pour enregistrer des données dans un fichier au format CSV ainsi que les fonctionnalités des instructions .SaveAs, .Close et  Application.DisplayAlerts. L’assertion Local:=True retient les formats locaux du système d’exploitation (ici, les formats français) en lieu et place des formats américains standard comme caractéristiques de format du fichier de destination (à savoir, entre autres, délimiteur de champ point-virgule au lieu de la virgule et décimale virgule au lieu du point).

Tous les articles en rapport avec l’importation de données.

Approfondir le sujet : Programmer en VBA / Découvrir la série d’articles Maîtriser Excel

Share Button
The following two tabs change content below.
Après seize années passées en cabinet d’expertise-comptable et de commissariat aux comptes (où j’ai exercé comme expert-comptable et chef de mission audit), j’ai pris le poste de directeur comptable d’un groupe de distribution automobile en novembre 2014. Au cours de ma carrière, j’ai acquis une expérience significative en audit et en exploitation des systèmes d’information (analyse de données, automatisation des tâches, programmation informatique) au service de la production des comptes annuels et consolidés. C’est cette expérience personnelle et ma passion pour l’informatique que je partage sur ce blog. Mon CV / Réalisations personnelles et projets informatiques / Ma collection / Me contacter

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.