2013-09-26 11 views
20

Uczę się Excel VBA przez ostatnie dwa lata i mam pomysł, że czasami właściwe jest pozbywanie się zmiennych na końcu segmentu kodu. Na przykład, widziałem to zrobić w tym kawałku adaptacją Ron de Bruin's code for transferring Excel to HTML:Kiedy zmienna VBA programu Excel powinna zostać zabita lub ustawiona na Nothing?

Function SaveContentToHTML (Rng as Range) 

     Dim FileForHTMLStorage As Object 
     Dim TextStreamOfHTML As Object 
     Dim TemporaryFileLocation As String 
     Dim TemporaryWorkbook As Workbook 

... 

     TemporaryWorkbook.Close savechanges:=False 
     Kill TemporaryFileLocation 
     Set TextStreamOfHTML = Nothing 
     Set FileForHTMLStorage = Nothing 
     Set TemporaryWorkbook = Nothing 

End Function 

zrobiłem kilka poszukiwania na ten temat i okazało się bardzo niewiele poza, jak to zrobić, w jednym poście a statement that no local variables need to be cleared forum, gdyż przestaje istnieć pod adresem End Sub. Zgaduję, opierając się na powyższym kodzie, który może nie być prawdziwy w End Function lub w innych okolicznościach, z którymi się nie spotkałem.

Więc moje pytanie sprowadza się do tego:

  • Czy jest gdzieś w sieci, która wyjaśnia, kiedy i dlaczego do zmiennej porządki, a ja po prostu nie znalazłem?

A jeśli nie może ktoś tutaj proszę wyjaśnić ...

  • Kiedy jest zmienna porządki Excel VBA konieczne, a kiedy nie?
  • A dokładniej ... Czy istnieją określone zmienne zastosowania (zmienne publiczne? Zmienne zdefiniowane w funkcjach?), Które pozostają załadowane w pamięci dłużej niż przez niż podrzędne, a zatem mogą powodować problemy, jeśli nie będę czyścić po mnie?

Odpowiedz

31

VB6/zastosowań VBA deterministyczne podejście do obiektów destylujących. Każdy obiekt przechowuje liczbę odniesień do siebie. Kiedy liczba osiągnie zero, obiekt ulega zniszczeniu.

Zmienne gwarantowane do czyszczenia obiektów (ustawione na Nothing), gdy wychodzą poza zakres, zmniejsza to liczniki odwołań w ich obiektach. Nie wymaga ręcznej akcji.

Istnieją tylko dwa przypadki, gdy chcemy wyraźnego Czyszczenie:

  1. Kiedy chcesz obiekt zostać zniszczone przed jego zmiennej wykracza poza zakres (np twoja procedura zajmie dużo czasu, aby wykonaj, a obiekt przechowuje zasób, więc chcesz jak najszybciej zniszczyć obiekt, aby zwolnić zasób).

  2. Gdy masz kołowe odniesienie między dwoma lub więcej obiektami.

    If objectA przechowuje Odniesienia do objectB i objectB przechowuje odniesienie do objectA, dwa obiekty nigdy nie będzie zniszczone, chyba że hamulec łańcucha przez jawne ustawienie objectA.ReferenceToB = Nothing lub objectB.ReferenceToA = Nothing.

Wyświetlany fragment kodu jest niepoprawny. Ręczne czyszczenie nie jest wymagane. Nawet ręczne czyszczenie jest nawet szkodliwe, ponieważ daje ci false sense of more correct code.

Jeśli masz zmienną na poziomie klasy, zostanie ona wyczyszczona/zniszczona, gdy instancja klasy zostanie zniszczona. Możesz ją wcześniej zniszczyć, jeśli chcesz (patrz pozycja 1.).

Jeśli masz zmienną na poziomie modułu, będzie ona czyszczona/niszczona po wyjściu z programu (lub, w przypadku VBA, po zresetowaniu projektu VBA). Możesz ją wcześniej zniszczyć, jeśli chcesz (patrz pozycja 1.).

Poziom dostępu do zmiennej (publiczny lub prywatny) nie wpływa na jej żywotność.

+1

Dzięki GSerg, wyjaśnienie to jest jasne i zwięzłe i daje mi dużo lepszy zmysł do zarządzania zmiennego. Jedno dodatkowe pytanie: mówisz "poziom dostępu do zmiennej nie ma wpływu na jej żywotność". Czy wiesz, czy to życie jest ograniczone, gdy wartość jest ustawiona po raz pierwszy przez aktywny kod (start) i kiedy kod, który kod osiąga znacznik 'End' (koniec)? Czy kończy się, gdy projekt się resetuje? Próbowałem przetestować tę teorię, ustawiając wartość zmiennej publicznej, która została przyciemniona w innym module, ale zmienna nigdy nie pojawiła się w oknie locals, więc nie mogłem zaobserwować kiedy spadła. –

+0

@KarlRookey Public vs private różni się od poziomu klasy w porównaniu z poziomem procedury. Kontakty publiczne i prywatne nie wpływają na czas życia. Poziom klasy oznacza, że ​​zmienna żyje tak długo, jak żyje klasa. Poziom modułu oznacza zmienną, o ile projekt nie jest resetowany. Zauważ, że "życie" i "zawiera coś" nie są synonimami. Zmienna może żyć i zawierać "Nic". – GSerg

3

VBA korzysta z garbage collector, który jest realizowany przez reference counting.

Może istnieć wiele odniesień do danego obiektu (np Dim aw = ActiveWorkbook tworzy nowe odniesienie do aktywnym skoroszycie), więc garbage collector czyści tylko obiekt, gdy oczywiste jest, że nie istnieją żadne inne odniesienia. Ustawienie na Nic to wyraźny sposób zmniejszania liczby odwołań. Liczba jest niejawnie zmniejszana po wyjściu z zakresu.

Ściśle rzecz biorąc, w nowoczesnych wersjach Excela (2010+) ustawienie Nic nie jest konieczne, ale były problemy ze starszymi wersjami programu Excel (dla których obejście było jawnie ustawione)