Macro copia formule



  • Macro copia formule
    di Valeria80 data: 10/06/2013 18:14:09

    Ciao a tutti,
    ho una macro che funziona ma che è molto lenta e vorrei trovare un'alternativa più veloce.
    In pratica nello sheet "DB" devo copiare e incollare le formule che si trovano nella riga 2 delle colonne dalla A alla J fino a quando la colonna K ha dei valori. La lunghezza della colonna K varia di volta in volta, le formule vanno copiate nelle colonne dalla A alla J a partire dalla riga 3.
    Dato che la colonna K può arrivare ad avere anche 50.000 righe, la macro diventa lentissima.

    C'è modo di creare una macro più veloce con lo stesso risultato?

    Grazie a tutti in anticipo
    Valeria
     
    Sub Importa_DB()
        Dim wk2 As Workbook
        Dim sh2 As Worksheet
        Application.ScreenUpdating = False
        Set wk2 = ThisWorkbook
        Set sh2 = wk2.Worksheets("DB")
     
        With sh2
            n = Worksheets("DB").Cells(Worksheets("DB").Rows.Count, "K").End(xlUp).Row 
            If n > 1 Then
                n = n - 1
                For i = 2 To n Step 1
                    Worksheets("DB").Range("A" & i & ":J" & i).Copy
                    Worksheets("DB").Range("A" & i + 1 & ":J" & i + 1).PasteSpecial xlPasteFormulas
                Next i
            Else
                MsgBox "Non ci sono formule da copiare", vbInformation
            End If
        End With
    End Sub


  • Sintassi ciclo for
    di adriprivate (utente non iscritto) data: 10/06/2013 18:14:12

    Ciao ragazzi e buon inizio settimana..

    Volevo capire una cosa...
    es.

    dim a as integer
    dim risultato1 as double,....... risultato8 as double
    dim costo1 as double,........ costo8 as double
    dim matrice as double

    matrice = "0.4"
    costo1 = labelxxxxx 'assegno in una variabile dei valori presenti nelle label
    costo2 = labelyyyyy
    ...
    costo8 = labelzzzzz


    'calcolo il vari risultati dividendo i valori di due variabili e li asseno a delle label denominate lbl1, lbl2......lbl8
    For a = 1 To 8
    risultato(a) = costo(a) / matrice '
    UserForm1.Controls("LBL" & (a)) = risultato(AA)
    risultato(a) = CSng(Replace("LBL" & (a), ".", ","))
    Next


    La sintassi corretta per assegnare ad una variabile il nome risultato1... risultato8 costo1.... costo8, ed ad una label lbl1... lbl8 qual'è?

    Nei vostri precedenti post o visto che avete usato .controls per le label mentre per le variabili semplicemente nomevariabile(a)....

    Spero di essere stato chiaro..


    Buona serata!



  • di mabolsie data: 10/06/2013 18:39:44

    @ Valeria80

    purtroppo elaborare 50.000 righe è un bel carico ed il codice che hai usato mi sembra adatto allo scopo, dipende tutto dal computer (che computer hai ? ) nel senso Processore e Ram, se hai una ram inferiore ai 4 GB è facile che sia dovuto a quello se ne hai meno è probabile che ti si blocchi l'elaborazione del codice.

    Quindi o cambi il computer o riduci le righe o porti pazienza.

    Ciao Max

    @Adriprivate

    Hai sbagliato ad inserire la discussione, devi aprire una nuova discussione.

    Ciao Max



  • di Vecchio Frac data: 10/06/2013 19:10:07

    @Valeria80
    Questo è il genere di sfide che mi piacciono ^_^
    Appena ho un attimo vedo di studiare la cosa.
    Max ha ragione sulla potenza di elaborazione, ma in genere qualcosa si può comunque provare a fare.






  • di Valeria80 data: 11/06/2013 10:49:08

    Il pc ha 4 gb di RAM, per ora deve elaborare "solo" 20.000 righe quindi porta a termine il risultato ma ci impiega quasi 2 ore...
    Ora faccio una domanda abbastanza sciocca, ma di programmazione non ne so molto: se io mettessi una cella in un altro sheet con una banale formula che mi conta i valori presenti nella colonna K dello sheet "DB" ogni volta avrei il numero di "arrivo" della macro. Non c'è modo di dire alla macro copia le formule in blocco (e non una per una) da riga 2 a riga n dove n è pari alla cella con il conta valori?
    Ciao a tutti e grazie
    Valeria



  • di isy data: 11/06/2013 11:51:23

    Ciao

    Per poterti aiutare hai la possibilità di allegare un foglio con un esempio di formule presenti.
    Nel caso non sia possibile ridurre la complessità delle formule potresti calcolarne il valore nella cella.
    Ovviamente ci sarà un aggiornamento dei dati tramite vba per aggiornare il foglio eliminando gran parte delle formule.
    In attesa...



  • di Valeria80 data: 11/06/2013 19:27:00

    Ciao isy,
    ti allegherò il file non appena avrò modo di fare uno zip o un rar (in ufficio ho altri software).
    Fondamentalmente si tratta solo di cerca verticale e qualche divisione, nessuna formula particolare, anche se da quello che so i cerca verticale sono formule pesanti.
    L'altro problema è che il DB è scaricato da SAP, e i dati copiati da SAP rendono il file pesante (ad oggi sono ca 40 MB, considerando che il file è pieno di altri sheet con cerca.verticale e info.dati.pivot). Per cui credo che questi fattori rallentino di molto la macro.

    Ciao a tutti e grazie
    Valeria



  • di HarryBosch data: 12/06/2013 11:29:09

    Ciao Valeria e un saluto a tutti

    Nel codice che hai postato noto diverse cose che rallentano decisamente l'esecuzione: in particolare il fatto che copi, tramite un ciclo for, una riga per volta. Semplicemente, visto che le formule si portano appresso i propri riferimenti, copiare in blocco la riga interessata sull'intero intervallo.

    Poi, anche se influisce di poco, ti preoccupi di definire il foglio "DB":
    Set sh2 = wk2.Worksheets("DB")
    e poi utilizzi il With riproponendo gli stessi riferimenti alla cartella e al foglio, che invece andrebbero evitati. Il punto antecedente al range già completa il riferimento al foglio definito in precedenza.
    Il riferimento alla cartella Workbook puoi evitarlo, a patto di non trovarti in altra cartella di lavoro.

    Nota che Application.screenupdating, andrebbe reimpostato a True prima dell'uscita.

    Ti propongo una revisione del codice che dovrebbe fare quello che intendi, e credo molto più velocemente.




     
    Sub Importa_DB()
        Dim sh2 As Worksheet
        Dim n As Integer
        
        Application.ScreenUpdating = False
        Set sh2 = Sheets("DB")
     
        With sh2
            n = .Cells(.Rows.Count, "K").End(xlUp).Row
            If n > 1 Then
                    .Range("A2:J2").Copy
                    .Range("A2:J" & n).PasteSpecial xlPasteFormulas
            Else
                MsgBox "Non ci sono formule da copiare", vbInformation
            End If
        End With
        Application.ScreenUpdating = True
    End Sub
    



  • di Valeria80 data: 12/06/2013 12:27:12

    L'elaborazione ora è rapidissima. Grazie mille HarryBosch (se il tuo nickname si riferisce al personaggio di Connelly mi sembra azzeccato ).

    Grazie a tutti per avermi fornito il vostro supporto.

    Buona giornata
    Valeria



  • di Vecchio Frac data: 12/06/2013 12:48:29

    Il grande Harry colpisce ancora ;)





  • di HarryBosch data: 12/06/2013 13:30:35

    ... e in effetti il nik nasce proprio dal personaggio di Connelly, di cui sono stato tanto appassionato :)

    Ma già VecchioFrac lo aveva intuito qualche tempo addietro ^_^



  • di Valeria80 data: 12/06/2013 14:23:11