Kiedy zrobić:
Set r = Range("A1")
Co naprawdę jesteś naprawdę robota jest taka:
Dim r As Variant
Set r = Application.ActiveSheet.Range("A1")
więc zadeklarować wszystkie zmienne i zawsze określić Option Explicit
w górnej części każdego modułu - ten sposób VBA odmówi skompilować kod, który używa zmiennych (lub niezgłoszonych literówek). I zadeklarować zmienne z wyraźną typu:
Dim r As Range
Range
obiekt wie o jego Parent
, który jest arkusz należy do; dlatego, jak zauważyłeś, ten zakres jest ważny dla aktywnego arkusza roboczego. I pozostaje na tym arkuszu, nawet jeśli aktywujesz kolejny arkusz (który i tak nie musiałbyś robić 99,999% czasu).
Dlatego nie można to zrobić:
Worksheets("Sheet42").r.Value = 1
Ponieważ r
nie jest członkiem obiektu Worksheet
- jest to zmienna lokalna obiekt, który wskazuje na bardzo konkretny adres na bardzo konkretnym arkuszu.Teraz, kiedy robisz Worksheets("Sheet42")
, jesteś naprawdę dostęp do właściwości domyślnej klasy Worksheets
zbiór, który jest jego Item
nieruchomości:
Dim sheet As Worksheet
Set sheet = Worksheets.Item("Sheet42")
a Worksheets
Collection Item
właściwość zwraca Object
, co oznacza, że każdy członek zadzwonić dodać po tym będzie późno-bound/rozwiązane w czasie wykonywania:
Dim obj As Object
Set obj = Worksheets.Item("Sheet42")
obj.AnythingYouWantHereWillCompileAnyway
w czasie wykonywania, VBA zapytuje interfejs obiektu szukać AnythingYouWantHereWillCompileAnyway
i nie okaże się, że członek - i to w jaki sposób dostajesz błąd wykonania 438 - "obiekt nie obsługuje tej właściwości lub metody".
można przenieść tego typu bezpieczeństwa z powrotem w czasie kompilacji (zamiast run-time), pracując z początku związana połączeń, czyli pracować z Worksheet
interfejsu/klasy zamiast Object
:
Dim obj As Worksheet
Set obj = Worksheets.Item("Sheet42")
obj.AnythingYouWantHereWillCompileAnyway 'nope. that won't compile anymore.
Po zapytaniu w jaki sposób mogę przypisać zakres (który był już ustawiony) do innego arkusza?, zakładasz, że obiekt Range
jest niczym więcej niż adresem - i to założenie jest błędne.
A Range
to dużo więcej niż tylko adres. Gdyby był to tylko adres, byłby to dosłowny ciąg znaków, a nie obiekt.
Jeśli chcesz zmienną, która reprezentuje adres, można to zrobić za pomocą String
zmiennej:
Dim a As String
a = "A1"
Dim r1 As Range
Set r1 = Sheet1.Range(a)
Dim r2 As Range
Set r2 = Sheet2.Range(a)
Kudos dla nie zalegających na 'Select' i' Activate' po sobie sprawę, że bez zastrzeżeń 'Range' wywołuje niejawnie patrz aktywny arkusz. –