Sự khác biệt giữa dim và set trong vba là gì


82

Xin lỗi vì tôi là một người mới trong VBA.

Đôi khi tôi sử dụng

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

Những lần khác tôi sử dụng

Set r = Range("A1")

Sự khác biệt là gì? Và khi nào tôi nên sử dụng những gì?

Câu trả lời:


78

Không có lý do gì để sử dụng settrừ khi đề cập đến một tham chiếu đối tượng. Bạn chỉ nên sử dụng nó trong bối cảnh đó. Đối với tất cả các kiểu dữ liệu đơn giản khác, chỉ cần sử dụng một toán tử gán. Tuy nhiên, bạn nên dim(thứ nguyên) TẤT CẢ các biến:

Ví dụ về các kiểu dữ liệu đơn giản sẽ là integer, long, boolean, string. Đây chỉ là các kiểu dữ liệu và không có các phương thức và thuộc tính riêng.

Dim i as Integer
i = 5

Dim myWord as String
myWord = "Whatever I want"

Ví dụ về một objectsẽ là a Range, a Worksheethoặc a Workbook. Chúng có các phương pháp và thuộc tính riêng.

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

Nếu bạn cố gắng sử dụng dòng cuối cùng mà không có Set, VB sẽ báo lỗi. Bây giờ bạn đã objectkhai báo, bạn có thể truy cập các thuộc tính và phương thức của nó.

myString = myRange.Value

3
Tôi có thể vui lòng biết bạn đã tham khảo hướng dẫn hoặc cuốn sách nào để hiểu điều này không?
Ram

18
Câu trả lời này không thực sự giải thích "tại sao"
kizzx2

1
VBA rất thông minh, nó không yêu cầu bạn phải nói cho nó biết bạn đang làm cái quái gì giống như rất nhiều ngôn ngữ. Tuy nhiên, điều này làm tăng thêm thời gian. Nếu bạn đang sử dụng toàn bộ các kích thước khác nhau trên tất cả các loại biến thể khác nhau thì thời gian đó sẽ cộng dồn. Nếu bạn cho VBA biết điều gì sẽ xảy ra khi nó nhìn thấy một biến thì nó không cần phải giải quyết. Ngoài ra, nếu bạn nói với VBA rằng một biến là một số nguyên không phải là một chuỗi, thì nó sẽ không chiếm nhiều RAM. Mặc dù điểm thứ hai có lẽ không hợp lệ trong các dự án VBA nhỏ phổ biến, nhưng thực hành mã hóa vẫn tốt.
Nhanh chóng

Có thể sử dụng Setmà không Dimnhập biến trước không?
chí

64

Tuy nhiên, tôi không nghĩ đây là điều bạn đang thực sự hỏi.

Đôi khi tôi sử dụng:

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

Điều này sẽ không bao giờ hiệu quả. Nếu không, Setbạn sẽ nhận được lỗi thời gian chạy # 91 Biến đối tượng hoặc Với biến khối không được đặt . Điều này là do bạn phải sử dụng Setđể gán giá trị biến cho một tham chiếu đối tượng. Sau đó, đoạn mã trên sẽ hoạt động.

Tôi nghĩ đoạn mã dưới đây minh họa những gì bạn thực sự đang hỏi. Giả sử chúng ta không khai báo một kiểu và thay vào đó hãy rlà một Variantkiểu.

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

Vì vậy, chúng ta hãy chia nhỏ những gì xảy ra ở đây.

  1. r được khai báo là một biến thể

    `Dim r` ' TypeName(r) returns "Empty", which is the value for an uninitialized variant
    
  2. rđược đặt thành Rangeô chứa "A1"

    Set r = Range("A1") ' TypeName(r) returns "Range"
    
  3. rđược đặt thành giá trị của thuộc tính mặc định của Range("A1").

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

Trong trường hợp này, thuộc tính mặc định của một Phạm vi là .Value, vì vậy hai dòng mã sau là tương đương.

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

Để biết thêm về các thuộc tính đối tượng mặc định, vui lòng xem "Thành viên mặc định của một lớp" của Chip Pearson .


Đối với Setví dụ của bạn :

Những lần khác tôi sử dụng

Set r = Range("A1")

Điều này sẽ không hoạt động nếu không khai báo trước đó rlà một Rangehoặc Variantđối tượng ... bằng cách sử dụng Dimcâu lệnh - trừ khi bạn chưa Option Explicitbật, điều bạn nên làm. Luôn luôn. Nếu không, bạn đang sử dụng số nhận dạng mà bạn chưa khai báo và tất cả chúng đều được khai báo ngầm là Biến thể .


@PierreClaverie Có :) nó bao gồm các tài liệu tham khảo ban đầu cho DimSet
Wolf

1
@Wolf không chắc bạn có biết không, nhưng bản giới thiệu ngôn ngữ VBA hiện được duy trì trên github. github.com/OfficeDev/VBA-content/blob/master/VBA/…
RubberDuck

@RubberDuck Tôi không biết (tôi mới sử dụng vb *), cảm ơn bạn đã thêm ghi chú này.
Wolf

Chào mừng bạn @Wolf. Tôi biết tài liệu VBA & VB6 cũ có thể khó tìm thấy những ngày này.
RubberDuck

8

Dim: bạn đang xác định một biến (ở đây: r là một biến kiểu Range)

Đặt: bạn đang đặt thuộc tính (ở đây: đặt giá trị của r thành Phạm vi ("A1") - đây không phải là một kiểu, mà là một giá trị).

Bạn phải sử dụng set với các đối tượng, nếu r là kiểu đơn giản (ví dụ: int, string), thì bạn chỉ cần viết:

Dim r As Integer
r=5


2

Nếu một biến được định nghĩa là một đối tượng, ví dụ như Dim myfldr As Folder, nó sẽ được gán một giá trị bằng cách sử dụng từ khóa, "Set".


1

Dim là viết tắt của Dimension và được sử dụng trong VBA và VB6 để khai báo các biến cục bộ.

Mặt khác, thiết lập không liên quan gì đến khai báo biến. Các Settừ khóa được sử dụng để gán một biến đối tượng đến một đối tượng mới.

Hy vọng rằng làm rõ sự khác biệt cho bạn.


0

Theo trợ giúp của VBA trên câu lệnh SET, nó thiết lập một tham chiếu đến một đối tượng. Vì vậy nếu bạn thay đổi một thuộc tính thì đối tượng thực tế cũng sẽ thay đổi.

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

các thuộc tính khác của Vars cũng thay đổi, vì vậy:

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

thực tế tất cả các vars đều giống nhau!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.