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ị
 
3 ý trên em hiểu sâu được vấn đề hơn. Trường hợp "Muốn biến thành mảng 1 chiều phải thêm các công đoạn khác, chẳng hạn dùng For... Next hoặc hàm TRANSPOSE" em hiểu được nhưng cách làm theo Transpost thì chưa biết, xin Sư phụ cho ví dụ.
Cảm ơn Sư phụ và Thầy Mỹ
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)
 
Lần chỉnh sửa cuối:
Upvote 1
Vậy anh cho em xin 1 ví dụ nho nhỏ để em hiểu thêm về nó hen. Thanks
Ví dụ thế này:
- A1:A10 chứa các số nào đó
- Dùng vòng lập lấy các số lẻ trong A1:A10 và chuyển sang cột C
Đương nhiên ta có tính toán (để biết số nào lẻ) chứ không chuyển nguyên vùng nên buộc phải vòng lập rồi
PHP:
Sub Test()
  Dim sArray, Arr(), i As Long, j As Long
  sArray = Range("A1:A10").Value
  ReDim Arr(1 To UBound(sArray), 1 To 1)
  For i = 1 To UBound(sArray)
    If sArray(i, 1) Mod 2 Then
       j = j + 1
      Arr(j, 1) = sArray(i, 1)
    End If
  Next
  Range("C1:C10") = Arr
End Sub


Anh nói đoạn code thứ 2 phải không anh, mà sao nó vẫn hiểu nó hay thiệt chứ. Mà chắc mang( 1 to n, 1 to m,...) cái này rất quan trọng phải không anh, vì em thấy nếu khai báo mang (1 to 10) thì nó sẽ là mảng 1 chiều liền??
Chú ý rằng mang( 1 to n, 1 to m) khác với mang(n, m) ---> Cái đầu thì vị trí phần tử đầu tiên được tính từ 1, còn cái sau, vị trí của phần tử đầu tiên được tính từ 0. Vậy mang(n, m) <===> mang(0 to n, 0 to m)
Có những mảng mà ta không khống chế được chỉ số của phần tử đầu tiên. Ví dụ:
- Mảng lấy từ 1 list của ListBox, ComboBox thì phần tử đầu tiên luôn bắt đầu bằng 0
- Mảng lấy từ Range thì phần tử đầu tiên luôn bắt đầu từ 1

Tóm lại: Chỉ có thể khống chế được chỉ số của phần tử đầu tiên đối với những mảng do chính ta tạo ra
 
Upvote 1
Em hiểu như thế này có đúng không mảng (Array) sẽ nạp những ô nào là lẽ ở vùng A1:A10 vào trong Array tức là {1,3,5,7,9} với thứ tự này nó sẽ bung ra ở vùng B1:B10 thật ra mình chỉ cần B1:B5 là đủ rồi, mà sao có khi em nạp dữ liệu vào mạng khi bung ra có xuất hiện chữ #N/A là sao anh
PHP:
Sub Test()
  Dim sArray, Arr(), i As Long, j As Long
  sArray = Range("A1:B10").Value
  ReDim Arr(1 To UBound(sArray), 1 To UBound(sArray,2))
  For i = 1 To UBound(sArray)
    If sArray(i, 1) Mod 2 Then
        j = j + 1
      Arr(j, 1) = sArray(i, 1)
      Arr(j, 2) = sArray(i, 2)
   End If
  Next
  Range("C1:D10") = Arr
