Créer des factures ZUGFeRD et XRechnung avec VB6, VB5 et VBA – liaison tardive et anticipée

Membres du SDK
ActualDeliveryDate_102 AddPaymentMeans() AddProduct_Comfort() AddTradePaymentTerms() AddTradeTax() BuyerAddressLine1 BuyerCity BuyerCountry BuyerName BuyerPostCode
Termes métier
BT-1 Invoice number BT-2 Invoice issue date BT-3 Invoice type code BT-5 Invoice currency code BT-31 Seller VAT identifier BT-72 Actual delivery date BG-25 Invoice line BG-23 VAT breakdown
Exemples de code
Ligne de commande, VB6 / VBScript (COM)
Publié le

En bref : les applications Visual Basic 6, Visual Basic 5 et VBA (Access, Excel, Word) créent des factures électroniques conformes à la EN 16931 (ZUGFeRD 2.x, Factur-X, XRechnung) via l'interface COM du SDK Aloaha ZUGFeRD. Une migration vers .NET n'est pas nécessaire. Deux voies sont possibles : la liaison tardive avec CreateObject("Aloaha_ZUGFeRD.XML"), sans référence, ou la liaison anticipée avec une référence à la bibliothèque de types « Aloaha ZUGFeRD Toolkit ». Votre programme crée la facture PDF comme auparavant ; le SDK écrit le XML et l'intègre dans le PDF (facture ZUGFeRD hybride, PDF/A-3).

Liaison tardive ou anticipée ?

Liaison tardiveLiaison anticipée
Créer l'objetSet alo = CreateObject("Aloaha_ZUGFeRD.XML")Set alo = New Aloaha_ZUGFeRD.XML
Référence dans le projetnonoui, « Aloaha ZUGFeRD Toolkit »
IntelliSense dans l'IDEnonoui
Contrôle des noms et des paramètresà l'exécutionà la compilation
Paramètres facultatifsles omettre en fin de liste
Enregistrement de la DLLnécessaire dans les deux cas – effectué par le programme d'installation du SDK

La liaison tardive est robuste lorsque vous distribuez sur de nombreux postes et fonctionne de la même manière en VBScript. La liaison anticipée est plus confortable pendant la programmation. Les deux utilisent les mêmes méthodes.

Prérequis

  • Windows avec .NET Framework 4.7.2 ou ultérieur.
  • SDK Aloaha ZUGFeRD depuis la page de téléchargement. Le programme d'installation du SDK (MSI) enregistre l'interface COM pour 32 et 64 bits.
  • Attention à l'architecture : les programmes VB5 et VB6 sont toujours en 32 bits. VBA s'exécute avec l'architecture d'Office – un Office 64 bits nécessite l'enregistrement 64 bits.
  • Distribution manuelle sans programme d'installation : enregistrez la DLL en tant qu'administrateur avec le Regasm de l'architecture correspondante – pour 32 bits depuis C:\Windows\Microsoft.NET\Framework\v4.0.30319\, pour 64 bits depuis Framework64 :
    regasm /codebase Aloaha_ZUGFeRD.dll
    Les fichiers nécessaires sont décrits dans Register libraries.
  • Autotest COM : le paquet zugferdbinaries.zip contient le script zugferd_com_test.vbs. Il vérifie l'enregistrement et l'architecture et crée l'objet à titre de test. Pour le test 32 bits sur un Windows 64 bits :
    C:\Windows\SysWOW64\cscript.exe //nologo zugferd_com_test.vbs
  • Clé de licence : vous obtenez une licence d'essai gratuite et complète par e-mail à info@aloaha.com.

Étape par étape

  1. Installer le SDK (ou enregistrer la DLL, voir ci-dessus).
  2. Créer l'objet, définir la clé de licence et le profil.
  3. Renseigner l'en-tête de facture, le vendeur, l'acheteur et les données de paiement.
  4. Ajouter les lignes dans une boucle (AddProduct_Comfort).
  5. Définir la ventilation de la TVA par taux (AddTradeTax) et les totaux (WriteTotals).
  6. Enregistrer le XML (SaveXML) et l'intégrer dans la facture PDF existante (MergeXMLIntoPDF).
  7. Contrôler la première facture avec un validateur – voir Comment contrôler ma XRechnung avant l'envoi ?

Toujours transmettre les montants avec un point décimal

Le SDK attend des montants sous forme de texte avec un point comme séparateur décimal ("59.50"). Avec des paramètres régionaux Windows français ou allemands, Format$ écrit une virgule. Cette fonction d'aide (Betrag = montant) fonctionne en VB5, VB6 et VBA (VB5 ne connaît pas encore Replace) :

Public Function Betrag(ByVal Wert As Double) As String
    Dim s As String, p As Integer
    s = Format$(Wert, "0.00")
    p = InStr(s, ",")
    If p > 0 Then Mid$(s, p, 1) = "."
    Betrag = s
End Function

Variante 1 : liaison tardive avec CreateObject

