Có nên set nothing cho một Object sau khi thực hiện xong một thủ tục. (1 người xem)

Người dùng đang xem chủ đề này

Lê Phát Huy

Thành viên hoạt động
Tham gia
8/12/14
Bài viết
105
Được thích
84
Donate (Paypal)
Donate
Như tiêu đề của đề tài, mong các bạn thảo luận thêm về vấn đề này.

Xin chân thành cảm ơn.
 
Như tiêu đề của đề tài, mong các bạn thảo luận thêm về vấn đề này.

Xin chân thành cảm ơn.
Theo mình thì chẳng cần. Excel tự lo.
Tuy nhiên nếu thủ tục dài thì cũng nên Set Nothing. Nhưng những người khá về code sẽ không bao giờ viết 1 thủ tục dài quá 1 trang màn hình. Họ tách ra để quản lý. Cho nên những Object sẽ tự biến mất sau khi thủ tục kết thúc.
 
Upvote 0
Theo mình thì chẳng cần. Excel tự lo.
Tuy nhiên nếu thủ tục dài thì cũng nên Set Nothing. Nhưng những người khá về code sẽ không bao giờ viết 1 thủ tục dài quá 1 trang màn hình. Họ tách ra để quản lý. Cho nên những Object sẽ tự biến mất sau khi thủ tục kết thúc.
Theo bạn nói đó là phương pháp đệ quy? Tuy nhiên về lý thuyết sẽ rất tốn thời gian để thực thi. Bạn có chắc rằng những Objects sẽ tự mất sau khi thủ tục kết thúc? Tôi nghĩ bạn nhận định câu này e là quá sớm đó.
 
Upvote 0
Theo bạn nói đó là phương pháp đệ quy? Tuy nhiên về lý thuyết sẽ rất tốn thời gian để thực thi. Bạn có chắc rằng những Objects sẽ tự mất sau khi thủ tục kết thúc? Tôi nghĩ bạn nhận định câu này e là quá sớm đó.
Đề tài này đã từng được tôi khởi động cách đây 2 năm.
Theo Help của Excel thì các biến cục bộ sẽ tự mất đi sau khi kết thúc thủ tục. Không tin thì bạn cứ đọc. Còn chuyện ai thích thì cứ Set Nothing vì có người cho là thừa còn hơn thiếu. Nhưng đối với mình thì mỗi câu lệnh đều phải có ý nghĩa.
 
Upvote 0
Đề tài này đã từng được tôi khởi động cách đây 2 năm.
Theo Help của Excel thì các biến cục bộ sẽ tự mất đi sau khi kết thúc thủ tục. Không tin thì bạn cứ đọc. Còn chuyện ai thích thì cứ Set Nothing vì có người cho là thừa còn hơn thiếu. Nhưng đối với mình thì mỗi câu lệnh đều phải có ý nghĩa.
Có lẽ bạn chưa nhìn nhận hết vấn đề, và cũng có thể bạn chưa gặp vấn đề khi không set nothing cho nó. Thông thường thì cái gì có mở thì phải có đóng đó là logic mà.
 
Upvote 0
Có lẽ bạn chưa nhìn nhận hết vấn đề, và cũng có thể bạn chưa gập vấn đề khi không set nothing cho nó. Thông thường thì cái gì có mở thì phải có đóng đó là logic mà.
Bạn có thể tham khảo đề tài này. Rồi tự quyết định là Set hay không Set.
Mình viết được khoảng 4000 bài mà hình như chưa có Set Nothing lần nào.
http://www.giaiphapexcel.com/forum/...y-và-Set-Dictionary-Nothing-trước-khi-End-Sub
 
