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ị
 
Em thì đoán như này:
Người ta chắc đang dùng một đoạn code nào đó, kết quả trả về là một mảng KQ (2 chiều, tạm gọi là hàng và cột như người ta mô tả). Tuy nhiên, nó xảy ra trường hợp số lượng kết quả (theo hàng, cột) nằm trong mảng KQ nhỏ hơn số hàng, cột của mảng KQ đã khai báo. Tức là trong mảng KQ đang dư các phần tử không có gì cả.
Và người ta cần làm gì đó (chưa biết ???) nên muốn "Redim" lại mảng KQ kia sao cho số hàng, cột của mảng KQ = số lượng kết quả thực tế trả về (theo hàng, cột), tất nhiên là vẫn giữ được các kết quả đã có trong mảng KQ.

Ví dụ:
Ban đầu có: KQ(1 to 5, 1 to 3)
Sau một đoạn code thì có:
KQ(1,1)=1
KQ(2,1)=2
KQ(3,1)=3
KQ(2,1)=4
KQ(2,2)=5
Kết quả mong muốn: KQ(1 to 3, 1 to 2) và vẫn giữ được các kết quả trong KQ đã có ở bước trên.
Dạ đúng như anh nói. Kết quả sau khi xử lý số dòng ở mảng KQ nó sẽ lớn hơn số dòng ở mảng mình tạo ban đầu ban đầu.
Bài đã được tự động gộp:

Hãy giải thích đỏ đỏ. Tốt nhất lấy thêm ví dụ để mô tả

Mảng 2 chiều? Đừng bắt người khác đoán khi bạn có thể tự nói.

Mã:
Redim Arr(LBound(result) to UBound(result), LBound(result, 2) to UBound(result, 2))

Nếu mảng kết quả có các chỉ số bắt đầu từ 1 thì gõ ít chút
Mã:
Redim Arr(1 to UBound(result), 1 to UBound(result, 2))

Ý là thế???
Em xin trình bày thêm. Mảng ban đầu của em là có 5 dòng, 3 cột. Sau khi xử lý số liệu kết quả trả về số dòng có thể lớn hơn hoặc nhỏ hơn số dòng ở mảng ban đầu (không xác định được). Vậy cho em hỏi làm thế nào để redim mảng bằng số số dòng, số cột ở kết quả xử lý không? Vi dụ Mảng ban đầu BD(5 dòng, 3 cột). , kết quả KQ(7dòng, 3 cột). Mình Redim KQ như thến nào để xác định được (7 dòng, 3 cột)
 
Lần chỉnh sửa cuối:
Upvote 0
Sau khi xử lý số liệu kết quả trả về số dòng có thể lớn hơn... Vi dụ Mảng ban đầu BD(5 dòng, 3 cột), kết quả KQ(7dòng, 3 cột)
Kết quả cuối cùng không có chuyện lớn hơn đâu. Nếu có lớn hơn thì trong code đã xử lý để mảng KQ có kích thước đủ lớn chứa hết các kết quả rồi.
Dạ đúng như anh nói. Kết quả sau khi xử lý số dòng ở mảng KQ nó sẽ lớn hơn số dòng ở mảng mình tạo ban đầu ban đầu.
Hồi chưa biết gì mình dùng code có sẵn cũng bị dính y chang, rồi phải viết thêm hàm để lấy các phần tử trong mảng kết quả... Thấy hơi buồn cười nhưng tạm dùng đã.
Bạn gửi cái code đang dùng đó lên đây, sẽ có cách xử lý cho kết quả hợp lý nhất.
 
Upvote 0
Kết quả cuối cùng không có chuyện lớn hơn đâu. Nếu có lớn hơn thì trong code đã xử lý để mảng KQ có kích thước đủ lớn chứa hết các kết quả rồi.

Hồi chưa biết gì mình dùng code có sẵn cũng bị dính y chang, rồi phải viết thêm hàm để lấy các phần tử trong mảng kết quả... Thấy hơi buồn cười nhưng tạm dùng đã.
Bạn gửi cái code đang dùng đó lên đây, sẽ có cách xử lý cho kết quả hợp lý nhất.
Nhờ anh xem giúp
ReDim dArr(1 To UBound(sArr) * 2, 1 To 13) . Để xử lý do dòng nhiều hơn nên x 2
Với code trong file ghi xuống sheet thì không có gì. Em muốn hỏi thêm xem có cách xử lý nào khác để vận dụng trong file của mình
 

File đính kèm

  • hoitest.xlsm
    61.2 KB · Đọc: 11
Upvote 0
Nhờ anh xem giúp
ReDim dArr(1 To UBound(sArr) * 2, 1 To 13) . Để xử lý do dòng nhiều hơn nên x 2
Với code trong file ghi xuống sheet thì không có gì. Em muốn hỏi thêm xem có cách xử lý nào khác để vận dụng trong file của mình
Mình thấy bắt đầu vòng vo rồi à. Nếu không nêu được trường hợp nào cần thiết như câu hỏi ban đầu thì dừng.
----
(Kiểu chung chung thì như vầy) Với mảng KQ( 1 To x, 1 to N), N là cố định thì có thể:
- Xoay 90 độ mảng KQ: KQ( 1 To N, 1 to x), sau khi xử lý được k cột kết quả thì dùng Redim Preserve KQ(1 To N, 1 to k) và viết một hàm TransposeArr() để xoay cái mảng KQ thành KQ(1 to k, 1 to N).
- Thêm biến để ghi nhớ số dòng, số cột kết quả. Muốn làm gì thì cứ lấy 2 biến đó mà dùng.
Ví dụ bạn viết một hàm trả về KQ( 1 To x, 1 to y) nhưng giờ viết sao kết quả trả về Res(1 to 3), với:
Res(1)=KQ( 1 To x, 1 to y)
Res(2)=N 'với N=1:x
Res(3)=M 'với M=1:y
(N, M là số dòng, cột kết quả thực tế).
 
Upvote 0
Mình thấy bắt đầu vòng vo rồi à. Nếu không nêu được trường hợp nào cần thiết như câu hỏi ban đầu thì dừng.
----
(Kiểu chung chung thì như vầy) Với mảng KQ( 1 To x, 1 to N), N là cố định thì có thể:
- Xoay 90 độ mảng KQ: KQ( 1 To N, 1 to x), sau khi xử lý được k cột kết quả thì dùng Redim Preserve KQ(1 To N, 1 to k) và viết một hàm TransposeArr() để xoay cái mảng KQ thành KQ(1 to k, 1 to N).
- Thêm biến để ghi nhớ số dòng, số cột kết quả. Muốn làm gì thì cứ lấy 2 biến đó mà dùng.
Ví dụ bạn viết một hàm trả về KQ( 1 To x, 1 to y) nhưng giờ viết sao kết quả trả về Res(1 to 3), với:
Res(1)=KQ( 1 To x, 1 to y)
Res(2)=N 'với N=1:x
Res(3)=M 'với M=1:y
(N, M là số dòng, cột kết quả thực tế).
Cảm ơn anh. Em tạo thêm 1 mảng rồi Redim lại theo biến k là lấy được số hàng.
 
Upvote 0
Càng đọc càng không hiểu

Nếu KQ đã có 7 dòng 3 cột rồi thì sao lại phải redim KQ để có 7 dòng 3 cột?
tại em trình bày kém quá. 7 dòng là sau khi xử lý số liệu mới biết. như vidu bài 1001 của em. Dòng dữ chỉ có 17 dòng (dữ liệu), nhưng sau khi xử lý số dòng nó lên 20 dòng (sheet2)
 
Upvote 0
Ví dụ thế này:
- Bạn có dữ liệu tại A1:A10
- Bạn muốn nối chuổi từ các cell ở vùng trên
- Bạn nghĩ ra có thể dùng làm Join để làm điều này
- Nhưng hàm Join chỉ làm việc với mảng 1 chiều
- Vậy việc của bạn phải biến Range("A1:A10") thành 1 mảng và phải là mảng 1 chiều
Ta làm như sau:
PHP:
Sub Test()
  Dim Arr
  Arr = Range("A1:A10").Value
  Arr = WorksheetFunction.Transpose(Arr)
  Range("B1") = Join(Arr, ", ")
End Sub
Rút gọn:
PHP:
Sub Test()
  Dim Arr
  Arr = WorksheetFunction.Transpose(Range("A1:A10"))
  Range("B1") = Join(Arr, ", ")
End Sub
Rút gọn tiếp:
PHP:
Sub Test()
  Range("B1") = Join(WorksheetFunction.Transpose(Range("A1:A10")), ", ")
End Sub
Tóm lại:
- Với 1 Range là 1 vùng có nhiều dòng, 1 cột thì khi qua hàm TRANSPOSE nó sẽ biến thành mảng 1 chiều
- Với 1 Range là 1 vùng có nhiều cột, 1 dòng thì khi qua hàm TRANSPOSE nó sẽ biến thành mảng 2 chiều (có thể mường tượng là mảng dọc) ---> Lại qua hàm TRANSPOSE tiếp lần nữa, nó sẽ biến thành mảng 1 chiều
Ví dụ: Nối chuổi các cell trong vùng A1:J1
PHP:
Sub Test()
  With WorksheetFunction
    Range("A2") = Join(.Transpose(.Transpose(Range("A1:J1"))), ", ")
  End With
End Sub
Phải 2 lần TRANSPOSE mới có thể biến Range("A1:J1") thành mảng 1 chiều
-------------
Nói thêm:
- Đã gọi là mảng 1 chiều thì không mường tượng nó là DỌC NGANG gì cả... đơn giàn là MẢNG 1 CHIỀU thôi
- Mảng 1 chiều và 2 chiều có thể mường tượng chúng khác nhau như khi so sánh ĐƯỜNG THẰNG và MẶT PHẲNG vậy (đường thẳng chỉ có duy nhất chiều dài, còn mặt phẳng thì mới có 2 chiều DỌC, NGANG)
Ví dụ thế này:
- Bạn có dữ liệu tại A1:A10
- Bạn muốn nối chuổi từ các cell ở vùng trên
- Bạn nghĩ ra có thể dùng làm Join để làm điều này
- Nhưng hàm Join chỉ làm việc với mảng 1 chiều
- Vậy việc của bạn phải biến Range("A1:A10") thành 1 mảng và phải là mảng 1 chiều
Ta làm như sau:
PHP:
Sub Test()
  Dim Arr
  Arr = Range("A1:A10").Value
  Arr = WorksheetFunction.Transpose(Arr)
  Range("B1") = Join(Arr, ", ")
End Sub
Rút gọn:
PHP:
Sub Test()
  Dim Arr
  Arr = WorksheetFunction.Transpose(Range("A1:A10"))
  Range("B1") = Join(Arr, ", ")
End Sub
Rút gọn tiếp:
PHP:
Sub Test()
  Range("B1") = Join(WorksheetFunction.Transpose(Range("A1:A10")), ", ")
End Sub
Tóm lại:
- Với 1 Range là 1 vùng có nhiều dòng, 1 cột thì khi qua hàm TRANSPOSE nó sẽ biến thành mảng 1 chiều
- Với 1 Range là 1 vùng có nhiều cột, 1 dòng thì khi qua hàm TRANSPOSE nó sẽ biến thành mảng 2 chiều (có thể mường tượng là mảng dọc) ---> Lại qua hàm TRANSPOSE tiếp lần nữa, nó sẽ biến thành mảng 1 chiều
Ví dụ: Nối chuổi các cell trong vùng A1:J1
PHP:
Sub Test()
  With WorksheetFunction
    Range("A2") = Join(.Transpose(.Transpose(Range("A1:J1"))), ", ")
  End With
End Sub
Phải 2 lần TRANSPOSE mới có thể biến Range("A1:J1") thành mảng 1 chiều
-------------
Nói thêm:
- Đã gọi là mảng 1 chiều thì không mường tượng nó là DỌC NGANG gì cả... đơn giàn là MẢNG 1 CHIỀU thôi
- Mảng 1 chiều và 2 chiều có thể mường tượng chúng khác nhau như khi so sánh ĐƯỜNG THẰNG và MẶT PHẲNG vậy (đường thẳng chỉ có duy nhất chiều dài, còn mặt phẳng thì mới có 2 chiều DỌC, NGANG)
Thưa thầy e không hiểu. Như thầy nói 1 range chuyển về mảng nó là mảng 2 chiều. Vậy range("A1:J1") chuyen ve mảng nó là mảng 2 chiều. Dung transpose 1 lần nó ra 1 chiều . Sao lại là 2 lần tranpose... Dạ e mới học nên chưa hiểu sâu mong thầy giảng ạ
 
Upvote 0
Thưa thầy e không hiểu. Như thầy nói 1 range chuyển về mảng nó là mảng 2 chiều. Vậy range("A1:J1") chuyen ve mảng nó là mảng 2 chiều. Dung transpose 1 lần nó ra 1 chiều . Sao lại là 2 lần tranpose... Dạ e mới học nên chưa hiểu sâu mong thầy giảng ạ
Thì tại nó... vậy đấy mà. Đọc chỗ "TÓM LẠI" và thuộc lòng là được
 
Upvote 0
Các thầy và các anh ơi! Em mới tìm hiểu về mảng nên gà mờ quá! Các thầy và các anh giúp em gỡ rối chỗ này được không ạ. Em có 1 sheet CSDL, Giờ em dùng 1 mảng động để lọc ra những kết quả em cần lấy, Ví dụ như màng KQ() của em đã có dữ liệu, giờ làm cách nào để tạo ra 1 file excel mới vớ 1 sheet và đổ được kết quả từ mảng KQ() này vào sheét mới ở workbook mới kia ạ? Các thầy giúp em với ạ
 
Upvote 0
Chào mọi người

Tôi có 01 gặp phải 1 vấn đề với 1 đoạn code như dưới đây rất mong nhận được giúp đỡ ạ:
Mã:
Sub hien_thi()
Dim Arr, Shp, a As Long, i As Long

With Sheet1
    .DrawingObjects.Visible = True
    Arr = Array("TB_lx_1", "TB_lx_2", "TB_lx_3", "TB_lx_4", "TB_lx_5", "TB_lx_7")
    a = .Shapes("TB_lx_1").Top
    For Each Shp In Arr
        For i = 1 To 7
            If .Cells(i, "B") = "" Then
                .Shapes("TB_lx_" & i).Visible = False
            End If
        Next i
        If .Shapes(Shp).Visible = False Then
            .Shapes("gia tri tiep theo cua Shp").Top = a ' giá trị tiếp theo ngay sau .Shapes(Shp) bị ẩn
        Else
            .Shapes("gia tri tiep theo cua Shp").Top = a + .Shapes(Shp).Height
        End If
    Next Shp
End With
End Sub

cái gia tri tiep theo cua Shp đó tôi phải viết sao mới đúng ạ???
 

File đính kèm

  • vi_du_ve_Shape.xlsb
    17.2 KB · Đọc: 8
Upvote 0
Chào mọi người

Tôi có 01 gặp phải 1 vấn đề với 1 đoạn code như dưới đây rất mong nhận được giúp đỡ ạ:
Mã:
Sub hien_thi()
Dim Arr, Shp, a As Long, i As Long

With Sheet1
    .DrawingObjects.Visible = True
    Arr = Array("TB_lx_1", "TB_lx_2", "TB_lx_3", "TB_lx_4", "TB_lx_5", "TB_lx_7")
    a = .Shapes("TB_lx_1").Top
    For Each Shp In Arr
        For i = 1 To 7
            If .Cells(i, "B") = "" Then
                .Shapes("TB_lx_" & i).Visible = False
            End If
        Next i
        If .Shapes(Shp).Visible = False Then
            .Shapes("gia tri tiep theo cua Shp").Top = a ' giá trị tiếp theo ngay sau .Shapes(Shp) bị ẩn
        Else
            .Shapes("gia tri tiep theo cua Shp").Top = a + .Shapes(Shp).Height
        End If
    Next Shp
End With
End Sub

cái gia tri tiep theo cua Shp đó tôi phải viết sao mới đúng ạ???
Cuối cùng là bạn muốn làm cái gì?
 
Upvote 0
Cuối cùng là bạn muốn làm cái gì?
Dạ. em muốn làm cái thông báo dạng hình ảnh phía dưới ạ.
giả sử em có 7 shapes cho 7 cái thông báo, tuy nhiên chỉ có 5 cái thông báo có dữ liệu, còn lại 2 cái không có thì sẽ ẩn đi.
nhưng khi ẩn cái thứ 3 và thứ 5 thì nó sẽ bị trống giữa nên em viết đoạn code kia để cho toàn bộ các shapes về sau sếp lần lượt ngay dưới vị trí của shapes đầu tiên có dữ liệu ạ.
 

File đính kèm

  • z1148476807202_447cea745a749a618dfabb60c6d24932.jpg
    z1148476807202_447cea745a749a618dfabb60c6d24932.jpg
    48.9 KB · Đọc: 19
Upvote 0
Dạ. em muốn làm cái thông báo dạng hình ảnh phía dưới ạ.
giả sử em có 7 shapes cho 7 cái thông báo, tuy nhiên chỉ có 5 cái thông báo có dữ liệu, còn lại 2 cái không có thì sẽ ẩn đi.
nhưng khi ẩn cái thứ 3 và thứ 5 thì nó sẽ bị trống giữa nên em viết đoạn code kia để cho toàn bộ các shapes về sau sếp lần lượt ngay dưới vị trí của shapes đầu tiên có dữ liệu ạ.
Vẫn chưa hiểu lắm.
Có điều thắc mắc rằng: Câu hỏi của bạn thì liên quan gì đến chủ đề "MẢNG TRONG VBA (ARRAY)"
???
 
Upvote 0
Trước hết em cảm ơn anh đã quan tâm,

Vẫn chưa hiểu lắm.
Có điều thắc mắc rằng: Câu hỏi của bạn thì liên quan gì đến chủ đề "MẢNG TRONG VBA (ARRAY)"
???

Vì học hành không đến nơi đến chốn thôi bác ạ,
Tuy nhiên em cũng đã giải quyết được vấn đề. bằng cách thay vì em thay đổi cái vị trí xuất hiện của từng shapes thì em thay đổi phần "text" viết trên từng shapes đó anh ạ
em shared file lên đây nếu ai có ý tưởng làm cái thông báo như vậy tham khảo ạ,
 

File đính kèm

  • vi_du_ve_Shape.xlsb
    28.4 KB · Đọc: 8
Upvote 0
Cho em hỏi muốn đưa các Cells rời rạc vào mảng thì làm như nào, VD em chọn ô A5, A7, A3 xong Chạy Macro thì 3 ô này sẽ đc ghi vào mảng. Mọi người giúp em với
 
Upvote 0
Cho em hỏi muốn đưa các Cells rời rạc vào mảng thì làm như nào, VD em chọn ô A5, A7, A3 xong Chạy Macro thì 3 ô này sẽ đc ghi vào mảng. Mọi người giúp em với
Hiểu không chắc lắm nhưng bạn thử code này xem sao
Mã:
Sub GhiMang()
Dim Arr As Variant
Dim i, j, k
k = Selection.Count
ReDim Arr(1 To k)
For Each i In Selection
    j = j + 1
    Arr(j) = i
Next i
Range("C1").Resize(1, UBound(Arr)) = Arr
End Sub
 
Upvote 0
Các anh chị cho em hỏi chút.
Giờ em muốn gán giá trị của 1 vùng bao gồm A1:A5, C1:C5, G1:G5 vào một mảng. Rồi từ mảng đó em lại gán giá trị vào 1 vùng khác B11:B15, D11:D15, E11:E15.
Có cách nào để thực hiện việc gán giá trị như vậy ko ạ?
 
Upvote 0
1. Mảng ngang với các giá trị từ A1 đến A10: Được, gán từng giá trị một.:

Nhưng vẫn là ngang nhé, nên nếu gán ngược xuống sheet thì phải coi chừng quên.

PHP:
Sub Test3 ()
Dim Arr(1 to 10)
For i = 1 to 10
Arr(i) = Cells(i, 1)
Next
Range("B1:B10") = Arr
Range("C5:L5") = Arr
End Sub
Ta sẽ thấy B1:B10 cả 10 ô có cùng giá trị của A1. trong khi đó C5:L5 hiện đầy đủ theo hàng ngang.
Em xin hỏi thầy và các anh chị, với sub text3 này thì từ B1:B10 đã điền arr vào nhưng C5:L5 thì chỉ có C5 được điền giá trị thì là vì sao? và em thay từ C5:C10 thì điền dữ liệu arr vào bình thường như vậy chỉ có thể điền cột chứ dòng không điền được.
 
Upvote 0
Web KT

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

Back
Top Bottom