Public Sub ErzeugeERechnung_LateBinding()
    Dim alo As Object
    Set alo = CreateObject("Aloaha_ZUGFeRD.XML")
    alo.Licensekey = "VOTRE-CLE-DE-LICENCE"
    alo.ZUGFeRD_Profile = 1                        ' 0 = BASIC, 1 = EN 16931 (COMFORT), 2 = EXTENDED

    ' en-tête : numéro (BT-1), texte, date (BT-2), format de date, nom, langue, devise (BT-5)
    Call alo.CreateInvoiceObject("RE-2027-0001", "Invoice as per order", _
                                 "20270104", "102", "", "DE", "EUR")
    alo.Document_TypeINT = 380                     ' BT-3 : 380 = facture, 381 = avoir
    alo.ActualDeliveryDate_102 = "20270104"        ' BT-72 : date de livraison

    ' vendeur avec numéro de TVA (BT-31)
    alo.WriteSeller "Muster GmbH", "20095", "Hamburg", "Hauptstr. 1", "", "DE", "DE123456789"

    ' acheteur
    alo.BuyerName = "Kunde AG"
    alo.BuyerAddressLine1 = "Marktplatz 5"
    alo.BuyerPostCode = "80331"
    alo.BuyerCity = "München"
    alo.BuyerCountry = "DE"

    ' paiement : 58 = virement SEPA (BT-81)
    alo.AddPaymentMeans 58, "SEPA credit transfer", "DE02120300000000202051", _
                        "Muster GmbH", "", "BYLADEM1001"
    alo.AddTradePaymentTerms "Payable within 30 days net"

    ' ligne (BG-25) : 10 pièces à 5,00 EUR, 19 %
    Call alo.AddProduct_Comfort(1, "", "ART-100", "10.00", "C62", "Paper A4", "500 sheets", _
                                "", "EUR", "", "C62", False, "", "", "", Betrag(5), "EUR", "1.00", _
                                "C62", "VAT", "S", "19.00", "", Betrag(50), "EUR", "", "")

    ' ventilation TVA (BG-23) : taxe, devise, base, devise, type, catégorie, taux
    alo.AddTradeTax Betrag(9.5), "EUR", Betrag(50), "EUR", "VAT", "S", "19.00"

    ' totaux (BG-22) : lignes, total TTC, montant dû, net, taxe
    alo.WriteTotals Betrag(50), Betrag(59.5), Betrag(59.5), Betrag(50), Betrag(9.5)

    ' enregistrer le XML et l'intégrer dans la facture PDF existante
    If alo.SaveXML("C:\Invoices\RE-2027-0001.xml") Then
        Call alo.MergeXMLIntoPDF("C:\Invoices\RE-2027-0001.xml", _
                                 "C:\Invoices\RE-2027-0001.pdf", _
                                 "C:\Invoices\RE-2027-0001_zugferd.pdf", _
                                 True, "", "VOTRE-CLE-DE-LICENCE")
    Else
        MsgBox alo.Last_Error
    End If
    Set alo = Nothing
End Sub

En pratique, remplacez les valeurs fixes par les champs de votre jeu d'enregistrements (recordset) et appelez AddProduct_Comfort dans une boucle sur les lignes. Pour une XRechnung destinée aux administrations allemandes, définissez en outre alo.isKOSIT = True et alo.LeitwegID.

Variante 2 : liaison anticipée avec une référence

  1. Sous VB6 : Project > References ; sous VBA : Outils > Références.
  2. Cochez « Aloaha ZUGFeRD Toolkit ». Si l'entrée ne figure pas dans la liste, choisissez le fichier Aloaha_ZUGFeRD.tlb via Parcourir ; il est fourni avec le SDK.
  3. Déclarez la variable avec le type de classe. Les appels restent les mêmes qu'avec la liaison tardive :
Dim alo As Aloaha_ZUGFeRD.XML
Set alo = New Aloaha_ZUGFeRD.XML
alo.Licensekey = "VOTRE-CLE-DE-LICENCE"
alo.ZUGFeRD_Profile = 1
' ... suite comme dans la variante 1

Avec la référence, l'IDE affiche toutes les méthodes et tous les paramètres (IntelliSense), et l'Explorateur d'objets (F2) présente l'interface complète. L'ordre des méthodes dans l'interface COM n'a pas changé depuis la version 10 ; les nouvelles fonctions ne sont ajoutées qu'à la fin. Les programmes compilés avec une référence continuent donc de fonctionner avec les versions plus récentes du SDK.

Les méthodes surchargées portent d'autres noms en COM

COM ne connaît pas la surcharge. Si une méthode existe plusieurs fois en .NET, la deuxième variante reçoit le suffixe _2 en VB6 et VBA :

Nom en VB6/VBAParamètres
WriteTotalsmontants sous forme de texte ("59.50")
WriteTotals_2montants en Double
AddProduct_Comfortnuméro de ligne sous forme de nombre
AddProduct_Comfort_2numéro de ligne sous forme de texte (p. ex. "1.1")
AddPaymentMeansmoyen de paiement sous forme de nombre (UNTDID 4461, p. ex. 58)
AddPaymentMeans_2moyen de paiement sous forme de texte ("58")

