Archivage automatique des factures + Nouvelle facture
Bonjour,
Je suis en train d'aider ma petite soeur en lui faisant un Sheet de facturation pour son auto-entreprise.
J'ai créé différentes feuilles :
- le template de la facture (!Facture)
- la liste de ses articles (!Articles)
- la liste de ses clients (!Clients)
- l'archivage facture (!ArchivageFacture)
- la création d'un nouveau numéro de facture en fonction de la dernière créée (!NouveauNum)
Je me permets de faire appel à vos connaissances pour une aide qui me serait précieuse.
En effet, j'aimerai qu'à partir du moment où elle a créé sa facture, il y ait un script :
1) qui enregistre chacune des données présentes dans sa !Facture sur son !ArchivageFacture
2) qui remet la !Facture en vierge
Si jamais vous avez un peu de temps à apporter à ma demande, je vous en serais infiniment reconnaissant ! Je suis perdu depuis quasi 2 jours...
Merci d'avance,
Bonne journée et prenez soin de vous !
Ci-joint le doc :
Bonjour,
il serait préférable de mettre un lien vers ton projet Google Sheets https://www.sheets-pratique.com/fr/cours/partage
Merci de ta réponse, j'ai essayé hier d'enregistrer un script, il fonctionne mais le souci est que tout n'est pas correctement "archiver"...
Donc de la feuille Facture > ArchiveFacture :
H8:I8 > col A
H6:I6 > col B
H11:J11 > col C
H16:I16 > col D
Pour ce qui est de la colonne "Références" jusqu'à "Montant HT", il se peut qu'elle ait une seule ligne sur sa facture, comme 10. Il y a possibilité "d'archiver" uniquement les cellules avec une valeur différente de 0 ?
Si oui, alors :
B19:C34 > col E
D19:G34 > col F
H19:H34 > col G
I19:I34 > col H
J19:J34 > col I
J35:J36 > col J
D'autre part, j'ai tenté de trouver un script pour :
- convertir la facture (après quelques modifications, uniquement A1:K54) en PDF
- envoyer un mail avec ce pdf à l'adresse mail du client en question (col F feuille Clients)
- avoir une sauvegarde de ce pdf dans son drive
Je ne trouve pas encore comment faire mais je continue mes recherches.
En tout état de cause, un grand merci sincère pour l'aide que tu m'apportes (et que vous apportez en général sur le forum).
Bonne journée
- merci, je vais m'y mettre, donc il peut y avoir autant de lignes que de postes non nuls !
- pour le pdf, je vais recherche ce qui a déjà été fait sur ce forum
D'autre part, j'ai tenté de trouver un script pour :
- convertir la facture (après quelques modifications, uniquement A1:K54) en PDF
- envoyer un mail avec ce pdf à l'adresse mail du client en question (col F feuille Clients)
- avoir une sauvegarde de ce pdf dans son drive
function envoiCopieFeuillePDF() {
DocumentApp.getActiveDocument();
DriveApp.getFiles();
// variables
const doc = SpreadsheetApp.getActive();
const docID = '________mettre_ici_l_ID___du___fichier_____________';
const feuilleID = '__ID_feuille__';
const email = '___email_destinataire____;
const dossier = DriveApp.getFolderById('__________ID_du_dossier______________');
const d = Utilities.formatDate(new Date(), "GMT+1", "yyyyMMdd")
const fichier = '____nom___du___fichier____suivi_ici_de_sa_date____________' + "_" + d + ".pdf"
const objet = 'Test pdf';
const corps = "Veuillez trouver ci-joint ...";
// Création du fichier pdf
const url = 'https://docs.google.com/spreadsheets/d/' + docID + '/export?';
const exportOptions =
'exportFormat=pdf&format=pdf' +
'&size=A4' +
'&portrait=true' + // orientation portrait, false pour paysage
'&fitw=false' + // pas d'ajustement en largeur
'&sheetnames=false&printtitle=false' + // pas de nom ni de titre à l'impression
'&pagenumbers=false&gridlines=false' + // pas de numérotation, pas de grille
'&fzr=false' + // frozen rows = pas de répétition de l'en-tête
'&gid=' + feuilleID;
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var reponse = UrlFetchApp.fetch(url + exportOptions, params).getBlob();
// Envoi email avec fichier attaché
GmailApp.sendEmail(email, objet, corps, {
htmlBody: corps,
attachments: [{
fileName: fichier,
content: reponse.getBytes(),
mimeType: "application/pdf"
}]
});
// Sauvegarde du fichier.
dossier.createFile(reponse.setName(fichier));
}
Merci beaucoup Steelson, je teste cela de suite :)
Pour l'archivage,
Donc de la feuille Facture > ArchiveFacture :
H8:I8 > col A
H6:I6 > col B
H11:J11 > col C
H16:I16 > col D
Pour ce qui est de la colonne "Références" jusqu'à "Montant HT", il se peut qu'elle ait une seule ligne sur sa facture, comme 10. Il y a possibilité "d'archiver" uniquement les cellules avec une valeur différente de 0 ?
Si oui, alors :
B19:C34 > col E
D19:G34 > col F
H19:H34 > col G
I19:I34 > col H
J19:J34 > col I
J35:J36 > col J
dis moi si c'est ok, je ferai ensuite la remise à blanc
function archiver(){
var doc = SpreadsheetApp.getActiveSpreadsheet();
var facture = doc.getSheetByName('Facture');
var adresses1 = ["H8","H6","H11","H16","J35"];
var destination1 = ["A","B","C","D","J"];
var adresses2 = ["B","D","H","I","J"];
var destination2 = ["E","F","G","H","I"];
var archive = doc.getSheetByName('ArchivageFacture');
var ligne = premLigneVide(archive)
for (var i=19;i<=34;i++){
if (facture.getRange("J"+i).getValue() != 0){
for (var x = 0; x < adresses1.length; x++){
archive.getRange(destination1[x] + ligne).setValue(facture.getRange(adresses1[x]).getValue());
}
for (var x = 0; x < adresses2.length; x++){
archive.getRange(destination2[x] + ligne).setValue(facture.getRange(adresses2[x] + i).getValue());
}
ligne += 1
}
}
}
function premLigneVide(f) {
var col = 'A';
var valeurs = f.getRange(col + ':' + col).getValues().join().split(",");
var vide = valeurs.indexOf("") + 1;
return vide;
}
Avant toute chose, merci !
Pour le script pdf, je l'ai mis en pratique sur le sheet final mais quelques bugs subsistent :
- Je reçois bien un mail en fonction de l'adresse que j'insère dans le script
- J'ai bien un archivage qui se fait dans mon file de destination
- Mais le pdf n'est pas correct, j'ai un fichier doc de ligne et pas de "screenshot" de ma facture
D'ailleurs j'ai vu en cherchant un peu sur internet, qu'en insérant "export?format=pdf" après l'url, que la personne pouvait avoir un pdf directement. Ca peut fonctionner avec une sélection d'une feuille (ex : A1:K54) ?
Pour le script archivage, je viens d'ouvrir les droits et donc de le tester :
Voilà ce que cela me donne
Je cherchais plus quelque chose comme ça en fait
Par contre le script pour remettre à blanc ne fonctionne pas
Merci encore énormément en tout cas !
Bonjour,
Pour le script pdf, je l'ai mis en pratique sur le sheet final mais quelques bugs subsistent :
- Je reçois bien un mail en fonction de l'adresse que j'insère dans le script
- J'ai bien un archivage qui se fait dans mon file de destination
- Mais le pdf n'est pas correct, j'ai un fichier doc de ligne et pas de "screenshot" de ma facture
si tu as bien un fichier dans ton drive, est-ce que tu l'as bien aussi attaché au mail que tu as reçu ? quel est ce bug ? pourquoi le pdf n'est pas correct ?
D'ailleurs j'ai vu en cherchant un peu sur internet, qu'en insérant "export?format=pdf" après l'url, que la personne pouvait avoir un pdf directement. Ca peut fonctionner avec une sélection d'une feuille (ex : A1:K54) ?
ma seule expérience est sur une feuille complète.
J'attends d'abord ta réponse à la question ci-dessus.
Pour le script archivage, je viens d'ouvrir les droits et donc de le tester :
Voilà ce que cela me donneJe cherchais plus quelque chose comme ça en fait
C'était volontaire, pour notamment pouvoir faire des statistiques par exemple sur le nombre de références "appliquées" (sorte d'analyse 80/20), sur le "panier" moyen (ou facture moyenne) par client, CA par mois, etc.
J'ai 2 solutions :
- faire comme tu dis, et s'interdire ensuite toute synthèse/statistique
- alléger la lecture en faisant une MFC sur le n° de facture.
quelle est ta préférence ?
Par contre le script pour remettre à blanc ne fonctionne pas
Normal, je ne l'ai pas encore fait.
si tu as bien un fichier dans ton drive, est-ce que tu l'as bien aussi attaché au mail que tu as reçu ? quel est ce bug ? pourquoi le pdf n'est pas correct ?
Comme des images vaudront mieux que des mots , voici ce qu'il se passe :
Je reçois ce mail
Et quand je clique sur le pdf voilà ce que cela m'affiche
C'était volontaire, pour notamment pouvoir faire des statistiques par exemple sur le nombre de références "appliquées" (sorte d'analyse 80/20), sur le "panier" moyen (ou facture moyenne) par client, CA par mois, etc.
J'ai 2 solutions :
1. faire comme tu dis, et s'interdire ensuite toute synthèse/statistique
2. alléger la lecture en faisant une MFC sur le n° de facture.quelle est ta préférence ?
En glanant sur internet j'avais trouvé la fonction NB.SI, et quand je l'ai testée, j'arrive à récupérer les données de la colonne E en fonction de la référence.
La 1ère solution me parait donc plus approprié à ce qu'elle recherche.
Il y a possibilité aussi de mettre la nouvelle facture en première ligne, donc de descendre la facture précédente ?
Normal, je ne l'ai pas encore fait.
Effectivement c'est tout de suite plus compliqué qu'elle fonctionne
Encore un grand merci à toi Steelson !
Comme des images vaudront mieux que des mots , voici ce qu'il se passe :
Et quand je clique sur le pdf voilà ce que cela m'affiche
je vais investiguer de mon côté avec un essai sur un de mes fichiers
En glanant sur internet j'avais trouvé la fonction NB.SI, et quand je l'ai testée, j'arrive à récupérer les données de la colonne E en fonction de la référence.
Oui pour le nombre de références, mais on ne verra pas par exemple le nombre de références par mois...
J'ai essayé d'appliquer une MFC sur le fichier, mais comme la feuille est pseudo-protégée c'est compliqué
La 1ère solution me parait donc plus approprié à ce qu'elle recherche.
Il y a possibilité aussi de mettre la nouvelle facture en première ligne, donc de descendre la facture précédente ?
C'est toi qui décide de toute façon, et je la mettrai en tête.
Pour le pdf, j'ai bien reçu la facture (mise en page à améliorer)
avec ce bout de code
function envoyer() {
DocumentApp.getActiveDocument();
DriveApp.getFiles();
// variables
const doc = SpreadsheetApp.getActive();
const docID = '1aQeTa3TRhKOmN83dMCAZXICSogxkARjyB0WXcUdMvNw';
const feuilleID = '0';
const email = '_______email_____';
const dossier = DriveApp.getFolderById('___________id du dossier_________');
const fichier = "facture.pdf"
const objet = 'Facture';
const corps = "Veuillez trouver ci-joint ...";
// Création du fichier pdf
const url = 'https://docs.google.com/spreadsheets/d/' + docID + '/export?';
const exportOptions =
'exportFormat=pdf&format=pdf' +
'&size=A4' +
'&portrait=true' + // orientation portrait, false pour paysage
'&fitw=false' + // pas d'ajustement en largeur
'&sheetnames=false&printtitle=false' + // pas de nom ni de titre à l'impression
'&pagenumbers=false&gridlines=false' + // pas de numérotation, pas de grille
'&fzr=false' + // frozen rows = pas de répétition de l'en-tête
'&gid=' + feuilleID;
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var reponse = UrlFetchApp.fetch(url + exportOptions, params).getBlob();
// Envoi email avec fichier attaché
GmailApp.sendEmail(email, objet, corps, {
htmlBody: corps,
attachments: [{
fileName: fichier,
content: reponse.getBytes(),
mimeType: "application/pdf"
}]
});
// Sauvegarde du fichier.
dossier.createFile(reponse.setName(fichier));
}
vérifie bien l'ID du dossier dans lequel tu veux archiver, et les droits éventuels sur ce dossier
vérifie bien l'ID du dossier dans lequel tu veux archiver, et les droits éventuels sur ce dossier
Je regarde ça de suite
La 1ère solution me parait donc plus approprié à ce qu'elle recherche.
Il y a possibilité aussi de mettre la nouvelle facture en première ligne, donc de descendre la facture précédente ?
C'est toi qui décide de toute façon, et je la mettrai en tête.
Mets l'encadrement par MFC
function archiver(){
var doc = SpreadsheetApp.getActiveSpreadsheet();
var facture = doc.getSheetByName('Facture');
var adresses1 = ["H8","H6","H11","H16","J35"];
var destination1 = ["A","B","C","D","J"];
var adresses2 = ["B","D","H","I","J"];
var destination2 = ["E","F","G","H","I"];
var archive = doc.getSheetByName('ArchivageFacture');
var ligne = 2
archive.insertRowBefore(ligne);
for (var x = 0; x < adresses1.length; x++){
archive.getRange(destination1[x] + ligne).setValue(facture.getRange(adresses1[x]).getValue());
}
for (var i=19;i<=34;i++){
if (facture.getRange("J"+i).getValue() != 0){
if (ligne!=2){
archive.insertRowBefore(ligne);
}
for (var x = 0; x < adresses2.length; x++){
archive.getRange(destination2[x] + ligne).setValue(facture.getRange(adresses2[x] + i).getValue());
}
ligne += 1
}
}
}
Bon, tu es tout simplement : un GÉNIE !
J'ai modifié deux trois trucs pour que ça corresponde à mon fichier final, et c'est impressionnant...
J'ai même réussi à redimensionner le pdf en mettant un true sur l'option "fitw", au final, tout tient dans une page !
Juste une dernière chose pour le pdf : j'aimerai récupéré l'adresse mail qui se situe dans les cellule H15:J15 de ma feuille Facture, mais je n'y arrive pas...
Encore un grand merci à toi Steelson, vraiment !
J'ai réussi !!!!!! (petite fierté personnelle)
Bon même si c'est surtout grâce à toi !
Bon, tu es tout simplement : un GÉNIE !
J'ai modifié deux trois trucs pour que ça corresponde à mon fichier final, et c'est impressionnant...
J'ai même réussi à redimensionner le pdf en mettant un true sur l'option "fitw", au final, tout tient dans une page !
Juste une dernière chose pour le pdf : j'aimerai récupéré l'adresse mail qui se situe dans les cellule H15:J15 de ma feuille Facture, mais je n'y arrive pas...
Encore un grand merci à toi Steelson, vraiment !
Voilà ce que j'ai mis en code :
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Facture").getRange("H15:J15")
var emailAddress = emailRange.getValues()
J'ai même réussi à éditer ta function 'effacer' !
function effacer(){ {
var feuille = SpreadsheetApp.getActive (). getSheetByName ('Facture');
var sheet = SpreadsheetApp.getActiveSpreadsheet()
sheet.getRange ('H11:J11'). clearContent ();
sheet.getRange ('H17:I17'). clearContent ();
sheet.getRange ('B20:C35'). clearContent ();
sheet.getRange ('H20:H35'). clearContent ();
}
Encore un ÉNORME merci de ma part et de ma petite soeur Steelson !
Je clôture la discussion, et maintenant que j'ai bien compris tout ton code (après l'avoir longuement étudié var, cons, for, etc...) si jamais je peux aider avec mes maigres connaissances l'une ou l'un d'entre vous, ce sera avec plaisir !
Merci sincèrement, et bon weekend à toi !