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,599
Được thích
2,908
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ị
 
Nếu cột C có công thức thì lại... phiền
Ủng hộ cách dùng 2 mảng riêng, không đụng chạm gì nhau sẽ không.. mích lòng

Thầy ơi em dùng hai mảng riêng rồi mà sao em làm không chuẩn ở đâu mà không được như kết quả mong muốn nhỉ. mảng tarr đang bị lệch đi một ô.
 
Upvote 0
Dùng 1 mảng có cái lợi là tách rời phần code tổng hợp dữ liệu ra phỏi phần code ghi lại dữ liệu. Dễ kiểm soát hơn

Range("A1").Resize(Ubound(dArr), 2).Value = dArr ' copy 2 cột đầu xuống cột A và B
For i = 1 to UBound(dArr) ' chuyển giá trị từ cột thứ 4 sang cột 1
dArr(i, 1) = dArr(i, 4)
Next i
Range("D1").Resize(Ubound(dArr), 1).Value = dArr ' copy cột 1 xuống cột D

Dùng 2 mảng có thể nhanh hơn 1chút, vì tiết kiệm được phần chuyển giá trị. Nếu dữ liệu là số thì đoạn này rất nhanh, không thành vấn đề.
 
Upvote 0
Dùng 1 mảng có cái lợi là tách rời phần code tổng hợp dữ liệu ra phỏi phần code ghi lại dữ liệu. Dễ kiểm soát hơn

Range("A1").Resize(Ubound(dArr), 2).Value = dArr ' copy 2 cột đầu xuống cột A và B
For i = 1 to UBound(dArr) ' chuyển giá trị từ cột thứ 4 sang cột 1
dArr(i, 1) = dArr(i, 4)
Next i
Range("D1").Resize(Ubound(dArr), 1).Value = dArr ' copy cột 1 xuống cột D

Dùng 2 mảng có thể nhanh hơn 1chút, vì tiết kiệm được phần chuyển giá trị. Nếu dữ liệu là số thì đoạn này rất nhanh, không thành vấn đề.

Bạn VetMini có thể xem cách mình làm ở bài #812 xem vì sao nó không nhảy đúng được không?
 
Upvote 0
Không biết về đường dài, find có nhanh hơn hay không. Nhưng với dữ liệu hiện tại, thì mảng nhanh hơn đó.
Mã:
    lIndex = Application.WorksheetFunction.Match(sArr1(i, 1), Rng, 0)
xử lý trên range thường chậm hơn trên mảng, dùng find hoặc Match mặc dù code giảm 1 vòng lập nhưng không bù được tốc độ, rất nhiều bài dùng mảng kết hợp Dic là nhanh nhất, nếu dữ liệu phù hợp, như bài nầy không cần dùng Dic vẫn giảm được số vòng lập
 
Upvote 0
Em có 2 vùng dữ liệu (về kích thước bằng nhau). Em dùng hàm Application.Union nối hai vùng đó lại và gán nó vào mảng (Cụ thể trong file đính kèm em thấy không đúng)). Vậy mong Thầy, Anh(Chị) cho em hỏi mình có thể tạo mảng bằng cách như vậy không ạ
 

File đính kèm

  • Taomang.xlsb
    17.6 KB · Đọc: 20
Lần chỉnh sửa cuối:
Upvote 0
Em có 2 vùng dữ liệu (về kích thước bằng nhau). Em dùng hàm Application.Union nối hai vùng đó lại và gán nó vào mảng (Cụ thể trong file đính kèm em thấy không đúng)). Vậy mong Thầy, Anh(Chị) cho em hỏi mình có thể tạo mảng bằng cách như vậy không ạ
Khi 2 vùng không liên tục như trường hợp của bạn thì không được.
Bạn kiểm tra: msgbox cot (kết quả =1)
Nếu thay Set eRng = .Range("B6:B18") khi đó Rng là vùng liên lục, và kết quả (1) = (2)
 
