Excel : collecter des données juridiques sur les entreprises avec l’API SIRENE – 2ème partie : base SIRET (établissements)

Dans un monde économique aussi mouvant où les crises de succèdent aussi rapidement, les entreprises ont besoin d’obtenir et de maintenir des informations financières et juridiques, fiables et en permanence à jour, sur leurs partenaires (clients, fournisseurs…). Que ce soit pour créer ou mettre à jour des fiches tiers (outil stratégique dans le cadre de la dématérialisation de la facturation, documentation de la conformité Sapin 2), accorder du crédit à des clients actuels ou nouveaux (évaluation du risque de défaillance, solvabilité…).

API SIRENE SIRET XL

Le répertoire SIRENE (Système Informatique pour le Répertoire des ENtreprises et des Etablissements) dont la gestion est confiée à l’INSEE permet de télécharger ses données notamment sous forme de fichier texte. L’INSEE est ainsi chargé d’identifier les entreprises au sens large et plus précisément les entrepreneurs individuels, les personnes morales soumises au droit commercial, les institutions et services de l’État et les collectivités territoriales, certaines associations. Toutes les mises à jour d’entreprises et d’établissements (créations, modifications, cessations) enregistrés dans SIRENE proviennent des informations déclaratives des entreprises auprès du Guichet Unique et de certains Centres de Formalités des Entreprises (CFE).

Le répertoire SIRENE est interrogeable par API (Application Programming Interface ou interface de programmation applicative) à partir d’un numéro SIREN (entreprise ou unité légale) ou d’un SIRET (établissement d’une entreprise).

Une API assure l’interface entre deux systèmes. Par exemple, les logiciels de paye télétransmettent les Déclarations Sociales Nominatives (DSN) vers les serveurs de l’État par l’intermédiaire d’une API. Le fonctionnement d’une API est simple. Un logiciel envoie une requête à un site internet ou à un autre logiciel par le biais de son API. Le site internet exécute la requête, interroge ses bases de données et renvoie le résultat au logiciel, qui intègre les données reçues dans son processus de calcul. Les API assurent ainsi l’interaction entre des logiciels d’éditeurs différents.

>>> Pour aller plus loin : Le principe de la diffusion en ligne avec autorisation de rediffusion gratuite (ou open data) des données du registre national du commerce et des sociétés (RNCS, fourni par l’INPI) et du fichier SIRENE (fourni par l’INSEE) a été acté par la loi Macron du 6 août 2015. Le site Data Inpi, lancé en décembre 2019, a mis en oeuvre la diffusion de ces données. L’INPI propose désormais une API ainsi qu’un FTP. A partir de ces moyens de diffusion, tout opérateur privé a la possibilité d’intégrer ces données dans ses propres produits, commerciaux ou gratuits, et de les rediffuser à sa guise. Plusieurs acteurs privés ont commencé à occuper ce nouveau champ des possibles, à l’image de Pappers ou de Société.Ninja.

Le présent article propose au lecteur de créer un classeur Excel doté d’un code VBA qui interroge le répertoire SIRENE. Il sera composé de deux parties :

Prérequis : obtention d’une clef d’identification :

Pour utiliser l’API SIRENE, il est nécessaire d’obtenir gratuitement une clef d’identification (token) à insérer dans le code site des API SIRENE. Sans ce token, le code VBA et le classeur Excel seront inopérants. Plus de détails : cliquer ici.

Le code VBA :

Le code VBA est pour une bonne part commun à celui de SIREN (cf la 1ère partie de cet article) et présente quelques particularités marginales liées au numéro SIRET.

'-----------------------------------------------------------------------------------------------------------------------
'  Collecte de données d'entreprises à l'aide de l'API SIRENE
'  Ecrit par Benoît RIVIERE, v1 10/2023
'
'  Plus d'infos : https://www.auditsi.eu/?p=11941
'-----------------------------------------------------------------------------------------------------------------------


Option Explicit


'Déclaration des constantes
'---URL de l'API Sirene
Const URL_API_SIRENE = "https://api.insee.fr/entreprises/sirene/V3/"


