У чому різниця між dim і set в vba


82

Вибачте мене, як новачка у VBA.

Іноді я використовую

Dim r as Range
r = Range("A1")

Інший раз використовую

Set r = Range("A1")

Яка різниця? І коли мені що використовувати?

Відповіді:


78

Немає жодної причини для використання, setякщо не йдеться про посилання на об’єкт. Доброю практикою є використання його лише в цьому контексті. Для всіх інших простих типів даних просто використовуйте оператор присвоєння. Хороша ідея dim(вимірювати) ВСІ змінні, однак:

Приклади простих типів даних було б integer, long, boolean, string. Це лише типи даних і не мають власних методів та властивостей.

Dim i as Integer
i = 5

Dim myWord as String
myWord = "Whatever I want"

Прикладом objectможе бути a Range, a Worksheetабо a Workbook. Вони мають свої методи та властивості.

Dim myRange as Range
Set myRange = Sheet1.Range("A1")

Якщо ви спробуєте використовувати останній рядок без Set, VB видасть помилку. Тепер, коли у вас є objectзаявлений, ви можете отримати доступ до його властивостей та методів.

myString = myRange.Value

3
Чи можу я, будь ласка, знати, до якого підручника чи книги ви звернулись, щоб зрозуміти це?
Рам

18
Ця відповідь насправді не пояснює "чому"
kizzx2

1
VBA дуже розумна, вона не вимагає від вас, щоб ви сказали їй, що ви, на біса, робите, як багато мов. Однак це додає часу. Якщо ви використовуєте цілу низку різних вимірів для всіляких різних варіантів, то це додає час. Якщо ви скажете VBA, чого очікувати, коли вона побачить змінну, тоді вона не повинна її обробляти. Також якщо ви скажете VBA, що змінна є цілим числом, а не рядком, тоді вона не займе стільки оперативної пам'яті. Хоча останній пункт, мабуть, не настільки дійсний у звичайних невеликих проектах VBA, це все-таки хороша практика кодування.
Швидкий

це нормально використовувати Setбез Dimвведення змінної спочатку?
solstice333

64

Однак я не думаю, що це насправді ви просите.

Іноді я використовую:

    Dim r as Range
    r = Range("A1")

Це ніколи не спрацює. Без Setвас ви отримаєте помилку виконання # 91 Змінна об'єкта або Змінна блоку не встановлена . Це пов’язано з тим, що ви повинні використовувати Setдля присвоєння значення змінних посилання на об’єкт. Тоді код вище буде працювати.

Я думаю, що наведений нижче код ілюструє те, про що ви насправді питаєте. Давайте припустимо , що ми не оголосити тип , і нехай rбути Variantтип замість.

Public Sub test()
    Dim r
    debug.print TypeName(r)

    Set r = Range("A1")
    debug.print TypeName(r)

    r = Range("A1")
    debug.print TypeName(r)
End Sub

Отже, давайте розберемо те, що тут відбувається.

  1. r оголошено як Варіант

    `Dim r` ' TypeName(r) returns "Empty", which is the value for an uninitialized variant
    
  2. rвстановлено Rangeвміщує комірку "А1"

    Set r = Range("A1") ' TypeName(r) returns "Range"
    
  3. rвстановлено значення властивості за замовчуванням для Range("A1").

    r = Range("A1") ' TypeName(r) returns "String"
    

У цьому випадку типовою властивістю Range є .Value, тому наступні два рядки коду еквівалентні.

r = Range("A1")
r = Range("A1").Value

Детальніше про властивості об’єкта за замовчуванням див. У розділі “Члена класу за замовчуванням” Чіпа Пірсона .


Що стосується вашого Setприкладу:

Інший раз використовую

Set r = Range("A1")

Це не спрацювало б без попереднього оголошення про те, що rце Rangeабо Variantоб'єкт ... за допомогою Dimоператора - якщо ви не Option Explicitввімкнули, що слід. Завжди. В іншому випадку ви використовуєте ідентифікатори, які ви не оголосили, і всі вони неявно оголошені як варіанти .


@PierreClaverie Так :) це включає оригінальні посилання на Dim and Set
Wolf

1
@Wolf не впевнений, чи знаєте ви про це, але посилання на мову VBA тепер підтримується на github. github.com/OfficeDev/VBA-content/blob/master/VBA/…
RubberDuck

@RubberDuck Я не знав (я новачок у vb *), дякую за додавання цієї примітки.
Вовк

Ласкаво просимо @Wolf. Я знаю, що сьогодні важко знайти VBA та старі документи VB6.
RubberDuck

8

Dim: ви визначаєте змінну (тут: r - змінна типу Range)

Встановити: ви встановлюєте властивість (тут: встановіть для значення r значення Range ("A1") - це не тип, а значення).

Вам потрібно використовувати set з об’єктами, якби r був простим типом (наприклад, int, рядок), то ви просто написали б:

Dim r As Integer
r=5


2

Якщо змінна визначена як об'єкт, наприклад, Dim myfldr як папка, їй присвоюється значення за допомогою ключового слова "Встановити".


1

Dim це скорочення від Dimension і використовується у VBA та VB6 для оголошення локальних змінних.

Набір, з іншого боку, не має нічого спільного з оголошеннями змінних. SetВикористовується ключове слово , щоб призначити змінну об'єкта на новий об'єкт.

Сподіваюся, це з’ясовує для вас різницю.


0

Згідно з довідкою VBA щодо оператора SET, він встановлює посилання на об'єкт. Тому, якщо ви зміните властивість, фактичний об'єкт також зміниться.

Dim newObj as Object
Set var1=Object1(same type as Object)
Set var2=Object1(same type as Object)
Set var3=Object1(same type as Object)
Set var4=Object1(same type as Object)
Var1.property1=NewPropertyValue

інші властивості Vars також змінюються, отже:

Var1.property1=Var2.property1=Var3.property1=Var4.property1=Object1.Property1=NewpropertyValue`

насправді всі вари однакові!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.