Upvote 0
Khi 2 vùng không liên tục như trường hợp của bạn thì không được.
Bạn kiểm tra: msgbox cot (kết quả =1)
Nếu thay Set eRng = .Range("B6:B18") khi đó Rng là vùng liên lục, và kết quả (1) = (2)
Dạ cám ơn anh. Em đang tập tành viết hàm tìm dữ liệu theo cấu trúc kiểu (Vungdulieu; MaTK;Vungdulieu) nên em định ép 2 vùng đó vào 1 mảng và thực thi trên mảng đó .
 
Upvote 0
Định nghĩa của mảng là vùng dữ liệu liên tục.
VBA cho phép bạn chuyển 1 vùng range sang mảng vì nó không đi ngược định nghĩa này. Nếu vùng range của bạn khong liên tục, VBA phải có cách định nghĩa lại cách chuyển biến (map) từ 2 vùng khong liên tục thành 1 vùng liên tục.
Hiện thời thì MS chưa thấy cần thiết phải định nghĩa lại cho nên nó chưa cho phép làm.

Kỹ thuật gần nhất là tạo 1 mảng với 2 mảng
Dim mang(1 to 2) as variant
mang(1) = range1.value
mang(2) = range2.value

Lúc xét mảng thì nhét code, hễ hết mang(1) thì chuyển sang mang(2)
(code như thế nào thì phải tuỳ cách dùng)
 
Upvote 0
Định nghĩa của mảng là vùng dữ liệu liên tục.
VBA cho phép bạn chuyển 1 vùng range sang mảng vì nó không đi ngược định nghĩa này. Nếu vùng range của bạn khong liên tục, VBA phải có cách định nghĩa lại cách chuyển biến (map) từ 2 vùng khong liên tục thành 1 vùng liên tục.
Hiện thời thì MS chưa thấy cần thiết phải định nghĩa lại cho nên nó chưa cho phép làm.

Kỹ thuật gần nhất là tạo 1 mảng với 2 mảng
Dim mang(1 to 2) as variant
mang(1) = range1.value
mang(2) = range2.value

Lúc xét mảng thì nhét code, hễ hết mang(1) thì chuyển sang mang(2)
(code như thế nào thì phải tuỳ cách dùng)
Cám ơn thầy cho em hiểu thêm kiến thức về mảng. Lúc đầu em nhầm tưởng dùng hàm Union gép lại thì tạo được 1 vùng liên tục
 
Upvote 0
Ý định của em là muốn bớt cái tArr cho nhẹ bớt như trong file đính kèm. Anh sửa hộ em với
Bạn để ý thêm:
- Nếu vùng chọn là 1 cell thì sao?
- Nếu vùng chọn nhiều hơn 1 cột, nhiều hơn 1 hàng thì sao?
- Có cần phải xoay lại vùng về chiều đứng không?
- Nếu vùng chọn là nhiều hàng, nhiều cột thì mặc định bạn chọn hàng 1 (cột 1) chẳng hạn, và xét các phần tử ở 2 vùng khi cùng chỉ số.
 
Upvote 0
Trường hợp của bạn tôi nghĩ có lẽ dùng kỹ thuật 1 mảng lớn liên tục là DỄ NHẤT.

1. Tìm số dòng tổng cộng.
2. Lúc copy từ range1 ra mảng copy dư thêm luôn tất cả số dòng
3. copy từ range2 ra 1 mảng tạm
4. copy mảng tạm vào phần dư trên mảng chính.

Tôi nhớ hình như thớt này đã có bài như thế rồi. Bạn chịu khó tìm. Nếu không thấy thì tôi nghĩ khả năng bạn viết code này không khó.
 
Upvote 0
Trường hợp của bạn tôi nghĩ có lẽ dùng kỹ thuật 1 mảng lớn liên tục là DỄ NHẤT.

1. Tìm số dòng tổng cộng.
2. Lúc copy từ range1 ra mảng copy dư thêm luôn tất cả số dòng
3. copy từ range2 ra 1 mảng tạm
4. copy mảng tạm vào phần dư trên mảng chính.

Tôi nhớ hình như thớt này đã có bài như thế rồi. Bạn chịu khó tìm. Nếu không thấy thì tôi nghĩ khả năng bạn viết code này không khó.
Dạ . Trước em làm theo cấu trúc hàm VLOOKUP (được có 1 chiều thôi ạ). Nhưng thấy cấu trúc hàm Sumif hay hay nên thử xem có được không
Cám ơn thầy nhiều. Rất mong được sự giúp đỡ từ thầy./
 
Upvote 0
Code Vlookup nhiều vùng nè:

Mã:
' hàm sử dụng VLookup để tìm trên nhiều ranges
' lưu ý là hàm được đơn giản hoá, khong có các code trắc nghiệm sự hợp lý của tham số
' tham số:
' vl: trị cần tìm
' rgs: mảng các ranges
' col: cột cần trả về
' khong có tham thứ tư vì tìm từng range khong thể thực hiện theo kiểu tìm khoảng (1, -1)
' nếu muốn tìm kiểu này bắt buộc phải chập các ranges lại và sắp xếp tăng/giảm dần

Function MRVLookup(byVal vl, byVal rgs, byVal col)
Dim rg as range
For each rg in rgs
MRVLookup = Application.Vlookup(vl, rg, col, 0)
If Not IsError(MRVLookup) Then Exit Function
Next rg
End Function

' code gọi hàm
ketqua = MRVLookup(tricantim, Array( Sheet1.Range("A1:C10"), Sheet1.Range("A100:C150"), Sheet2.Range("B1:D10") ), 3)
If Not IsError(ketqua) Then
 
Upvote 0
Em có 2 vùng dữ liệu (về kích thước bằng nhau). Em dùng hàm Application.Union nối hai vùng đó lại và gán nó vào mảng (Cụ thể trong file đính kèm em thấy không đúng)). Vậy mong Thầy, Anh(Chị) cho em hỏi mình có thể tạo mảng bằng cách như vậy không ạ
Làm vầy nè:
Mã:
Function BigRange(ByVal SrcRng As Range) As Range
  Set BigRange = Range(Replace(SrcRng.Address, ",", ":"))
End Function
Sub Taomang2()
  Dim SRng As Range, eRng As Range
  Dim Rng As Range, hang As Long, Cot As Long
  Dim sArr
  With Sheet1
    Set SRng = .Range("A6:A18"): Set eRng = .Range("C6:C18")
    Set Rng = BigRange(.Range(SRng, eRng))
    sArr = Rng.Value
    hang = UBound(sArr, 1): Cot = UBound(sArr, 2)
    .Range("I6").Resize(hang, Cot) = sArr
  End With
End Sub
 
Upvote 0
Code tạo một mảng lớn liên tục từ 2 ranges
Mã:
' có 2 ranges, rg1 và rg2. Tạo một mảng lớn với dữ liệu từ 2 ranges này
Dim mang, mangPhu
Dim soCot as Long, soDong as Long, i as Long, j as long
soCot = Application.Max(rg1.columns.count, rg2.columns.count) ' số cột bắt buộc phải là số lớn giữa 2 ranges
soDong = rg1.rows.count + rg2.rows.count ' số dòng là tổng 2 ranges
mang = rg1.Resize(soDong, soCot).Value ' chép rg1 vào mảng, với số dòng dư
mangPhu = rg2.Resize(, soCot).Value ' chép rg2 vào mảng phụ
soDong = rg1.rows.count ' bắt đầu chép mảng phụ vào mảng chính
For i = 1 to rg2.rows.count
  soDong = soDong + 1
  For j = 1 to soCot
    mang(soDong, j) = mangPhu(i, j)
  Next j
Next i
 
Upvote 0
Web KT

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

Back
Top Bottom