'-----------------------------------------------------------------------------------------------------------------------
' Contrôle de la validité d'un numéro SIREN
' Infos : https://www.auditsi.eu/?p=11607
'-----------------------------------------------------------------------------------------------------------------------
'Algorithme de Luhn applicable aux numéros SIREN et SIRET
'-----------------------------------------------------------------------------------------------------------------------

'Vérifie la clef de contrôle d'une chaîne (qui contient la clef) selon l'algorithme de Luhn
Private Function VérifieClefLuhn(Chaîne As String) As Boolean
    'Déclaration des variables
    Dim LongueurChaîne As Integer
    Dim i As Integer
    Dim Position As Integer
    Dim Chiffre As Integer
    Dim Addition As Integer
        
    'Calcule le nombre de caractères de la Chaîne
    LongueurChaîne = Len(Chaîne)
    
    Addition = 0
    Position = 0
    
    'Parcourt chaque chiffre de la variable Chaîne de droite à gauche
    For i = LongueurChaîne To 1 Step -1
        Position = Position + 1
        
        'Lit le chiffre en cours (position i dans la Chaîne)
        Chiffre = CInt(Mid(Chaîne, i, 1))
        
        'Si la position est paire (à partir de la droite), multiplier par 2
        If Position Mod 2 = 0 Then 'si le reste de la division i/2= 0 -> position paire sinon impaire
            Chiffre = Chiffre * 2
            'Si le résultat de la multiplication est supérieur à 9, soustraire 9
            If Chiffre > 9 Then
                Chiffre = Chiffre - 9
            End If
        End If
        
        'Additionne les chiffres au fur et à mesure de l'exécution de la boucle (impairs*2 + pairs)
        Addition = Addition + Chiffre
    Next i
    
    'Calcule la clef de contrôle
    VérifieClefLuhn = (Addition Mod 10) = 0
End Function

'Vérifie la validité de la clef contenue dans un numéro SIREN
'   Valeur de retour :
'       - VRAI : clef correcte
'       - FAUX : clef erronnée ou longueur du numéro SIREN fourni <> 9
Function VérifieClefLuhn_SIREN(Chaîne As String) As Boolean
    Select Case Len(Chaîne)
        Case 9:
            VérifieClefLuhn_SIREN = VérifieClefLuhn(Chaîne)
        Case Else:
            VérifieClefLuhn_SIREN = False
    End Select
End Function

'Vérifie la validité de la clef contenue dans un numéro SIRET
'   Valeur de retour :
'       - VRAI : clef correcte
'       - FAUX : clef erronnée ou longueur du numéro SIRET fourni <> 14
Function VérifieClefLuhn_SIRET(Chaîne As String) As Boolean
    Select Case Len(Chaîne)
        Case 14:
            VérifieClefLuhn_SIRET = VérifieClefLuhn(Chaîne)
        Case Else:
            VérifieClefLuhn_SIRET = False
    End Select
End Function


'-----------------------------------------------------------------------------------------------------------------------
' Contrôle de la validité d'un numéro SIREN
' Infos : https://www.auditsi.eu/?p=11620
'-----------------------------------------------------------------------------------------------------------------------
'Algorithme de Luhn applicable aux numéros SIREN et SIRET
'-----------------------------------------------------------------------------------------------------------------------

'Calcule la clef de contrôle d'une chaîne (qui ne contient pas la clef) selon l'algorithme de Luhn
Private Function CalculeClefLuhn(Chaîne As String) As Integer
    'Déclaration des variables
    Dim LongueurChaîne As Integer
    Dim i As Integer
    Dim Position As Integer
    Dim Chiffre As Integer
    Dim Addition As Integer
        
    'Calcule le nombre de caractères de la Chaîne
    LongueurChaîne = Len(Chaîne)
    
    Addition = 0
    
    'Parcourt chaque chiffre de la variable Chaîne de droite à gauche
    For i = LongueurChaîne To 1 Step -1
        Position = Position + 1
        
        'Lit le chiffre en cours (position i dans la Chaîne)
        Chiffre = CInt(Mid(Chaîne, i, 1))
        
        'Si la position est paire (à partir de la droite), multiplier par 2
        If Position Mod 2 <> 0 Then 'si le reste de la division i/2= 0 -> position paire sinon impaire
            Chiffre = Chiffre * 2
            'Si le résultat de la multiplication est supérieur à 9, soustraire 9
            If Chiffre > 9 Then
                Chiffre = Chiffre - 9
            End If
        End If
        
        'Additionne les chiffres au fur et à mesure de l'exécution de la boucle (impairs*2 + pairs)
        Addition = Addition + Chiffre
    Next i
    
    'Calcule la clef de contrôle
    CalculeClefLuhn = (10 - (Addition Mod 10)) Mod 10
End Function


'Calcule la clef d'un numéro SIRET (13 caractères)
'   Valeur de retour :
'       - chiffre positif de 0 à 9 : clef de contrôle
'       - -1                       : longueur du numéro SIRET fourni (sans clef de contrôle) <> 13
Function CalculeClefLuhn_SIRET(Chaîne As String) As Integer
    Select Case Len(Chaîne)
        Case 13:
            CalculeClefLuhn_SIRET = CalculeClefLuhn(Chaîne)
        Case Else:
            CalculeClefLuhn_SIRET = -1
    End Select
End Function


'Calcule un numéro SIRET (14 caractères) à partir de deux paramètres : le n° SIREN et le n° d'établissement
'   Valeur de retour :
'       - N° SIRET sur 14 caractères
'       - -1                       : longueur du numéro SIRET fourni (sans clef de contrôle) <> 13
Function Calcule_SIRET(SIREN As String, Etablissement As Integer) As Variant
Dim SIRET13 As String
    SIRET13 = SIREN & Format(Etablissement, "0000")
    Select Case Len(SIRET13)
        Case 13:
            Calcule_SIRET = SIRET13 & CStr(CalculeClefLuhn_SIRET(SIRET13))
        Case Else:
            Calcule_SIRET = -1
    End Select
End Function


'-----------------------------------------------------------------------------------------------------------------------
'Interrogation et collecte des données de l'API SIRENE
Function Interrogation_API_SIRENE(SIREN_ou_SIRET As String, Clef_API_SIRENE As String) As String
    Dim Type_Numéro As String
    Dim Requête_XMLHTTP As Object
    Dim Réponse_Requête As Variant
    Dim Statut_Requête As Integer
    Dim Message_Erreur As String
    
    'Test de la validité du n° SIREN ou du n° SIRET
    '(en cas de non conformité : retour d'un message d'erreur)
    Select Case Len(SIREN_ou_SIRET)
        Case 9:
            If VérifieClefLuhn_SIREN(SIREN_ou_SIRET) = False Then
                Interrogation_API_SIRENE = "Erreur 999. Numéro SIREN " & SIREN_ou_SIRET & " non conforme"
                Exit Function
            End If
            Type_Numéro = "siren"
        Case 14:
            If VérifieClefLuhn_SIRET(SIREN_ou_SIRET) = False Then
                Interrogation_API_SIRENE = "Erreur 998. Numéro SIRET " & SIREN_ou_SIRET & " non conforme"
                Exit Function
            End If
            Type_Numéro = "siret"
        Case Else:
            Interrogation_API_SIRENE = "Erreur 997. Longueur numéro SIREN / SIRET " & SIREN_ou_SIRET & " non conforme"
            Exit Function
    End Select
        
    'Création de l'objet Requête_XMLHTTP pour effectuer la requête sur l'API SIRENE
    Set Requête_XMLHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    
    'Création et envoi de la requête
    With Requête_XMLHTTP
        'Envoi de la requête GET à l'API SIRENE
        .Open "GET", URL_API_SIRENE & Type_Numéro & "/" & SIREN_ou_SIRET, False
        'Authentification à l'aide de la clef (token)
        .SetRequestHeader "Authorization", "Bearer " & Clef_API_SIRENE
        'Envoi de la requête
        .Send
        'Réception de la réponse
        Réponse_Requête = .ResponseText
        'Statut de la requête
        Statut_Requête = .Status '200 = Ok sinon statut en erreur
    End With
    
    'Libère l'objet Requête_XMLHTTP
    Set Requête_XMLHTTP = Nothing
    
    'En fonction du statut de la réponse...
    Select Case Statut_Requête
        Case 200:  '...statut Ok -> retourne le résultat de la requête
            'Remplace les données Null par "" (chaîne vide)
            Réponse_Requête = Replace(Réponse_Requête, "null", "")
            'Retourne ke texte de la réponse
            Interrogation_API_SIRENE = Réponse_Requête
        Case Else: '...statut en erreur -> retourne un message d'erreur
            Select Case Statut_Requête
                Case 400:
                    Message_Erreur = "Nombre incorrect de paramètres ou les paramètres sont mal formatés"
                Case 401:
                    Message_Erreur = "Jeton d'accès manquant ou invalide"
                Case 404:
                    Message_Erreur = "Entreprise non trouvée dans la base Sirene"
                Case 406:
                    Message_Erreur = "Le paramètre 'Accept' de l'en-tête HTTP contient une valeur non prévue"
                Case 414:
                    Message_Erreur = "Requête trop longue"
                Case 429:
                    Message_Erreur = "Quota d'interrogations de l'API dépassé"
                Case 500:
                    Message_Erreur = "Erreur interne du serveur"
                Case 503:
                    Message_Erreur = "Service indisponible"
            End Select
            Message_Erreur = "Erreur " & Statut_Requête & ". " & Message_Erreur
            Interrogation_API_SIRENE = Message_Erreur
    End Select
