› Sviluppare funzionalita su Microsoft Office con VBA › Salva file con Nome (dati presi da celle diverse) sia in excel che PDF
-
AutoreArticoli
-
Ciao a tutti,
Spero possiate aiutarmi ne avrei davvero bisogno per velocizzare il lavoro che svolgo. Ho necessità di creare una macro che salvi il file sia in excel che PDF in una cartella specifica e che il nome del file prenda alcuni dati da alcune celle. Non so se mi sono spiegato. È possibile farlo?
Per facilitare la comprensione allego il file in questione e vi spiego i passaggi che dovrei fare:
1. una volta compilato il preventivo si passa al foglio "Output"
2. creare un tasto che permetta il salvataggio della pagina output sia in excel che in pdf in una cartella specifica ad esempio una cartella situata nel desktop "preventivi" che ha al suo interno altre 2 cartelle "PDF" ed "excel"
3. Il salvataggio del file deve prendere il nome di alcune celle della pagine input con questa formattazione e cioè "N41 - N42 - N43 - N44"
Ringrazio tutti per l'aiuto, io non saprei davvero da dove incominciare e spero che qualcuno riesca a darmi una mano
Allegati:
You must be logged in to view attached files.Ti sei spiegato ed è possibile farlo.
Per cominciare avvia un registratore di macro ed esegui le operazioni descritte: salva file con nome, seleziona cartella di destinazione, conferma, poi esporta in pdf (senza preoccuparti per adesso dei dati che stanno su altre celle).
Quindi torna indietro e riesamina il codice.
Depuralo di goni schifezza che il registratore inevitabilmente aggiunge.
Torna qui, allega il file, mostra eventuali difficoltà e le risolveremo.
Quindi parleremo del secondo step (inserire dati nel nome di file prelevandoli da altre celle) quando avrai del codice pulito e un esempio di file in modo da non dover ricostruire da zero lo scenario d'uso.Hai modificato il tuo post e aggiunto il file di esempio come chiedevo io, mentre scrivevo il mio post 😀
Bene. Quanto ho scritto però rimane valido relativamente a chiederti di fare un tentativo su un file fornito di macro 😉
grazie tante vecchio frac, ci mancherebbe ci provo non sono molto bravo con vba il registratore macro non dovrei avere problemi ad usarlo.
per quanto riguarda la pulizia cosa dovrei togliere giusto per capire?
ad ogni modo ci provo e ti faccio sapere e grazie ancora dell'aiuto mi risolverebbe tanti casini. facciamo davvero tanti preventivi e fare quest'operazione manualmente ogni volta è un caos
per quanto riguarda la pulizia cosa dovrei togliere giusto per capire?
E' praticamente impossibile dirtelo adesso. Non ho idea del tuo grado di confidenza con VBA. Quello che per me è superfluo magari per te è importante per capire il meccanismo. Di solito però quando si legge il codice si vedono subito le istruzioni ridondanti o inutili. Nel dubbio lascia pure tutto, che poi ti accompagniamo nella pulizia magari con una spiegazione del perchè certe istruzioni si possono ridurre, togliere o semplificare.
grazie tante vecchio frac, ci mancherebbe ci provo non sono molto bravo con vba il registratore macro non dovrei avere problemi ad usarlo.
Sì, l'automazione serve a questo ed è importante saperci mettere le mani perchè ti riduce i tempi manuali e diventi molto più produttivo solo se sai cosa stai facendo. E' per questo che è meglio farti mettere il naso e non proporti soluzioni già fatte.
ciao vecchio frac, allora la registrazione l'ho fatta ed a parte la questione del nome file che abbiamo detto vedevamo in seguito funziona egregiamente. il file viene salvato nelle cartelle sia in excel che pdf. il codice è molto piccolo non mi pare vada eliminata qualcosa. ad ogni modo posto il codice ed il nuovo file con le macro:
mi servirebbe anche un altra cosa se possibile. Nella cella N41 del file excel che viene salvato c'è il numero dell'ultimo preventivo salvato. Avrei bisogno che il file vergine quello che utilizzo per fare ogni nuovo preventivo prendesse il numero dalla cella N41 dell'ultimo preventivo + 1. in pratica il file vergine al suo avvio in automatico nella casella B1 prende la numerazione + 1 della cella N41 dell'ultimo preventivo excel
ps. per rinominare il preventivo con le date ho allegato un secondo file dove ho formattato le celle N43 ed N44 altrimenti le / probabilmente nel nome non le prende. quindi se ti serve il file usa quello con la dicitura 1 alla fine. non sapevo come eliminare gli allegati
Sub SalvaExcelPDF2() ' ' SalvaExcelPDF2 Macro ' ' Scelta rapida da tastiera: CTRL+r ' ChDir "C:\Users\Anna\Desktop\Preventivi Eurolido\Excel" ActiveWorkbook.SaveAs Filename:= _ "C:\Users\Anna\Desktop\Preventivi Eurolido\Excel\a Schema Preventivo VBA.xlsm" _ , FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False Sheets("Output").Select ActiveSheet.Range("$A$5:$C$64").AutoFilter Field:=3, Criteria1:="<>" ChDir "C:\Users\Anna\Desktop\Preventivi Eurolido\PDF" ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _ "C:\Users\Anna\Desktop\Preventivi Eurolido\PDF\a Schema Preventivo VBA.pdf", _ Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas _ :=False, OpenAfterPublish:=False Sheets("Input").Select End SubAllegati:
You must be logged in to view attached files.Molto bene Frost, direi un gran risultato per non averci mai smanettato prima 👍
Di solito non si codifica una cartella di destinazione "secca" ma si prevede la possibilità di farla scegliere all'utente. Se però sai già che rimane fissa ed immutabile, allora va bene anche questa soluzione.
La riga con l'autofilter è un refuso? Hai fatto un filtro mentre era attivo il registratore. Se era intenzionale, lascia pure la riga di codice altrimenti puoi cancellarla.Noto però che non è rispettata la condizione di formare il nuovo file con le celle di cui hai parlato nell'altro post. Puoi creare il nome di file concatenando una stringa composta dai vari range interessati. Come ti sei accorto il carattere "/" non è consentito da Windows come nome di file, puoi fare un Replace per modificarlo.
Inoltre forse vuoi salvare come file xlsx e non come xlsm; allora bisogna variare il parametro FileFormat del comando SaveAs.Nel mio file di test c'era una cosa così, vedi se vuoi/puoi prendere spunto:
s = "@A - @B - @C - @D" For i = 1 To 4 v = Choose(i, "N41", "N42", "N43", "N44") s = Replace(s, "@" & Chr$(64 + i), Worksheets("Input").Range(v)) Next Worksheets("Output").SaveAs fd.SelectedItems(1) & "\EXCEL\" & Replace(s, "/", "_") & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False Worksheets("Output").ExportAsFixedFormat xlTypePDF, fd.SelectedItems(1) & "\PDF\" & Replace(s, "/", "_") & ".pdf"Per inciso, ti raccomando sempre di inserire Option Explicit in testa ai tuoi moduli e di dichiarare sempre le variabili che usi, col tipo corretto. Sul perché, se vuoi ti faccio una lezione a parte 🙂
Avrei bisogno che il file vergine quello che utilizzo per fare ogni nuovo preventivo prendesse il numero dalla cella N41 dell'ultimo preventivo + 1
Quando hai inserito il numero di preventivo mandato in stampa, modificala cella che ti interessa aumentandone il valore:
With Worksheets("Input") .Range("N41").Value = .Range("N41").Value + 1 End WithE a questo punto ti conviene ragionare come se dovessi creare un nuovo foglio, cui punti un riferimento, salvandolo indipendentemente dal file originale (quello con la macro). Ti allego il file come l'ho modificato io.
Allegati:
You must be logged in to view attached files.Scusami tanto vecchio frac ma mi sono perso un po
ti rispondo per punti:
1. la destinazione della cartella è secca quindi può andar bene quello che fa il registratore
2. l'autofilter è intenzionale quindi può rimanere
3. il salvataggio con nome delle celle non l'ho proprio fatto perchè sto cercando su internet ma non riesco a capire come modificare. Ad ogni modo io ho già previsto delle celle che abbiano la formattazione corretta le celle N43 e N44 le ho formattate con data 20-ago-2023 in modo che non abbiano problemi nel rinominare il file(ti allego file). quindi il replace non servirebbe basterebbe che il file nel suo salvataggio prendesse "N41 - N42 - N43 - N44" (possibilmente anche con i trattini tra ogni cella/contenuto)
4. Il file salvato va bene che sia un xlsx.
5. per l'aumento del numero di preventivo preferirei se possibile che il file originale rimanesse quello e che ogni volta che io apro quel file aumenta di 1 rispetto all'ultima stampa
p.s.
scusami ma mi sono perso un po
Allegati:
You must be logged in to view attached files.Sì mi era chiaro il tuo scenario.
Controlla il file che ho allegato e provalo. Con qualche ritocco il tuo codice è funzionalmente uguale al mio 🙂il problema è che il file che mi hai inviato non mi funziona forse sbaglio qualcosa io.
1. mi da questo errore e mi sembra che non ci sia la variabile "s"

2. vorrei eliminare l'apertura della finestra di dialogo in modo da salvare direttamente nel percorso basta che tolgo l'apice? da questo comando? 'p = "C:\Users\Anna\Desktop\Preventivi Eurolido\Excel"
3. poi ho fatto un'altra prova inserendo la variabile "s" in questo modo
`Sub save_as() Dim fd As FileDialog Dim p As String Dim t As String Dim v As Variant Dim s As Variant Dim i As Integer Dim wb1 As Workbook Dim wb2 As Workbook Set wb1 = ThisWorkbook Set wb2 = Workbooks.Add wb1.Worksheets("Output").Copy after:=wb2.Worksheets(wb2.Worksheets.Count) 'permetto all'utnte di scegliere la cartella di destinazione '-------------------------------------------------------------------------- Set fd = Application.FileDialog(4) ' 4 --> msoFileDialogFolderPicker With fd .Title = "Seleziona la cartella in cui salvare" If .Show = 0 Then Exit Sub End With p = fd.SelectedItems(1) 'in alternativa a quanto sopra posso codificare il percorso di destinazione direttamente qui: '(togliere l'apice per rendere effettivo il codice) 'p = "C:\Users\Anna\Desktop\Preventivi Eurolido\Excel" '-------------------------------------------------------------------------- s = "@A - @B - @C - @D" For i = 1 To 4 v = Choose(i, "N41", "N42", "N43", "N44") s = Replace(s, "@" & Chr$(64 + i), wb1.Worksheets("Input").Range(v)) Next wb2.Worksheets("Output").SaveAs p & "\EXCEL\" & Replace(s, "/", "_") & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False wb2.Worksheets("Output").ExportAsFixedFormat xlTypePDF, p & "\PDF\" & Replace(s, "/", "_") & ".pdf" wb2.Close False wb1.Range("N41").Value = wb1.Range("N41").Value + 1 End Sub `va in funzionamento ma reagisce cosi

in pratica mi apre la finestra di dialogo per salvare ma si vede anche che mi spezza la pagina output in 2. mentre il registratore mi salvava direttamente i file in modo corretto l'unica cosa che non faceva è rinominare i file correttamente ed inserire la numerazione + 1 al preventivo
1) Sulla variabile "s" naturalmente l'errore è mio perché l'avevo dichiarata in precedenza ma poi ho tolto l'istruzione Dim (o meglio l'ho sostituita dichiarando "p" ma non ho rimesso "s").
Nell'elenco delle varabili inserisci "Dim s as string".2) Come hai ben capito, togli la parte in cui si apre il Filedialog e lascia la dichiarazione diretta del percorso. Cioè tutta questa:
Set fd = Application.FileDialog(4) ' 4 --> msoFileDialogFolderPicker With fd .Title = "Seleziona la cartella in cui salvare" If .Show = 0 Then Exit Sub End With p = fd.SelectedItems(1)puoi toglierla. Elimina l'apice prima dell'istruzione che definisce "p" col suo percorso e sei a posto.
3) E' solo un problema di visualizzazione (del file originale, comunque).
In ogni caso sul numero progressivo c'era un errore sul range, che correggo in questa revisione:
Option Explicit Sub save_as() Dim fd As FileDialog Dim p As String Dim s As String Dim t As String Dim v As Variant Dim i As Integer Dim wb1 As Workbook Dim wb2 As Workbook Set wb1 = ThisWorkbook Set wb2 = Workbooks.Add wb1.Worksheets("Output").Copy after:=wb2.Worksheets(wb2.Worksheets.Count) p = "C:\Users\Anna\Desktop\Preventivi Eurolido\Excel" s = "@A - @B - @C - @D" For i = 1 To 4 v = Choose(i, "N41", "N42", "N43", "N44") s = Replace(s, "@" & Chr$(64 + i), wb1.Worksheets("Input").Range(v)) Next wb2.Worksheets("Output").SaveAs p & "\EXCEL\" & Replace(s, "/", "_") & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False wb2.Worksheets("Output").ExportAsFixedFormat xlTypePDF, p & "\PDF\" & Replace(s, "/", "_") & ".pdf" wb2.Close False With wb1.Worksheets("Input") .Range("N41").Value = .Range("N41").Value + 1 End With End SubMa non vorrei importi niente, era solo per suggerire un approccio. Se ti trovi meglio a modificare il codice che hi già prodotto e che funziona, fai pure. Dal mio esempio puoi solo prendere lo spunto per aggiustare il progressivo del preventivo 🙂
Ma non vorrei importi niente, era solo per suggerire un approccio. Se ti trovi meglio a modificare il codice che hi già prodotto e che funziona, fai pure. Dal mio esempio puoi solo prendere lo spunto per aggiustare il progressivo del preventivo
ma che scherzi mi stai aiutando ed io ci capisco ben poco da poter modificare per come mi passa la testa. ad ogni modo ho provato a modificare cosi ma mi da un errore 400 ed inoltre non capisco perchè mi crea ed apre un nuovo file cartel1 ti faccio vedere. io non vorrei che excel apra un altro file vorrei solo che li salvasse con quel determinato nome in excel e pdf ma non me lo deve aprire. il codice che sto usando è quello che mi hai postato prima
Sub save_as() Dim fd As FileDialog Dim p As String Dim s As String Dim t As String Dim v As Variant Dim i As Integer Dim wb1 As Workbook Dim wb2 As Workbook Set wb1 = ThisWorkbook Set wb2 = Workbooks.Add wb1.Worksheets("Output").Copy after:=wb2.Worksheets(wb2.Worksheets.Count) p = "C:\Users\Anna\Desktop\Preventivi Eurolido\Excel" s = "@A - @B - @C - @D" For i = 1 To 4 v = Choose(i, "N41", "N42", "N43", "N44") s = Replace(s, "@" & Chr$(64 + i), wb1.Worksheets("Input").Range(v)) Next wb2.Worksheets("Output").SaveAs p & "\EXCEL\" & Replace(s, "/", "_") & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False wb2.Worksheets("Output").ExportAsFixedFormat xlTypePDF, p & "\PDF\" & Replace(s, "/", "_") & ".pdf" wb2.Close False With wb1.Worksheets("Input") .Range("N41").Value = .Range("N41").Value + 1 End With End Subl'errore è questo

sinceramente mi sono un po arenato. Ti sto facendo impazzire ti chiedo scusa ma per il lavoro e la sua velocità sarebbe davvero importante che funzionasse per come ti ho detto.
L'idea di questo codice è generare un file temporaneo con quel particolare foglio, che viene salvato nella cartella stabilita (sia in formato Excel che in formato pdf). Poi si chiude e di sè non rimane altro (wb2.Close False). L'errore 400, che ogni tanto appare ed è uno spauracchio, è di difficile interpretazione. Il codice in sè è banale quanto del tutto innocuo e non coinvolge altre librerie. Bisogna che ci pensi un po' su.
capisco, il problema è che i file non si salvano proprio.
ti posso chiedere un ultima cosa ma se volessi modificare il codice che veniva dal registratore aggiungendo solo il rinomina come dovrei fare dove dovrei aggiungere il codice riesci ad aiutarmi solo in questo? il numero preventivo è secondario. ma dato che il registratore faceva il suo lavoro ma mancava solo il rinomina file basterebbe anche solo quello. purtroppo non ho le competenze per arrivarci da solo
se mi risolvi questo giuro che ti lascio in pace
allora spero apprezzerai la buona volontà. io ho risolto smanettando con questo codice cosi
Option Explicit Sub save_as() Dim fd As FileDialog Dim p As String Dim s As String Dim t As String Dim v As Variant Dim i As Integer Dim wb1 As Workbook Dim wb2 As Workbook Set wb1 = ThisWorkbook Set wb2 = Workbooks.Add wb1.Worksheets("Input").Copy after:=wb2.Worksheets(wb2.Worksheets.Count) p = "C:\Users\Anna\Desktop\Preventivi Eurolido" s = "@A - @B - @C - @D" For i = 1 To 4 v = Choose(i, "B3", "B1", "B6", "B7") s = Replace(s, "@" & Chr$(64 + i), wb1.Worksheets("Input").Range(v)) Next wb2.Worksheets("Input").SaveAs p & "\EXCEL\" & Replace(s, "/", "-") & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False wb1.Worksheets("Output").Copy after:=wb2.Worksheets(wb2.Worksheets.Count) ActiveSheet.Range("$A$5:$C$64").AutoFilter Field:=3, Criteria1:="<>" p = "C:\Users\Anna\Desktop\Preventivi Eurolido" s = "@A - @B - @C - @D" For i = 1 To 4 v = Choose(i, "B3", "B1", "B6", "B7") s = Replace(s, "@" & Chr$(64 + i), wb1.Worksheets("Input").Range(v)) Next wb2.Worksheets("Output").ExportAsFixedFormat xlTypePDF, p & "\PDF\" & Replace(s, "/", "-") & ".pdf" wb2.Close False Range("B1").Select Selection.ClearContents Range("B4").Select Selection.ClearContents Range("B5").Select Selection.ClearContents With wb1.Worksheets("Input") .Range("B3").Value = .Range("B3").Value + 1 End With End SubI file vengono salvati e rinominati correttamente. l'unico problema è nel file pdf che viene salvato e spezzato a metà. ti allego il file pdf che viene generato cosi ti faccio capire. Se posso esserti di aiuto secondo me il problema deriva dal fatto che il pdf viene generato dalla pagina Input mentre manualmente io faccio questi passaggi:
1. vado nella pagina Output
2. Faccio l'autofilter
3. Salvo con nome in pdf
Spero riuscirai a risolvermelo e ti ringrazio tanto per tutto l'aiuto e soprattutto per avermi spronato a risolvere anche in autonomia. Grazie
Allegati:
You must be logged in to view attached files.secondo me il problema deriva dal fatto che il pdf viene generato dalla pagina Input
Bè ma nel codice l'istruzione di salvataggio del pdf è chiara:
wb2.Worksheets("Output").ExportAsFixedFormatFaccio un paio di prove e ti dico.
Grazie mille
Ultima cosa magari mentre fai le prove.
Quando salvo il PDF ho bisogno che salvi solo l'output
Mentre quando salvo l'excel avrei bisogno di tutto il file comprensivo degli altri fogli mentre adesso mi salvo solo il foglio input
io nel frattempo sto facendo 1000 prove ti do un altro input di pensiero.
Se faccio la stampa pdf da VBA me lo taglia, mentre se faccio la stampa andando nella pagina output, salva con nome, pdf non me lo taglia (infameeee di un programma)
ti allego i due file cosi ti faccio vedere
Allegati:
You must be logged in to view attached files.secondo me il problema deriva dal fatto che il pdf viene generato dalla pagina Input
Risolto... banalmente la copia da un foglio a un altro non aggiusta la larghezza di colonna che quindi sfora la pagina e crea l'effetto sballato. Ecco la nuova versione del codice:
Option Explicit Sub save_as() Dim p As String Dim s As String Dim v As Variant Dim i As Integer Dim wb1 As Workbook Dim wb2 As Workbook Set wb1 = ThisWorkbook Set wb2 = Workbooks.Add wb1.Worksheets("Output").Copy after:=wb2.Worksheets(wb2.Worksheets.Count) p = "C:\Users\Anna\Desktop\Preventivi Eurolido" s = "@A - @B - @C - @D" For i = 1 To 4 v = Choose(i, "N41", "N42", "N43", "N44") s = Replace(s, "@" & Chr$(64 + i), wb1.Worksheets("Input").Range(v)) Next wb2.Worksheets("Output").Columns("A:A").ColumnWidth = 44.57 wb2.Worksheets("Output").SaveAs p & "\EXCEL\" & Replace(s, "/", "-") & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False wb1.Worksheets("Output").Copy after:=wb2.Worksheets(wb2.Worksheets.Count) wb2.Worksheets("Output").Range("$A$5:$C$64").AutoFilter Field:=3, Criteria1:="<>" wb2.Worksheets("Output").ExportAsFixedFormat xlTypePDF, p & "\PDF\" & Replace(s, "/", "-") & ".pdf" wb2.Close False End SubMentre quando salvo l'excel avrei bisogno di tutto il file comprensivo degli altri fogli mentre adesso mi salvo solo il foglio input
Ah ok. Allora si dovrà fare la copia integrale del Workbook, non solo del foglio di Output. Un attimo e arrivo 🙂
Questa dovrebbe essere la proposta finale, che salva il file originale integralmente. Ho ribaltato un po' il concetto iniziale, ma funziona. Mi scuso per tutti gli errori che un po' ingenuamente ho commesso in questo thread.
Option Explicit Sub save_as() Dim p As String Dim s As String Dim v As Variant Dim i As Integer Dim wb1 As Workbook Dim wb2 As Workbook Set wb1 = ThisWorkbook Set wb2 = Workbooks.Add p = "C:\Users\Anna\Desktop\Preventivi Eurolido" s = "@A - @B - @C - @D" For i = 1 To 4 v = Choose(i, "N41", "N42", "N43", "N44") s = Replace(s, "@" & Chr$(64 + i), wb1.Worksheets("Input").Range(v)) Next wb1.Worksheets.Copy before:=wb2.Worksheets(1) wb2.SaveAs p & "\EXCEL\" & Replace(s, "/", "-") & ".xlsx", FileFormat:=xlWorkbookDefault With wb2.Worksheets("Output") .Columns("A:A").ColumnWidth = 44.57 .Range("$A$5:$C$64").AutoFilter Field:=3, Criteria1:="<>" .ExportAsFixedFormat xlTypePDF, p & "\PDF\" & Replace(s, "/", "-") & ".pdf" End With wb2.Close True End SubSpero scherzi quando ti scusi dopo che ti ho portato finito una giornata intera ahahhaha
Cmq lo provo e ti faccio sapere
E grazie mille ancora
GENIOOOOOOOOOOOO
grazie tanta ho provato e sembra che sia tutto ok. grazie mille dell'aiuto vecchio frac
-
AutoreArticoli
