2013-08-24 28 views
5

Sto riscontrando un problema piuttosto semplice con la macro. In esso, assegno una formula a una cella. Mi piacerebbe non calcolarlo all'inizio e fare il calcolo solo dopo che è stata completata un'altra parte di Macro. Ho pensato di fare qualcosa del genere:Excel e VBA: ignora la formula di calcolo nella macro

Application.Calculation = xlCalculationManual 
Cells(StartRow, 4 + i).Formula = "FORMULA" 
... 
Application.Calculation = xlCalculationAutomatic 

Ma questo non funziona. Arresta i calcoli automatici, ma non per quella cella: esegue comunque il calcolo subito dopo aver assegnato la formula. C'è un modo per saltarlo?

Per chiarire il concetto esatto di questo: nel mio codice reale sto assegnando una formula a un gruppo di celle in un ciclo. Ogni volta che lo assegno a una cella, lo calcola. Ho pensato che se prima li assegnassi tutti e poi fare il calcolo - sarebbe più veloce. In realtà è. Quindi, invece di assegnarlo a un ciclo, lo assegno alla prima cella e poi lo compio automaticamente. Le formule compilate automaticamente attendono fino a quando non abilito il calcolo automatico e ottengo una macro molto più veloce. Tuttavia, il assignemnt iniziale è ancora calcolato, il che rende la macro quasi due volte più lenta.

+0

solo un pensiero da provare: puoi mantenere la formula in qualche cella nascosta? E nella tua sola macro, PasteSpecial la formula? Con un po 'di fortuna che funziona come il riempimento automatico e calcola solo alla fine ... –

risposta

7
  1. luogo la formula nella cella con un carattere di prefisso
  2. continuare la macro
  3. "attivare" la formula

ad esempio:

Sub dural() 
    With Range("A1") 
     .Value = "'=1+2" 
     MsgBox " " 
     .Value = .Value 
    End With 
End Sub 
+0

Brilliant trick. Ogni giorno imparo qualcosa di nuovo :) – Vikas

+0

Questo è intelligente. – enderland

+0

Questo è fantastico :) – pokrishka

2

@alex, è può ritardare il calcolo come risposta @Gary. Tuttavia, stavi facendo la domanda perché hai bisogno di "SPEED to CYCLE through cells" mentre assegni una formula, giusto?

Se sì, dal mio punto di vista, se NON utilizzando le formule fino TUTTI le formule vengono assegnati nel foglio excel, si otterrà un sacco di velocità scrivendo tutte le formule a una volta utilizzando un array (un singolo passaggio in VBA).

La procedura è: innanzitutto inserire tutte le formule in un array VBA di stringhe e in seguito utilizzare ad esempio Range("B1:B100").Formula = ArrayWithFormulas. Nell'esempio si assegnano 100 formule contemporaneamente, senza ricalcolo intermedio.

Vedrai un grande miglioramento in VELOCITÀ se usi un array per scrivere tutte le celle su quelle invece di scrivere una cella per cella! (Non eseguire il loop utilizzando cells(r,c+i) se sono presenti molte celle). Qui un esempio:

Sub CreateBunchOfFormulas() 
    Dim i As Long 
    Dim ARRAY_OF_FORMULAS() As Variant 'Note: Don't replace Variant by String! 
    ReDim ARRAY_OF_FORMULAS(1 To 100, 1 To 1) 
          ' For Vertical use: (1 to NumRows,1 to 1) 
          ' for Horizontal: (1 to 1,1 to NumCols) 
          ' for 2D use: (1 to NumRows,1 to NumCols) 
    'Create the formulas... 
    For i = 1 To 100 
    ARRAY_OF_FORMULAS(i, 1) = "=1+3+" & i ' Or any other formula... 
    Next i 

    ' <-- your extra code here... 
    '  (New formulas won't be calculated. They are not in the Excel sheet yet! 
    '  If you want that no other old formula to recalculate use the old trick: 
    '  Application.Calculation = xlCalculationManual) 

    'At the very end, write the formulas in the excel at once... 
    Range("B1:B100").Formula = ARRAY_OF_FORMULAS 

End Sub 

Se si desidera un ritardo in più nella nuova formula, quindi è possibile utilizzare trucco @Gary, ma applicato a una vasta gamma, non a una singola cella.Per questo iniziano le formule con un ' come '=1+2 e aggiungere il seguente codice alla fine:

'... previous code, but now formulas starting with (') 
    Range("B1:B100").Formula = ARRAY_OF_FORMULAS 
    'Formulas not calculated yet, until next line is executed 
    Range("B1:B100").Value = Range("B1:B100").Value ' <~~ @Gary's trick 
End Sub 

scorso, un piccolo snipped: se le formule sono in una disposizione orizzontale (Mezzi una formula per la colonna A, l'altro per colonna B, ecc) e solo un piccolo numero di colonne, allora si può tenere a mente l'una versione più breve del precedente codice:

Dim a as Variant 'Note that no() needed 
a = Array("=1+3","=4+8","=5*A1","=sum(A1:C1)") 
Range("A1:D1").Formula = ARRAY_OF_FORMULA ' Just a single row 
' or... 
Range("A1:D100").Formula = ARRAY_OF_FORMULA ' If you want to repeat formulas 
              ' in several rows. 

Infine, è possibile utilizzare il metodo .FormulaR1C1 invece di .Formula in tutto il codice precedente esempi, se vuoi un modo semplice per usare riferimenti relativi nella tua formula ...

Spero che questo aiuti!

+0

Sembra interessante. Grazie! Finora ho usato il suggerimento di Gary abbastanza bene. Aggiungo formule con apostrofo in un ciclo all'intero intervallo e poi le eseguo tutte con Range (qualunque) .Value = Range (qualunque) .Valore – pokrishka

+0

Buono! Se vedi che devi migliorare la velocità, puoi usare questo ;-). Altri suggerimenti sulla velocità, qui: [(1) Excel VBA: efficienza e prestazioni] (http://www.avdf.com/apr98/art_ot003.html) - [(2) codifica rapida] (http: // blogs .msdn.com/excel/archive/2009/03/12/excel-vba-performance-coding-best-practices.aspx) - [(3) Informazioni Microsoft sul passaggio di un array a VB] (http: // support. microsoft.com/kb/153090/en-us) –

Problemi correlati