2013-08-24 16 views
5

Mam dość prosty problem z Makro. W nim przypiszę formułę do komórki. Nie chciałbym go najpierw obliczyć i wykonać obliczenia dopiero po zakończeniu jakiejś innej części makra. Pomyślałem, że zrobiłbym coś takiego:Excel i VBA: Pomiń obliczanie formuły w makrze

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

Ale to nie działa. Zatrzymuje automatyczne obliczenia, ale nie dla tej komórki - nadal wykonuje obliczenia zaraz po przypisaniu formuły. Czy istnieje sposób, aby to pominąć?

Aby wyjaśnić dokładną prpose tego: w moim rzeczywistym kodzie przypisuję formułę do grupy komórek w cyklu. Za każdym razem, gdy przypiszę ją do jednej komórki - oblicza ją. Pomyślałem, że jeśli najpierw przypiszę je wszystkie, a potem wykonam obliczenia - będzie szybciej. W rzeczywistości to. Zamiast przypisywać je w cyklu, przypisuję je do pierwszej komórki, a następnie do automatycznego wypełniania. Wypełnione formułą poczekaj, aż włączę automatyczne obliczenia i otrzymam znacznie szybsze makro. Jednak początkowy assignemnt jest nadal obliczany, co sprawia, że ​​makro jest prawie dwa razy wolniejsze.

+0

Po prostu myśl, którą możesz wypróbować: możesz zachować wzór w jakiejś ukrytej komórce - a tylko w makrze PasteSpecial? Przy odrobinie szczęścia, które działa podobnie do autouzupełniania i oblicza się tylko na końcu ... –

Odpowiedz

7
  1. miejsce formuła w komórce o charakterze prefiksu
  2. kontynuować makro
  3. "aktywować" formułę

na przykład:

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

Olśniewająca sztuczka. Codziennie uczę się czegoś nowego :) – Vikas

+0

To jest sprytne. – enderland

+0

To jest genialne :) – pokrishka

2

@Alex, ty może opóźnić obliczenie jako odpowiedź @Gary. Jednak zadałeś to pytanie, ponieważ potrzebujesz "PRĘDKOŚĆ DO CYKLU PRZEZ komórki" podczas przypisywania formuły, prawda?

Jeśli tak, to z mojego punktu widzenia, jeśli jesteś NIE użyciu formuły aż ALL wzory są przypisane w arkuszu Excel, to zyska dużo prędkości dzięki zapisaniu wszystkich formuł w raz używając tablicy (jeden krok w VBA).

Procedura: najpierw umieść wszystkie formuły w tablicy napisów VBA, a następnie użyj na przykład Range("B1:B100").Formula = ArrayWithFormulas. W tym przykładzie przypisujesz 100 wzorów na raz, bez ponownego przeliczania pomiędzy.

Będziesz widział dużą poprawę w SPEED jeśli użyjesz tablicy, aby napisać wszystkie komórki w nich zamiast pisać komórki po komórce! (Nie używaj pętli, używając cells(r,c+i), jeśli masz dużo komórek do przejścia). Oto jeden z przykładów:

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 

Jeśli chcesz dodatkowe opóźnienie w nowej formule, a następnie można użyć @Gary tricka, ale stosuje się do zakresu, a nie pojedynczej komórki.W tym celu uruchomić formuł z ' jak '=1+2 i dodaj następujący kod na końcu:

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

ostatni małej snipped: jeśli formuły są w układzie poziomym (Znaczy jeden wzór na kolumnie A, inne dla kolumna B, etc), a tylko niewielka liczba kolumn, można pamiętać o krótszą wersję poprzedniego kodu:

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. 

Wreszcie, można użyć metody .FormulaR1C1 zamiast .Formula w całym poprzednim kodzie przykłady, jeśli chcesz mieć łatwy sposób użycia względnych odniesień w formule ...

Mam nadzieję, że to pomoże!

+0

Brzmi interesująco. Dzięki! Do tej pory z powodzeniem stosowałem sugestię Gary'ego. Dodaję formuły z apostrofem w cyklu do całego zakresu, a następnie uruchamiam je wszystkie z Range (cokolwiek) .Value = Range (cokolwiek) .Value – pokrishka

+0

Dobrze! Jeśli zauważysz, że musisz poprawić prędkość, możesz użyć tego ;-). Więcej wskazówek na temat prędkości, tutaj: [(1) Excel VBA: Wydajność i wydajność] (http://www.avdf.com/apr98/art_ot003.html) - [(2) Szybkie kodowanie] (http: // blogs .msdn.com/excel/archive/2009/03/12/excel-vba-performance-coding-best-practices.aspx) - [(3) Informacje o przekazaniu tablicy do VB przez firmę Microsoft] (http: // support. microsoft.com/kb/153090/en-us) –