Nhờ giải thích chi tiết về biến toàn cục

Liên hệ QC

BuiQuangThuan

❆❆❆❆❆❆❆❆❆❆❆❆
Tham gia
17/12/10
Bài viết
2,475
Được thích
2,931
Giới tính
Nam
Xin chào mọi người.
Hiện tại có 1 vài điểm khiến cháu/em vẫn còn lấn cấn và chưa hiểu thực sự về biến toàn cục. Hỏi lên đây nhờ mọi người có thể chỉ dạy thêm.
Để lợi dụng việc không phải duyệt đi duyệt lại dữ liệu nhiều lần với data để tìm ra kết quả dựa vào điều kiện nào đó.
Ví dụ chẳng hạn:
Với data ban đầu (*) Cháu có thể duyệt qua và nạp toàn bộ data cần vào Dictionary với Key và Item mong muốn
Phần Dictionary này sẽ được sử dụng nhiều lần cho nhiều module khác nhau.
Ở 1 data khác hay 1 module khác. Muốn sử dụng Dic ở phần đầu đã nạp mà không cần phải nạp lại data.
Việc nạp lại data chỉ thực hiện khi mà dữ liệu data ban đầu (*) có thêm dữ liệu
Do cháu vẫn đang mơ hồ về việc biến toàn cục. Cảm phiền các chú bác, anh chị nào đang đọc và hiểu ý cháu đang muốn hỏi có thể chỉ rõ cho cháu hiểu hơn về vấn đề này được không ạ
Nếu có thể ví dụ minh họa sơ sơ cho cháu thì càng tốt ạ.
Xin cảm ơn nhiều ạ
 
Xin chào mọi người.
Hiện tại có 1 vài điểm khiến cháu/em vẫn còn lấn cấn và chưa hiểu thực sự về biến toàn cục. Hỏi lên đây nhờ mọi người có thể chỉ dạy thêm.
Để lợi dụng việc không phải duyệt đi duyệt lại dữ liệu nhiều lần với data để tìm ra kết quả dựa vào điều kiện nào đó.
Ví dụ chẳng hạn:
Với data ban đầu (*) Cháu có thể duyệt qua và nạp toàn bộ data cần vào Dictionary với Key và Item mong muốn
Phần Dictionary này sẽ được sử dụng nhiều lần cho nhiều module khác nhau.
Ở 1 data khác hay 1 module khác. Muốn sử dụng Dic ở phần đầu đã nạp mà không cần phải nạp lại data.
Việc nạp lại data chỉ thực hiện khi mà dữ liệu data ban đầu (*) có thêm dữ liệu
Do cháu vẫn đang mơ hồ về việc biến toàn cục. Cảm phiền các chú bác, anh chị nào đang đọc và hiểu ý cháu đang muốn hỏi có thể chỉ rõ cho cháu hiểu hơn về vấn đề này được không ạ
Nếu có thể ví dụ minh họa sơ sơ cho cháu thì càng tốt ạ.
Xin cảm ơn nhiều ạ
Biến Dict mà để toàn cục nhưng dữ liệu nguồn lại có thể thay đổi thì cũng khá bất tiện. Phải kiểm soát được khi nào dữ liệu nguồn thay đổi (ví dụ như worksheet_change) thì lại phải nạp lại dict. Làm kiểu này có khi phải tính toán nhiều hơn kiểu nạp dict trong mỗi lần chạy code.
Còn biến toàn cục thì khai báo public để đầu module là được
 
Xin chào mọi người.
Hiện tại có 1 vài điểm khiến cháu/em vẫn còn lấn cấn và chưa hiểu thực sự về biến toàn cục. Hỏi lên đây nhờ mọi người có thể chỉ dạy thêm.
Để lợi dụng việc không phải duyệt đi duyệt lại dữ liệu nhiều lần với data để tìm ra kết quả dựa vào điều kiện nào đó.
Ví dụ chẳng hạn:
Với data ban đầu (*) Cháu có thể duyệt qua và nạp toàn bộ data cần vào Dictionary với Key và Item mong muốn
Phần Dictionary này sẽ được sử dụng nhiều lần cho nhiều module khác nhau.
Ở 1 data khác hay 1 module khác. Muốn sử dụng Dic ở phần đầu đã nạp mà không cần phải nạp lại data.
Việc nạp lại data chỉ thực hiện khi mà dữ liệu data ban đầu (*) có thêm dữ liệu
Do cháu vẫn đang mơ hồ về việc biến toàn cục. Cảm phiền các chú bác, anh chị nào đang đọc và hiểu ý cháu đang muốn hỏi có thể chỉ rõ cho cháu hiểu hơn về vấn đề này được không ạ
Nếu có thể ví dụ minh họa sơ sơ cho cháu thì càng tốt ạ.
Xin cảm ơn nhiều ạ
Bác Vẹt có viết truyện ngắn về cái này.

Giá mà minh họa như 7 viên ngọc rồng thì tốt biết mấy. --=0 --=0 --=0
 
Để hiểu biến "toàn cục", cần phải có 2 khái niệm. Thứ nhất là về bộ nhớ, và thứ hai là sự "nhìn thấy".
Nói cách khác, biến được chứa trong góc nào của bộ nhớ, và làm cách nào để truy cập biến (điển hình, bị che khuất tức là không nhìn thấy, mà không thấy thì không truy cập được)

Cách xác định toàn cục/biến nội:
Biến toàn cục có thể được khai báo ở bất cứ module nào (trừ class module). Lúc khai báo, cần nhớ rõ rằng biến toàn cục phải được khai báo trước bất cứ lệnh Sub hay Function nào trong module.
Biến nội được khai báo sau lệnh Sub hay Function. Tất cả các biến nội khai báo giữa 2 dòng Sub/Function và EndSub/Function hoàn toàn là của riêng Sub/Func ấy.

Bộ nhớ (life):
VBA chia bộ nhớ ra làm hai phần, phần bộ nhớ ụ (heap memory) và phần bộ nhớ ngăn xếp (stack memory). Tạm thời ở bài này không giải thích tại sao có những tên quái lạ này.
Phần bộ nhớ ụ là phần lâu dài (permanent), thuộc về chung cả Project. Biến chứa trong phần này sẽ giữ trị của chúng cho đến khi bị dọn rác, hoặc cả project kết thúc (hết chạy). Biến toàn cục được VBA chứa trong phần này, vì vậy chúng được khởi trị chỉ một lần (lúc khai báo). Sau đó, chúng tùy thuộc vào chỗ nào hoặc lúc nào gán trị khác.
Phần bộ nhớ ngăn xếp thuộc về function/sub. Biến chứa trong phần này sẽ bị hủy khi function/sub kết thúc (Exit/End Sub/Function). Biến nội được chứa trong phần này, vì vậy chúng được khởi trị với mỗi lượt gọi của sub/func, và xóa trị khi thoát sub/func.
Nói cách khác, biến toàn cục được giữ suôt khoảng thời gian chạy prooject. Biến nội chỉ được giữ trong thời gian chạy sub/func

Khả năng "được nhìn thấy" (visibility):
Biến toàn cục hiển hiện khắp Project. Muốn giấu nó không cho module khác thấy thì khai nó là Private. Từ khóa Private không hề ảnh hưởng tính chất "toàn cục" của biến. Private chỉ là một lệnh dẫn trình dịch, bảo trình dịch rằng "các món này chỉ thấy được trong module này, các modules khác sẽ không nhìn thấy". Nói cách khác, nó vẫn nằm chình ình đó, nhưng module khác truy cập vào sẽ bị ẩy ra (lỗi).
Biến nội thì không cần nói thêm. Của ai nấy xài, sub/func khác không được rớ vào (thực ra thì có thấy được đâu mà "rớ"). Lưu ý rằng dối với sub/func đệ quy thì mỗi lượt gọi tính là một sub/func khác.
Nếu một biến được truy cập đến trong một sub/func mà không được khai báo thì VBA sẽ lần lượt xét:
- Xét tất cả modules để tìm xem biến ấy có được khai báo là toàn cục hay không. Lưu ý rằng nếu không phải module hiện tại thì nó phải được khai Public, VBA mới cho nhìn thấy.
- Nếu không "nhìn thấy" biến toàn cục nào cả thì VBA mặc định đây là biến nội.
Đó là lý do chính mà người ta khuyên dùng Option Explicit. (Không hẳn là việc "tường minh", tránh gõ sai chính tả...)
Nếu tôi đang đọc code mà thấy một biến a được truy cập, không thấy khai báo thì tôi nhớ lại đầu module có thấy câu "Option Excplcit"? Nếu có thì tôi biết chắc a có được khai báo đâu đó, và là toàn cục. Nếu không có thì tôi phải đi tìm xem a có được khai báo Public ở đâu chăng trước khi kết luận nó là toàn cục hay biến nội.

Khi một biến được khai báo nội thì bên trong sub/func ấy, nó sẽ che biến toàn cục trùng tên. Nói cách khá, nếu code của bạn có mọt biến toàn cục a, nhưng bên trong sub xx bạn lại khai báo a (biến nội) thì mội truy cập đến a trong sub xx sẽ là a biến nội, khong phải a toàn cục.

Xong phần lý thuyết, thực hành thì rất dễ:

Vấn đề của bạn thì hiển nhiên là nên khai cái đít sần kia là toàn cục, đỡ phải dựng đối tượng và nạp dữ liệu mỗi lần truy cập.
Cấu trúc thường dùng là

Public DIC As Object
-------------------------- (VBA tự động vẽ một lằn gạch phân biệt giữa khai báo biến toàn cục và sub/func)

Sub KhoiDIC()
Set DIC = CreateObject.....
' đọc data và nạp vào DIC ở đây
End Sub

Sub LamViecA() ' cùng module
If DIC Is Nothing Then KhoiDIC
' làm việc ở đây
End Sub

Sub LamViecB() ' module khác
If DIC Is Nothing Then KhoiDIC
' làm việc ở đây
End Sub

Với cấu trúc code này, DIC là một biến toàn cục, được sử dụng triệt để, mọi sub/func trong module hiện tại hay modules khác đều có thể truy cập và update nó. Vì bạn muốn nhiều modules thấy nó cho nên dùng từ khóa Public. Bình thường tôi sẽ dùng từ khóa Private để tránh rắc rối bằng cách che không cbo các modules khác truy cập nó.
Trong bất cứ code nào cần đến cái Dic này, bạn thêm dòng code xét xem nó đã được nạp dữ liệu chưa, nếu chưa thì dựng đối tượng và tùy tiện nạp dữ liệu. Lưu ý là nếu dữ liêu có thể thay đổi thì code LamViec cũng phải cập nhật nó.
Đại khái là vậy. Bạn làm quen rồi sẽ biết cách sửa đổi cho hạp ý mình, uyển chuyển theo từng hoàn cảnh.
 
Để hiểu biến "toàn cục", cần phải có 2 khái niệm. Thứ nhất là về bộ nhớ, và thứ hai là sự "nhìn thấy".
Nói cách khác, biến được chứa trong góc nào của bộ nhớ, và làm cách nào để truy cập biến (điển hình, bị che khuất tức là không nhìn thấy, mà không thấy thì không truy cập được)

Cách xác định toàn cục/biến nội:
Biến toàn cục có thể được khai báo ở bất cứ module nào (trừ class module). Lúc khai báo, cần nhớ rõ rằng biến toàn cục phải được khai báo trước bất cứ lệnh Sub hay Function nào trong module.
Biến nội được khai báo sau lệnh Sub hay Function. Tất cả các biến nội khai báo giữa 2 dòng Sub/Function và EndSub/Function hoàn toàn là của riêng Sub/Func ấy.

Bộ nhớ (life):
VBA chia bộ nhớ ra làm hai phần, phần bộ nhớ ụ (heap memory) và phần bộ nhớ ngăn xếp (stack memory). Tạm thời ở bài này không giải thích tại sao có những tên quái lạ này.
Phần bộ nhớ ụ là phần lâu dài (permanent), thuộc về chung cả Project. Biến chứa trong phần này sẽ giữ trị của chúng cho đến khi bị dọn rác, hoặc cả project kết thúc (hết chạy). Biến toàn cục được VBA chứa trong phần này, vì vậy chúng được khởi trị chỉ một lần (lúc khai báo). Sau đó, chúng tùy thuộc vào chỗ nào hoặc lúc nào gán trị khác.
Phần bộ nhớ ngăn xếp thuộc về function/sub. Biến chứa trong phần này sẽ bị hủy khi function/sub kết thúc (Exit/End Sub/Function). Biến nội được chứa trong phần này, vì vậy chúng được khởi trị với mỗi lượt gọi của sub/func, và xóa trị khi thoát sub/func.
Nói cách khác, biến toàn cục được giữ suôt khoảng thời gian chạy prooject. Biến nội chỉ được giữ trong thời gian chạy sub/func

Khả năng "được nhìn thấy" (visibility):
Biến toàn cục hiển hiện khắp Project. Muốn giấu nó không cho module khác thấy thì khai nó là Private. Từ khóa Private không hề ảnh hưởng tính chất "toàn cục" của biến. Private chỉ là một lệnh dẫn trình dịch, bảo trình dịch rằng "các món này chỉ thấy được trong module này, các modules khác sẽ không nhìn thấy". Nói cách khác, nó vẫn nằm chình ình đó, nhưng module khác truy cập vào sẽ bị ẩy ra (lỗi).
Biến nội thì không cần nói thêm. Của ai nấy xài, sub/func khác không được rớ vào (thực ra thì có thấy được đâu mà "rớ"). Lưu ý rằng dối với sub/func đệ quy thì mỗi lượt gọi tính là một sub/func khác.
Nếu một biến được truy cập đến trong một sub/func mà không được khai báo thì VBA sẽ lần lượt xét:
- Xét tất cả modules để tìm xem biến ấy có được khai báo là toàn cục hay không. Lưu ý rằng nếu không phải module hiện tại thì nó phải được khai Public, VBA mới cho nhìn thấy.
- Nếu không "nhìn thấy" biến toàn cục nào cả thì VBA mặc định đây là biến nội.
Đó là lý do chính mà người ta khuyên dùng Option Explicit. (Không hẳn là việc "tường minh", tránh gõ sai chính tả...)
Nếu tôi đang đọc code mà thấy một biến a được truy cập, không thấy khai báo thì tôi nhớ lại đầu module có thấy câu "Option Excplcit"? Nếu có thì tôi biết chắc a có được khai báo đâu đó, và là toàn cục. Nếu không có thì tôi phải đi tìm xem a có được khai báo Public ở đâu chăng trước khi kết luận nó là toàn cục hay biến nội.

Khi một biến được khai báo nội thì bên trong sub/func ấy, nó sẽ che biến toàn cục trùng tên. Nói cách khá, nếu code của bạn có mọt biến toàn cục a, nhưng bên trong sub xx bạn lại khai báo a (biến nội) thì mội truy cập đến a trong sub xx sẽ là a biến nội, khong phải a toàn cục.

Xong phần lý thuyết, thực hành thì rất dễ:

Vấn đề của bạn thì hiển nhiên là nên khai cái đít sần kia là toàn cục, đỡ phải dựng đối tượng và nạp dữ liệu mỗi lần truy cập.
Cấu trúc thường dùng là

Public DIC As Object
-------------------------- (VBA tự động vẽ một lằn gạch phân biệt giữa khai báo biến toàn cục và sub/func)

Sub KhoiDIC()
Set DIC = CreateObject.....
' đọc data và nạp vào DIC ở đây
End Sub

Sub LamViecA() ' cùng module
If DIC Is Nothing Then KhoiDIC
' làm việc ở đây
End Sub

Sub LamViecB() ' module khác
If DIC Is Nothing Then KhoiDIC
' làm việc ở đây
End Sub

Với cấu trúc code này, DIC là một biến toàn cục, được sử dụng triệt để, mọi sub/func trong module hiện tại hay modules khác đều có thể truy cập và update nó. Vì bạn muốn nhiều modules thấy nó cho nên dùng từ khóa Public. Bình thường tôi sẽ dùng từ khóa Private để tránh rắc rối bằng cách che không cbo các modules khác truy cập nó.
Trong bất cứ code nào cần đến cái Dic này, bạn thêm dòng code xét xem nó đã được nạp dữ liệu chưa, nếu chưa thì dựng đối tượng và tùy tiện nạp dữ liệu. Lưu ý là nếu dữ liêu có thể thay đổi thì code LamViec cũng phải cập nhật nó.
Đại khái là vậy. Bạn làm quen rồi sẽ biết cách sửa đổi cho hạp ý mình, uyển chuyển theo từng hoàn cảnh.
Xin cảm ơn anh, bài viết mạch lạc và rất dễ hiểu.
 
