В чем разница между dim и set в vba

82

Простите меня, поскольку я новичок в VBA.

Иногда я использую

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

В других случаях я использую

Set r = Range("A1")

В чем разница? И когда что использовать?

Ram
источник

Ответы:

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
Могу я узнать, к какому учебнику или книге вы обращались, чтобы понять это?
Ram
18
Этот ответ на самом деле не объясняет «почему»
kizzx2
1
VBA очень умен, он не требует, чтобы вы рассказывали ему, что, черт возьми, вы делаете, как многие языки. Однако это добавляет времени. Если вы используете целый ряд различных размеров на всевозможных различных вариациях, это добавляет время. Если вы укажете VBA, чего ожидать, когда он увидит переменную, то ему не придется это решать. Кроме того, если вы скажете VBA, что переменная является целым числом, а не строкой, она не займет столько оперативной памяти. Хотя последний пункт, вероятно, не так актуален для обычных небольших проектов VBA, он по-прежнему является хорошей практикой кодирования.
Rapid
можно ли использовать 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содержащую ячейку "A1"

    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включили, что вам следует. Всегда. В противном случае вы используете идентификаторы, которые вы не объявили, и все они неявно объявлены как Варианты .

RubberDuck
источник
@PierreClaverie: Да :) он включает оригинальные отсылки к Dim and Set
Wolf
1
@Wolf не уверен, знаете ли вы, но ссылка на язык VBA теперь поддерживается на github. github.com/OfficeDev/VBA-content/blob/master/VBA/…
RubberDuck
@RubberDuck Я не знал (я новичок в vb *), спасибо за добавление этой заметки.
Wolf
Добро пожаловать, @Wolf. Я знаю, что в наши дни может быть трудно найти VBA и старые документы VB6.
RubberDuck 07
8

Dim: вы определяете переменную (здесь: r - это переменная типа Range)

Set: вы устанавливаете свойство (здесь: установите значение r равным Range ("A1") - это не тип, а значение).

Вы должны использовать набор с объектами, если бы r был простым типом (например, int, string), вы бы просто написали:

Dim r As Integer
r=5
Тобиас Шитковски
источник
3

Dim просто объявляет значение и тип.

Set присваивает значение переменной.

Джастин Нисснер
источник
2

Если переменная определена как объект, например, Dim myfldr As Folder, ей присваивается значение с помощью ключевого слова «Set».

user2479175
источник
1

Dim является сокращением от Dimension и используется в VBA и VB6 для объявления локальных переменных.

Set, с другой стороны, не имеет ничего общего с объявлениями переменных. SetИспользуется ключевое слово , чтобы назначить переменную объекта на новый объект.

Надеюсь, это проясняет вам разницу.

IqbalHamid
источник
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`

на самом деле все вары одинаковы!

Соруш
источник