formateur informatique

Numérotation automatisée de factures Excel en VBA

Accueil  >  Bureautique  >  Excel  >  Excel VBA  >  Numérotation automatisée de factures Excel en VBA
Livres à télécharger


Pour partager cette vidéo sur les réseaux sociaux, voici son url absolue :

Pour l'intégrer sur votre site internet ou blog, vous pouvez l'embarquer :

Sujets et formations similaires :


Numérotation automatique de Factures

Dans de précédentes formations, nous avons appris à bâtir une facturation automatisée avec Excel. La fonction RechercheV nous a permis d'extraire dynamiquement les informations du catalogue, en fonction des références articles. Puis avec un code Visual Basic, nous avons intégré la gestion de stocks et l'automatisation par interface graphique.



Facture Excel avec Stocks pour automatisation numérotation en VBA

Pour peaufiner l'application professionnelle, nous souhaitons ajouter un système de numérotation automatique. Chaque nouvelle facture sera un incrément de la précédente facturation validée.

Facturation Excel
Comme toujours, pour concentrer nos travaux sur l'essentiel, nous récupérons le modèle complet de facturation Excel. Grâce à une ligne de code VBA Excel dans la procédure événementielle Workbook_Open, l'interface graphique s'affiche automatiquement à l'ouverture du classeur. Notez à ce titre, l'extension xlsm du classeur pour la gestion du code Visual Basic.

Si vous choisissez une référence à l'aide de la liste déroulante en indiquant une quantité et que vous cliquez sur le bouton Ajouter, l'article est rapatrié à la suite sur la facturation. Des formules se chargent de calculer les montants hors taxes. Les informations des produits sont extraites de la feuille articles, par une fonction RechercheV qui récupère la référence à rechercher, transmise par le code VBA Excel. Si vous cliquez sur le bouton Valider la facture, les stocks du catalogue sont mis à jour en fonction des quantités achetées.

Et comme la facture a été validée, la numérotation de la prochaine devra être incrémentée. Dans notre exemple, la référence srt-106 devra remplacer la référence srt-105.

Accès aux données externes en VBA Excel
Pour des raisons de sécurité, nous proposons d'externaliser l'archivage de la numérotation. Un fichier texte fera l'affaire. A chaque ouverture de la facturation, un code VBA doit accéder à ce fichier pour récupérer son contenu et l'inscrire dans la cellule de numérotation. A chaque fois qu'une facture est validée, par clic sur le bouton de l'interface, le numéro en cours incrémenté doit être inscrit dans ce fichier texte, à la place de l'ancien.
  • Créer le fichier numerotation.txt dans le dossier où a été téléchargé le classeur Excel,
  • L'ouvrir, y écrire le numéro 106 puis le fermer en l'enregistrant,
  • Sur la facturation Excel, cliquer sur la croix du UserForm pour fermer l'interface,
  • Réaliser le raccourci clavier ALT + F11 pour basculer dans l'éditeur de code VBA Excel,
  • Dans l'explorateur de projets sur la gauche, double cliquer sur l'élément facture,
Interface graphique de facturation VBA Excel, UserForm en conception

Nous affichons ainsi l'interface graphique(Userform) de la facturation en mode conception. Si l'explorateur de projets n'est pas visible dans votre environnement, vous devez cliquer sur le menu Affichage en haut de l'éditeur. Vous choisissez alors Explorateur de projets dans la liste.
  • Double cliquer sur le bouton Valider la facture depuis le UserForm,
Nous basculons ainsi dans la feuille de code VBA et plus précisément entre les bornes de la procédure valider_Click. Le code présent entre ces bornes se déclenche au clic sur le bouton. L'incrémentation du numéro de facture ne doit intervenir que si cette dernière est validée par l'utilisateur. Et cet événement intervient au clic sur le bouton Oui à la demande de confirmation par MsgBox. La partie du code concerné se situe donc entre les bornes de l'instruction conditionnelle If.

If (reponse = 6) Then
...
End If


C'est dans cette branche que nous devons ajouter les instructions permettant la numérotation automatique. Mais pour améliorer la structure, nous choisissons de créer une procédure indépendante que nous nommerons numerotation. Si la facture est validée par le vendeur, le code de cette procédure doit donc être appelé pour être exécuté.
  • Dans l'instruction If, juste avant le End If, ajouter l'appel suivant :
numerotation

Certes nous avons anticipé puisque cette procédure n'existe pas encore. Si bien que si nous exécutions le code à ce stade, une erreur serait retournée. Nous devons créer cette procédure indépendante. Et pour ce faire, les modules sont particulièrement adaptés.
  • Enregistrer les modifications (CTRL + S),
  • Cliquer sur le menu Insertion en haut de l'éditeur de code,
  • Dans la liste choisir Module,
Créer un module de code Visual Basic Excel pour procédure indépendante

Le Module1 apparait dans l'arborescence de l'explorateur de projets sur la gauche.
  • Double cliquer sur le Module1 pour afficher sa feuille de code au centre,
  • Dans sa feuille de code, créer la procédure numerotation, comme suit :
Sub numerotation()

End Sub


Le code que nous saisirons entre ces bornes s'exécutera donc, au clic sur le bouton Valider la facture du UserForm, si l'utilisateur confirme le message de validation. L'objectif est d'inscrire le numéro incrémenté dans le fichier numerotation.txt. Ce numéro est inscrit en cellule G2 : srt-105. Le préfixe est toujours le même : srt-. Le numéro à extraire est donc 105. Il doit être incrémenté (106) avant d'être exporté. Nous avons donc besoin d'une variable pour stocker ce numéro. Une variable est de même nécessaire afin de mémoriser le chemin d'accès au fichier texte.
  • Entre les bornes de la procédure, ajouter les déclarations de variables suivantes :
Dim chemin_fichier As String: Dim numero As Integer

Nous déclarons fort logiquement la variable chemin_fichier comme un String, afin de pouvoir stocker une chaîne de caractères. La variable numero quant à elle est déclarée comme un entier (Integer) afin de pouvoir être incrémentée.

Après la déclaration des variables vient l'affectation. La propriété Path de l'objet ThisWorkbook renvoie le chemin d'accès complet au classeur actif (ThisWorkbook). Moyennant un antislash, il faut ajouter à ce chemin par concaténation, le nom du fichier texte pour qu'il soit complet : ThisWorkbook.Path & 'numerotation.txt'. Pour stocker le numéro à incrémenter dans la variable numero, il faut d'abord supprimer le préfixe. La fonction VBA Replace permet de remplacer une occurrence dans une chaîne de caractères, par une autre. Sa syntaxe est la suivante :

Replace(chaine, terme_a_remplacer, terme_de_remplacement)

La chaîne correspond au contenu de la cellule G2 que l'on peut désigner avec l'objet Range (Range('G2')). La propriété Value d'un objet Range permet d'accéder au contenu de la cellule. Le terme à remplacer est srt- . Le terme de remplacement est un chaîne vide (''), pour supprimer ce préfixe.
  • En conséquence de ces remarques, ajouter les affectations suivantes :
numero = Int(Replace(Range('G2').Value, 'srt-', '')) + 1
chemin_fichier = ThisWorkbook.Path & 'numerotation.txt'

MsgBox numero & '-' & chemin_fichier


La fonction Int permet de convertir explicitement en entier, la chaîne récupérée et retravaillée grâce à la fonction Replace. A cet entier, nous ajoutons une unité (+ 1) pour incrémenter la numérotation. Nous ajoutons à ce code un test temporaire avec la fonction MsgBox pour nous assurer que nous avons bien stocké les bonnes valeurs.
  • Enregistrer les modifications et exécuter le code (F5),
Incrémentation automatique du numéro de facture en VBA Excel



Comme l'illustre la capture ci-dessus, le numéro est extrait et incrémenté. De plus le chemin d'accès complet au fichier texte est parfaitement recomposé. Il s'agit donc désormais d'accéder à ce fichier en écriture pour y inscrire ce numéro. La formation VBA Excel pour importer et exporter des données, nous avait appris à coder l'accès séquentiel aux fichiers. Nous allons nous inspirer de ces enseignements.
  • Ajouter une apostrophe (') devant la ligne du MsgBox pour la passer en commentaire,
  • Puis, ajouter les instructions suivantes à la suite :
Open chemin_fichier For Output As #1
Print #1, Replace(numero, ' ', '')
Close #1


L'instruction Open suivi du chemin du fichier permet d'accéder à ce dernier en mémoire. For Output permet d'indiquer que nous y accédons en écriture et non en lecture. Si un contenu existe, il est écrasé. Enfin,As #1, permet d'allouer une adresse mémoire sous forme de numéro. Ce numéro doit être libre. Pas de souci dans notre cas puisqu'il s'agit du seul accès mémoire réalisé. C'est par ce numéro désormais que nous désignons le fichier pour y écrire. Ainsi, l'instruction Print permet d'écrire dans le fichier référencé par son adresse (#1), l'information qui lui est passée en paramètre. Cette information n'est autre que le numéro incrémenté. Notez que nous le retravaillons à la volée afin de purger les espaces résiduels potentiels (Replace(numero,' ', '')). Une fois l'écriture terminée, le fichier doit être déchargé de la mémoire grâce à l'instruction Close suivi de l'adresse #1 qui le désigne. C'est en libérant les ressources que l'écriture se fait de la mémoire vers le disque dur, dans le fichier désigné. Il s'agit maintenant de vérifier si cette inscription en dur s'effectue bien.
  • Enregistrer les modifications et exécuter le code (F5),
  • Ouvrir le fichier numerotation.txt pour consulter son contenu,
Exportation de la numérotation automatique des factures Excel en VBA dans un fichier externe

Comme l'illustre la capture ci-dessus, le numéro incrémenté est parfaitement inscrit.

Modifier les attributs de fichiers externes
Nous souhaitons ajouter une sécurité sur le fichier de la numérotation automatique, afin qu'il ne risque pas d'être modifié ou supprimé par mégarde. Nous proposons d'accéder à ses propriétés pour modifier certains attributs. Nous souhaitons que le fichier soit caché et en lecture seule. La formation VBA Excel pour accéder aux propriétés des fichiers, nous a appris les instructions permettant de modifier ces attributs.
  • Dans la partie déclarative de la procédure, ajouter les deux déclarations suivantes :
Dim objet_fichier: Dim le_fichier

Il s'agit de deux variables non typées. En effet elles vont servir à instancier une classe ActiveX pour hériter des propriétés et méthodes permettant de manipuler les fichiers du système. Et c'est la fonction VBA CreateObject qui rend possible cette instanciation.
  • Après l'affectation de la variable chemin_fichier, ajouter les deux affectations suivantes :
Set objet_fichier = CreateObject('scripting.filesystemobject')
Set le_fichier = objet_fichier.getfile(chemin_fichier)


Le mot clé Set est obligatoire pour instancier une classe. C'est le paramètre scripting.filesystemobject, passé à la fonction CreateObject qui permet d'instancier la classe pour manipuler les fichiers et les dossiers. Cet objet propose alors une méthode getfile qui permet de pointer sur le fichier qui lui est passé en paramètre (chemin_fichier). Nous affectons la variable le_fichier de cet objet retourné désignant le fichier précisément. Dès lors l'objet le_fichier propose la méthode Attributes qui peut être réglée sur différentes valeurs numériques afin d'affecter les propriétés du fichier en question.

Comme nous l'enseigne l'aide en ligne de Microsoft, la valeur 1 place le fichier en lecture seule tandis que la valeur 2 le transforme en fichier caché. Et ces constantes peuvent se combiner. Ainsi la valeur 3 (2 + 1) affectée à la propriété Attributes, transforme le fichier en fichier caché et en lecture seule.
  • A la fin de la procédure, après le Close #1 et avant le End Sub, ajouter l'affectation suivante :
le_fichier.Attributes = 3
  • Enregistrer les modifications et tester le code (F5),
Si nous accédons au dossier du fichier de numérotation et que nous affichons la colonne Attributs, nous remarquons la présence des indications RH. R est la première lettre de ReadOnly pour lecture seule tandis que H est la première lettre de Hidden pour caché. Bien sûr, vous devez indiquer à l'explorateur Windows d'afficher les fichiers masqués si vous souhaitez le visualiser.

Attributs de fichiers externes modifiés par le code VBA pour protéger les données en lecture seule

Si nous tentons de modifier les informations du fichier, Windows ne nous y autorise pas. C'est parfait, le fichier est correctement protégé grâce à la modification de ses attributs par le code VBA. Mais désormais un problème se pose. Comme le fichier est protégé contre l'écriture, le code VBA lui-même n'est plus autorisé à y écrire. C'est ce qu'illustre la capture ci-dessous.

Privilèges écritue et accès fichier refusés au code VBA en ReadOnly

Cela signifie que le code Visual Basic Excel doit d'abord ôter la protection du fichier pour pouvoir y écrire. Une fois l'écriture terminée, il doit réactiver cette protection. Il suffit de régler la propriété Attributes à 0 pour éliminer toutes ces options.
  • Avant l'instruction Open de l'accès en écriture, ajouter l'affectation suivante :
le_fichier.Attributes = 0

Désormais si nous exécutons le code, non seulement VBA peut modifier les informations du fichier, mais l'utilisateur lui, n'a pas le droit d'intervenir. Le code VBA complet de la procédure numerotation est la suivant :

Sub numerotation()
Dim chemin_fichier As String: Dim numero As Integer
Dim objet_fichier: Dim le_fichier

numero = Int(Replace(Range('G2').Value, 'srt-','')) + 1
chemin_fichier = ThisWorkbook.Path & 'numerotation.txt'
Set objet_fichier = CreateObject('scripting.filesystemobject')
Set le_fichier = objet_fichier.getfile(chemin_fichier)
le_fichier.Attributes = 0

Open chemin_fichier For Output As #1
Print #1, Replace(numero, ' ', '')
Close #1

le_fichier.Attributes = 3
End Sub




Accès en lecture aux fichiers externes
L'application n'est pas totalement terminée. A l'ouverture de la facture, un code VBA doit récupérer le dernier numéro incrémenté pour l'inscrire en G2. Sans cette étape, la numérotation restera toujours figée sur le même nombre. L'accès en lecture se fait toujours avec l'instruction Open mais accompagnée de la méthode For Input. Ce code doit se déclencher au moment de l'ouverture du classeur.
  • Dans l'explorateur de projets, double cliquer sur l'objet ThisWorkbook,
Dans les bornes de la procédure événementielle Workbook_Open, nous trouvons fort logiquement l'instruction : facture.Show. La méthode Show de l'objet UserForm nommé facture, commande son affichage. Et comme cette ligne se déclenche sur l'événement de l'ouverture du classeur, l'interface s'affiche en même temps. Nous devons ajouter les lignes de code VBA permettant d'accéder au contenu du fichier numerotation.txt en lecture.
  • Au début de la procédure, avant facture.Show, ajouter les lignes suivantes :
Dim chemin_fichier As String: Dim numero As String
chemin_fichier = ThisWorkbook.Path & 'numerotation.txt'


Il s'agit d'une réplication du code précédent. Nous stockons le chemin complet d'accès au fichier, dans la variable chemin_fichier, déclarée comme un String à cet effet. Bien sûr la variable numero doit permettre de stocker l'information récupérée du fichier.
  • Toujours avant l'instruction facture.Show, ajouter les instructions suivantes :
Open chemin_fichier For Input As #1
Line Input #1, numero
Close #1

Range('G2').Value = 'srt-' & numero


Nous accédons donc au fichier texte en lecture (For Input). Comme précédemment, cette lecture s'effectue en mémoire, raison pour laquelle nous définissons un numéro d'allocation (#1). L'instruction Line Input permet de récupérer les informations ligne à ligne, soit la première ligne ici. Elle est accompagnée de l'adresse mémoire pour désigner le fichier à lire. L'information récupérée (La numérotation) est stockée dans la variable passée en paramètre (numero). Nous libérons ensuite les ressources en déchargeant le fichier de la mémoire (Close #1). Et nous reconstruisons le code de la facturation incrémenté par concaténation en cellule G2 (Range('G2').Value= 'srt-' & numero).
  • Enregistrer les modifications et tester le code (F5),
Incrémentation automatique VBA du numéro de facture Excel à chaque nouvelle commande

Comme l'illustre la capture ci-dessus, l'ancienne numérotation a bien été remplacée par la nouvelle, issue du fichier texte qui avait mémorisé le nombre incrémenté, suite à la validation de la facturation. Si nous validons une nouvelle facture, nous constatons qu'à l'ouverture suivante, le numéro de facturation a bien été incrémenté.

Le processus est parfaitement fonctionnel. Pour parfaire l'application, il s'agirait de nettoyer la facture après validation pour la réinitialiser et de récupérer dans la foulée le nouveau numéro. Ainsi, plusieurs factures pourraient être émises dans successivement.

Le code VBA complet à l'ouverture du classeur est le suivant :

Private Sub Workbook_Open()
Dim chemin_fichier As String: Dim numero As String

chemin_fichier = ThisWorkbook.Path & 'numerotation.txt'

Open chemin_fichier For Input As #1
Line Input #1, numero
Close #1

Range('G2').Value = 'srt-' & numero
facture.Show
End Sub


 
Sur Facebook
Sur G+
Sur Youtube
Les livres
Contact
Mentions légales



Partager la formation
Partager sur Facebook
Partager sur Google+
Partager sur Twitter
Partager sur LinkedIn