@VetMini cảm ơn chú nhiều. Cháu sẽ đọc kỹ bài viết để có thể ứng dụng cho công việc cá nhân của bản thân. Và hiểu đúng những gì còn đang mơ hồ
Bài đã được tự động gộp:

Biến Dict mà để toàn cục nhưng dữ liệu nguồn lại có thể thay đổi thì cũng khá bất tiện. Phải kiểm soát được khi nào dữ liệu nguồn thay đổi (ví dụ như worksheet_change) thì lại phải nạp lại dict. Làm kiểu này có khi phải tính toán nhiều hơn kiểu nạp dict trong mỗi lần chạy code.
Còn biến toàn cục thì khai báo public để đầu module là được
Giả sử dữ liệu nguồn thay đổi. Dựa vào target để nạp thêm vào chứ ko phải chạy lại từ đầu. Liệu có bị sót không nhỉ anh gì ơi
 
Lần chỉnh sửa cuối:
Lúc viết bài trên, tôi cố tình bỏ qua biến Static cho giản dị.

Nếu bạn nào thắc mắc, cứ tạm hiểu rằng biến Static là đứa con lai giữa toàn cục và biến nội.

Về cách khai báo, biến Static được khai báo bên trong Sub/Func như biến nội.

Về "nhìn thấy" thì nó in hệt như biến nội. Tức là khai báo bên trong Sub/Func nào thì chỉ Sub/Func ấy biết nó thôi.

Về bộ nhớ thì nó in hệt như biến toàn cục, tức là nó được chứa trong bộ nhớ ụ (heap). Chỉ khởi trị một lần duy nhất, và từ đó giữ lấy bất cứ trị nào được gán. Khi Sub/Func thoát thì nó cũng không bị hủy. Khi Sub/Func được gọi lần kế tiếp thì nó mang trị được gán lần trước. (khác với biến nội khởi trị lại mỗi lần Sub/Func được gọi)
 
Giả sử dữ liệu nguồn thay đổi. Dựa vào target để nạp thêm vào chứ ko phải chạy lại từ đầu. Liệu có bị sót không nhỉ anh gì ơi
Cũng có thể là nạp thêm, mà cũng có thể là bớt đi (xóa bớt dữ liệu chẳng hạn). Trên bảng tính họ xóa dòng trùng lặp. Trong Dic không tính kỹ lại xóa luôn Key thì mệt, mà muốn chính xác thì phải tính toán nhiều. Chi bằng nạp lại Dic, mình hay chọn phương án như vậy, nhanh hay chậm 1,2 giây không quá quan trọng bằng việc có thể bị sai sót, nhầm lẫn
 
Theo cá nhân, thì biến nào cần phải dùng toàn cục cho lợi thế để không phải khai báo nhiều lần nạp lại nhiều lần trong các Sub hay Function | hoặc các hằng số thì em mới dùng. Còn lại thì em toàn nạp và giải phóng.
Em chưa đến trình độ phải tiết kiệm tài nguyên nên em cứ theo nguyên tắc trên thôi.
 
@VetMini cảm ơn chú nhiều. Cháu sẽ đọc kỹ bài viết để có thể ứng dụng cho công việc cá nhân của bản thân. Và hiểu đúng những gì còn đang mơ hồ
Bài đã được tự động gộp:


Giả sử dữ liệu nguồn thay đổi. Dựa vào target để nạp thêm vào chứ ko phải chạy lại từ đầu. Liệu có bị sót không nhỉ anh gì ơi
Dictionary nếu lưu trữ dữ liệu nhiều như tự điển tiếng Việt sẽ khá nặng, mỗi lần tra 1 từ phải chạy ra nhà sách rinh tự điển về sẽ tốn nhiều thời gian và công sức, chỉ nên rinh quyển từ điển về 1 lần và dùng nhiều lần, khi có dịp lên nhà sách thì chịu khó cập nhật tự điển mới
Dữ liệu nạp vào Dic nên lưu ở 1 sheet riêng, và tạo sự kiện nạp Dic
Mã:
Private Sub Worksheet_Deactivate()
  'Nap du lieu vào dictionary
End Sub
Tùy tình huống có thể xét điều kiện để nạp dic lúc đó sẽ giảm số lần nạp dic rất nhiều
 
...
Em chưa đến trình độ phải tiết kiệm tài nguyên nên em cứ theo nguyên tắc trên thôi.
Ở GPE này thowngf là viết code chạy tuồn tuột. Rất ít truonwgf hợp sub này gọi sub kia sub kia gọi sub nọ lằng nhằng dây dưa rễ má. Vì vậy chuyện "tiết kiệm tài nguyên" theo ý bạn gần như không cần thết.

Chú:
Tài nguyên bộ nhớ: khi hàm A gọi hàm B thì có một đống biến được đẩy vào ngăn xếp. Khi B gọi C thì lại thêm một đống nữa. Vài lần như thế, nếu mỗi hàm có một vài mảng lớn thì năng xếp có thể hết chỗ.
Tài nguyên khác: hàm A giữ tài nguyên X, B cũng cần X. Nếu có một cái gì chung để quản lý X thì A và B không phải giành nhau.
 
Đây là tình trạng lười vận động, đa số GPEr gặp phải...
Sai. Khai báo biến toàn cục (cụ thể là Dict) thì trên GPE rất ít người.
Cụ thể trường hợp của tôi:
- 1 Dict là danh sách cửa hàng, 1 Dict là danh sách mặt hàng, 1 Dict là danh sách khu vực, 1 Dict là danh sách nhân viên, ... tổng cộng 8 Dict (ở 2 file master data).
- 6, 7 module viết riêng, mỗi module sử dụng 1 sheet dữ liệu chứa điều kiện, mỗi module cho kết quả riêng. Và tất cả các module đều dùng đến cả 2 Dict trên.
- Có tùy chọn chạy riêng từng module và chạy 1 lần tuần tự các modules cho người dùng có máy mạnh yếu khác nhau, hoặc chỉ cần chạy riêng lấy 1 kết quả.
- Nạp Dict viết trong 1 module riêng để gọi.
- Không chỉ Dict, biến mảng cũng phải nạp 1 lần và cũng phải khai báo public

Nếu không khai báo Public thì cứ phải mở file, nạp 4 Dict, đóng file 6, 7 lần. Tất nhiên về mặt tốc độ thì không nói (năm mười giây hay nửa phút không là gì cả), nhưng code viết nhẹ nhàng hơn.
GPEr mà bé bo nói không làm tới mức đó, không gọi là lười, mà gọi là không biết các thủ thuật.

Hình dưới đây cho thấy public 8 Dict, 11 mảng dùng trong cả 8, 9 modules


1695114719894.png

1695114602431.png
 
<quote orig=bebo...>
Đây là tình trạng lười vận động, đa số GPEr gặp phải...
<end quote>
Sai. Khai báo biến toàn cục (cụ thể là Dict) thì trên GPE rất ít người.
....
Không hẳn sai. Y nói chuyện về nghĩa đen (đen thui luôn) của đít toàn cục...
Chỉ là y chủ quan. Việc "cục" này tùy thuộc vào bẩm sinh và ăn uống nhiều hơn do vận động.
Việc chủ quan thứ hai là tự dưng cá mè một lứa, gọi mọi người là GPEr thì hơi kém lịch sự.
 
Lần chỉnh sửa cuối:
Nếu không khai báo Public thì cứ phải mở file, nạp 4 Dict, đóng file 6, 7 lần. Tất nhiên về mặt tốc độ thì không nói (năm mười giây hay nửa phút không là gì cả), nhưng code viết nhẹ nhàng hơn.
Cái này là đúng này. Tại trong code cháu cứ phải viết đi viết lại Dic trong khi có khi nó là data chết. Họa chăng mới có sự thay đổi. Cám ơn mọi người, đặc biệt là @VetMini và các chú, anh chị trên diễn dàn đã giải thích cặn kẽ cho cháu hiểu
 
@BuiQuangThuan
Tham khảo thêm ADO Recordset, ứng dụng bạn nhé.

Nạp vào Dictionary mà để đó là một cái "dại dột", Dictionary ngốn hết RAM, thì "out of memory" mà không biết lỗi chi chi.

Trang tính Excel nó là dạng XML, là một dạng cơ sở dữ liệu ADODB bổ trợ, nên rất nhanh. Tiết kiệm.
 
Phán tầm bậy, *.xls cướp đâu ra xml.

----
Em đố bài #13, tại sao không dựng 1 cái dic_0 thôi, rồi toàn bộ các dic_khác set theo dic_0 vừa dựng.
Cái này mới hay đó. Bữa lâu mình có nhắc tới cái này rồi.
 
Em đố bài #13, tại sao không dựng 1 cái dic_0 thôi, rồi toàn bộ các dic_khác set theo dic_0 vừa dựng.
Cái này mới hay đó. Bữa lâu mình có nhắc tới cái này rồi.
Chịu thua. Mình chỉ làm theo thói quen. Thực ra nguyên bộ code đó làm từng phần (từng module), làm 1 phần rồi khách hàng kêu thêm, thêm, thêm. Một lần là thêm 1 vài Dict, nên gộp lại vào 1 thủ tục như vậy.
Vụ hay hay là không biết thật.
 
...
Em đố bài #13, tại sao không dựng 1 cái dic_0 thôi, rồi toàn bộ các dic_khác set theo dic_0 vừa dựng.
Cái này mới hay đó. Bữa lâu mình có nhắc tới cái này rồi.
Không hiểu rõ câu hỏi lắm.

Nếu bạn nói là chỉ dựng Dic_0 (CreateObject...), các cái khác Set theo đấy?
Từ khóa: reference
Khi Set một biến vào một đối tượng, VBA sẽ trỏ biến vào đối tượng ấy. Như vậy, ta chỉ có một đít là thực sự, mấy biến khác chỉ là các tên khác nhau của nó.
Từ khóa thứ hai: kết nối sớm.
Nếu dùng kiểu kết nối sớm (không qua CreateObject...) thì khi biến được sử dụng lần đầu tiên, VBA sẽ dựng đối tượng. Viecj Set qua lại có thể không hiệu quả lắm (tôi phải xem code mới khẳng định được)

Nếu bạn muốn nói tại sao không dùng 1 đít và tọng tất cả mọi thứ vào?
Từ khóa: partition.
Đít sần là công cụ của Script Engine. Tác giả nó chỉ chú ý về tốc độ chứ không về thanh lý dữ liệu hỗn tạp. Vì vậy, đít sần không thể làm công việc "phân khoa".
Ta có thể gộp đủ kiểu key/item vào một đít nhưng hàm truy cập hàng loạt của nó (key collection, item collection) không thể phân biệt các loại khác nhau.

Chú thích: về ADO. Phiên bản cũ của ADO cũng bị vấn đề về resource locking. Đôi khi làm việc trên Excel, nó lock recordset khiến sinh lỗi "out of memory". Mãi về sau này MS mới khắc phục được.
Vả lại, ADO dùng cổ máy Access để đọc file Excel. Chưa hẳn đã là hiệu quả nhất.
Kể từ phiên bản 2016 (download bổ sung vào phiên bản 2010.2013) MS đặt trọng tâm vào Data Model. Chỉ khi sử dụng Data Model thì Excel mới dùng cổ máy gần giống như SQL Server Express, rất hiệu quả.
 
Lần chỉnh sửa cuối:
Em đố bài #13, tại sao không dựng 1 cái dic_0 thôi, rồi toàn bộ các dic_khác set theo dic_0 vừa dựng.
Cái này mới hay đó. Bữa lâu mình có nhắc tới cái này rồi.
Nếu em hiểu đúng ý anh thì cái này nó chỉ trỏ tới cái Dic_0 kia thôi chứ thực chất là 1 dic thôi anh
 
Web KT
Back
Top Bottom