2013-08-24 16 views
5

Ich habe ein ziemlich einfaches Problem mit Macro. Darin weise ich einer Zelle eine Formel zu. Ich möchte es nicht zuerst berechnen und erst nach einem anderen Teil von Macro rechnen. Ich dachte, ich würde so etwas tun:Excel & VBA: Formel in Makro überspringen

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

Aber das funktioniert nicht. Es stoppt die automatischen Berechnungen, aber nicht für diese Zelle - es führt immer noch die Berechnung aus, nachdem ich die Formel zugewiesen habe. Gibt es eine Möglichkeit, es zu überspringen?

Um das genaue zu klären: In meinem tatsächlichen Code weise ich einer Gruppe von Zellen in einem Zyklus eine Formel zu. Jedes Mal wenn ich es einer Zelle zuordne - es berechnet es. Ich dachte mir, wenn ich sie alle erst zuweisen und dann die Berechnung machen würde - es wäre schneller. In der Tat ist es. Anstatt es in einem Zyklus zuzuweisen, weise ich es der ersten Zelle zu und fülle es dann automatisch aus. Automatisch ausgefüllte Formeln warten, bis ich die automatische Berechnung aktiviere und ich ein viel schnelleres Makro erhalte. Jedoch wird die anfängliche Zuweisung immer noch berechnet, was das Makro fast doppelt so langsam macht.

+0

nur ein Gedanke zu versuchen: können Sie die Formel in einer versteckten Zelle behalten - und in Ihrem Makro nur PasteSpecial die Formel? Mit ein bisschen Glück funktioniert das ähnlich wie beim Autofill und berechnet erst am Ende ... –

Antwort

7
  1. Ort die Formel in der Zelle mit einem Präfixzeichen
  2. weiterhin das Makro
  3. "aktivieren", um die Formel

zum Beispiel:

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

Brilliant Trick. Ich lerne täglich etwas neues hier :) – Vikas

+0

Das ist schlau. – enderland

+0

Das ist genial :) – pokrishka

2

@ Alex, Sie kann die Berechnung als @Gary-Antwort verzögern. Sie stellten jedoch die Frage, weil Sie "SPEED to CYCLE durch Zellen" benötigen, während Sie eine Formel zuweisen, richtig?

Wenn ja, aus meiner Sicht, wenn Sie NICHT mit den Formeln bis ALL die Formeln in der Excel-Tabelle zugeordnet sind, werden Sie eine viel Geschwindigkeit gewinnen, indem sie alle Formeln schriftlich einmal mit einem Array (ein einzelner Schritt in VBA).

Die Prozedur ist: zuerst legen Sie alle Formeln zu einem VBA-Array von Zeichenfolgen und später zum Beispiel Range("B1:B100").Formula = ArrayWithFormulas verwenden. In diesem Beispiel ordnen Sie 100 Formeln gleichzeitig zu, ohne dass Sie dazwischen neu berechnen müssen.

Sie werden eine große Verbesserung in SPEED sehen, wenn Sie ein Array verwenden, um alle Zellen auf einen zu schreiben, anstatt Zelle für Zelle zu schreiben! (Schleife nicht mit cells(r,c+i), wenn Sie viele Zellen durchlaufen haben). Hier ein Beispiel:

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 

Wenn Sie eine zusätzliche Verzögerung in der neuen Formel möchten, dann können Sie @Gary Trick verwenden, aber auf einen Bereich angewendet wird, nicht auf eine einzelne Zelle.Dazu die Formeln mit einem ' wie '=1+2 starten und den folgenden Code am Ende hinzufügen:

'... 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 

Last, einem kleinen snipped: wenn Ihre Formeln sind in einer horizontalen Anordnung (Mittel eine Formel für die Spalte A, andere für Spalte B, usw.) und nur eine kleine Anzahl von Spalten, dann können Sie behalten die eine kürzere Version des vorherigen Code in dem Sinne:

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. 

Schließlich können Sie die Methode verwenden .FormulaR1C1 statt .Formula in allen vorherigen Code Beispiele, wenn Sie eine einfache Möglichkeit haben, relative Referenzen in Ihrer Formel zu verwenden ...

Hoffe, das hilft!

+0

Klingt interessant. Vielen Dank! Bisher habe ich Garys Vorschlag ziemlich erfolgreich angewendet. Ich füge Formeln mit einem Apostroph in einem Zyklus zum gesamten Bereich hinzu und führe sie dann alle mit Bereich (was auch immer). Wert = Bereich (was auch immer). Wert – pokrishka

+0

Gut! Wenn Sie sehen, dass Sie die Geschwindigkeit verbessern müssen, können Sie das verwenden ;-). Weitere Tipps zur Geschwindigkeit finden Sie hier: [(1) Excel VBA: Effizienz und Leistung] (http://www.avdf.com/apr98/art_ot003.html) - [(2) Schnelle Codierung] (http: // blogs .msdn.com/excel/archive/2009/03/12/excel-vba-performance-coding-best-practice.aspx) - [(3) Microsoft-Informationen zum Übergeben eines Arrays an VB] (http: // support. microsoft.com/kb/153090/en-us) –