End Function


'-----------------------------------------------------------------------------------------------------------------------
'Extraction des données
'Informations sur cette fonction : https://www.auditsi.eu/?p=9377
Function Extraction_Champ_API_SIRENE(Réponse_Requête_SIRENE As Variant, NomChamp As String) As Variant
    Dim PositionDébut As Long
    Dim NomChamp_A_rechercher As String
    Dim Donnée As Variant
    
    NomChamp_A_rechercher = Chr(34) & NomChamp & Chr(34) & ":"
    
    PositionDébut = InStr(Réponse_Requête_SIRENE, NomChamp_A_rechercher)
    
    Select Case PositionDébut
        Case 0: 'champ non trouvé -> retour vide
            Extraction_Champ_API_SIRENE = ""
        Case Else: 'sinon retourne la donnée correspondante
            PositionDébut = PositionDébut + Len(NomChamp_A_rechercher)
            Donnée = Replace(Mid(Réponse_Requête_SIRENE, PositionDébut, InStr(Right(Réponse_Requête_SIRENE, Len(Réponse_Requête_SIRENE) - PositionDébut + 1), ",") - 1), Chr(34), "")
            Select Case NomChamp
                Case "dateCreationUniteLegale", "dateDernierTraitementUniteLegale", "dateSuppressionUniteLegale":
                    Donnée = Left(Donnée, 10)
                    Donnée = CDate(Right(Donnée, 2) & "/" & Mid(Donnée, 6, 2) & "/" & Left(Donnée, 4))
            End Select
            Extraction_Champ_API_SIRENE = Donnée
    End Select
End Function

Le classeur Excel :

Le classeur Excel est proposé en libre téléchargement en bas de cette page.

La cellule B31 comprend le numéro SIRET qui sera interrogé. Il peut être saisi manuellement par l’utilisateur. Mais, dans notre exemple, il est constitué du numéro SIREN saisi en cellule B6 auquel est adjoint (par l’esperluette &) le code NIC du siège social de l’entreprise stocké en cellule C13 (obtenu par la formule =Extraction_Champ_API_SIRENE($B$7;B13)) afi d’obtenir le numéro SIRET du siège social :

=B6&C13

La base du classeur Excel et les fonctions créées par le code VBA sont communes avec le traitement des entreprises (SIREN) présentées en première partie.

Ainsi, pour interroger l’API SIRENE à partir du numéro SIRET, la cellule B32 contient la formule suivante :

=Interrogation_API_SIRENE($B$31;$B$2)

L’interrogation d’un numéro SIRET et d’un numéro SIREN (cf 1ère partie de cet article) sont réalisées par la même fonction (Interrogation_API_SIRENE). Cette fonction reconnaît automatiquement  la nature du numéro en fonction de sa longueur (9 = SIREN, 14 = SIRET à l’aide de la fonction Len()).

La réponse retournée par le serveur SIRENE prend la même forme que pour un numéro SIREN avec toutefois des champs de données propres au numéro SIRET (base des établissements) :

{“header”:{“statut”:200,”message”:”ok”},”etablissement”:{“siren”:”312212301″,”nic”:”02001″,”siret”:”31221230102001″,”statutDiffusionEtablissement”:”O”,”dateCreationEtablissement”:”2011-10-13″,”trancheEffectifsEtablissement”:”22″,”anneeEffectifsEtablissement”:”2020″,”activitePrincipaleRegistreMetiersEtablissement”:,”dateDernierTraitementEtablissement”:”2023-07-19T03:41:07″,”etablissementSiege”:true,”nombrePeriodesEtablissement”:2,”uniteLegale”:{“etatAdministratifUniteLegale”:”A”,”statutDiffusionUniteLegale”:”O”,”dateCreationUniteLegale”:”1978-01-01″,”categorieJuridiqueUniteLegale”:”5599″,”denominationUniteLegale”:”RENAULT RETAIL GROUP”,”sigleUniteLegale”:,”denominationUsuelle1UniteLegale”:,”denominationUsuelle2UniteLegale”:,”denominationUsuelle3UniteLegale”:,”sexeUniteLegale”:,”nomUniteLegale”:,”nomUsageUniteLegale”:,”prenom1UniteLegale”:,”prenom2UniteLegale”:,”prenom3UniteLegale”:,”prenom4UniteLegale”:,”prenomUsuelUniteLegale”:,”pseudonymeUniteLegale”:,“activitePrincipaleUniteLegale”:”45.11Z”,”nomenclatureActivitePrincipaleUniteLegale”:”NAFRev2″,”identifiantAssociationUniteLegale”:,”economieSocialeSolidaireUniteLegale”:”N”,”societeMissionUniteLegale”:”N”,”caractereEmployeurUniteLegale”:”O”,”trancheEffectifsUniteLegale”:”52″,”anneeEffectifsUniteLegale”:”2020″,”nicSiegeUniteLegale”:”02001″,”dateDernierTraitementUniteLegale”:”2023-10-12T11:09:32″,”categorieEntreprise”:”GE”,”anneeCategorieEntreprise”:”2020″},”adresseEtablissement”:{“complementAdresseEtablissement”:”1ER-2E ETAGE”,”numeroVoieEtablissement”:”2″,”indiceRepetitionEtablissement”:,”typeVoieEtablissement”:”AV”,”libelleVoieEtablissement”:”DENIS PAPIN”,“codePostalEtablissement”:”92140″,”libelleCommuneEtablissement”:”CLAMART”,”libelleCommuneEtrangerEtablissement”:,”distributionSpecialeEtablissement”:,“codeCommuneEtablissement”:”92023″,”codeCedexEtablissement”:,”libelleCedexEtablissement”:,”codePaysEtrangerEtablissement”:,”libellePaysEtrangerEtablissement”:},”adresse2Etablissement”:{“complementAdresse2Etablissement”:,”numeroVoie2Etablissement”:,”indiceRepetition2Etablissement”:,”typeVoie2Etablissement”:,”libelleVoie2Etablissement”:,”codePostal2Etablissement”:,”libelleCommune2Etablissement”:,”libelleCommuneEtranger2Etablissement”:,”distributionSpeciale2Etablissement”:,”codeCommune2Etablissement”:,”codeCedex2Etablissement”:,”libelleCedex2Etablissement”:,”codePaysEtranger2Etablissement”:,”libellePaysEtranger2Etablissement”:},”periodesEtablissement”:[{“dateFin”:,”dateDebut”:”2012-12-01″,”etatAdministratifEtablissement”:”A”,”changementEtatAdministratifEtablissement”:false,”enseigne1Etablissement”:,”enseigne2Etablissement”:,”enseigne3Etablissement”:,”changementEnseigneEtablissement”:false,”denominationUsuelleEtablissement”:,”changementDenominationUsuelleEtablissement”:false,”activitePrincipaleEtablissement”:”70.10Z”,”nomenclatureActivitePrincipaleEtablissement”:”NAFRev2″,”changementActivitePrincipaleEtablissement”:true,”caractereEmployeurEtablissement”:”O”,”changementCaractereEmployeurEtablissement”:false},{“dateFin”:”2012-11-30″,”dateDebut”:”2011-10-13″,”etatAdministratifEtablissement”:”A”,”changementEtatAdministratifEtablissement”:false,”enseigne1Etablissement”:,”enseigne2Etablissement”:,”enseigne3Etablissement”:,”changementEnseigneEtablissement”:false,”denominationUsuelleEtablissement”:,”changementDenominationUsuelleEtablissement”:false,”activitePrincipaleEtablissement”:”45.11Z”,”nomenclatureActivitePrincipaleEtablissement”:”NAFRev2″,”changementActivitePrincipaleEtablissement”:false,”caractereEmployeurEtablissement”:”O”,”changementCaractereEmployeurEtablissement”:false}]}}