End Sub
Với đoạn code này em sẽ lấy nhưng số lẽ ở vùng A1:B10 với B1:B10 giá trị từ 11 đến 20 vậy mình có cách nào ngắn hơn hay không anh. Thanks
Code vậy là được rồi. Có điều A1:B10 đang bố trí có trật tự nên bạn chỉ dùng 1 vòng lập (bạn ngầm hiểu rằng nếu cột 1 là số lẻ thì cột 2 cũng là số lẻ). Trong trường hợp A1:B10 chứa số tùy ý và không theo trật tự nào thì bạn buộc phải dùng 2 vòng lập (duyệt từ trên xuống và từ trái qua phải)
PHP:
Sub Test1()
  Dim sArray, Arr(), i As Long, j As Long, iR As Long
  sArray = Range("A1:B10").Value
  ReDim Arr(1 To UBound(sArray), 1 To UBound(sArray, 2))
  For i = 1 To UBound(sArray, 1)
    For j = 1 To UBound(sArray, 2)
      If sArray(i, j) Mod 2 Then
        Arr(Int(iR / 2) + 1, (iR Mod 2) + 1) = sArray(i, j)
        iR = iR + 1
     End If
    Next
  Next
  Range("C1:D10") = Arr
End Sub
Thử xem!
 
Lần chỉnh sửa cuối:
Upvote 1
nếu em không muốn khai báo là sh.name <> "Tonghop" mà muốn
nó duyệt từ sheet1, sheet2, sheet3 thì sao
Em có thể dùng
PHP:
  For sh = 1 To 3   
With Sheet(sh)  
 dg = Sheet(I).[A99000].End(xlUp).Row   

sArr = .Range("A5:AA" & dg).Value
...........
  next sh
như vậy được không?
 
Lần chỉnh sửa cuối:
Upvote 1
1.
Tôi muốn mãng ArrKQ trở về kích thước của nó tôi dùng
PHP:
ReDim Preserve ArrKQ(1 To s, 1 To 5)
Vì sao nó báo lỗi nhỉ
2. Xin các anh chị giúp đỡ hàm để nối các mãng
Ví dụ tôi có các mãng Arr01, Arr02, Arr03 ...Arr(n) có cùng kích thước ngang. Bây giờ tôi cần hàm cho kết quả là mãng ArrKQ là nối tất cả các mãng đó thành 1 mãng.
Bây giờ tôi áp dụng 3 mãng thì chỉ cần dùng: Ví dụ hàm ArrKQ(Arr01, Arr02, Arr03)
Xin cảm ơn các anh chị
ReDim Preserve ArrKQ(1 To s, 1 To 5)
Híc, cái thằng ReDim Preserve không cho chơi kiểu đó đâu, nó hổng cho ReDim Preserve theo chiều thứ 1 đâu
Thí dụ:
ReDim Preserve ArrKQ(1 To 5, 1 To s)
thì nó hổng cự nự bạn đâu
Tôi muốn mãng ArrKQ trở về kích thước của nó tôi dùng
Trong bài của bạn có thể khai báo chính xác kích thước mảng ArKQ như sau
SoA = Application.WorksheetFunction.CountIf([A2:A10], "a")
ReDim ArrKQ(1 To SoA * UBound(Arr02) + UBound(Arr01) - SoA, 1 To UBound(Arr01, 2))
Còn câu 2 ....mình hổng hiểu
Thân
Híc
 
Lần chỉnh sửa cuối:
Upvote 1
Hướng dẫn giúp mình các gọi các model
SUB ten_ham()
Trong cá ngoăng cụ thể khai bao như thế nào để nó hiểu là biến truyền thông tin và biến nhận giá trị. XIn cảm ơn!
Bạn đang hỏi tôi về chủ đề nào vậy? Bạn phải trích bài đó vào đây, chứ hỏi như thế tôi biết đường đâu mà trả lời?
 
Upvote 1
em mới học và mới đọc qua các bài đầu ở bài viết chủ đề về mảng này
các ACE và các thầy cho em hỏi em làm 1 đoạn này sai chỗ nào với
Mã:
Sub tinh()
    Dim gan, lrow2, lrow
    Dim i, j, k, dem As Integer
    Dim Arr, arr1
    lrow = Range("C" & Rows.Count).End(xlUp).Row
    
    ReDim lrow2(1 To lrow - 5, 1)
    lrow2 = Range("C6:D" & lrow)
    
    ReDim Arr(1 To UBound(lrow2), 1)
    ReDim gan(1 To UBound(lrow2), 1)
    ReDim arr1(1 To UBound(lrow2), 1)
    
    For i = 1 To UBound(lrow2)
        Arr(i, 1) = -1
    Next
    
    For i = 1 To UBound(lrow2)
        dem = 1
        For j = i + 1 To UBound(lrow2)
        
            If lrow2(j, 1) = lrow2(i, 1) Then
                dem = dem + 1
                Arr(j, 1) = 0
            End If
            
        Next
        
        If Arr(i, 1) <> 0 Then
            k = k + 1
            Arr(i, 1) = dem
            arr1(k, 1) = Arr(i, 1)
            gan(k, 1) = lrow2(i, 1)
        End If
    
    Next
    
        Range("M6:N" & lrow) = arr1
        Range("O6:P" & lrow) = gan
End Sub

hai range kết quả của em nó ko vào đúng ý của e
Range("M6:N" & lrow) = arr1 #kết quả lại hiện ở cột N
Range("O6:p" & lrow) = gan #kết quả lại hiện ở cột P
Bạn phải khai báo ReDim Arr(1 To UBound(lrow2), 1 to 1)
Lưu ý 1 to 1 chứ không phải là 1
Số 1 đó được hiểu là 0 to 1 và theo đó số cột là 2 chứ không phải 1. Do vậy các kết quả ghi vào Arr(x, 1) sẽ nằm ở cột 2.
 
Upvote 1
Tôi nghĩ chỗ này nó cũng có vấn đề đó:
Mã:
    For i = 1 To UBound(lrow2)
        dem = 1
        For j = i + 1 To UBound(lrow2)
Tuy nó không lỗi nhưng vòng lặp cuối cùng dường như nó sẽ lặp không phải là con số UBound(lrow2)+1 mà chỉ lặp lại UBound(lrow2).
 
Upvote 1
Msgbox xuất ra tiếng Việt không đúng: mận = m?n nên chịu khó nhé:
PHP:
Option Explicit
Sub test()
Dim i&, k&, arr(), rng, qua As String, ten As String
rng = Worksheets("Sheet1").Range("A1:F3").Value
ReDim arr(1 To 6, 1 To 2)
    For i = 1 To 6
        If rng(3, i) = "o" Then
            k = k + 1
            Select Case k
                Case Is = 1
                    qua = "Danh sach qua gom: " & rng(1, i)
                    ten = "Danh sach ten gom: " & rng(2, i)
                Case Else
                    qua = qua & ", " & rng(1, i)
                    ten = ten & ", " & rng(2, i)
            End Select
            arr(k, 1) = rng(1, i)
            arr(k, 2) = rng(2, i)
        End If
    Next
Worksheets("Sheet2").Range("A2").Resize(k, 2).Value = arr
MsgBox qua & vbLf & ten
End Sub
Em cám ơn anh nhiều ạ. Nhưng hình như thiếu mất điều kiện rồi ạ. hì
mạn phép thêm vào code của anh như sau có hợp lý không ạ:
Mã:
Option Explicit
Sub test()
Dim count&, i&, k&, arr(), rng, qua As String, ten As String
rng = Worksheets("Sheet1").Range("A1:F3").Value

Dim rng1 As Range
Set rng1 = Worksheets("Sheet1").Range("A3:F3")
count = WorksheetFunction.CountIf(rng1, "o")
    If count = 0 Then
        MsgBox "Danh sach rong"
        Exit Sub
    End If
ReDim arr(1 To 6, 1 To 2)
    For i = 1 To 6
        If rng(3, i) = "o" Then
            k = k + 1
            Select Case k
                Case Is = 1
                    qua = "Danh sach qua gom: " & rng(1, i)
                    ten = "Danh sach ten gom: " & rng(2, i)
                Case Else
                    qua = qua & ", " & rng(1, i)
                    ten = ten & ", " & rng(2, i)
            End Select
            arr(k, 1) = rng(1, i)
            arr(k, 2) = rng(2, i)
    
        End If
    Next
    
Worksheets("Sheet2").Range("A2").Resize(k, 2).Value = arr
MsgBox qua & vbLf & ten
End Sub
Bài đã được tự động gộp:

Muốn code array thì căn bản để học như vầy:

1. Code làm trực tiếp với mảng
code sử dụng:
- kỹ thuật chép range qua mảng
- kỹ thuật chép mảng trở lại range, với giới hạn số dòng, số cột.
- kỹ thuật chuyển cột thành dòng, và dòng thành cột.

Mã:
Sub S1()
' sub copy một bảng dữ liệu (hàng ngang) và tách ra hai bảng hàng dọc tùy theo x/o
' lưu ý: vì đầu vào hàng ngang và đầu ra hàng dọc nên cột copy thành dòng và ngược lại
' lưu ý 2: code tôi viết theo kiểu lười biếng, không khai báo biến, và dùng [ ] để tham chiếu range. Kiểu tham chiếu này viết nhanh nhưng tínCode sử dụng h chậm.
a = Sheet1.[a1].CurrentRegion.Value ' chuyển dữ liệu cần thiết vào mảng
ReDim b1(1 To UBound(a, 2), 1 To UBound(a, 1)) ' định dạng mảng đầu ra
ReDim b2(1 To UBound(a, 2), 1 To UBound(a, 1))
For i = 1 To UBound(a, 2) ' duyệt mang đàu vào theo hàng ngang
    ' r1 là số dòng mảng b1, r2 là số dòng mảng b2
    Select Case a(3, i)
    Case "x" ' chép vào bảng x theo hàng dọc
        r1 = r1 + 1
        b1(r1, 1) = a(1, i)
        b1(r1, 2) = a(2, i)
    Case "o" ' chép vào bảng o theo hàng dọc
        r2 = r2 + 1
        b2(r2, 1) = a(1, i)
        b2(r2, 2) = a(2, i)
    End Select
Next i
If r1 > 0 Then
    Sheet2.[a1].Resize(r1, 2) = b1 ' chép lại sheet2
Else
    MsgBox "Khong co dong x nao ca"
End If
If r2 > 0 Then
    Sheet2.[e1].Resize(r2, 2) = b2 ' chép lại sheets
Else
    MsgBox "Khong co dong 0 nao ca"
End If
End Sub

2. Code cải tiến một chút:
Code sử dụng:
- Kỹ thuật chép range qua mảng, có transpose
- Kỹ thuật ghi mảng đầu ra ngay chỗ mảng đầu vào

Mã:
Sub S2()
' sub copy một bảng dữ liệu (hàng ngang) và tách ra hai bảng hàng dọc tùy theo x/o
' lưu ý: vì code chuyển đầu vào từ hàng ngang thảnh dọc cho nên cứ duyệt và chép thẳng thừng
' lưu ý 2: code tôi viết theo kiểu lười biếng, không khai báo biến, và dùng [ ] để tham chiếu range.
a = Application.Transpose(Sheet1.[a1].CurrentRegion)
ReDim b(1 To UBound(a, 1), 1 To UBound(a, 2)) ' định dạng mảng thứ hai của đầu ra, mảng thứ nhất thì dùng lại mảng đầu vào.
For i = 1 To UBound(a, 1)
    Select Case a(i, 3)
    Case "x"
        r1 = r1 + 1
        a(r1, 1) = a(i, 1)
        a(r1, 2) = a(i, 2)
    Case "o"
        r2 = r2 + 1
        b(r2, 1) = a(i, 1)
        b(r2, 2) = a(1, 1)
    End Select
Next i
If r1 > 0 Then
    Sheet2.[a1].Resize(r1, 2) = a ' chép lại sheet2
Else
    MsgBox "Khong co dong x nao ca"
End If
If r2 > 0 Then
    Sheet2.[e1].Resize(r2, 2) = b ' chép lại sheet2
Else
    MsgBox "Khong co dong 0 nao ca"
End If
End Sub

Tôi không buồn viết code tóm lược như yêu cầu bài #1524. Vì đó không phải là kỹ thuật mảng mà thớt bảo rằng mình muốn học như bào #1522 đã nói. Mặt khác, tôi không khuyến khích chuyện "thêm nữa", được voi đòi tiên.
Em cám ơn anh VetMini nhiều ạ, mong được học nhiều điều hơn nữa từ các anh ạ.
 
Lần chỉnh sửa cuối:
Upvote 1
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ị
Như thế này nè bạn
PHP:
Dim Arr As Variant
Arr = [A1:A10].Value
 
Upvote 0
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ị

Có lẽ nên hỏi lại cho rõ là "gán giá trị của các cells từ A1:A10 các phần tử của Mãng Arr" có nghĩa là:
- Gán các giá trị của Cells từ A1 đến A10 vào 1 mảng Arr
- Gán các giá trị của Cells từ A1 đến A10 từ/ bằng 1 mảng Arr

Eo ôi, tiếng Việt!
 
Upvote 0
Có lẽ nên hỏi lại cho rõ là "gán giá trị của các cells từ A1:A10 các phần tử của Mãng Arr" có nghĩa là:
- Gán các giá trị của Cells từ A1 đến A10 vào 1 mảng Arr
- Gán các giá trị của Cells từ A1 đến A10 từ 1 mảng Arr

Eo ôi, tiếng Việt!
Dạ ý em là
PHP:
Gán các giá trị của Cells từ A1 đến A10 vào 1 mảng Arr
Em làm theo cách của anh huuthang_bd đã được nhưng sao em thử thí nghiệm xuất một phẩn tử theo dạng:
1. Arr(i) thì báo lỗi
2. Arr(i,1) cho kết quả giá trị của phần tử thứ i
3. Arr(1,i) thì báo lỗi
Em đang tự học về Mãng, xin các anh chị giải thích thêm. Xin cảm ơn
 
Upvote 0
Arr(i, j) là phần tử của mảng tại dòng i, cột j của mảng
Do khai báo Dim Arr As variant và không khai báo chiều, nên mặc định Arr là mảng 2 chiều
A1:A10 là mảng dọc, không có nghĩa là mảng 1 chiều, đó là mảng 2 chiều: 1 chiều 10 dòng và 1 chiều 1 cột.

Muốn khai báo mảng 1 chiều thì khai báo
Dim Arr As variant
Redim Arr(10)
Nhưng lúc này mặc định mảng 1 chiều lại là mảng ngang.
Và muốn cho là mảng 1 chiều thực sự, thì không được gán giá trị 1 lần cho nó bằng 1 range trong bảng tính.

Túm lại, mảng dọc bắt buộc là mảng 2 chiều. Mảng ngang thì tuỳ theo cách gán giá trị, gán bằng range trên sheet thì 2 chiều.

Thí dụ 2 sub sau:

PHP:
Sub Test1()
Dim Arr As Variant
ReDim Arr(1 To 10)
Arr = Range("A1:J1").Value
MsgBox Arr(4)
End Sub
PHP:
Sub Test2()
Dim Arr As Variant
ReDim Arr(1 To 10)
For i = 1 To 10
Arr(i) = Cells(1, i)
Next
MsgBox Arr(4)
End Sub
Test1 sẽ bị lỗi. Mà phải sửa thành MsgBox Arr(1, 4)
 
Lần chỉnh sửa cuối:
Upvote 0
Arr(i, j) là phần tử của mảng tại dòng i, cột j của mảng
Do khai báo Dim Arr As variant và không khai báo chiều, nên mặc định Arr là mảng 2 chiều
A1:A10 là mảng dọc, không có nghĩa là mảng 1 chiều, đó là mảng 10 dòng 1 cột.

Muốn khai báo mảng 1 chiều thì khai báo
Dim Arr As variant
Redim Arr(10)
Nhưng lúc này mặc định mảng 1 chiều lại là mảng ngang.

Túm lại, mảng dọc bắt buộc là mảng 2 chiều.
Xin anh giải thích thêm
1. Thế trường hợp Mãng 1 chiều là mãng ngang với các phần tử là giá trị từ A1 đến A10 không được hả anh ?
2. Như trên anh khái báo
PHP:
Dim Arr As variant
Redim Arr(10)
Không khai báo luôn
PHP:
Dim Arr(10)
Mà phải Redim ?
Cảm ơn anh nhiều
 
Upvote 0
Xin anh giải thích thêm
1. Thế trường hợp Mãng 1 chiều là mãng ngang với các phần tử là giá trị từ A1 đến A10 không được hả anh ?
2. Không khai báo luôn Dim Arr(10)Mà phải Redim
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.

2. Khai báo Arr(10) hay Khai báo Arr rồi ReDim Arr(10):

Tác dụng giống nhau. Nhưng Redim có cái lợi hơn vì cứ khai báo mảng khi kích thước mảng chưa biết. Sau đó tính toán kích thước xong mới ReDim lại.

3. Ghi chú:
Mặc định phần tử đầu của mảng đánh số 0, nên Arr(10) sẽ có 11 phần tử từ 0 đến 10. Và khi gán Cell(i, j) cho phần tử, sẽ bị lỗi vì không có cells(0,j) hoặc cells(i, 0)
Có 2 cách để cho Arr bắt đầu bằng 1:

- Dùng câu lệnh Option Base 1 trên đầu module
- Khai báo Arr(1 to 10), hoặc Arr(1 to 10, 1 to 1)
 
Upvote 0
Xin anh giải thích thêm
1. Thế trường hợp Mãng 1 chiều là mãng ngang với các phần tử là giá trị từ A1 đến A10 không được hả anh ?
2. Như trên anh khái báo
PHP:
Dim Arr As variant
Redim Arr(10)
Không khai báo luôn
PHP:
Dim Arr(10)
Mà phải Redim ?
Cảm ơn anh nhiều
Ban chỉ cần nhớ điều này:
- Range và mảng không giống nhau
- 1 Range sau khi biến đổi thành mảng thì đó luôn là mảng 2 chiều
- Muốn biến thành mảng 1 chiều phải thêm các công đoạn khác, chẳng hạn dùng For... Next hoặc hàm TRANSPOSE
-----------
Hiểu thế là mọi chuyện êm xuôi
 
Upvote 0
Ban chỉ cần nhớ điều này:
- Range và mảng không giống nhau
- 1 Range sau khi biến đổi thành mảng thì đó luôn là mảng 2 chiều
- Muốn biến thành mảng 1 chiều phải thêm các công đoạn khác, chẳng hạn dùng For... Next hoặc hàm TRANSPOSE
-----------
Hiểu thế là mọi chuyện êm xuôi
3 ý trên em hiểu sâu được vấn đề hơn. Trường hợp "Muốn biến thành mảng 1 chiều phải thêm các công đoạn khác, chẳng hạn dùng For... Next hoặc hàm TRANSPOSE" em hiểu được nhưng cách làm theo Transpost thì chưa biết, xin Sư phụ cho ví dụ.
Cảm ơn Sư phụ và Thầy Mỹ
 
Upvote 0
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)

Dẫu rằng nói 1 chiều thì không có dọc ngang, tựa như đường thẳng, và khác với mặt phẳng. Nhưng đó là xét theo hệ quy chiếu là đứng trong không gian 1 chiều và đang chỉ nhận thức được 1 chiều.

Giả sử tồn tại 1 thế giới mà sinh vật ở đó chỉ nhận thức được 1 chiều trong không gian, thì khi 1 vật thể di chuyển dọc theo đường thẳng, anh ta sẽ trông thấy sự dịch chuyển. Nếu 1 sinh vật ở hành tinh khác đến và nhận thức được không gian 2 chiều, anh ta đi ra khỏi đường thẳng vào chiều thứ 2. Vậy sinh vật tại đó sẽ nghĩ gì? Nó cho rằng sinh vật lạ đã biến mất.
Còn đối với sinh vật ở hành tinh khác đến, thì nghĩ: tao đâu có biến mất, mày chỉ đi được theo chiều X của tao, còn tao đi 2 hướng, vừa X vừa Y.
(Suy luận tương tự giữa không gian 2 chiều, 3 chiều, và n chiều)

Và khi sinh vật lạ này kể cho đồng hương của nó nghe, nó sẽ kể: Tụi nó chỉ đi ngang hông à, hông có ra khỏi cái đường thẳng đó được.

Chữ ngang để làm chi? để vẽ ra cho đồng hương nó hiểu.

Tưởng tượng xong, quay về Array. Array 1 chiều mà gán xuống sheet (bảng 2 chiều), thì phải gán ngang. Gán dọc là sai.
Nên
vẫn phải
hình dung
mảng 1 chiều

mảng
ngang!

Vì ta là thành viên GPE, thế giới GPE là thế giới bảng tính có ít nhất 2 chiều, và ta là sinh vật nhận thức được n chiều.
 
Lần chỉnh sửa cuối:
Upvote 0
Chữ ngang để làm chi? để vẽ ra cho đồng hương nó hiểu.
Tưởng tượng xong, quay về Array. Array 1 chiều mà gán xuống sheet (bảng 2 chiều), thì phải gán ngang. Gán dọc là sai.
Dạ, cái này em biết nhưng nhiều lúc em sợ rằng mường tượng nhiều quá sẽ dẫn đến ngộ nhận
Giống như trường hợp Add List cho 1 ListBox
- Em có dữ liệu tại A1:A3
- Muốn muốn Add dữ liệu này vào ListBox1
- Mường tượng rằng ListBox được xếp theo chiều dọc, mà thằng A1:A3 cũng đang dọc, vậy thì cứ Add thoải mái
PHP:
Sub Test1()
  Sheet1.ListBox1.List() = Range("A1:A3").Value
End Sub
Test thử thấy OK
Còn hơi nghi ngờ, Test thử bằng code thứ 2:
PHP:
Sub Test2()
  Dim Arr
  Arr = Sheet1.ListBox1.List
  MsgBox IsArray(Arr)
End Sub
Kết quả = TRUE???
Vậy là sao?
Từ 1 mảng "dọc" (2 chiều) sau cho vào ListBox, lấy ra kiểm tra nó lại thành "ngang" (1 chiều)
???
Test tiếp 1 sub khác:
PHP:
Sub Test3()
  Dim Arr
  Arr = Array("a", "b", "c")
  Sheet1.ListBox1.List() = Arr
End Sub
Arr đương nhiên là mảng 1 chiều, và nó "ngang" theo cách nói của sư phụ, vậy mà vẫn Add vào ListBox được bình thường
Đồng ý rằng có sự "biến đổi" gì đó trong quá trình Add List nhưng nếu ngay từ đầu mình quá tin vào cái vụ "ngang" này thì không khỏi có lúc bị lúng túng (em đã từng bị vậy)
Cũng giống như trường hợp mảng 1 chiều khi gán vào Sheet thì phải gán theo chiều ngang, nhưng khi lấy dữ liệu "ngang" ấy từ sheet để biến nó thành mảng thì mảng ấy lại vẫn cứ... 2 chiều (chẳng làm cách nào cho nó "ngang" được nếu không thông qua quá trình biến đổi)
Thôi thì ngay từ đầu khẳng định rằng mảng 1 chiều không "ngang, dọc" gì cả... Có "ngang" chăng là do ta tự mường tượng ra cho phù hợp với những suy luận của riêng ta mà thôi
Ẹc... Ẹc...
(Mong sư phụ đừng giận em phản biện, vì đàng nào thì mấy cái Array này cũng do sư phụ dạy em)
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom