Các câu hỏi về mảng trong VBA (Array)

Liên hệ QC

viehoai

Thành viên gắn bó
Tham gia
22/5/09
Bài viết
2,600
Được thích
2,907
Xin các anh chị giúp đỡ Code Gán các giá trị của một Range là các phần tử của Mãng
Ví dụ: Tôi có các giá trị của Range("A1:A10"). Tôi muốn viết code để gán giá trị của các cells từ A1:A10 là các phần tử của Mãng Arr chẳn hạn.
Xin cảm ơn các anh chị
 
Xin gửi các bác cái hình có bảng. Em quên mất
 

File đính kèm

  • 111.PNG
    111.PNG
    9.5 KB · Đọc: 71
Upvote 0
Hỏi về khai báo mảng lồng

mọi người cho em hỏi vấn đề thế này
ví dụ như ta khai báo
Arr(2) => Arr(0), Arr(1), Arr(2)
rồi Arr(0) = range("A1:A3")
rồi Arr(1) = range("B1:B3")
rồi Arr(2) = range("C1:C3")
thì ta được 1 mảng lồng ghép với nhau
là Arr(0)(1,1)
Arr(0)(2,1)
Arr(0)(3,1)
......< chỗ này không biết đúng ko nữa>
vậy cho em hỏi
ta có thể khai báo kích thước của Arr(0) lại Arr(0) (0 to 10)
cái chỗ màu đỏ đó có được không, và khai báo lại thế nào vậy ạ
 
Upvote 0
Có đến vài cách thực hiện. Tôi hỏi lý do là để dùng cách đúng nhất. Trả lời khơi khơi thế lấy gì mà mò.
Thôi nhường người khác vậy.
học hỏi thêm thì không chỉ được sao bác @@
tại có vấn đề thế này

ví dụ em muốn chèn giá trị của mảng vào A1:D10
khai báo C1: Arr(3) thì được 4 giá trị tương đương 4 cột (ở đây do số cột không cố định nên không thể khai báo nhiều mảng được nên em nghĩ cách dùng mảng thế này thì số cột thay đổi linh động hơn.) tương đương 1 Arr(x) là 1 mảng (rõ hơn xin đọc tiếp)
---------------------------------------------------------------------------------------------------------------
rồi lý do tại sao lại làm như thế mà không dùng C2: Arr(1 to x, 1 to y) - y cột x dòng (đơn giản)
là do em chỉ muốn điền kết quả theo cột chứ không điền nguyên mảng xuống cells
---------------------------------------------------------------------------------------------------------------
vì sao lại muốn như thế ? => ví dụ như em muốn điền xuống A1:D10
và ở cột C1:C10 lại có công thức
nếu như dùng C2 thì cột C sẽ mất đi công thức nên em muốn dùng theo C1 là điền từng mảng xuống cho cột A, B, D, vì vậy công thức tại cột C sẽ không mất
em có nghĩ ra 1 cách là khai báo 1 mảng ArrTam(1000) hoăc Arr(1 to 1000, 1 to 1) rồi gán nó vô mảng Arr là Arr(0) = ArrTam, Arr(1) = ArrTam.....
theo cách này thì cũng đúng ý nhưng lại tống tài nguyên cho mảng ArrTam -> ảnh hưởng đến chạy code
vấn đề là thế. mong được sự giúp đỡ từ bác và mọi người
 
Lần chỉnh sửa cuối:
Upvote 0
em có nghĩ ra 1 cách là khai báo 1 mảng ArrTam(1000) hoăc Arr(1 to 1000, 1 to 1) rồi gán nó vô mảng Arr là Arr(0) = ArrTam, Arr(1) = ArrTam.....
theo cách này thì cũng đúng ý nhưng lại tống tài nguyên cho mảng ArrTam -> ảnh hưởng đến chạy code
vấn đề là thế. mong được sự giúp đỡ từ bác và mọi người

Trình độ về tài nguyên của tôi chỉ biết đến việc dùng mảng tĩnh (fixed size & predeclared type) sẽ được một vùng nhớ liên tục và do đó hiệu quả hơn mảng động.
Còn việc tốn tài nguyên cho mảng tạm có ảnh hưởng đến chạy code hay không thì quá mức hiểu biết của tôi.