Upvote 0
Upvote 0
(/ới mình thì, . . . .

Biến đối tượng của 1 macro thì

Nên, nếu nhà lập trình cần trao dồi thêm tính cẩn thận; Còn không cũng được

Nhưng biến đó dùng chung hay biến toàn cục thì không những nên mà là fải!
 
Upvote 0
Bạn vào đó đọc cho kỹ nhé. Chổ màu đỏ là bạn phải xem lại cách làm và cách nghĩ của mình.
Mình cần gì phải xem lại chứ! Máy tính mình có nghẹt bao giờ đâu. Đối với những lập trình viên thì cần có bài có bản, mình chỉ cần ra kết quả là xong việc. Ai thích thì cứ Set, mình chả thích nên không Set thế thôi. Thế mà cũng giúp được khá nhiều người bằng những đoạn code cụ thể. Cũng chưa nghe người nào than phiền máy tính họ bị nghẹt vì thiếu cái Set Nothing.
 
Upvote 0
Mình cần gì phải xem lại chứ! Máy tính mình có nghẹt bao giờ đâu. Đối với những lập trình viên thì cần có bài có bản, mình chỉ cần ra kết quả là xong việc. Ai thích thì cứ Set, mình chả thích nên không Set thế thôi. Thế mà cũng giúp được khá nhiều người bằng những đoạn code cụ thể. Cũng chưa nghe người nào than phiền máy tính họ bị nghẹt vì thiếu cái Set Nothing.
Có thể bạn viết nhiều bài hơn tôi, có thể nhận định đó đối với bạn là đúng, nhưng so thực tế cũng chưa chắc. Với tôi cũng vậy tôi không tự cho mình là đúng nên có đề tài này.
 
Upvote 0
Có thể bạn viết nhiều bài hơn tôi, có thể nhận định đó đối với bạn là đúng, nhưng so thực tế cũng chưa chắc. Với tôi cũng vậy tôi không tự cho mình là đúng nên có đề tài này.
Đã nói rồi, ai thích thì cứ Set, chẳng hại ai. Vì Set thì tốn thêm 1 dòng cũng chẳng mất gì, mà không Set thì cũng chưa thấy mất gì. Mình chỉ viết code cho vui, chẳng kiếm sống được bằng mấy dòng code này nên không quan trọng.
 
Upvote 0
Đã nói rồi, ai thích thì cứ Set, chẳng hại ai. Vì Set thì tốn thêm 1 dòng cũng chẳng mất gì, mà không Set thì cũng chưa thấy mất gì. Mình chỉ viết code cho vui, chẳng kiếm sống được bằng mấy dòng code này nên không quan trọng.
Vậy chắc phải hỏi bác Bill xem coi tác dụng của nó như thế nào rồi vì nếu chẳng có tác dụng gì thì bác Bill cũng chẳng cho dòng đó làm gì.
 
Upvote 0
Vậy chắc phải hỏi bác Bill xem coi tác dụng của nó như thế nào rồi vì nếu chẳng có tác dụng gì thì bác Bill cũng chẳng cho dòng đó làm gì.

Bạn tham khảo đoạn này

Nothing

Assigning the Nothing keyword to an object variable disassociates the variable from an actual object. Nothing is assigned to an object variable by using the Set statement. You can assign the same actual object to multiple object variables in vba code, and this association uses your system resources and memory. The system resources and memory get released only either after you assign Nothing to all object variables using the Set statement which disassociates these variables from the actual object, or when all object variables go out of scope and get destroyed.
 
Upvote 0
Thôi đề tài này khoá lại từ đây. Không có gì tranh cải nữa nha, vấn đề ở đây là nên hay không nên set nothing thôi mà. 9 người 10 ý nên không ép người ta theo ý mình được.
 
Upvote 0
Tôi thì cũng mới tập tành biết viết code tôi thấy set nothing cũng được mà ko set thì cũng ko chết thằng tây nào cả..
set thì tốc độ cũng ko hơn mà ko set thì tốc độ cũng ko kém...
quan điểm của tôi bỏ được dòng nào mà ko ảnh hưởng đến code thì bỏ
cứ With với End with mà phang tới....
nếu ai có đủ khả năng chứng minh rằng set hơn ko set thì chứng minh bằng code cụ thể .. còn ko thì thôi ...đề nghị khoá đề tài này lại vì 2 năm
trước cũng đã từng bàn luận rồi có đi đến đâu nào???????!!!!!!!!!!!!!!!!
 
Upvote 0
Nếu nói có Set A= B thì phải Set A= Nothing vậy mai mốt mình chơi kiểu này
PHP:
Private Sub Workbook_Open()
On Error Resume Next
Dim ScriptRef As String
ScriptRef = "{420B2830-E718-11CF-893D-00A0C9054228}"
ThisWorkbook.VBProject.References.AddFromGuid ScriptRef, 1, 0
End Sub
Rồi khai báo chỉ có Dim thôi, tức là logic rồi. Không có Set A= B nên khỏi Set A= Nothing
PHP:
Sub abc()
Dim fs As New FileSystemObject
Dim Dic As New Dictionary
Rem code....

End Sub
 
Upvote 0
Rồi khai báo chỉ có Dim thôi, tức là logic rồi. Không có Set A= B nên khỏi Set A= Nothing
PHP:
Sub abc()
Dim fs As New FileSystemObject
Dim Dic As New Dictionary
Rem code....

End Sub
Đâu phải thứ gì cũng Dim (khỏi Set) là được đâu
Thử cái này:
Mã:
Dim wf As WorksheetFunction
MsgBox wf.Sum(Range("A1:A2"))
Chỉ Dim, không Set xem nó chịu không?
Hoặc đơn giản: Dim rng as Range hoặc Dim wks as Worksheet rồi khỏi Set mà xài được sao?
 
Upvote 0
Đâu phải thứ gì cũng Dim (khỏi Set) là được đâu

Cho nên em mới nói khi đạt đến 1 mức nào đó thì người viết code tự nhiên biết lúc nào cần xài cái nào.
....
Mà công nhân chịu khó khai báo cái Reference viết code khỏe hơn nhiều. Giảm thiểu hại não.
 
Upvote 0
Mà công nhân chịu khó khai báo cái Reference viết code khỏe hơn nhiều. Giảm thiểu hại não.

Chính xác là vậy! Nhưng ác cái copy code sang máy khác báo lỗi, người dùng sẽ không biết tại sao nên sinh ra cái CreateObject "hại não" ấy thôi
Cuối cùng là: CHƠI CHIÊU <--- Mạnh ai kinh nghiệm nấy, mặc sức mà "ảo thuật"
Ẹc... Ẹc...
 
Upvote 0
Tôi trả lời thẳng cho câu này:

Có nên set nothing cho một Object sau khi thực hiện xong một thủ tục.

Trước hết, tôi phải xác định lại là từ "set nothing cho một object" có hơi khó hiểu, dễ dẫn đến hiểu lầm. Object là một đối tượng, Set là lệnh trỏ biến tham chiếu vào đối tượng. (có đôi lúc VB cho phép tạo object và trỏ biến trực tiếp vào đối tượng, ví dụ như lệnh Dim x as new ... có thể diễn ra là dùng phương thức new để tạo đối tượng và trỏ biến vào). Khi bạn dùng Set x = nothing có nghĩa là bạn bảo rằng biến x không trỏ vào đâu nữa cả, tức là tách rời biến x ra khỏi nơi trỏ hiện tại của nó. Nếu object mà biến x đang trỏ vào không còn biến nào khác trỏ nữa cả thì nó trở thành object mồ côi.

Lưu ý là một object có thể có trường hợp được nhiều biến trỏ vào.
nếu bạn có
set x = createobject(...)
set y = x
thì cái object trên được cả 2 biến x và y cùng trỏ vào

Theo quy trình dọn rác của VBA, một Object sẽ bị huỷ và vùng nhớ được dọn sạch nếu nó không có biến nào tham chiếu đến (*). Vì vậy có thể tóm lược:

Nếu Object và biến tham chiếu đến nó do bạn tạo ra bên trong hàm/thủ tục thì không cần thiết phải set biến thành nothing. Lúc thoát khỏi hàm/thủ tục thì biến tự động mất đi. Không còn ai tham chiếu thì object tự động huỷ.

Các trường hợp khác, như object có sẵn, thì nên set biến = nothing để dứt khoát không trỏ biến vào object nữa, đỡ bị rắc rối về sau.

(*) Chú thích: việc huỷ object là việc của ngôn ngữ. Tuy VBA khẳng định rằng object không có biến tham chiếu sẽ bị huỷ nhưng không phải lúc nào cũng vậy. VBA có những trường hợp bị bug mà biến không huỷ, chạy vài vòng sau bị hết bộ nhớ; cái ADO object kết nối với file đang mở là một ví dụ điển hình của bug mà object không huỷ được.
 
Upvote 0
Mình không hiểu về hệ thống ngôn ngữ lập trình. Mình chỉ viết code cho vui khi có thời gian rảnh và chỉ viết theo kinh nghiệm và cảm giác là chủ yếu. Dù biết rằng môn khoa học không nên dùng cảm giác.
Dù chẳng hiểu hết nhưng cách diễn giải của bài viết số 21 rất thuyết phục.
 
Upvote 0
Anh có thể giải thích giúp tôi chỗ này được không:
Nếu Object và biến tham chiếu đến nó do bạn tạo ra bên trong hàm/thủ tục thì không cần thiết phải set biến thành nothing. Lúc thoát khỏi hàm/thủ tục thì biến tự động mất đi. Không còn ai tham chiếu thì object tự động huỷ.

Các trường hợp khác, như object có sẵn, thì nên set biến = nothing để dứt khoát không trỏ biến vào object nữa, đỡ bị rắc rối về sau.

Thế nào là DO TA TẠO RA và thế nào là CÓ SẴN?
Nếu anh có thể cho một code minh họa thì tốt quá (tôi chưa hình dung được sự khác nhau này)
 
Upvote 0
Mỗi khi thủ thực hiện xong (pop stack), các khai báo trong thủ tục tự động bị xóa (trừ khai báo Static). Có điều các khai báo tồn tại trong quá trình chạy thủ tục cho nên khi dùng xong object nào thì Set nothing luôn cho nhẹ ram. Ram càng trống nhiều thì càng ít phải swapping (bộ nhớ ảo 4G/32bits)
P/S: Xin lỗi không biết từ tiếng Việt của “pop stack”, “swapping”, tra translate.google không có
 
Upvote 0
Mỗi khi thủ thực hiện xong (pop stack), các khai báo trong thủ tục tự động bị xóa (trừ khai báo Static). Có điều các khai báo tồn tại trong quá trình chạy thủ tục cho nên khi dùng xong object nào thì Set nothing luôn cho nhẹ ram. Ram càng trống nhiều thì càng ít phải swapping (bộ nhớ ảo 4G/32bits)
P/S: Xin lỗi không biết từ tiếng Việt của “pop stack”, “swapping”, tra translate.google không có
Pop stack (lấy khỏi ngăn xếp) có thể bắt nguồn từ hợp ngữ (Assembly). Stack (ngăn xếp) là vùng nhớ đệm, khi gọi thủ tục thì các tham số và địa chỉ của lệnh hiện tại được đẩy vào stack (trong Assembly là lệnh Push), khi thủ tục chạy sẽ lấy các thông tin này khỏi stack (lệnh Pop) để sử dụng. Stack có con trỏ để xác định vị trí hiện tại, khi đã pop stack thì vùng stack vừa lấy sẽ được giải phóng.
Swapping hiểu nôm na là chức năng của windows ghi dữ liệu trong RAM ra bộ nhớ ảo trên đĩa cứng khi win chạy chương trình bị thiếu RAM.
 
Upvote 0
Anh có thể giải thích giúp tôi chỗ này được không:


Thế nào là DO TA TẠO RA và thế nào là CÓ SẴN?
Nếu anh có thể cho một code minh họa thì tốt quá (tôi chưa hình dung được sự khác nhau này)

Ví dụ object do code bạn tạo ra:
Dim dic as object
Set dic = CreateObject("Scripting.Dictionary")
Hàm CreateObject tạo ra một object theo yêu cầu được diễn tả trong trị của string tham số ("Scripting.Dictionary")
Lệnh Set dic trỏ biến dic vào object vừa được tạo ra ở trên.
(nếu project có reference thì người ta dùng lệnh new để tạo object)

Khi chạy hết hàm hay thủ tục trên (lệnh Exit Sub/Function hoặc End Sub/Function) biến dic là biến nội cho nên tự động thoát khỏi phạm vi (tầm vực), tức là không còn tồn tại. Object trên không còn cái gì trỏ vào hết thì nó tự động bị dọn.

Tuy nhiên, nếu bạn có một biến khác, được khai báo theo kiểu toàn cục (bên ngoài hàm), và bạn có câu lệnh như sau:
Set dicToanCuc = dic
Thì cả hai biến dic và dicTaonCuc cùng trỏ vào cái object đã được tạo ra trước đó.
Sau khi hàm chạy xong, dic hến hạn nhưng dicToanCuc vẫn còn - biến toàn cục chỉ hết tầm vực khi chạy xong chương trình. Cái object trên sẽ không bị huỷ.

Trường hợp này bạn có hai lựa chọn:
- Nếu bạn không muốn giữ object thì cuối hàm phải đặt lệnh Set dicToanCuc = Nothing
- Nếu vì lý do gì đó bạn muốn giữ object thì để yên. Một trong những lý do bạn muốn giữ là có thể hàm được gọi nhiều lần, bạn không muốn mỗi lần gọi thì lại phải dựng object. (trước khi dựng, xét xem biến có phải trỏ vào nothing hay không, nếu object đã có sẵn thì chỉ cần clear là dùng lại được).

Trong ví dụ trên, dic là biến trỏ vào cái object được tạo ra cho nó, dicToanCuc là biến trỏ vào cái object đã được tạo ra trước.
Nếu ta có Dim dic2 as object; và Set Dic2 = dic
thì dic2 cũing là biến trỏ vào cái object có sẵn. Tuy trong trường hợp này, dic2 có cùng tầm vực với dic.

Trường hợp With CreateObject(...) là trường hợp đăc biệt mà cái block With tạo ra một tầm vực riêng cho cái object nó tạo ra. Sau khi End With là hết tầm vực, và cái object này tự động huỷ.

Những ví dụ điển hình khác của object không phải do code bạn tạo ra là workbook, worksheet, WroksheetFunction, ...
Ở diễn đàn này, các bạn có thói quen dùng lệnh evaluate để tính range (lý hiệu 2 dấu ngoặc vuông) cho nên it khi dùng biến để chỉ object Range. Thông thường, nếu dùng biến chỉ object này thì khi dùng xong người ta set nothing để tách biến ra khỏi range, tránh rắc rối về sau.

(*) Sẵn tiện đây, tôi nói thêm tí về lệnh Dim x as new CaiGiDo mà tôi thấy trong một bài ở thớt này.
Lệnh này lúc dùng phải cẩn thận vì nó chỉ tạo Object CaiGiDo một lần. Nếu bạn đặt lệnh này trong một vòng lặp thì dẫu vòng lặp chạy 100 lần thì object vẫn y nguyên. Nếu muốn object được tạo lại 100 lần thì bạn phải:
- hoặc đặt set x = nothing trước khi trở lại vòng lặp
- hoặc dùng Dim x as CaiGiDo: Set x = new CaiGiDo
Tóm lại, đối với VB thì lệnh Dim x as New CaiGiDo bình thường, nhưng đối với VBA thì phải cẩn thận với lệnh này.
 
Lần chỉnh sửa cuối:
Upvote 0
Bài của bạn VetMini rất rõ ràng. Nếu như bạn nào dùng ADO thì sẽ thấy rất rõ điều này.
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom