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ị
 
Chỗ này: Const N as Long = 5 và để trên cùng (Lần trước một bác chỉ cho mình như vậy).
Thêm ý ở bài #1038 nữa nhé :)
Mã:
UBound(sArr) * N
'...'
K
'//Cần kiểm tra so với số dòng tối đa của bảng tính

Mã:
For J = 1 To UBound(sArr, 2) '// thêm biến gán giá trị UBound(sArr, 2)  để không phải gọi lại chỗ đó nhiều lần
 
Upvote 0
Chỗ này: Const N as Long = 5 và để trên cùng (Lần trước một bác chỉ cho mình như vậy).
Thêm ý ở bài #1038 nữa nhé :)
Mã:
UBound(sArr) * N
'...'
K
'//Cần kiểm tra so với số dòng tối đa của bảng tính

Mã:
For J = 1 To UBound(sArr, 2) '// thêm biến gán giá trị UBound(sArr, 2)  để không phải gọi lại chỗ đó nhiều lần
Dạ. Cái này Anh nhắc Em mấy lần mà Em toàn quên thôi. Em cám ơn Anh nhiều
 
Upvote 0
Xin cảm ơn anh, chị và các bạn đã giúp đỡ ạ.
Các code trên đều chạy ra kết quả OK rồi.

Trong trường hợp dữ liệu trả về trong cột K:L (dữ liệu cột C đưa sang cột L,dữ liệu cột D đưa sang cột K) như ảnh kèm thì code của @quanghai1969 và @♫ђöล♥ßล†♥†µ♫(ôi cái tên ..đẹp ^^) thì phải sửa như thế nào ạ?
Híc mong các bạn đừng hiểu nhầm ạ , OT đang học hỏi để biết cách tự điều chỉnh,chứ thực tế dữ liệu hiện tại đang không phải như vậy,nhưng cũng có thể sẽ gặp ạ.
Nếu các bạn có thời gian mong được các bạn chỉ dẫn ạ.

Untitled.jpg
 
Upvote 0
Chỗ này em nhớ có một bác nói là dùng một vòng lặp thôi.. :rolleyes:

Code ngắn cũng có cái hay nhưng khó nhìn thuật toán trong code. Code dài lê thê nhìn thấy gớm nhưng cần điều chỉnh thì lại dễ hơn đối với những người chỉ dùng VBA trong công việc văn phòng hàng ngày. Người khéo sẽ biết chọn phương án phù hợp cho từng trường hợp mà.
 
Upvote 0
Xin cảm ơn anh, chị và các bạn đã giúp đỡ ạ.
Các code trên đều chạy ra kết quả OK rồi.

Trong trường hợp dữ liệu trả về trong cột K:L (dữ liệu cột C đưa sang cột L,dữ liệu cột D đưa sang cột K) như ảnh kèm thì code của @quanghai1969 và @♫ђöล♥ßล†♥†µ♫(ôi cái tên ..đẹp ^^) thì phải sửa như thế nào ạ?
Híc mong các bạn đừng hiểu nhầm ạ , OT đang học hỏi để biết cách tự điều chỉnh,chứ thực tế dữ liệu hiện tại đang không phải như vậy,nhưng cũng có thể sẽ gặp ạ.
Nếu các bạn có thời gian mong được các bạn chỉ dẫn ạ.

View attachment 206779
Em chế nó ra thế này. Nhân tiện luyện mấy cái Anh @befaint chỉ
PHP:
Sub ChuyenDL()
    Dim sArr(), dArr(), I As Long, Idx As Long, K As Long, J As Long, _
    R As Long, C As Long, Jdx As Long, sRng As Range
Const N As Long = 5
Set sRng = Range("K1")
sArr = Range("C1", Range("C" & Rows.Count).End(xlUp)).Resize(, 2).Value
R = UBound(sArr, 1): C = UBound(sArr, 2)
If R > Rows.Count - sRng.Row Then
    MsgBox "Hands On.com"
    Exit Sub
End If
ReDim dArr(1 To R * N, 1 To C)
For I = 1 To UBound(sArr)
    If sArr(I, 1) <> Empty Then
        For Idx = 1 To N
            K = K + 1: Jdx = 0
            For J = C To 1 Step -1
                Jdx = Jdx + 1:  dArr(K, Jdx) = sArr(I, J)
            Next J
        Next Idx
    End If
Next I
sRng.Resize(K, UBound(sArr, 2)) = dArr
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Em chế nó ra thế này. Nhân tiện luyện mấy cái Anh @befaint chỉ
PHP:
Sub ChuyenDL()
    Dim sArr(), dArr(), I As Long, Idx As Long, K As Long, J As Long, R As Long, C As Long, Jdx As Long
Const N As Long = 5
sArr = Range("C1", Range("C" & Rows.Count).End(xlUp)).Resize(, 2).Value
R = UBound(sArr, 1): C = UBound(sArr, 2)
ReDim dArr(1 To R * N, 1 To C)
For I = 1 To UBound(sArr)
    If sArr(I, 1) <> mpty Then
        For Idx = 1 To N
            K = K + 1: Jdx = 0
            For J = C To 1 Step -1
                Jdx = Jdx + 1:  dArr(K, Jdx) = sArr(I, J)
            Next J
        Next Idx
    End If
Next I
With Range("K1")
    If K < Rows.Count - .Row Then
        If K Then .Resize(K, UBound(sArr, 2)) = dArr
    Else
        MsgBox "Hands On.com"
    End If
End With
End Sub

Xin chào ♫ђöล♥ßล†♥†µ♫,
Cảm ơn bạn rất nhiều, code bị lỗi dòng "If sArr(I, 1) <> mpty Then", OT sửa lại "If sArr(I, 1) <> Empty Then" thì OK rồi bạn ạ.
Chắc bạn sửa luôn trên này chưa thử code (OT thấy người nào giỏi giỏi cái gì đó có ích, thấy ngưỡng mộ quá ^^)
 
Upvote 0
Xin cảm ơn anh, chị và các bạn đã giúp đỡ ạ.
Các code trên đều chạy ra kết quả OK rồi.

Trong trường hợp dữ liệu trả về trong cột K:L (dữ liệu cột C đưa sang cột L,dữ liệu cột D đưa sang cột K) như ảnh kèm thì code của @quanghai1969 và @♫ђöล♥ßล†♥†µ♫(ôi cái tên ..đẹp ^^) thì phải sửa như thế nào ạ?
Híc mong các bạn đừng hiểu nhầm ạ , OT đang học hỏi để biết cách tự điều chỉnh,chứ thực tế dữ liệu hiện tại đang không phải như vậy,nhưng cũng có thể sẽ gặp ạ.
Nếu các bạn có thời gian mong được các bạn chỉ dẫn ạ.

View attachment 206779
Thử code này, dữ liệu gì mà bắt đầu từ hàng 1, ngộ vậy, muốn từ hàng nào thì sửa trong code nhé:
Mã:
Public Sub Teo()
    Dim Vung, Kq, I, J
    Vung = Range([C2], [C50000].End(xlUp)).Resize(, 2)
    ReDim Kq(1 To UBound(Vung) * 5, 1 To 2)
        For I = 1 To UBound(Kq)
            J = J + IIf(I Mod 5 = 1, 1, 0)
            Kq(I, 2) = Vung(J, 1): Kq(I, 1) = Vung(J, 2)
        Next I
    [K2].Resize(UBound(Kq), 2) = Kq
End Sub
Thân
 
Upvote 0
Nếu dữ liệu 65536 dòng x 20 cột mà xài WorksheetFunction thì có mà tèo téo teo...

Cho vô mảng chạy 2 dòng For cho nó đẹp code nó bay cái Vèo :D:p
20x65000 = 1,3 triệu Variants
Máy cùi 1 chút cũng vỡ mật (out of memory) khỏi cần vòng pho phiếc gì cả.
 
Upvote 0
Thử code này, dữ liệu gì mà bắt đầu từ hàng 1, ngộ vậy, muốn từ hàng nào thì sửa trong code nhé:
Mã:
Public Sub Teo()
    Dim Vung, Kq, I, J
    Vung = Range([C2], [C50000].End(xlUp)).Resize(, 2)
    ReDim Kq(1 To UBound(Vung) * 5, 1 To 2)
        For I = 1 To UBound(Kq)
            J = J + IIf(I Mod 5 = 1, 1, 0)
            Kq(I, 2) = Vung(J, 1): Kq(I, 1) = Vung(J, 2)
        Next I
    [K2].Resize(UBound(Kq), 2) = Kq
End Sub
Thân

Xin chào @concogia ,
Cảm ơn bạn đã quan tâm và giúp đỡ dữ liệu Oanh Thơ gửi lên hiện thời mang tính minh họa mục đích để Oanh Thơ học hỏi về mảng và chắc chắn sau hi vọng sau sẽ ứng dụng được ít nhiều vào thực tế trong công việc ạ.
Không ngờ mảng lại tuyệt vời đến với đến vậy.Nhanh, nhanh quá!
 
Upvote 0
Xin chào các bạn,
Tôi muốn gán vùng dữ liệu C1:O1 vào DataValidation/list cho ô A1 và tôi đã thử code dưới bị lỗi chưa biết cách, nhờ các bạn xem giúp.
Mã:
Sub TestValidation()
    Dim ary As Variant
    ary = Sheets("Sheet1").Range("C1:O1").Value
    ary = Application.Transpose(ary)
    With Sheets("Sheet1").Cells(1, 1).Validation
        .Delete
        .Add Type:=xlValidateList, Formula1:=Join(ary, ",")
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = ""
        .ShowInput = True
        .ShowError = True
    End With
    Sheets("Sheet1").Cells(1, 2).Resize(UBound(ary)).Value = ary
End Sub
 
Upvote 0
Nếu là mình thì sẽ làm như sau:

B1: Đánh số cách quãng các dòng lệnh & thêm các dòng lệnh để bẫy lỗi, như sau:
Mã:
Sub TestValidation()
    Dim ary As Variant
On Error GoTo LoiCT
2    ary = Sheets("Sheet1").Range("C1:O1").Value
    ary = Application.Transpose(ary)
4    With Sheets("Sheet1").Cells(1, 1).Validation
        .Delete
6        .Add Type:=xlValidateList, Formula1:=Join(ary, ",")
        .IgnoreBlank = True:            .InCellDropdown = True
8        .InputTitle = "":                   .ErrorTitle = ""
        .InputMessage = "":             .ErrorMessage = ""
10        .ShowInput = True:              .ShowError = True
    End With
12    Sheets("Sheet1").Cells(1, 2).Resize(UBound(ary)).Value = ary
Err_:   Exit Sub
LoiCT:
    MsgBox Error, , Erl
    Resume Err_
End Sub
B1.1 Chạy thử Code để biết gần đúng dòng nào bị lỗi & lỗi là gì
(Sau khi thực hiện, macro báo ta biết dòng 6 bị lỗi; Nhưng ta đang đánh số cách quãng, nên lỗi có thể ở dòng 5 hay 7 nữa kia;)
B1.2: Ta lại tìm đúng dòng bị lỗi bằng cách đánh lại chỉ là:
PHP:
Sub TestValidation()
    Dim ary As Variant
On Error GoTo LoiCT
    ary = Sheets("Sheet1").Range("C1:O1").Value
    ary = Application.Transpose(ary)
    With Sheets("Sheet1").Cells(1, 1).Validation
5        .Delete
6        .Add Type:=xlValidateList, Formula1:=Join(ary, ",")
7        .IgnoreBlank = True:            .InCellDropdown = True
        .InputTitle = "":                   .ErrorTitle = ""
        .InputMessage = "":             .ErrorMessage = ""
        .ShowInput = True:              .ShowError = True
    End With
    Sheets("Sheet1").Cells(1, 2).Resize(UBound(ary)).Value = ary
Err_:   Exit Sub
LoiCT:
    MsgBox Error, , Erl
    Resume Err_
End Sub
Sau khi lặp lại B1.1 ta biết đúng dòng 6 bị lỗi & nội dung lỗi là gì.

B2: Tìm mã lỗi của nội dung lỗi & viết lại cách dòng lệnh để bẫy lỗi:
Bằng cách thay dòng lệnh
MsgBox Error, , Erl
bỡi dòng lệnh: MsgBox Err, , Error
Ta biết được Err => 5
Ta sửa lại các dòng lệnh bẫy lỗi như sau:
Mã:
' . . .     '
Err_:   Exit Sub
LoiCT:
    If Err = 5 Then
        Resume Err_
    Else
        Resume Next
    End If
End Sub

Bạn thử tiếp tục tìm lỗi của đứa con tinh thần của bạn thử xem sao & chúc thành công!
 
Upvote 0
Xin chào các bạn,
Tôi muốn gán vùng dữ liệu C1:O1 vào DataValidation/list cho ô A1 và tôi đã thử code dưới bị lỗi chưa biết cách, nhờ các bạn xem giúp.
Mã:
Sub TestValidation()
    Dim ary As Variant
    ary = Sheets("Sheet1").Range("C1:O1").Value
    ary = Application.Transpose(ary)
    With Sheets("Sheet1").Cells(1, 1).Validation
        .Delete
        .Add Type:=xlValidateList, Formula1:=Join(ary, ",")
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = ""
        .ShowInput = True
        .ShowError = True
    End With
    Sheets("Sheet1").Cells(1, 2).Resize(UBound(ary)).Value = ary
End Sub
Sai do JOIN chỉ chấp nhận mảng 1 chiều. Trong code của bạn ở thời điểm ADD thì ary là mảng 2 chiều có 13 dòng và 1 cột.

Sửa thành
Mã:
Sub TestValidation()
Dim ary As Variant
    ary = Sheets("Sheet1").Range("C1:O1").Value
    ary = Application.Transpose(ary)
    
    Sheets("Sheet1").Cells(1, "B").Resize(UBound(ary)).Value = ary
    ary = Application.Transpose(ary)
    
    With Sheets("Sheet1").Cells(1, "A").Validation
        .Delete
        .Add Type:=xlValidateList, Formula1:=Join(ary, ",")
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = ""
        .ShowInput = True
        .ShowError = True
    End With
End Sub

Sau dòng
Mã:
ary = Sheets("Sheet1").Range("C1:O1").Value
ary là mảng 2 chiều có 1 dòng và 13 cột.

Sau dòng
Mã:
ary = Application.Transpose(ary)
thứ nhất ary là mảng 2 chiều có 13 dòng và 1 cột

Sau dòng
Mã:
ary = Application.Transpose(ary)
thứ hai ary là mảng 1 chiều có 13 phần tử (không có khái niệm dòng hay cột). Lúc này ary mới được vinh dự hầu ông JOIN.

Nói cho cùng tôi và nhiều người chỉ hơn bạn chủ yếu là chúng tôi đọc help còn bạn không đọc. Một kho kiến thức ngay bên cạnh mà cứ chạy đi hỏi đâu đâu.

12345.JPG
 
Upvote 0
Nếu là mình thì sẽ làm như sau:

B1: Đánh số cách quãng các dòng lệnh & thêm các dòng lệnh để bẫy lỗi, như sau:
Mã:
Sub TestValidation()
    Dim ary As Variant
On Error GoTo LoiCT
2    ary = Sheets("Sheet1").Range("C1:O1").Value
    ary = Application.Transpose(ary)
4    With Sheets("Sheet1").Cells(1, 1).Validation
        .Delete
6        .Add Type:=xlValidateList, Formula1:=Join(ary, ",")
        .IgnoreBlank = True:            .InCellDropdown = True
8        .InputTitle = "":                   .ErrorTitle = ""
        .InputMessage = "":             .ErrorMessage = ""
10        .ShowInput = True:              .ShowError = True
    End With
12    Sheets("Sheet1").Cells(1, 2).Resize(UBound(ary)).Value = ary
Err_:   Exit Sub
LoiCT:
    MsgBox Error, , Erl
    Resume Err_
End Sub
B1.1 Chạy thử Code để biết gần đúng dòng nào bị lỗi & lỗi là gì
Không cần đoạn trên cũng biết "gần đúng" lỗi ở đâu. Khi chạy code thì dòng
Mã:
.Add Type:=xlValidateList, Formula1:=Join(ary, ",")
bị đánh dấu - cứ cho là gần đúng đi.
...
Sau khi lặp lại B1.1 ta biết đúng dòng 6 bị lỗi & nội dung lỗi là gì.

B2: Tìm mã lỗi của nội dung lỗi
Khi bị lỗi thì sẽ có cửa sổ nhẩy ra ghi rõ nội dung lỗi và cả mã lỗi. Chả cần làm gì cũng biết nội dung và mã lỗi. Muốn biết lỗi ở dòng nào (cứ cho là gần đúng đi) thì nhấn Debug ở cửa sổ báo lỗi.

112233.JPG

Cũng chả cần tới hàm Error
Mã:
MsgBox Err.Description, , Err.Number
Khi cần thì Err.Clear, Err.Raise. Tất cả nằm trong đối tượng Err

Tìm dòng lỗi chỉ là một chuyện nhỏ. Mà thường thì ta cũng được chỉ ra "khu vực" bị lỗi. Cái quan trọng là tìm ra nguyên nhân, thủ phạm. Để làm được điều đó thì phải chịu khó tư duy, phán đoán và nếu cần thì đọc trợ giúp. Đọc về cái gì thì tư duy và phán đoán sẽ chỉ đường.

Vd. trong trường hợp ở trên thì giá trị xlValidateList là hợp lệ - ít ra là ta có 99% chắc chắn là thế. Còn lại Join(ary, ",") thì "nhìn" có vẻ "ổn", nhưng đây là hàm chứ không phải là hằng như xlValidateList. Vậy ta tìm đọc lại về JOIN xem có chỗ nào ta dùng sai dấu, sai ký tự hay sai gì đó không. Có rất nhiều khi ta có hàm xịn, dùng mấy năm rồi, nhưng hôm nay giở chứng. Nếu là hàm xịn, mà JOIN là hàm xịn, thì 99% lỗi là do truyền tham số không hợp lệ vào hàm.
 
Upvote 0
Tìm dòng lỗi chỉ là một chuyện nhỏ. Mà thường thì ta cũng được chỉ ra "khu vực" bị lỗi. Cái quan trọng là tìm ra nguyên nhân, thủ phạm

Tuổi nhỏ làm việc nhỏ, tùy theo sức của mình mà lị!

Bạn í cần đi bộ lên các bậc thang VBA; Dù có thể 2 bậc 1 bước. Nhưng chưa thể đi thang máy được đâu; chắc vậy!
 
Upvote 0
Cháu cảm ơn hai bác SA_DQ và Siwtom đã giúp cháu.
Nhờ vào các giải thích chi tiết cháu cũng đã hiểu thêm một chút về mảng là như thế nào.
Hiện cháu đang loay hoay, khi gán dữ liệu mảng rồi,ví dụ:
ary = Sheets("Sheet1").Range("C1:O1").Value
thì làm thế nào để sử dụng các vòng lặp duyệt từng phần tử trong mảng 2 chiều để trả về mảng 1 chiều mà không phải sử dụngTranspose(ary)
nữa ạ.
Nếu hai bác và các bạn có hứng thú thời gian góp ý cho cháu thêm những cách để cháu tham khảo thêm ạ.
 
Upvote 0
Xin chào các bạn,
Nhờ các bạn giúp đỡ cho tôi trường hợp sau với, làm thế nào để có thể gán được các con số như trong list tại ô A1, với điều kiện:
Các con số được lấy trong vùng "C1:O1" (vấn đề đã được xử lý ở bài 1052),
Nhưng thêm 1 điều kiện rút ngắn list lại, loại bỏ những cột(list) không có số liệu trong vùng "C2:O12"

Untitled.jpg
 
Upvote 0
Xin chào các bạn,
Nhờ các bạn giúp đỡ cho tôi trường hợp sau với, làm thế nào để có thể gán được các con số như trong list tại ô A1, với điều kiện:
Các con số được lấy trong vùng "C1:O1" (vấn đề đã được xử lý ở bài 1052),
Nhưng thêm 1 điều kiện rút ngắn list lại, loại bỏ những cột(list) không có số liệu trong vùng "C2:O12"

View attachment 206982
đây bạn xem nhé không biết có ổn không :D
Mã:
Sub TestValidation()
Dim ary As Variant, i As Long
    ary = Sheets("Sheet1").Range("C1:O1").Value
    For i = 1 To UBound(ary, 2)
        If WorksheetFunction.CountA(Sheet1.Cells(2, 2 + i).Resize(10, 1)) = 0 Then
           ary(1, i) = Empty
        End If
    Next i
    
    ary = Application.Transpose(ary)
    
    Sheets("Sheet1").Cells(1, "B").Resize(UBound(ary)).Value = ary
    ary = Application.Transpose(ary)
    
    With Sheets("Sheet1").Cells(1, "A").Validation
        .Delete
        .Add Type:=xlValidateList, Formula1:=Join(ary, ",")
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = ""
        .ShowInput = True
        .ShowError = True
    End With
End Sub
 
Upvote 0
Tuổi nhỏ làm việc nhỏ, tùy theo sức của mình mà lị!

Bạn í cần đi bộ lên các bậc thang VBA; Dù có thể 2 bậc 1 bước. Nhưng chưa thể đi thang máy được đâu; chắc vậy!
Bạn để ý thì thấy tôi không nói tới đoạn
B1.2: Ta lại tìm đúng dòng bị lỗi bằng cách đánh lại chỉ là:
PHP:

Sub TestValidation()
Dim ary As Variant
On Error GoTo LoiCT
ary = Sheets("Sheet1").Range("C1:O1").Value
ary = Application.Transpose(ary)
With Sheets("Sheet1").Cells(1, 1).Validation
5 .Delete
6 .Add Type:=xlValidateList, Formula1:=Join(ary, ",")
7 .IgnoreBlank = True: .InCellDropdown = True
.InputTitle = "": .ErrorTitle = ""
.InputMessage = "": .ErrorMessage = ""
.ShowInput = True: .ShowError = True
End With
Sheets("Sheet1").Cells(1, 2).Resize(UBound(ary)).Value = ary
Err_: Exit Sub
LoiCT:
MsgBox Error, , Erl
Resume Err_
End Sub
Vì theo tôi đoạn đó có thể có ích cho người hỏi.

Còn những đoạn trước và sau nó không cần vì khi chạy code bạn đã được cung cấp thông tin quá rõ ràng rồi.
 
Upvote 0
Hiện cháu đang loay hoay, khi gán dữ liệu mảng rồi,ví dụ:
thì làm thế nào để sử dụng các vòng lặp duyệt từng phần tử trong mảng 2 chiều để trả về mảng 1 chiều mà không phải sử dụngTranspose(ary) nữa ạ.
Thì dùng FOR *** thôi.

Nhưng trước hết phải biết mảng có bao nhiêu dòng và cột để duyệt theo dòng hay cột hay theo cả dòng và cột.
arr = vung.Value
1. Nếu arr được khai báo là mảng (Dim arr()) thì khi vùng là 1 ô (cell) thì sẽ có lỗi. Khi Dim arr (arr là Variant) thì không có lỗi.

2. Nếu vung là 1 ô thì arr (Dim arr) là 1 giá trị, không phải là mảng.

3. Nếu vùng có 2 ô trở lên thì arr luôn là mảng 2 chiều. Chỉ số dòng và cột luôn tính từ 1, tức LBound(arr) = 1, LBound(arr, 2) = 1. Chỉ số cuối của dòng và cột là Ubound(arr) và UBound(arr, 2). Do LBound(arr) = 1, LBound(arr, 2) = 1 nên đó cũng là số dòng và số cột trong mảng arr.
LBound(arr) và Ubound(arr) là viết tắt của LBound(arr, 1) và Ubound(arr, 1).

Nếu vung là một đoạn dòng thì arr là mảng 2 chiều có 1 dòng và nhiều cột.
Nếu vùng là một đoạn cột thì arr là mảng 2 chiều có 1 cột và nhiều dòng.

Trong code tổng quát thì phải lường được dữ liệu để xem dữ liệu có có không, có thể chỉ là 1 giá trị hay luôn là mảng ... Vd. Muốn tuồn các giá trị từ B2 tới ô cuối cùng không trống trong cột B vào mảng. Có thể sẩy ra trường hợp không có dữ liệu (từ B2 trở đi đều trống), chỉ có 1 ô (B2<>"" và từ B3 là trống), và nhiều ô. Nhưng nếu muốn tuồn từ B2:C2 tới "cuối" thì chỉ sẩy ra 2 trường hợp: hoặc không có dữ liệu hoặc nhiều ô (ít nhất là 1 dòng tuồn vào mảng, mà dòng Bk:Ck luôn có 2 ô)
---------
Theo bạn thì code tuồn cứng nhắc một vùng có nhiều ô vào mảng nên ta cũng không kiểm tra mà biết ngay ary là mảng 2 chiều có 1 dòng và nhiều cột. Vậy ta duyệt mảng theo dòng.
Mã:
Sub test()
Dim c As Long, result(), ary, s As String
    ary = Sheets("Sheet1").Range("C1:O1").Value
    ReDim result(1 To UBound(ary, 2))
    For c = 1 To UBound(ary, 2) '   To UBound(result)
        result(c) = ary(1, c)
    Next c
    s = Join(result, ",")
    MsgBox s
End Sub

***: đừng phát âm là phò nhé. Lại nhớ hồi nhỏ ở phố có "chị" hay đi chơi với nhiều anh. Bọn trẻ chỉ trỏ và nói: phò phi dê. Các bạn trẻ có biết phi dê là gì không? :D
 
Lần chỉnh sửa cuối:
Upvote 0
đây bạn xem nhé không biết có ổn không :D
Mã:
Sub TestValidation()
Dim ary As Variant, i As Long
    ary = Sheets("Sheet1").Range("C1:O1").Value
    For i = 1 To UBound(ary, 2)
        If WorksheetFunction.CountA(Sheet1.Cells(2, 2 + i).Resize(10, 1)) = 0 Then
           ary(1, i) = Empty
        End If
    Next i
   
    ary = Application.Transpose(ary)
   
    Sheets("Sheet1").Cells(1, "B").Resize(UBound(ary)).Value = ary
    ary = Application.Transpose(ary)
   
    With Sheets("Sheet1").Cells(1, "A").Validation
        .Delete
        .Add Type:=xlValidateList, Formula1:=Join(ary, ",")
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = ""
        .ShowInput = True
        .ShowError = True
    End With
End Sub

Xin chào snow25,
Cảm ơn bạn đã tham gia & giúp đỡ, OT vừa mới test code trên trả về kết quả đúng với mong muốn của Oanh Thơ rồi.
Tuy nhiên khi sử dụng mảng, nhờ snow25 và các bạn có thể làm thể nào để không phải sử dụng đến:
1.WorksheetFunction (đại loại vòng lặp không can thiệp vào Range)
2.Transpose (hay là giới hạn ký tự)
3.Loại bỏ các phần tử rỗng (Empty) , ví dụ trong hình ảnh tại bài 1056 (Oanh Thơ đưa lên) làm thế nào khi mà trả về mảng 1 chiếu cuối cùng thì các phần tử trong mảng chỉ chưa 7 phần tử thay vì đưa cả 13 phần tử vào (bao gồm cả rỗng). Tương tự cụ thể làm sao, để:
Sheets("Sheet1").Cells(1, "B").Resize(UBound(ary)).Value = ary
Không có các ô trống xen kẽ ạ.
Qua việc tự tìm hiểu (có thể là là sai ạ) OT thơ nghĩ trường hợp 3 cần có sự tham gia của Dictionary thì có thể giải quyết được?
Nếu đúng nhờ snow25 và các bạn giúp đỡ OT một đoạn code sử dụng kết hợp Dictionary để OT thấy được sự liên quan ạ.
 
Upvote 0
Web KT
Back
Top Bottom