La lecture des champs de données s’opère également avec la fonction Extraction_Champ_API_SIRENE, ainsi pour lire le code postal de l’établissement (nom du champ : codePostalEtablissement) :

=Extraction_Champ_API_SIRENE($B$32;B41)

Le premier paramètre correspond à la réponse SIRENE (située ici en cellule B32 et le deuxième au nom du champ de données à extraire (ici codePostalEtablissement). Le résultat correspondant est : 92140.

Les principaux champs de données intéressants d’un établissement :

  • Les champs permettant de reconstituer l’adresse de l’établissement : complementAdresseEtablissement, numeroVoieEtablissement, indiceRepetitionEtablissement,
    typeVoieEtablissement, libelleVoieEtablissement, codePostalEtablissement, libelleCommuneEtablissement, libelleCommuneEtrangerEtablissement,
    distributionSpecialeEtablissement, codePaysEtrangerEtablissement, libellePaysEtrangerEtablissement, codeCedexEtablissement, libelleCedexEtablissement
  • Code INSEE de la commune de l’établissement : codeCommuneEtablissement
  • Etat administratif de l’établissement (Actif ou Cessé) : etatAdministratifEtablissement
  • En cas de reprise ou cession d’établissement : siretEtablissementPredecesseur, siretEtablissementSuccesseur, dateLienSuccession

La liste complète des champs de données disponibles consultable sur le site SIRENE.

Exemple d’utilisation : reconstituer l’adresse du siège social :

ADRESSE SIEGE SOCIAL

Autres moyens permettant de consulter des informations sur les entreprises :

___

Pour aller plus loin : articles en rapport avec SIRENE, SIREN, SIRET / Publicité légale des entreprises / API / Open Data

Share Button
Fonction API SIRENE - 2ème Partie SIRET
Fonction API SIRENE - 2ème Partie SIRET
Fonction-API-SIRENE-2eme-partie-SIRET.xlsm
33 KiB
25 téléchargements
Détails...
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

2 commentaires

  1. Bonjour,
    Les articles sont toujours aussi passionnants.
    J’avais récupéré la macro d’un précédent billet consacré à Pappers, puis je l’avais transcodifiée afin de collecter les données en masse de la base SIRENE. Celle-ci a l’avantage d’être gratuite pour un nombre illimitée de requêtes toutefois bridées à 30 interrogations par minute.
    L’objectif était de recouper les informations de nos bases clients et fournisseurs avec celles issues de l’INSEE ou encore de compléter la DAS avec les bonnes adresses et les bons codes NAF.
    Une version SIRENE 3.11 est disponible depuis le début de l’année 2024. Elle contient désormais les coordonnées Lambert des établissements qui peuvent servir à ceux travaillant dans le transport et ou la logistique.

    Vivement le prochain article !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

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