La consultazione del forum è libera per tutti.
Per poter porre un quesito è invece necessario essere un utente registrato (clicca qui se non lo sei).
Tutti gli utenti che richiedono un supporto, come da REGOLAMENTO, sono caldamente invitati ad allegare un file di esempio con l'indicazione di quello che si desidera ottenere.
Buongiorno, ben ritrovati,
avrei bisogno del vostro gentile supporto
So che dovrei allegare un file d'esempio ma provo a capire prima se possibile risolvere senza dato che sostanzialmente tutto funziona bene e il file in questione è voluminoso
Provo a spiegare la mia esigenza:
Dal Gestionale aziendale tiro fuori un file excel corposo che contiene i nomi degli agenti, le loro vendite nel mese di riferimento e importo il tutto nella mia cartella di lavoro, in un foglio che ho chiamato "CALCOLO". A questo punto, con l'aiuto del VBA, premendo un pulsante eseguo macro che elabora tutto il file completo e salva un file diverso per ogni agente, le sue vendite con le provvigioni calcolate
per ottenere questo, prendo come riferimento la prima riga che contiene il nome dell'agente fino all'ultima con la parola "totale agente", excel mi copia tutto cio che sta nel mezzo di queste righe in una nuova cartella di lavoro, imposta l'area di stampa e salva quest'ultima con il nome dell'agente e le sue provvigioni calcolate Dopo ciò si sposta di nuovo sulla cartella originaria contenente il resto dei dati e prosegue fino all'ultimo agente, creando e salvando un file per ognuno di loro con le loro provvigioni e permettendo a chi prima calcolava tutto a mano, di risparmiare ore di lavoro...
il tutto come dicevo, funziona bene ma nel momento in cui la macro va a creare la nuova cartella di lavoro per incollare il range di celle di quell'agente, succede che la nuova cartella si mette in primo piano davanti alla cartella originaria , fino a quando il codice stesso la salva e la chiude, e solo allora la cartella originaria ritorna in primo piano, Il tutto non crea problemi ma crea un effetto visivamente poco piacevole che vorrei evitare...
potevo evitare questa lunga spiegazione semplicemente chiedendo:
Esiste un modo per tenere in primo piano sempre e solo la cartella originaria mentre questa col codice che esegue crea un nuovo "workbook" inserisce le celle copiate e lo salva?
grazie mille
PS se devo postare il file di esempio cercherò di farlo epurandolo da dati sensibili così magari potete anche consigliarmi come ottimizzare il codice...
Grazie a tutti per l'aiuto
Un tempo, quando i mulini erano bianchi, esisteva l'istruzione Application.ScreenUpdating = False. Questa impediva lo "sfarfallio" proprio nella situazione che descrivi. Da Office 2013 c'è ancora ma non funziona più, per motivi che non starò qui a spiegare.
La risposta l'hai data tu stesso: "fino a quando il codice stesso la salva e la chiude, e solo allora la cartella originaria ritorna in primo piano". Ovvero, la cartella aperta rimane adesso sempre in primo piano, e non è una bella cosa.
Io risolvo così:
apro la CartellaAgente (diventa quella attiva)
CartellaAgente.Visible=False
CartellaPrincipale.Activate (restituisce vista della CartellaPrincipale).
Fino a qui facile. Poi, tutte le istruzioni relative a CartellaAgente devono essere svolte con
With Workbooks(CartellaAgente)
- istruzioni fino a
CartellaAgente.Visible=True
CartellaAgente.Save e
CartellaAgente.Close -
End With.
Lo sfarfallio scomparirà pur appesantendo (relativamente) tutto il processo a causa dell'Activate più che altro. Ma parliamo di millisecondi.
Naturalmente potresti automatizzare il tutto mettendo il nome dell'Agente(=cartella) in una variabile Public e creando una Sub che apre la cartella e la nasconde e quindi una che esegue
CartellaAgente.Visible=True
CartellaAgente.Save e
CartellaAgente.Close
o meglio Close con Save in una sola istruzione.
Se non è chiaro, chiedi. Buon lavoro.
Grazie, proverò ad integrare gli accorgimenti suggeriti e farò sapere
Salve ancora, per quanto riguarda la procedura che ho spiegato prima, vorrei specificare che
in realtà il nuovo foglio per ogni agente, viene generato duplicando il foglio di calcolo originale,
pulendolo dei dati non necessari e incollando solo il range relativo ai dati dell'agente interessato
Ho scelto il metodo
Sheets("CALCOLO").Copy che mi duplica il foglio di calcolo e che diventerà quello del singolo agente.
poi chiamo una sub che lo pulisce dei dati generali che lo contiene, e dopo , incollo i dati del singolo agente.
Ho scelto questo sistema perchè In questo modo duplico in modo automatico anche le intestazioni e una tabella fuori range che deve rimanere uguale per tutti gli agenti e che serve come riferimento e come "appoggio" per il calcolo provvigionale.
posto il pezzo del codice che funziona ma che purtroppo causa il passaggio alla finestra nuova, cosa che non vorrei che accadesse. Ovviamente alla chiusura del foglio di lavoro salvato, la finestra attiva torna ad essere quella del foglio originale, ma io vorrei che rimanesse sempre e solo quella.
Sheets("CALCOLO").Copy '***************************** 'duplica il foglio calcolo e poi chiama la sub PULIZIA per svuotarlo di dati non necessari 'in questo momento mi servirebbe che excel rimanesse sul foglio 'originale senza passare la finestra al foglio duplicato '******************************************************* NUOVOFILE = ActiveWorkbook.Name ' prende nota del nome '(che può essere tipo _CARTEL20 o CARTEL 21 ecc..) ActiveSheet.Name = nuovofoglio 'prende nota del nome del foglio (es."sheet1") Call pulizia ' chiama una sub di pulizia che seleziona un range di celle e lo svuota Workbooks(nomeorig).Activate 'attiva la cartella originaria dove sono presenti i dati del calcolo Worksheets("CALCOLO").Select ActiveSheet.Range("$A$" & rigainizio & ":" & "$L$" & riga).Copy 'copia il range che mi interessa Workbooks(NUOVOFILE).Activate 'attiva il nuovo foglio copiato e precedentemente pulito Worksheets(nuovofoglio).Activate '************** 'le seguenti righe partono da A2 nel nuovo foglio e incollano il range relativo ai dati 'dell'agente che servono, servendosi di variabili come r DoEvents Range("a2").Select ActiveSheet.Paste Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _ SkipBlanks:=False, Transpose:=False Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _ SkipBlanks:=False, Transpose:=False ActiveSheet.PageSetup.PrintArea = "$A$1" & ":" & "$L$" & r + 2 Cells(r + 2, 12).FormulaLocal = "=somma(L3:" & "L" & r & ")" 'alla fine si provvede a salvare il nuovo foglio con data e ora corrente e l'ultima istruzione lo chiude Range("A1").Select ActiveWorkbook.SaveAs Filename:=percorso & nuovofoglio & Format(Now(), "DD-MMM-YYYY hh mm AMPM") & ".xlsx" ActiveWorkbook.Close
Ho letto un po' e non leggerò oltre.
Per fare quello che vorresti queste istruzioni sono veleno:
Workbooks(NUOVOFILE).Activate
Worksheets(nuovofoglio).Activate
Qui devi invece dovresti lavorare con:
Range(.Cells(RigaInizio, ColonnaInizio), .Cells(RigaFine, ColonnaFine)).Copy_ Destination:=Sheets(nuovofoglio).Range("dovetipare")
With Workbooks(NUOVOFILE).Worksheets(nuovofoglio)
bla bla bla
Workbooks(NUOVOFILE).Close savechanges:=True
End with
Naturalmente la cartella principale sarò bloccata fino a fine esecuzione della routine ma lavora sottotraccia e non sfarfalla.
@emme
Grazie, cercherò di modificare il codice utilizzando questi accorgimenti,
o letto un po' e non leggerò oltre.
Per fare quello che vorresti queste istruzioni sono veleno:
Del resto sono cosciente di non essere capace di scrivere codice ottimizzato altrimenti non sarei nemmeno qui a chiedere consigli
Grazie comunque Appena avrò possibilità di ottimizzare il codice e constatato il funzionamento posterò la risoluzione
Buongiorno
scrivo per alcune osservazioni e per dire che non so per quale strano motivo,
nel mio caso ho provato ad usare application.screenupdating
ed ha funzionato, quindi mi esegue la macro come io desidero senza spostare la visualizzazione dal foglio principale. Ho provato a utilizzarla col codice originale che avevo scritto quindi prima di modificare il codice con gli accorgimenti suggeriti e la differenza quando elimino l'istruzione si nota. (sarà qualche release di office dove application.screenuptading è stata fixata? ) nel mio caso è andata bene
ciò non cambia che comunque applicherò i suggerimenti ricevuti e quindi
di sicuro resta il proposito di riscrivere il codice in modo piu "accademico" cosi da ottimizzarlo.
Resta il fatto che gli spunti ricevuti mi hanno spinto a studiare piu approfonditamente il modo di lavorare su workbooks e worksheets, la differenza tra "activate" e "select"
grazie ancora...
Saluti a tutti
Buongiorno.
A questo punto tutti noi abbiamo bisogno di un chiarimento:
che versione di office stai usando? Se antecedente a Office2013, sicuramente funziona.
Altrimenti significa che MS ha ripristinato la funzione, mantenendo il segreto come aveva fatto quando l'aveva disabilitata. E come anche per molte altre questioni irrisolte (una per tutte la gestione del calendario nativa, poi risolta con altri magici arzigogoli).
Un po' di storia della funzione: fino a Office 2010, quando si aprivano più file, questi finivano tutti sotto lo stesso ombrello: una istanza (Excel) aperta, più Workbooks. Da Office2013 non vale più: ogni Workbook, una istanza. Quindi si vedranno tanti Excel quanti Workbooks. Questo non permette l'uso dell'istruzione perché non dovrebbe saltare più da un Workbook all'altro ma da un Excel all'altro.
Se ripristinata è una grande notizia per tutto il mondo Vba!
Grazie per una risposta.
P.s.: vedo adesso che hai il 2013.
in questo articolo del 5 aprile 2019 MS lo dà come funzionante. Farò qualche prova.
non vorrei dire un'eresia ma sembrerebbe se ho capito bene leggendo qua e là (un pò anche nei forum in lingua inglese), che il metodo "doevents" ( che ho usato per tenere un form con una progress bar sempre ben visibile sullo schermo) risveglierebbe anche application.screenupdating
ma è un'informazione da prendere con le molle...
ripeto, sarà un'eresia, o magari semplicemente application.screenupdating FUNZIONA di nuovo...
Come supponevo a me non funziona. Ho costruito una semplice routine che copia alcune righe/colonne da un foglio a un secondo della stessa cartella (qui funziona ed è il tuo caso) e poi su un foglio di cartella diversa (qui non funziona) . DoEvents o no, il flickering non smette. Dovremmo entrare nel mondo SDI/MDI per risolvere la cosa, ma comunque sembra non tutto filerebbe liscio.
In Excel 2013 è stata introdotta la funzionalità SDI (Single Document Interface). Le cartelle di lavoro di Excel 2013 sono ora finestre di primo livello in Windows. In questa configurazione, Windows gestisce l'attivazione delle finestre anziché Excel che gestisce le finestre figlio come nelle versioni precedenti del programma.
Ho di nuovo girato un po' nel web e nessuno è riuscito a risolvere la questione se non attraverso le istruzioni ActiveWorkbook.Visible = False
ThisWorkbook.Activate
Una delle soluzioni, non da MS che non ha MAI risposto alle numerosissime richieste:
Dim wbName As Window
Set wbName = Windows("your workbook name")
wbName.Visible = False
other code here
wbName.Visible = True
o il flickering continua indisturbato.