Transmettez les énumérations comme le profil ou le moyen de paiement sous forme de nombres. Pour le type de facture (BT-3), il existe une propriété dédiée Document_TypeINT, voir Créer une facture et le type de facture (BT-3) (en allemand).

VB5, VBA et VBScript

  • Visual Basic 5 : le code ci-dessus fonctionne sans modification. La fonction d'aide Betrag n'utilise volontairement que des fonctions déjà disponibles en VB5.
  • VBA dans Access, Excel et Word : le même code dans un module standard. Avec un Office 64 bits, l'enregistrement 64 bits doit être présent (le programme d'installation du SDK fait les deux). La lecture des factures et l'exploitation des valeurs de ligne sont présentées dans Lire les valeurs de ligne en VBA et Access (en allemand).
  • VBScript : déclarez les variables sans type (Dim alo) et utilisez uniquement la liaison tardive ; le reste est identique.

Erreurs fréquentes

MessageCauseSolution
Erreur d'exécution 429 : « Un composant ActiveX ne peut pas créer d'objet »La classe COM n'est pas enregistrée, n'est enregistrée que pour l'autre architecture (p. ex. 32 bits avec un Office 64 bits), ou le .NET Framework est absent.Exécuter le programme d'installation du SDK ou enregistrer avec le Regasm correspondant ; zugferd_com_test.vbs indique la cause.
Erreur d'exécution 438 : « Propriété ou méthode non gérée par cet objet »Faute de frappe, ou la variante surchargée porte un autre nom (_2).Vérifier le nom ; avec une référence, l'Explorateur d'objets (F2) affiche tous les noms.
Erreur d'exécution 13 : « Incompatibilité de type »Du texte là où le SDK attend un nombre (ou inversement).Vérifier le type de paramètre de la variante, voir le tableau ci-dessus.
Erreur d'exécution 450 : « Nombre d'arguments incorrect »Trop de paramètres, ou un paramètre obligatoire manque.Comparer la liste des paramètres avec la référence de l'API.
Erreur Automation « Fichier introuvable »Enregistrée sans /codebase, et la DLL ne se trouve pas dans le GAC.Réenregistrer avec regasm /codebase.
Validateur : BR-CO-10, BR-S-08, BR-CO-17Les totaux ne correspondent pas aux lignes ou à la base d'imposition.Base d'imposition = net après remises, voir BR-S-08, BR-S-09 et BR-CO-17.

Si SaveXML renvoie False, la cause figure dans Last_Error.

Alternative sans COM : zugcmd

Si le code VB doit rester aussi inchangé que possible, votre programme écrit les données de facture dans des fichiers CSV et appelle l'outil en ligne de commande zugcmd, par exemple via Shell. zugcmd en produit une facture ZUGFeRD, Factur-X ou XRechnung et intègre le XML dans votre PDF.

Étape par étape, avec des fichiers d'exemple testés, l'appel depuis votre propre application et les noms de fichiers : Créer des factures électroniques via CSV et zugcmd depuis votre application.

Tous les appels en détail : démarrage rapide avec VB.NET – les méthodes et paramètres sont les mêmes en VB6. Un guide distinct existe pour Delphi : Créer ZUGFeRD et XRechnung avec Delphi.

Questions fréquentes

Puis-je créer des factures ZUGFeRD et des XRechnung avec Visual Basic 6 ?

Oui. Le SDK Aloaha ZUGFeRD dispose d'une interface COM que VB6 utilise via CreateObject("Aloaha_ZUGFeRD.XML") ou via une référence à « Aloaha ZUGFeRD Toolkit ». Une migration vers .NET n'est pas nécessaire.

Cela fonctionne-t-il aussi avec Visual Basic 5 ?

Oui. VB5 utilise la même interface COM. Seules des fonctions comme Replace n'y existent pas encore ; la fonction d'aide pour le point décimal de cet article s'en passe.

Cela fonctionne-t-il aussi dans Access ou Excel avec VBA ?

Oui, avec le même code dans un module standard. Avec un Office 64 bits, la DLL doit aussi être enregistrée pour 64 bits ; le programme d'installation du SDK s'en charge.

Ai-je besoin d'une référence à la bibliothèque de types ?

Non, pas pour la liaison tardive avec CreateObject. La référence (liaison anticipée) apporte IntelliSense et des contrôles à la compilation. La DLL doit être enregistrée dans les deux cas.

Que signifie l'erreur d'exécution 429 lors de CreateObject ?

La classe COM n'est pas enregistrée sur cet ordinateur, ou seulement pour l'autre architecture. Exécutez le programme d'installation du SDK ou enregistrez la DLL avec le Regasm correspondant ; le script zugferd_com_test.vbs indique la cause.

Pourquoi une méthode s'appelle-t-elle WriteTotals_2 en VB6 ?

COM ne connaît pas la surcharge. La deuxième variante .NET d'une méthode reçoit le suffixe _2. WriteTotals attend les montants sous forme de texte, WriteTotals_2 en Double.

Termes métier dans cet article : BT-1 BT-2 BT-3 BT-5 BT-31 BT-72 BG-25 BG-23 BG-22 BT-81 BT-106 BT-109 BT-110 BT-112 BT-115 BT-116