+ Rispondi al Thread
Visualizzazione dei risultati da 1 a 10 su 10

Discussione: Problema di ciclo e creazione di nuovi fogli di lavoro

  1. #1
    Thebeginner non è in linea Novello
    Post
    5

    Problema di ciclo e creazione di nuovi fogli di lavoro

    Buonasera a tutti,

    intanto sono contento di essere entrato a far parte della comunità e come si nota dal mio nick sono agli inizi della programmazione.

    Ho un woorkbook con uno sheets di reporting di nome REPORT, che viene alimentato da uno sheets dello stesso oggetto di nome DATI. In pratica, grazie ad una struttura di indice e confronta, ciclando il valore della cella C5 del foglio REPORT ho una alimentazione dinamica del report.
    A questo punto vorrei selezionare il contenuto dell'area RANGE("B5:J25") copiarla ed incollarla come valori su un nuovo
    foglio Excel e salvarlo in una cartella del mio desktop con il nome uguale al valore della cella Cells (4,2) del foglio REPORT.
    Ho provato con la sintassi for next e con l'ausilio del registratore di macro a scrivere del codice con risultati deludenti.

    Dal punto di vista logico ho schematizzato il problema come segue:

    1 ciclo sulla cella C5 del foglio REPORT;
    2 copia del range B5:J25 del foglio REPORT;
    3 apertura nuovo foglio di lavoro Excel;
    4 incolla su nuovo foglio Excel il contenutto copiato;
    5 Salva il foglio di lavoro sulla path come valore cella B4 dello sheets report;
    6 step i+1

    Sicuramente ho dei problemi a passare dal foglio di lavoro master con dati e report a quelli nuovi.
    Dal punto di vista logico ho impostato bene il problema? Qualcuno può darmi una mano.

    Grazie mille a chi vorrà aiutarmi

  2. #2
    L'avatar di dragone bianco
    dragone bianco non è in linea Moderatore Globale
    Luogo
    Aosta
    Post
    7,724
    Ciao Thebeginner, Benvenuto nel Forum

    Visto che sei alle prime armi con il VBA di Excel puoi consultare queste sezioni che contengono articoli in merito ad excel e il VBA in Generale
    Forum Excel - Articoli
    Forum Microsoft Office, Access, VBA - Articoli

    Premessa
    L'uso del registratore per alcuni operazioni è deludente (Come il caso Copia incolla)
    Tende a registrare tutto anche le selezioni dei foglio

    Esempio (Copia dal "foglio1" Cella "D2" nel "Foglio2" Cella "A1", Solo valore)
    Registratore Restituisce
    codice:
        Sheets("Foglio1").Select
        Range("D2").Select
        Selection.Copy
        Sheets("Foglio2").Select
        Range("A1").Select
        ActiveSheet.Paste
    Codice
    invece ti basta scrivere semplicemente (funziona anche con l'uso del CElls)
    codice:
    worksheets("Foglio2").range("A1")=worksheets("Foglio1").range("D2")

    per il tuo problema alcuni spunti
    usa 2 variabili WorkBook (gestisce i file)
    Uno per registrare il file corrente
    L'altro per creare un nuovo File
    Quando crei un nuovo file di solito agguerrisce quest'ultimo lo stato di attivo
    Per cambiare il file attivo usa "Activate" (per i file Excels)

    ES
    codice:
    Dim File_Corrente as Workbook
    Dim File_Nuovo as Workbook
    
    set File_Corrente=ActiveWorkbook 'memorizzo il file correntemente attivo
    set File_Nuovo = Workbooks.Add 'Memorizzo il nuovo file non ancora salvato
    
    File_Corrente.activate 'Per Scrupolo rendo attivo il file corrente
    Per salvarlo usa il SaveAs che ti permette di specificare il percorso completo e il nome del file
    e Close per chiuderlo
    Il close ti permette di poter salvare il file e dargli un nome (Vedi la guida in linea)
    codice:
    File_Nuovo.saveas("C:\Prova.xls") 'salvo il file
    File_Nuovo.close 'Chiudo il file
    Set File_Nuovo= nothing 'Distruggo la variabile
    ora nel tuo caso per copiare da un file all'altro è come l'esempio iniziale ma devi specificare il file
    Se hai 2 variabili WorkBook il codice è semplice
    codice:
    File_Nuovo.Worksheets("foglio1").Range("A1")=File_corrente.Worksheets("foglio2").Range("B1")
    avendo più celle contiggue puoi usare 2 cicli for nidificati e usare cell
    Es
    codice:
    for Riga=1 to 3
       For Colonna=2 to 4
           File_Nuovo.Worksheets("foglio1").cells(riga+2,colonna+2)=File_corrente.Worksheets("foglio1").cells(riga,colonna)
       next Colonna
    next riga
    copio le celle da "B1" a "D3" del "foglio1" del "mio file" nel "foglio1" del "file nuovo" nelle celle "D3 a F5"

    Ciao

  3. #3
    Thebeginner non è in linea Novello
    Post
    5
    Intanto ti ringrazio moltissimo dragone bianco del benvenuto e dei ricchi consigli che mi hai dato.
    Sto provando a strutturare lo script come mi hai suggerito.
    Ricapitolando la tattica è di creare due cartelle di lavoro con assegnamento al file dati ed al nuovo file che viene creato e salvato nella path specificata.
    Lettura/copia tramite ciclo per riga e colonna dell'intervallo del foglio dati ed incolla sul nuovo foglio dell'oggetto workbook.
    Iterazione del ciclo sulla cella C5 del foglio dell'oggetto workbook corrente.

    Provando ad scrivere il codice il debug mi segnala un errore di tipo non definito dall'utente.
    Stavo vedendo in altre parti del forum che dovrebbe mancare un riferimento ad una qualche libreria.

    Ti ringrazio davvero delle istruzioni sui vari assegnamenti delle variabili.

  4. #4
    L'avatar di dragone bianco
    dragone bianco non è in linea Moderatore Globale
    Luogo
    Aosta
    Post
    7,724
    Il codice da dove lo esegui
    Da excel???

    I codici che ti ho scritto sono del VBA Di excel se usi altro programma devi richiamare la libreria di excel
    Ciao

  5. #5
    Thebeginner non è in linea Novello
    Post
    5
    Si il codice lo eseguo da Excel.

    Il debugger restituisce errore all'assegnamento del File_Nuovo all'oggetto woorkbook.
    Ciao

  6. #6
    L'avatar di dragone bianco
    dragone bianco non è in linea Moderatore Globale
    Luogo
    Aosta
    Post
    7,724
    Ciao

    questo test funziona Bene
    codice:
    Sub prova()
    Dim File_Corrente As Workbook
    Dim File_Nuovo As Workbook
    
    Set File_Corrente = ActiveWorkbook 'memorizzo il file correntemente attivo
    Set File_Nuovo = Workbooks.Add 'Memorizzo il nuovo file non ancora salvato
    
    File_Corrente.Activate 'Per Scrupolo rendo attivo il file corrente
    
    File_Nuovo.SaveAs File_Corrente.Path & "\Prova.xls"
    File_Nuovo.Close
    
    Set File_Nuovo = Nothing
    Set File_Corrente = Nothing
    End Sub
    Nei Tread prima mi sono accorto ora che ho inserito delle parentesi di troppo su File_Nuovo.SaveAs
    I parametri devo definirli senza parentesi se non salvo il risultato in una variabile

    In questo esempio ho usato come parametro
    File_Corrente.Path & "\Prova.xls"

    File_Corrente.Path Restituisce il percorso del file corrente

    Eventualmente posta la porzione di codice che ti da problemi
    Ciao

  7. #7
    Thebeginner non è in linea Novello
    Post
    5
    Grazie ancora Dragone bianco.

    In realtà il debugger mi segnala errore (Tipo definito dall'utente non definito) già alla seconda istrtuzione quella di assegnamento
    del File_Nuovo all'oggetto woorbook:

    codice HTML:
     Dim File_Corrente As Workbook
        Dim File_Nuovo As Woorkbook
    Diciamo che ridendoci su mi sono arenato prima di iniziare

    Ciao

  8. #8
    L'avatar di dragone bianco
    dragone bianco non è in linea Moderatore Globale
    Luogo
    Aosta
    Post
    7,724
    Ciao Thebeginner

    Attento nella seconda riga cè una "o" di troppo
    "Workbook" e non "Woorkbook"

    Ciao

  9. #9
    Thebeginner non è in linea Novello
    Post
    5
    Ciao Dragone,
    ti ringrazio davvero tanto. Non vorrei abusare della tua disponibilità.
    Penso che si tratta di uno script troppo impegnativo per lo stato attuale delle mie conoscenze ( sto riscontrando diversi errori tra cui il 91 ).
    Potresti eventualmente consigliarmi un percorso formativo per arrivare a risolvere problemi del genere?

    Grazie mille di tutto

  10. #10
    L'avatar di Sensero
    Sensero non è in linea Novello
    Post
    33

    Soluzione con tre files

    Ciao TheBeginner,
    per quello che ho avuto modo di intendere quando abbiamo avuto l'occasione di parlare dell'argomento di questo thread, ho cercato di strutturare una soluzione che si appoggia su tre files:
    1) Uno di "Input", File_Corrente, da cui prendo i dati che variano tra una iterazione ed un'altra grazie ad indice/confronta
    2) Uno di "Output", File_Nuovo, in cui incollo i valori di quanto ho copiato dal file di input
    3) Un file di "Elenco", che mi consente di produrre ogni volta i files di output che desidero (tra l'altro, gestendo a priori il problema dei codici che con indice/confronta hanno come risultato #N/D, perché si possono escludere dall'elenco)

    Ecco il codice:

    codice:
    Sub Schede()
    
    'definisco la tipologia di variabili
    
    Dim File_Corrente As Workbook
    Dim File_Nuovo As Workbook
    Dim File_Elenco As Workbook
    
    
    'definisco il valore che assumono delle variabili con il prefisso del predicato Set
    
    Set File_Elenco = Workbooks.Open("C:\Test\Elenco.xlsx")     'memorizzo il file di Elenco codice, una colonna A di codici con cui etichettare le schede di output
    Set File_Corrente = Workbooks.Open("C:\Test\Input.xlsx")    'memorizzo il file di input
    Set File_Nuovo = Workbooks.Open("C:\Test\Template.xlsx")    'memorizzo il file di output
    
    'nascondo alla vista l'operare della macro
    
    Application.ScreenUpdating = False
    
    'Seleziono il file con l'elenco dei codici nella Colonna A che costituiranno i nomi dei miei files di output
    '(la cella A1 è una intestazione di colonna, i codici iniziano da A2)
    
    File_Elenco.Activate
    Range("A2").Select
    
    'Copio il valore nel mio elenco in una cella del file "Corrente" per farlo leggere alla formula Indice/Confronta
    
    File_Corrente.Worksheets("Foglio1").Range("C5") = File_Elenco.Worksheets("Foglio1").Range("A2")
    
    'Torno al file di Elenco, selezionando la cella con il primo codice della colonna
    
    File_Elenco.Worksheets("Foglio1").Activate
    Range("A2").Select
    
    'Avvio un loop per leggere tutti i codici in Elenco e creare un file di output
    
    Do While ActiveCell <> ""
    
    'valorizzo la cella C5 del File_Corrente con il valore attuale nella cella attiva del file elenco
    
    File_Corrente.Worksheets("Foglio1").Range("C5") = ActiveCell
    
    Set File_Nuovo = Workbooks.Open("C:\Test\Template.xlsx")    'memorizzo il file di output
    
    File_Corrente.Worksheets("Foglio1").Activate 'Per Scrupolo rendo attivo il file corrente
    
    'copio le informazioni da riportare su un file e foglio nuovo
    
    File_Corrente.Worksheets("Foglio1").Range("B5:J25").Copy
    
    'Seleziono il file e foglio, poi incollo i valori
    
    File_Nuovo.Worksheets("Foglio1").Activate
    Range("B5:J25").Select
    Selection.PasteSpecial xlPasteValues
    
    'Seleziono la cella C5 dove è riportata l'etichetta da usare per salvare il nuovo file
    
    File_Nuovo.Worksheets("Foglio1").Activate
    Range("C5").Select
    
    File_Nuovo.SaveAs "C:\Test\Output" & "\" & ActiveCell & ".xlsx" 'salvo il file con stringa variabile
    
    File_Nuovo.Close 'Chiudo il file
    
    'Seleziono un nuovo codice dal file elenco, scendendo di una cella grazie al riferimento relativo
    
    File_Elenco.Worksheets("Foglio1").Activate
    
    ActiveCell.Offset(1, 0).Range("A1").Select
    
    Loop
    
    'alla fine della creazione di tutti i files, chiudo il file corrente ed elenco senza salvarli
    
    File_Corrente.Close SaveChanges:=False
    File_Elenco.Close SaveChanges:=False
    
    'ripristino lo schermo
    
    Application.ScreenUpdating = True
    
    End Sub
    L'ho provato su mio pc e funziona. E' sufficiente:

    1) Creare la cartella C:\Test
    2) Creare la cartella C:\Test\Output
    3) Creare all'interno di C:\Test i seguenti tre files

    Elenco.xlsx
    Input.xlsx
    Template.xlsx

    Nel file di Input puoi valorizzare con dei numeri a caso il range B5:J25, per vedere come te li incolla nel file di output (Template). Occhio che nella cella C5 sia del cosiddetto file di input sia in quello di output sarà incollato il valore di elenco oggetto di indice/confronta, perché così ho inteso che poteva essere letto dalle formule nelle altre celle del foglio di "input".

    Nella cartella "Output" troverai tutti i files che la macro avrà prodotto.

    Male che va, se non dovesse funzionare, puoi contattarmi in MP per passarti i files su cui ho fatto girare questo codice. Ma non dovrebbero esserci problemi.

    Ciao!

+ Rispondi al Thread

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi