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

  • Thread starter Thread starter viehoai
  • Ngày gửi Ngày gửi
Liên hệ QC

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

  • 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

    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