Ngoài ra, theo trường phái học của tôi thì việc tốn bộ nhớ chỉ quan trọng khi người ta viết hàm gọi nhau liên tục, và nhất là hàm đệ quy, vì bộ nhớ ngăn xếp có giới hạn. Chứ code chạy chỉ một hàm duy nhất thì vài cái mảng hàng chục triệu bytes chả có nghĩa lý gì cả.
 
Upvote 0
học hỏi thêm thì không chỉ được sao bác @@...

Tôi đã quen với cái tật hỏi úp úp mở mở của quý vị.
Ở trên tôi nói rõ "có vài cách làm". Nếu tôi không hỏi ngược lại thì làm sao quý vị tiết lộ ra là mình đã biết 1 cách, nhưng còn chê nó dở.
 
Upvote 0
nếu như dùng C2 thì cột C sẽ mất đi công thức
Nếu bạn dung thuộc tính Formula thì sẽ không mất công thức (arr = Range(...).Formula)

------------------------------------
nên em muốn dùng theo C1 là điền từng mảng xuống cho cột A, B, D, vì vậy công thức tại cột C sẽ không mất
em có nghĩ ra 1 cách là khai báo 1 mảng ArrTam(1000) hoăc Arr(1 to 1000, 1 to 1) rồi gán nó vô mảng Arr là Arr(0) = ArrTam, Arr(1) = ArrTam.....
theo cách này thì cũng đúng ý nhưng lại tống tài nguyên cho mảng ArrTam -> ảnh hưởng đến chạy code
vấn đề là thế. mong được sự giúp đỡ từ bác và mọi người

Tôi cũng thường dùng cách 1, vèo cái là xong chứ có gì đâu mà tốn tài nguyên
 
Upvote 0
Em có code sau:

If Arr(J, 7) = "" And Arr(J, 8) = "" And Arr(J, 9) = "" Then

Code này có thể viết thành dạng Resize được không ạ? Em viết như này thì báo lỗi:

If Arr(J, 7).Resize(Rws, 3) then
 
Upvote 0
Em có code sau:

If Arr(J, 7) = "" And Arr(J, 8) = "" And Arr(J, 9) = "" Then

Code này có thể viết thành dạng Resize được không ạ? Em viết như này thì báo lỗi:

If Arr(J, 7).Resize(Rws, 3) then

Không, tại sao thì bạn tự suy nghĩ xem cho hiểu sâu và đúng hơn vì tôi không biết Arr thuộc loại biến gì(?)
 
Upvote 0
Arr là mảng winvista
Rws = Range("C65536").End(xlUp).Row

Arr() = [E9].Resize(Rws, 9).Value
ReDim dArr(1 To Rws, 1 To 2)
For J = 1 To UBound(Arr())
 
Upvote 0
@tueyennhi,

Nếu Dim Arr() As Variant
thì có thể viết:
if Arr(J, 7) + Arr(J, 8) + Arr(J, 9) = empty then

Resize là thuộc tính của range.
range.resize()
 
Upvote 0
Vậy thì chắc không có cách viết nào khác mà xử lý dữ liệu nhanh hơn cách viết này mọi người nhỉ:

PHP:
 If Arr(J, 7) = "" And Arr(J, 8) = "" And Arr(J, 9) = "" Then
        dArr(J, 2) = ""
 ElseIf Arr(J, 7) <> "" And Arr(J, 8) <> "" And Arr(J, 9) <> "" Then
        dArr(J, 2) = ""
 Else
        dArr(J, 2) = 1
 End If

Code trên để check sự tồn tại dữ liệu ở 3 ô. Nếu tất cả đều có dữ liệu hoặc không có dữ liệu thì ra giá trị ""
Còn lại là giá trị 1
 
Lần chỉnh sửa cuối:
Upvote 0
Viết kiểu này cho đơn giản (vì không biết dữ liệu Arr chắc chắn là dạng sô hay text?)
PHP:
if (Arr(J, 7) = "" And Arr(J, 8) = "" And Arr(J, 9) = "") or (Arr(J, 7) <> "" And Arr(J, 8) <> "" And Arr(J, 9) <> "") then 
   dArr(J, 2) = ""
else:   dArr(J, 2) = 1   : End If

còn nhanh hay chóng thì quan trọng gì khi dữ liệu có vài ngàn dòng, khi nào dữ liệu cực lớn (hàng chục triệu) thì mới quan tâm nhanh chậm, thêm nữa nhanh chậm vẫn quan trọng thuật toán tổng thể gốc , há chi mấy con kiến nhỏ này
 
Upvote 0
Vậy thì chắc không có cách viết nào khác mà xử lý dữ liệu nhanh hơn cách viết này mọi người nhỉ:

PHP:
 If Arr(J, 7) = "" And Arr(J, 8) = "" And Arr(J, 9) = "" Then
        dArr(J, 2) = ""
 ElseIf Arr(J, 7) <> "" And Arr(J, 8) <> "" And Arr(J, 9) <> "" Then
        dArr(J, 2) = ""
 Else
        dArr(J, 2) = 1
 End If

Code trên để check sự tồn tại dữ liệu ở 3 ô. Nếu tất cả đều có dữ liệu hoặc không có dữ liệu thì ra giá trị ""
Còn lại là giá trị 1

Code trước khi bạn sửa nhanh hơn, tuy nó trông rườm rà hơn.
VBA khong có tính chất xét biểu thức một cách thong minh. Khi gặp If (biểu thức 1) And (biểu thức 2) And (biểu thức 3) thì nó phải tính đủ cả 3 biểu thức. Khác với nhiều ngôn ngữ sau này (PHP chẳng hạn) xét theo kiểu thong minh, nếu (biểu thức 1) không thoả thì nó tự động biết không xét đến (biểu thức 2)
Vì vậy trường hợp nhiều điều kiện đặt lồng vào nhau chạy nhanh hơn dùng And
 
Upvote 0
Code trước khi bạn sửa nhanh hơn, tuy nó trông rườm rà hơn.
VBA khong có tính chất xét biểu thức một cách thong minh. Khi gặp If (biểu thức 1) And (biểu thức 2) And (biểu thức 3) thì nó phải tính đủ cả 3 biểu thức. Khác với nhiều ngôn ngữ sau này (PHP chẳng hạn) xét theo kiểu thong minh, nếu (biểu thức 1) không thoả thì nó tự động biết không xét đến (biểu thức 2)
Vì vậy trường hợp nhiều điều kiện đặt lồng vào nhau chạy nhanh hơn dùng And

Ừm nhưng không hiểu sao nó lại sai không đúng bằng cái này.
 
Upvote 0
Viết kiểu này cho đơn giản (vì không biết dữ liệu Arr chắc chắn là dạng sô hay text?)
PHP:
if (Arr(J, 7) = "" And Arr(J, 8) = "" And Arr(J, 9) = "") or (Arr(J, 7) <> "" And Arr(J, 8) <> "" And Arr(J, 9) <> "") then 
   dArr(J, 2) = ""
else:   dArr(J, 2) = 1   : End If

còn nhanh hay chóng thì quan trọng gì khi dữ liệu có vài ngàn dòng, khi nào dữ liệu cực lớn (hàng chục triệu) thì mới quan tâm nhanh chậm, thêm nữa nhanh chậm vẫn quan trọng thuật toán tổng thể gốc , há chi mấy con kiến nhỏ này

:D. Tại thấy các anh trên này toàn tốc độ 0,0..mấy giây mà mình thì toàn mất gần 1s :((. Nên ham hố
 
Upvote 0
Vậy thì chắc không có cách viết nào khác mà xử lý dữ liệu nhanh hơn cách viết này mọi người nhỉ:

PHP:
 If Arr(J, 7) = "" And Arr(J, 8) = "" And Arr(J, 9) = "" Then
        dArr(J, 2) = ""
 ElseIf Arr(J, 7) <> "" And Arr(J, 8) <> "" And Arr(J, 9) <> "" Then
        dArr(J, 2) = ""
 Else
        dArr(J, 2) = 1
 End If

Code trên để check sự tồn tại dữ liệu ở 3 ô. Nếu tất cả đều có dữ liệu hoặc không có dữ liệu thì ra giá trị ""
Còn lại là giá trị 1
Vầy có lẽ nhanh hơn
PHP:
If Arr(J, 7) = "" Xor Arr(J, 8) = "" Then
    dArr(J, 2) = 1
ElseIf Arr(J, 7) = "" Xor Arr(J, 9) = "" Then
    dArr(J, 2) = 1
Else
    dArr(J, 2) = ""
End If
Có thể chỗ cẫn tối ưu không phải là chỗ này
 
Upvote 0
Web KT
Back
Top Bottom