Các câu hỏi về mảng trong VBA (Array) (1 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ị
 
PHP:
 ReDim Arr(1 To UBound(sArray), 1 To UBound(sArray, 2))


Trong đoạn code trên tại sao mình không dùng là
1 to 2
mà phải là
1 To UBound(sArray, 2)


Giả sử lấy Range làm ví dụ minh họa và giả sử sArray = Range("gì gì đó").Value, khi ấy ta có:
- Tính theo chiều dọc: 1 là STT của phần tử đầu tiên và UBound(sArray, 1) là STT của phần tử cuối cùng (số 1 màu đỏ nghĩa là nói đến chiều thứ nhất)
- Tính theo chiều ngang: 1 là STT của phần tử đầu tiên và UBound(sArray, 2) là STT của phần tử cuối cùng (số 2 màu đỏ nghĩa là nói đến chiều thứ hai)
Giờ bạn muốn tạo 1 Array mới (biến tên là Arr) có kích thước bằng với sArray thì đương nhiên phải ReDim Arr(1 To UBound(sArray), 1 To UBound(sArray, 2)) ---> Đó là do bạn chưa biết trước phần tử cuối cùng có STT là bao nhiêu đâu mà ghi trực tiếp ---> Đương nhiên, nếu bạn biết chắc UBound(sArray, 2) = 2 (mảng Arr chắc chắn chỉ xài có 2 cột) thì cứ ghi thành ReDim Arr(1 To UBound(sArray), 1 To 2) cũng chẳng có vấn đề gì
(cái này gần giống với name động ấy)
 
Upvote 0
Bắt đầu học mảng từ đâu?

Em đang muốn học mảng nhưng không biết nên bắt đầu từ đâu?
Em đọc bài viết về Array nhưng (hình như cũng là người biết qua về Mảng rồi)
 
Upvote 0
Sorry, em post xong mấy thấy bài anh NDU
Em đã hiểu hơn rồi ạh
==========
 
Lần chỉnh sửa cuối:
Upvote 0
Em đang muốn học mảng nhưng không biết nên bắt đầu từ đâu?
Em đọc bài viết về Array nhưng (hình như cũng là người biết qua về Mảng rồi)
Thì mảng cũng gần giống với Range thôi, khi bạn dùng vòng lập duyệt qua Range thế nào thì mảng cũng thế ấy
Vậy, để bắt đầu với mảng, hãy thường xuyên làm những bài tập xử lý range liên quan đến vòng lập là được rồi
Bạn cứ nghĩ ra bất cứ đề tài nào cho việc xử lý dữ liệu trên bảng tính rồi post lên đây, mọi người sẽ nghĩ cách chuyển chúng sang mảng giúp bạn ---> Từ những ví dụ cụ thế ấy, bạn sẽ tiếp thu rất dễ dàng
 
Upvote 0
Ví dụ 1 (Học mảng): dùng vòng lặp quét và gán giá trị từ mảng vào range
- Sheet1 từ A1: A10 có dữ liệu tăng dần (nhưng ko đều nhau)
ví dụ
A1: 1
A2: 2
A3: 2
A4: 3
A5: 4
A6: 5
A7: 6
A8: 6
A9: 6
A10: 10

E đang dùng vòng lặp này để duyệt

PHP:
a = Sheet1.[A65000].End(xlUp).Row 

    If Sheet1.Cells(Sheet1.[A65000].End(xlUp).Row , 1) <> Sheet1.[A65000].End(xlUp).Row     Then

        For i = 1 To a

            Sheet1.Cells(i , 1) = i

        Next

Giờ em muốn dùng vòng lặp trong mảng nếu thấy sai thì gán vào trong range.

Xin Anh/Chị chỉ giúp
 
Upvote 0
Ví dụ 1 (Học mảng): dùng vòng lặp quét và gán giá trị từ mảng vào range
- Sheet1 từ A1: A10 có dữ liệu tăng dần (nhưng ko đều nhau)
ví dụ
A1: 1
A2: 2
A3: 2
A4: 3
A5: 4
A6: 5
A7: 6
A8: 6
A9: 6
A10: 10

E đang dùng vòng lặp này để duyệt

PHP:
a = Sheet1.[A65000].End(xlUp).Row 

    If Sheet1.Cells(Sheet1.[A65000].End(xlUp).Row , 1) <> Sheet1.[A65000].End(xlUp).Row     Then

        For i = 1 To a

            Sheet1.Cells(i , 1) = i

        Next

Giờ em muốn dùng vòng lặp trong mảng nếu thấy sai thì gán vào trong range.

Xin Anh/Chị chỉ giúp
Code chuyển sang mảng sẽ thế này
PHP:
Sub Test()
  Dim Arr, i As Long
  With Sheet1
    Arr = .Range(.[A1], .[A65000].End(xlUp)).Value
    For i = 1 To UBound(Arr, 1)
      Arr(i, 1) = i
    Next
    .Range(.[A1], .[A65000].End(xlUp)).Value = Arr
  End With
End Sub
Hoặc vầy:
PHP:
Sub Test()
  Dim Arr, i As Long
  With Sheet1
    Arr = .Range(.[A1], .[A65000].End(xlUp)).Value
    For i = 1 To UBound(Arr, 1)
      If Arr(i, 1) <> i Then Arr(i, 1) = i
    Next
    .Range(.[A1], .[A65000].End(xlUp)).Value = Arr
  End With
End Sub
- Đầu tiên gán mảng Arr bằng với vùng dữ liệu tại cột A (như vậy ta khỏi phải chỉnh lại kích thước của mảng) ---> Lưu ý rằng sau khi gán như vậy thì Arr sẽ là mảng 2 chiều với chiều thứ nhất có kích thước = số dòng của vùng dữ liệu, chiều thứ 2 có kích thước = 1 (tương đương với 1 cột dữ liệu)
- Duyệt toàn bộ mảng, gán lại STT
- Gán Arr kết quả xuống Range
 
Lần chỉnh sửa cuối:
Upvote 0
Ví dụ 2: Dùng dictionary & mảng để lọc duy nhất khi thỏa mãn một điều kiện
Dữ Liệu
Cột A ----Cột B-----Cột C
Tên ------Tiền------Kỳ

A1 -------10-------2011-11
A1 -------10-------2011-11
A1 -------10-------" "
A2 --------10--------2011-11
A2 --------10--------2011-12
A2 --------10--------

Xử lý: Chọn kỳ 2011-11
Kết Quả

Tên ------Tiền

A1 -------20
A2--------10
 

File đính kèm

Upvote 0
Ví dụ 2: Dùng dictionary & mảng để lọc duy nhất khi thỏa mãn một điều kiện
Dữ Liệu
Cột A ----Cột B-----Cột C
Tên ------Tiền------Kỳ

A1 -------10-------2011-11
A1 -------10-------2011-11
A1 -------10-------" "
A2 --------10--------2011-11
A2 --------10--------2011-12
A2 --------10--------

Xử lý: Chọn kỳ 2011-11
Kết Quả

Tên ------Tiền

A1 -------20
A2--------10
Đúng ra bài này phải nên giải quyết bằng PivotTable (vì đó mới là công cụ phù hợp)
Còn nếu viết code VBA và viết ở mức tổng quát nhất e rằng sẽ rất dài dòng
Vậy tôi viết theo đúng dữ liệu trong file của bạn nhé (dùng sự kiện Change)
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Address = "$F$11" Then
    Dim sArray, Arr(), tmp1, tmp2
    Dim lR As Long, n As Long
    sArray = Range("A2:C10000").Value
    ReDim Arr(1 To UBound(sArray, 1), 1 To 2)
    Range("G13:H10000").ClearContents
    With CreateObject("Scripting.Dictionary")
      For lR = 1 To UBound(sArray, 1)
        If sArray(lR, 3) = Target.Value Then
          tmp1 = sArray(lR, 1): tmp2 = sArray(lR, 2)
          If Not .Exists(tmp1) Then
            n = n + 1
            .Add tmp1, n
            Arr(n, 1) = tmp1
            Arr(n, 2) = tmp2
          Else
            Arr(.Item(tmp1), 2) = Arr(.Item(tmp1), 2) + tmp2
          End If
        End If
      Next
    End With
    If n Then Range("G13").Resize(n, 2).Value = Arr
  End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Ví dụ 2: Dùng dictionary & mảng để lọc duy nhất khi thỏa mãn một điều kiện
Dữ Liệu
Cột A ----Cột B-----Cột C
Tên ------Tiền------Kỳ

A1 -------10-------2011-11
A1 -------10-------2011-11
A1 -------10-------" "
A2 --------10--------2011-11
A2 --------10--------2011-12
A2 --------10--------

Xử lý: Chọn kỳ 2011-11
Kết Quả

Tên ------Tiền

A1 -------20
A2--------10

Làm như sau, lấy Hàm Filter2DArray của thầy ndu96081631,

Mã:
Function Filter2DArray(ByVal sArray, ByVal ColIndex As Long, ByVal FindStr As String, ByVal HasTitle As Boolean)
    Dim TmpArr, Arr, Dic, TmpStr, Tmp
    Dim i As Long, j As Long, Chk As Boolean, TmpVal As Double
    On Error Resume Next
    Set Dic = CreateObject("Scripting.Dictionary")
        TmpArr = sArray
        ColIndex = ColIndex + LBound(TmpArr, 2) - 1
        Chk = (InStr("><=", Left(FindStr, 1)) > 0)
    For i = LBound(TmpArr, 1) - HasTitle To UBound(TmpArr, 1)
        If Chk And FindStr <> "" Then
            TmpVal = CDbl(TmpArr(i, ColIndex))
            If Evaluate(TmpVal & FindStr) Then Dic.Add i, ""
        Else
            If Left(FindStr, 1) = "!" Then
                If Not (UCase(TmpArr(i, ColIndex)) Like UCase(Mid(FindStr, 2, Len(FindStr)))) Then Dic.Add i, ""
            Else
                If UCase(TmpArr(i, ColIndex)) Like UCase(FindStr) Then Dic.Add i, ""
            End If
        End If
    Next
    If Dic.Count > 0 Then
        Tmp = Dic.Keys
        ReDim Arr(LBound(TmpArr, 1) To UBound(Tmp) + LBound(TmpArr, 1) - HasTitle, LBound(TmpArr, 2) To UBound(TmpArr, 2))
            For i = LBound(TmpArr, 1) - HasTitle To UBound(Tmp) + LBound(TmpArr, 1) - HasTitle
                For j = LBound(TmpArr, 2) To UBound(TmpArr, 2)
                    Arr(i, j) = TmpArr(Tmp(i - LBound(TmpArr, 1) + HasTitle), j)
                Next
            Next
        If HasTitle Then
            For j = LBound(TmpArr, 2) To UBound(TmpArr, 2)
                Arr(LBound(TmpArr, 1), j) = TmpArr(LBound(TmpArr, 1), j)
            Next
        End If
    End If
    Filter2DArray = Arr
End Function


Sau đó biến ra:

Mã:
Sub LocDuyNhat()
    Dim i As Long, iR As Long
    Dim sArray, Arr()
    Sheet1.Range("G13:H100").ClearContents
    sArray = Filter2DArray(Sheet1.Range("A2:C8").Value, 3, Sheet1.Range("F11").Value, False)
    ReDim Arr(1 To UBound(sArray, 1), 1 To 3)
    With CreateObject("Scripting.Dictionary")
        For i = 1 To UBound(sArray, 1)
            If sArray(i, 1) <> vbNullString Then
                Tmp = sArray(i, 1) '<--- Day la cai can loc duy nhat
                If Not .Exists(Tmp) Then
                    iR = iR + 1
                    .Add Tmp, iR
                    Arr(iR, 1) = Tmp
                    Arr(iR, 2) = sArray(i, 2) '<--- Cot nay can cong don
                Else
                    Arr(.Item(Tmp), 2) = Arr(.Item(Tmp), 2) + sArray(i, 2)
                End If
            End If
        Next
    End With
    If iR Then Sheet1.Range("G13").Resize(iR, 2).Value = Arr
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Đúng ra bài này phải nên giải quyết bằng PivotTable (vì đó mới là công cụ phù hợp)
Còn nếu viết code VBA và viết ở mức tổng quát nhất e rằng sẽ rất dài dòng
Vậy tôi viết theo đúng dữ liệu trong file của bạn nhé (dùng sự kiện Change)
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Address = "$F$11" Then
    Dim sArray, Arr(), tmp1, tmp2
    Dim lR As Long, n As Long
    sArray = Range("A2:C10000").Value
    ReDim Arr(1 To UBound(sArray, 1), 1 To 2)
    Range("G13:H10000").ClearContents
    With CreateObject("Scripting.Dictionary")
      For lR = 1 To UBound(sArray, 1)
        If sArray(lR, 3) = Target.Value Then
          tmp1 = sArray(lR, 1): tmp2 = sArray(lR, 2)
          If Not .Exists(tmp1) Then
            n = n + 1
            .Add tmp1, n
            Arr(n, 1) = tmp1
            Arr(n, 2) = tmp2
          Else
            Arr(.Item(tmp1), 2) = Arr(.Item(tmp1), 2) + tmp2
          End If
        End If
      Next
    End With
    If n Then Range("G13").Resize(n, 2).Value = Arr
  End If
End Sub

Hình như Code của Thầy chưa đúng với yêu cầu ạ! Phải lọc điều kiện ở cột C và lọc duy nhất ở cột A mới đúng ý của tác giả.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Hình như Code của Thầy chưa đúng với yêu cầu ạ! Phải lọc điều kiện ở cột C và lọc duy nhất ở cột A mới đúng ý của tác giả.
- Điều kiện cột C chính là chổ này: If sArray(lR, 3) = Target.Value Then
- Lọc duy nhất chính là chổ này: If Not .Exists(tmp1) Then
- Cộng dồn chính là chổ này: Arr(.Item(tmp1), 2) = Arr(.Item(tmp1), 2) + tmp2
Còn như kết quả không đúng thì: TÁC GIẢ VUI LÒNG XEM LẠI DỮ LIỆU CỘT C (không đồng nhất)
Ẹc... Ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0
- Điều kiện cột C chính là chổ này: If sArray(lR, 3) = Target.Value Then
- Lọc duy nhất chính là chổ này: If Not .Exists(tmp1) Then
- Cộng dồn chính là chổ này: Arr(.Item(tmp1), 2) = Arr(.Item(tmp1), 2) + tmp2
Còn như kết quả không đúng thì: TÁC GIẢ VUI LÒNG XEM LẠI DỮ LIỆU CỘT C (không đồng nhất)
Ẹc... Ẹc...

Thầy thử xem lại, em đã so sánh kỹ mới nói vậy ạ.
 

File đính kèm

Upvote 0
Thầy thử xem lại, em đã so sánh kỹ mới nói vậy ạ.
Tôi không thấy có điều gì không ổn cả!
Bạn cho ví dụ cụ thể xem trường hợp nào sẽ cho kết quả sai?
---------------------
minhthien lưu ý thêm rằng: Ở đây người ta HỎI ĐỂ TÌM HIỂU VỀ ARRAY VÀ DICTIONARY chứ không phải giải quyết 1 vấn đề cụ thể---> Nếu mà Filer2DArray thì đến khi nào người ta mới học được đây?
 
Lần chỉnh sửa cuối:
Upvote 0
Minhthien cho mình hỏi cái hàm Filter2DArray có tác dụng gì trong code này vậy ???
Híc, sao cứ làm phức tạp thêm thế nhỉ
Híc híc

Hàm này để lọc lấy điều kiện là mã 201112, những mã khác bỏ qua. Sau đó mới lọc duy nhất ở cột A và cộng dồn ở cột B.

Tôi không thấy có điều gì không ổn cả!
Bạn cho ví dụ cụ thể xem trường hợp nào sẽ cho kết quả sai?
---------------------
minhthien lưu ý thêm rằng: Ở đây người ta HỎI ĐỂ TÌM HIỂU VỀ ARRAY VÀ DICTIONARY chứ không phải giải quyết 1 vấn đề cụ thể---> Nếu mà Filer2DArray thì đến khi nào người ta mới học được đây?

Chính vì thế em mới đi tắt là mượn hàm của Thầy cho nhanh, tác giả chủ yếu hỏi lọc duy nhất và cộng dồn. Nếu em AutoFilter trước rồi copy qua vùng khác rồi mới dùng thủ tục lọc duy nhất ở vùng mới này thì cũng được.
 
Upvote 0
Hàm này để lọc lấy điều kiện là mã 201112, những mã khác bỏ qua. Sau đó mới lọc duy nhất ở cột A và cộng dồn ở cột B.



Chính vì thế em mới đi tắt là mượn hàm của Thầy cho nhanh, tác giả chủ yếu hỏi lọc duy nhất và cộng dồn. Nếu em AutoFilter trước rồi copy qua vùng khác rồi mới dùng thủ tục lọc duy nhất ở vùng mới này thì cũng được.
Trời ơi là Trời
Mã:
.......
Vung = Range([A2], [A50000].End(xlUp)).Resize(, 3).Value
        For I = 1 To UBound(Vung)
            If Vung(I, 3) = [f11].Value Then
                If Not d.exists(Vung(I, 1)) Then
                    d.Add Vung(I, 1), Vung(I, 2)
                Else
                    d.Item(Vung(I, 1)) = d.Item(Vung(I, 1)) + Vung(I, 2)
                End If
            End If
        Next I
...............
Chỉ cần dùng If Vung(I, 3) = [f11].Value Then đã loại được các mã không thỏa điều kiện rồi mà.
Híc
 
Upvote 0
Hình như Code của Thầy chưa đúng với yêu cầu ạ! Phải lọc điều kiện ở cột C và lọc duy nhất ở cột A mới đúng ý của tác giả.
Code của thầy ndu hoàn toàn đúng với yêu cầu. Vấn đề ở chỗ định dạng dữ liệu ở cột C không đồng nhất. Chỉ cần chỉnh 1 tí trong code là có thể khắc phục tình trạng này:
Mã:
If [B]CStr[/B](sArray(lR, 3)) = Target.Value Then
 
Upvote 0
Tôi không thấy có điều gì không ổn cả!
Bạn cho ví dụ cụ thể xem trường hợp nào sẽ cho kết quả sai?
---------------------
minhthien lưu ý thêm rằng: Ở đây người ta HỎI ĐỂ TÌM HIỂU VỀ ARRAY VÀ DICTIONARY chứ không phải giải quyết 1 vấn đề cụ thể---> Nếu mà Filer2DArray thì đến khi nào người ta mới học được đây?

Đúng là dữ liệu kỳ chưa đồng nhất... ẹc
Cám ơn các Anh
Em sẽ nghiên cứu ví dụ và hỏi những chỗ chưa hiểu

Cám ơn Anh
 
Upvote 0
Trời ơi là Trời
Mã:
.......
Vung = Range([A2], [A50000].End(xlUp)).Resize(, 3).Value
        For I = 1 To UBound(Vung)
            If Vung(I, 3) = [f11].Value Then
                If Not d.exists(Vung(I, 1)) Then
                    d.Add Vung(I, 1), Vung(I, 2)
                Else
                    d.Item(Vung(I, 1)) = d.Item(Vung(I, 1)) + Vung(I, 2)
                End If
            End If
        Next I
...............
Chỉ cần dùng If Vung(I, 3) = [f11].Value Then đã loại được các mã không thỏa điều kiện rồi mà.
Híc



Code của thầy ndu hoàn toàn đúng với yêu cầu. Vấn đề ở chỗ định dạng dữ liệu ở cột C không đồng nhất. Chỉ cần chỉnh 1 tí trong code là có thể khắc phục tình trạng này:
Mã:
If [B]CStr[/B](sArray(lR, 3)) = Target.Value Then

Hihihi, dữ liệu và cấu trúc của người ta để vậy nên làm vậy, chứ thay đổi sao được! Tuy nhiên, có như vậy mới vừa được trả lời và vừa được học hỏi thêm phải không các Thầy!
 
Upvote 0
Về đoạn code này
PHP:
ReDim Arr(1 To UBound(sArray, 1), 1 To 2)

Có phải là sau khi chế biến, vùng đích chỉ còn 2 cột và số dòng bị co lại mình phải redim
và Mảng mới Arr có
Số dòng mới tương đương là
1 To UBound(sArray, 1) và
Số cột mới là 1 To 2
 
Upvote 0
Về đoạn code này
PHP:
ReDim Arr(1 To UBound(sArray, 1), 1 To 2)

Có phải là sau khi chế biến, vùng đích chỉ còn 2 cột và số dòng bị co lại mình phải redim
và Mảng mới Arr có
Số dòng mới tương đương là
1 To UBound(sArray, 1) và
Số cột mới là 1 To 2

Chính xác là như vậy đó.
 
Upvote 0
Về đoạn code này
PHP:
ReDim Arr(1 To UBound(sArray, 1), 1 To 2)

Có phải là sau khi chế biến, vùng đích chỉ còn 2 cột và số dòng bị co lại mình phải redim
và Mảng mới Arr có
Số dòng mới tương đương là
1 To UBound(sArray, 1) và
Số cột mới là 1 To 2
Nếu bạn biết trước chỉ có 2 dữ liệu cần lấy thì lúc khai báo bạn khỏi Redim cũng được
Dim Arr(1 to 2, 1 to 2) là đủ
Còn khai báo ReDim Arr(1 To UBound(sArray, 1), 1 To 2) là dư nhiều lắm tốn bộ nhớ nữa và tương đương ReDim Arr(1 To 8, 1 To 2). Mà khai báo vậy cho chắc ăn muốn khai báo đủ thì dùng hàm đếm duy nhất cũng được
 
Upvote 0
Về đoạn code này
PHP:
ReDim Arr(1 To UBound(sArray, 1), 1 To 2)

Có phải là sau khi chế biến, vùng đích chỉ còn 2 cột và số dòng bị co lại mình phải redim
và Mảng mới Arr có
Số dòng mới tương đương là
1 To UBound(sArray, 1) và
Số cột mới là 1 To 2
Không đúng vì lúc đó chưa chế biến gì cả
Khai báo lại mảng Arr có số dòng bằng với số dòng của sArray vì lúc đó mình chưa biết số dòng chính xác của mảng Arr ( với đề bài này, số dòng của Arr luôn nhỏ hơn số dòng của sArray)
Sau khi chạy xong vòng lặp, hoàn thành em "Đít to" lúc đó mới biết chính xác số dòng của Arr
Thân
 
Upvote 0
Code của thầy ndu hoàn toàn đúng với yêu cầu. Vấn đề ở chỗ định dạng dữ liệu ở cột C không đồng nhất. Chỉ cần chỉnh 1 tí trong code là có thể khắc phục tình trạng này:
Mã:
If [B]CStr[/B](sArray(lR, 3)) = Target.Value Then
Không được!
Chính là tôi cố tình để y nguyên thế đấy ---> Text và Number phải có sự phân biệt chứ ---> Nếu người dùng nhập sai thì đấy là lỗi của họ, không phải do code mà ra
-----------------------------------
Nếu bạn biết trước chỉ có 2 dữ liệu cần lấy thì lúc khai báo bạn khỏi Redim cũng được
Dim Arr(1 to 2, 1 to 2) là đủ
Còn khai báo ReDim Arr(1 To UBound(sArray, 1), 1 To 2) là dư nhiều lắm tốn bộ nhớ nữa và tương đương ReDim Arr(1 To 8, 1 To 2). Mà khai báo vậy cho chắc ăn muốn khai báo đủ thì dùng hàm đếm duy nhất cũng được
Chúng ta có nhiều cách để tạo ra mảng kết quả:
1> Khai báo dư như tôi đã làm
2> Sau khi chạy xong kết quả, lại thêm 1 vòng lập nữa để "tỉa" cho kích thước vừa đủ
3> Dùng hàm đếm như bạn nói
Cho dù là cách nào thì tốc độ cũng gần như nhau thôi (vì cách nào cũng phải chịu "tốn" cái gì đó)
 
Lần chỉnh sửa cuối:
Upvote 0
Đúng ra bài này phải nên giải quyết bằng PivotTable (vì đó mới là công cụ phù hợp)
Còn nếu viết code VBA và viết ở mức tổng quát nhất e rằng sẽ rất dài dòng
Vậy tôi viết theo đúng dữ liệu trong file của bạn nhé (dùng sự kiện Change)
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Address = "$F$11" Then
    Dim sArray, Arr(), tmp1, tmp2
    Dim lR As Long, n As Long
    sArray = Range("A2:C10000").Value
    ReDim Arr(1 To UBound(sArray, 1), 1 To 2)
    Range("G13:H10000").ClearContents
    With CreateObject("Scripting.Dictionary")
      For lR = 1 To UBound(sArray, 1)
        If sArray(lR, 3) = Target.Value Then
          tmp1 = sArray(lR, 1): tmp2 = sArray(lR, 2)
          If Not .Exists(tmp1) Then
            n = n + 1 ' để đếm số phần tử duy nhất
            .Add tmp1, n
            Arr(n, 1) = tmp1
            Arr(n, 2) = tmp2
          Else
            Arr(.Item(tmp1), 2) = Arr(.Item(tmp1), 2) + tmp2
          End If
        End If
      Next
    End With
    If n Then Range("G13").Resize(n, 2).Value = Arr
  End If
End Sub

Trong đoạn code trên có 2 chỗ em chưa hiểu. Giải thích giúp em nhé
ý 1:
Em hiểu n dùng để đếm số phần tử duy nhất nhưng cấu trúc câu
PHP:
 .Add tmp1, n
Thì n đứng sau Tmp1 hiểu và đọc như nào?

Ý 2
PHP:
Arr(.Item(tmp1), 2)
Câu .Item(tmp1) trả về số thứ tự trong mảng Arr phải không? (em hiểu như hàm match dùng trong INdex?/???
 
Upvote 0
Em hỏi xong thì đã tự hiểu đuợc 2 ý trên rồi. Giờ em xin hỏi một ví dụ khác về mảng
Ví dụ 3: Ghép hai mảng để tạo 1 mảng tạm


Tên-------------Loại-------------Tiền
A1---------------USD-------------10
A1---------------USD-------------10
A1---------------VND-------------10
A1---------------VND-------------10
A1---------------USD-------------10

Kết Quả
Tên-------------Loại-------------Tiền
A1---------------USD-------------30
A1---------------VND-------------20



Thay vì xét mảng 1 thỏa mãn đk1 và mảng 2 thỏa mãn đk2 --> tỉnh tổng

giờ em có thể nối mảng 1 và mảng mảng 2 thành một mảng mới (Mảng tạm). Và mảng này mình chỉ cần xét 1 điều kiện thôi. Thì làm như nào?

Để tránh phải xét 2 điều kiện, em nối Mảng Tên & Loại lại rồi xét duy nhất sau đó tính tổng
thì cách ghep mảng tạm này như nào?

XIn chỉ giúp
 
Lần chỉnh sửa cuối:
Upvote 0
Em hỏi xong thì đã tự hiểu đuợc 2 ý trên rồi. Giờ em xin hỏi một ví dụ khác về mảng
Ví dụ 3: Ghép hai mảng để tạo 1 mảng tạm


Tên-------------Loại-------------Tiền
A1---------------USD-------------10
A1---------------USD-------------10
A1---------------VND-------------10
A1---------------VND-------------10
A1---------------USD-------------10

Kết Quả
Tên-------------Loại-------------Tiền
A1---------------USD-------------30
A1---------------VND-------------20



Thay vì xét mảng 1 thỏa mãn đk1 và mảng 2 thỏa mãn đk2 --> tỉnh tổng

giờ em có thể nối mảng 1 và mảng mảng 2 thành một mảng mới (Mảng tạm). Và mảng này mình chỉ cần xét 1 điều kiện thôi. Thì làm như nào?

Để tránh phải xét 2 điều kiện, em nối Mảng Tên & Loại lại rồi xét duy nhất sau đó tính tổng
thì cách ghep mảng tạm này như nào?

XIn chỉ giúp
Thì cứ ghép bình thường bằng toán tử & thôi mà
Mình tạo một biến Ghep cho bạn dễ hình dung
Mã:
Public Sub DitTo()
    Dim Vung, I, d, K, Mg(), Ghep, kK
    Set d = CreateObject("scripting.dictionary")
    Vung = Range([A3], [A10000].End(xlUp)).Resize(, 3).Value
    ReDim Mg(1 To UBound(Vung, 1), 1 To UBound(Vung, 2))
        For I = 1 To UBound(Vung)
            Ghep = Vung(I, 1) & Vung(I, 2)
                If Not d.exists(Ghep) Then
                    K = K + 1
                    d.Add Ghep, K
                    Mg(K, 1) = Vung(I, 1): Mg(K, 2) = Vung(I, 2): Mg(K, 3) = Vung(I, 3)
                Else
                    kK = d.Item(Ghep)
                    Mg(kK, 3) = Mg(kK, 3) + Vung(I, 3)
                End If
        Next I
    [E3].Resize(1000, UBound(Vung, 2)).ClearContents
    [E3].Resize(UBound(Mg), UBound(Vung, 2)) = Mg
End Sub
 

File đính kèm

Upvote 0
Trong lúc chờ đợi em mầy mò 1 code (dựa trên code của Anh NDU) nhưng code không chạy
Chỉ giúp em code sai ở đâu nhé. Em sẽ học hỏi nhiều qua ví dụ này

PHP:
  Target.Address = "$B$1" Then
     ' cho hang nhap
             Dim sArray, Arr(), tmpTen, tmpTien, tmpLoai
             Dim lR As Long, n As Long
           ' sArray = Sheet1.Range("A2:C1000").Value

             ReDim Arr(1 To UBound(sArray, 1), 1 To 4)
             Sheet2.Range("A5:T10000").ClearContents
             With CreateObject("Scripting.Dictionary")
               For lR = 1 To UBound(sArray, 1)
                 If sArray(lR, 20) = Target.Value Then
                   tmpTen = sArray(lR, 1): tmpTien = -sArray(lR, 5): tmpLoai = sArray(lR, 6)
                   If Not .Exists(tmpTen) Then
                    
                     n = n + 1
                     .Add tmpTen, n
                     Arr(n, 1) = tmpTen
                     Arr(n, 3) = tmpLoai
                     Arr(n, 4) = tmpTien
                 
                    
                   Else
                     ' neu co nhieu hon 1 Ten
                             If Not .exits(tmpLoai) Then ' neu chi co 1 loai ngoai te
                                 m = .Item(tmpTen) + 1
                                 .Add tmpLoai, m
                                  Arr(m, 1) = tmpTen
                                  Arr(m, 3) = tmpLoai
                                  Arr(m, 4) = tmpTien
                              Else
                                
                                 Arr(m, 4) = Arr(m, 4) + tmpTien
                              End If
                   End If
                 End If
               Next
              
             End With
             If m Then Sheet2.Range("A5").Resize(n, 4).Value = Arr
 
Lần chỉnh sửa cuối:
Upvote 0
Em hỏi xong thì đã tự hiểu đuợc 2 ý trên rồi. Giờ em xin hỏi một ví dụ khác về mảng
Để tránh phải xét 2 điều kiện, em nối Mảng Tên & Loại lại rồi xét duy nhất sau đó tính tổng
thì cách ghep mảng tạm này như nào?
XIn chỉ giúp
PHP:
Sub testcong1()
Dim d As Object, Arr(), sArr, lRow As Long, lR As Long, lC As Long, item, KQ
Set d = CreateObject("Scripting.Dictionary")
With Sheets("sheet1")
.Range("K2:M100").Clear
sArr = .Range("A1:C6").Value
ReDim Arr(1 To UBound(sArr, 1), 1 To UBound(sArr, 2))
    For lRow = 1 To UBound(sArr, 1)
    item = sArr(lRow, 1) & " " & sArr(lRow, 2)
        If Not d.Exists(item) Then
            lR = lR + 1
            d.Add item, lR
            KQ = Split(item, " ", 2)
            Arr(lR, 1) = KQ(0)
            Arr(lR, 2) = KQ(1)
            Arr(lR, 3) = sArr(lRow, 3)
        Else
            Arr(d.item(item), 3) = Arr(d.item(item), 3) + sArr(lRow, 3)
        End If
    Next lRow
.Range("K2").Resize(lR, 3).Value = Arr
End With
End Sub
Ngoài cách của Chú Concongia mình có thể dùng hàm Split trực tiếp trên phép nối mảng cũng được
 

File đính kèm

Upvote 0
Cám ơn Anh Hùng
Cũng ví dụ trên, nhưng em thử để các cột không liên tục nhau thì không được
Ví dụ
Vùng dữ liệu gốc có 27 cột

Cột tên = cột 8 (cột H)
Cột Loại = Cột 13
Cột Tiền = Cột 12

Em thử ghép nhưng nó báo lỗi ở NEXT

PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Address = "$B$1" Then
        Dim dg As Long
        Dim d As Object, Arr(), sArr, lRow As Long, lR As Long, item
        Set d = CreateObject("Scripting.Dictionary")
        dg = Sheet1.[A99000].End(xlUp).Row
        Sheet5.Range("A5:T65000").ClearContents
        With Sheet1
        sArr = .Range("A5:AA" & dg).Value
        ReDim Arr(1 To UBound(sArr, 1), 1 To UBound(sArr, 27))
           
            For lRow = 1 To UBound(sArr, 1)
            If sArr(lRow, 27) = Target.Value Then
                item = sArr(lRow, 8) & sArr(lRow, 13)
                If Not d.Exists(item) Then
                    lR = lR + 1
                    d.Add item, lR
                    Arr(lR, 1) = sArr(lRow, 8)
                    Arr(lR, 3) = sArr(lRow, 13)
                    Arr(lR, 4) = sArr(lRow, 12)
                Else
                    Arr(d.item(item), 4) = Arr(d.item(item), 4) + sArr(lRow, 12)
                End If
            Next lRow
        Sheet5.Range("A5").Resize(lR, 4).Value = Arr
        End With

  End If
 
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Cám ơn Anh Hùng
Cũng ví dụ trên, nhưng em thử để các cột không liên tục nhau thì không được
Ví dụ
Vùng dữ liệu gốc có 27 cột

Cột tên = cột 8 (cột H)
Cột Loại = Cột 13
Cột Tiền = Cột 12

Em thử ghép nhưng nó báo lỗi ở NEXT
Với những bài toán có sự tính toán tương đối phức tạp, bạn nên đưa file lên để test cho dễ nhé
 
Upvote 0
Em gửi lại ví dụ nhé
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Em gửi lại ví dụ nhé
Code của bạn chạy được mà
Chỉ là dưới cuối code có ghi dòng Option Base 1 ---> Điều này là không được phép
Xem thông báo lỗi cũng thấy nó nói rằng "Chỉ có comment mới được ghi ở dưới các dòng End Sub, End Function.... "
Vậy, xóa đoạn Option Base 1 ở cuối code là được rồi
Ngoài ra:
- Cũng không cần Option Base 1 ở đầu code luôn, vì mảng được tạo thành từ Range luôn có Base =1, bất chấp Option Base đầu code là bao nhiêu
- Option Base này chỉ có tác dụng với mảng do bạn tự tạo ra (ví dụ biến Arr trong code của bạn)... nhưng bạn đã ReDim Arr(1 to... ) nên cũng đã khai báo nó là Base 1 rồi còn gì
 
Lần chỉnh sửa cuối:
Upvote 0
Em gửi lại ví dụ nhé
Bạn làm gì 2 đoạn dữ vậy chỉ cần duyệt qua từng sheet rồi gán kết quả vào sheet tổng hợp là được rồi mà đọc không hiểu thật đó bạn nói Bill là những ký hiêu IMP, EXP ??? hay là số Invoice vậy? Nếu sai thì mình thấy chỉ có EXP000003 còn IMP000003 thì sai số tổng thôi mà
 
Upvote 0
Code của bạn chạy được mà
Chỉ là dưới cuối code có ghi dòng Option Base 1 ---> Điều này là không được phép
Xem thông báo lỗi cũng thấy nó nói rằng "Chỉ có comment mới được ghi ở dưới các dòng End Sub, End Function.... "
Vậy, xóa đoạn Option Base 1 ở cuối code là được rồi
Ngoài ra:
- Cũng không cần Option Base 1 ở đầu code luôn, vì mảng được tạo thành từ Range luôn có Base =1, bất chấp Option Base đầu code là bao nhiêu
- Option Base này chỉ có tác dụng với mảng do bạn tự tạo ra (ví dụ biến Arr trong code của bạn)... nhưng bạn đã ReDim Arr(1 to... ) nên cũng đã khai báo nó là Base 1 rồi còn gì

To: Anh NDU
Anh kiểm tra lại file của em xem
Bill EXP0003 của sheet2 có 2 loại tiên (10 là VND; 10 là USD) nhưng qua sheet tổng hợp nó tính thành 20. (bị sai vì không đúng loại tiền)
Làm thử lồng ghép với Split (học thêm split) nhưng không được)

To Anh Hùng
Em có 02 sheet IMP & EXP tương ứng sheet1 & 2
Nhưng bill (tại cột 8) có kỳ thỏa mãn kỳ tại sheet Tổng hợp ô B1 thì lọc qua sheet Tổng hợp ạh

Bill là những ký hiêu IMP, EXP ???

Bill là vận đơn đính kèm dưới invoice Anh ạh. Em ký hiệu IMP & EXP để phân biệt là sheet IMP & EXP cho tiện thôi

Em đang học mảng nên chưa biết cách lồng duyệt qua 2 sheet

Anh giúp nhé
 
Lần chỉnh sửa cuối:
Upvote 0
Dùng split dễ hiểu quá
Em dùng split làm được rồi nhưng với chỉ là sheet1
Sheet 2 có cấu trúc tương tự sheet 1 thì code sau mình phải sửa như nào để nó duyệt qua sheet1 và sheet 2 ??


Em gửi file nhé

PHP:
Option Base 1
Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Address = "$B$1" Then
        Dim dg As Long
        Dim d As Object, Arr(), sArr, lRow As Long, lR As Long, item
        Set d = CreateObject("Scripting.Dictionary")
        dg = Sheet1.[A99000].End(xlUp).Row
        Sheet5.Range("A5:T65000").ClearContents
        With Sheet1
        sArr = .Range("A5:AA" & dg).Value
        ReDim Arr(1 To UBound(sArr, 1), 1 To 4)
        
           
            For lRow = 1 To UBound(sArr, 1)
            If sArr(lRow, 27) = Target.Value Then
                
                item = sArr(lRow, 8) & " " & sArr(lRow, 13)
                If Not d.Exists(item) Then
                lR = lR + 1
                d.Add item, lR
                KQ = Split(item, " ", 2)
                Arr(lR, 1) = KQ(0)
                Arr(lR, 3) = KQ(1)
                Arr(lR, 4) = sArr(lRow, 12)
                Else
                Arr(d.item(item), 4) = Arr(d.item(item), 4) + sArr(lRow, 12)
                End If
            End If
                MsgBox lRow
            Next lRow
    Sheet5.Range("A5").Resize(lR, 4).Value = Arr
        End With
  End If
 
End Sub
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Dùng split dễ hiểu quá
Em dùng split làm được rồi nhưng với chỉ là sheet1
Sheet 2 có cấu trúc tương tự sheet 1 thì code sau mình phải sửa như nào để nó duyệt qua sheet1 và sheet 2 ??


Em gửi file nhé

PHP:
Option Base 1
Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Address = "$B$1" Then
        Dim dg As Long
        Dim d As Object, Arr(), sArr, lRow As Long, lR As Long, item
        Set d = CreateObject("Scripting.Dictionary")
        dg = Sheet1.[A99000].End(xlUp).Row
        Sheet5.Range("A5:T65000").ClearContents
        With Sheet1
        sArr = .Range("A5:AA" & dg).Value
        ReDim Arr(1 To UBound(sArr, 1), 1 To 4)
        
           
            For lRow = 1 To UBound(sArr, 1)
            If sArr(lRow, 27) = Target.Value Then
                
                item = sArr(lRow, 8) & " " & sArr(lRow, 13)
                If Not d.Exists(item) Then
                lR = lR + 1
                d.Add item, lR
                KQ = Split(item, " ", 2)
                Arr(lR, 1) = KQ(0)
                Arr(lR, 3) = KQ(1)
                Arr(lR, 4) = sArr(lRow, 12)
                Else
                Arr(d.item(item), 4) = Arr(d.item(item), 4) + sArr(lRow, 12)
                End If
            End If
                MsgBox lRow
            Next lRow
    Sheet5.Range("A5").Resize(lR, 4).Value = Arr
        End With
  End If
 
End Sub
Nếu cấu trúc các sheet hoàn toàn giống nhau, bạn khai báo cho biến sArr thành biến động.
-Cho biến Sh chạy qua các sheet, nếu tên của sheet không phải là "TONGHOP" thì khai báo biến sArr là vùng Sh.Range("A5:AA" & dg).Value lấy tổng số dòng của các mảng trong các sheet để khai báo lại số dòng của mảng kết quả
- Cho biến Sh chạy qua các sheet, nếu tên của sheet không phải là "TONGHOP" thì khai báo biến sArr là vùng Sh.Range("A5:AA" & dg).Value, tiếp tục chạy code,các phần khác không thay đổi
Thân
 
Upvote 0
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
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
Lỡ Sheet Tổng hợp là sheets(3) làm sao bạn nó chung bạn làm sao cũng được trừ sheet bạn tổng hợp ra là được rồi, đâu bạn làm theo gợi ý của Chú Concogia coi nếu không được thì gửi file lên
 
Upvote 0
PHP:
Option Base 1
Private Sub Worksheet_Change(ByVal Target As Range)
'On Error GoTo Err
If Target.Address = "$B$1" Then
        Dim dg As Long
        Dim sh As Worksheet
        Dim d As Object, Arr(), sArr, lRow As Long, lR As Long, item
        Set d = CreateObject("Scripting.Dictionary")
        Sheet5.Range("A5:T65000").ClearContents
       
For I = 1 To 3
        With sh(I)
        
     
            dg = sh.[A99000].End(xlUp).Row
            sArr = .Range("A5:AA" & dg).Value
            ReDim Arr(1 To UBound(sArr, 1), 1 To 4)
            
           
            For lRow = 1 To UBound(sArr, 1)
                If sArr(lRow, 27) = Target.Value And sArr(lRow, 7) <> "KLV" Then
                
                    item = sArr(lRow, 8) & " " & sArr(lRow, 13)
                    If Not d.Exists(item) Then
                        lR = lR + 1
                        d.Add item, lR
                        KQ = Split(item, " ", 2)
                        Arr(lR, 1) = KQ(0)
                        Arr(lR, 3) = KQ(1)
                        Arr(lR, 4) = -(sArr(lRow, 12))
                        Else
                        Arr(d.item(item), 4) = (Arr(d.item(item), 4) - sArr(lRow, 12))
                    End If
                 End If
               
             Next lRow
                
             Sheet5.Range("A5").Resize(lR, 4).Value = Arr
          End With
 
    
Next
End If

Err:
End Sub
Ví dụ 4: duyệt qua nhiều sheet, dùng mảng & Dic, Split để lọc duy nhất về sheet 5 khi thỏa mãn điều kiện nào đó

Tổng hợp dữ liệu Sheet IMP, EXP, NKX vào sheet F-C-R report (sheet 5).
(...em lỡ đặt tên sheet 4 là sheet tổng hợp...nên sửa lại)

code hiện tại báo lỗi tại with sh(I). Em loay hoay mãi chưa được ạh
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Ví dụ 4: duyệt qua nhiều sheet, dùng mảng & Dic, Split để lọc duy nhất về sheet 5 khi thỏa mãn điều kiện nào đó
Tổng hợp dữ liệu Sheet IMP, EXP, NKX vào sheet F-C-R report (sheet 5).
(...em lỡ đặt tên sheet 4 là sheet tổng hợp...nên sửa lại)

code hiện tại báo lỗi tại with sh(I). Em loay hoay mãi chưa được ạh
Bạn nghiên cứu đoạn code này nhen
PHP:
Private Sub Worksheet_Change(ByVal Target As Range)
  If Target.Address = "$B$1" Then
        
        Dim Arr(), sArr, lRow As Long, lR As Long, item, sh As Worksheet, KQ
        Sheet5.Range("A5:D65000").ClearContents
        With CreateObject("Scripting.Dictionary")
        
        For Each sh In Worksheets
            If sh.Name <> "TONGHOP" Then
        
                sArr = sh.Range(sh.[A5], sh.[A65536].End(xlUp)).Resize(, 27).Value
                
                     For lRow = 1 To UBound(sArr, 1)
                        If sArr(lRow, 27) = Target.Value Then
                            item = sArr(lRow, 8) & " " & sArr(lRow, 13)
                          
                                If Not .Exists(item) Then
                                     lR = lR + 1
                                    .Add item, lR
                                    
                                    KQ = Split(item, " ", 2)
                                    ReDim Preserve Arr(1 To UBound(sArr, 1) * 2, 1 To 4)
                                    Arr(lR, 1) = KQ(0)
                                    Arr(lR, 3) = KQ(1)
                                    Arr(lR, 4) = sArr(lRow, 12)
                                Else
                                    Arr(.item(item), 4) = Arr(.item(item), 4) + sArr(lRow, 12)
                                End If
                        End If
                      Next lRow
                End If
               
            Next sh
           
        End With
        Sheet5.Range("A5").Resize(lR, 4).Value = Arr
  End If
 
End Sub
 

File đính kèm

Upvote 0
Cám ơn Anh Hùng rất nhiều
Như vậy em nghĩ mãi không ra

Những sheet khác không cùng cấu trúc em có thể đặt tên là Tổng họp 1 , 2, 3...v..v rồi dùng left duyệt

Em hiểu rồi
 
Upvote 0
TV_câu hỏi 5: Dùng mảng để so sánh dữ liệu giữa 2 sheet, những dữ liệu chưa có đem qua sheet thứ 3

Ví dụ 5:
- Sheet1: từ A1:A10 có dữ liệu là Test01, Test02...., Test10
- Sheet2: Từ A1:A5 có dữ liệu là Test06,Test06, Test07,Test08,Test09

Dùng mảng để so sánh
- Dem từng phần từ trong mảng Sheet1 so sánh với sheet2
- PHần từ nào chưa có --> đem qua Sheet3

Như vậy có 06 phần từ sau sẽ được bê qua sheet3 (Test01,
Test02,Test03,Test04,Test05,Test10)

Em định ghép mảng và dùng Dic để làm nhưng khó quá
 
Upvote 0
Hãy làm bằng những thao tác căn bản nhất về mảng:
Xác định các vùng dữ liệu
Tạo các mảng chứa dữ liệu
Xác định (bằng cách suy luận, phỏng đoán) kích thước mảng kết quả, ReDim mảng kết quả.
Dùng vòng lặp duyệt qua mảng này, xét điều kiện (có hoặc không có liên quan đến mảng kia), nếu thoả gán vào mảng kết quả
gán mảng kết quả xuống sheet.

Nói chung, sử dụng mảng chỉ loanh quanh mấy bước trên thôi.

Còn suy luận thế nào, dùng thuật toán nào, ăn thua cái đầu. Bây giờ bài nào cũng chỉ, cũng làm mẫu, mà không tự nghĩ, thì chả bao giờ tự làm được.

Bài này so với bài 136 còn dễ hơn nhiều, nhưng 136 làm được, bài này không? tại sao?
 
Lần chỉnh sửa cuối:
Upvote 0
TV_câu hỏi 5: Dùng mảng để so sánh dữ liệu giữa 2 sheet, những dữ liệu chưa có đem qua sheet thứ 3

Ví dụ 5:
- Sheet1: từ A1:A10 có dữ liệu là Test01, Test02...., Test10
- Sheet2: Từ A1:A5 có dữ liệu là Test06,Test06, Test07,Test08,Test09

Dùng mảng để so sánh
- Dem từng phần từ trong mảng Sheet1 so sánh với sheet2
- PHần từ nào chưa có --> đem qua Sheet3

Như vậy có 06 phần từ sau sẽ được bê qua sheet3 (Test01,
Test02,Test03,Test04,Test05,Test10)

Em định ghép mảng và dùng Dic để làm nhưng khó quá
- Dễ nhất là dùng Advanced Filter
- Nếu muốn học về mảng, xem bài này:
http://www.giaiphapexcel.com/forum/showthread.php?48469-Tạo-hàm-so-sánh-2-danh-sách&
Trong mảng, cứ nói đén việc tìm kiếm, xác định sự tồn tại của 1 phần tử trong 1 danh sách hoặc lọc duy nhất, hãy nghĩ đến Dictionary
 
Upvote 0
Xin giải thích giúp em đoạn code này
PHP:
ReDim Preserve Arr(1 To UBound(SArr, 1) * 2, 1 To 10)
 
Upvote 0
đoạn code trên sao lại phải có đoạn *2 ạh?
UBound(SArr, 1) * 2
 
Upvote 0
đoạn code trên sao lại phải có đoạn *2 ạh?
UBound(SArr, 1) * 2
Người ta muốn mở rộng kích thước của mảng Arr với chiều thứ nhất gấp đôi chiêu thứ nhất của SArr ---> Quét qua 2 sheet, nếu không nhân 2 thế hóa ra kích thước của Arr bị thiếu làm sao?
Ví dụ:
- Chiều thứ nhất của SArr là 10
- Vậy chiều thứ nhất của Arr là 20
Thế thôi
 
Lần chỉnh sửa cuối:
Upvote 0
Trường hợp số sheet qua là 3 thì sẽ là
UBound(SArr,1) *3


Phải không Anh?

 
Upvote 0
PHP:
Option Base 1

Private Sub Worksheet_Change(ByVal Target As Range)
 Application.ScreenUpdating = False
 'On Error GoTo Err
  If Target.Address = "$B$1" And Target.Value = "" Then
        
        Dim Arr(), SArr, lRow As Long, lR As Long, item, sh As Worksheet, KQ
        Sheet5.Range("A5:T65000").ClearContents
        With CreateObject("Scripting.Dictionary")
        
        For Each sh In Worksheets
            If Left(sh.Name, 2) <> "RP" Then
        
                SArr = sh.Range(sh.[A5], sh.[A65536].End(xlUp)).Resize(, 25).Value
                
                     For lRow = 1 To UBound(SArr, 1)
                        If SArr(lRow, 21) = Target Then ' column 21 la cot ky FCR
                            item = SArr(lRow, 8) & " " & SArr(lRow, 13)
                                If Not .Exists(item) Then
                                     lR = lR + 1
                                    .Add item, lR
                                    
                                    KQ = Split(item, " ", 2)
                                    ReDim Preserve Arr(1 To UBound(SArr, 1) * 3, 1 To 13)
                                    Arr(lR, 1) = SArr(lRow, 6) ' ngay HD
                                    Arr(lR, 2) = KQ(0)  ' van don
                                    Arr(lR, 3) = SArr(lRow, 7) ' head
                                    Arr(lR, 4) = SArr(lRow, 9) ' cty
                                    Arr(lR, 5) = SArr(lRow, 10) ' tax code
                                    Arr(lR, 6) = SArr(lRow, 11) ' Dien giai
                                    Arr(lR, 7) = SArr(lRow, 2) ' so hoa don
                                    Arr(lR, 8) = KQ(1)  ' ngoai te
                                    Arr(lR, 9) = SArr(lRow, 12) ' truoc thue
                                    Arr(lR, 10) = SArr(lRow, 16) ' thue
                                    Arr(lR, 11) = SArr(lRow, 17) ' sau thue
                                    Arr(lR, 12) = SArr(lRow, 14) ' ty gia
                                    Arr(lR, 13) = SArr(lRow, 23) ' remark OSF
                                Else
                                    Arr(.item(item), 9) = (Arr(.item(item), 9) + SArr(lRow, 12))
                                    Arr(.item(item), 10) = (Arr(.item(item), 10) + SArr(lRow, 16))
                                    Arr(.item(item), 11) = (Arr(.item(item), 11) + SArr(lRow, 17))
                                End If
                        End If
                      Next lRow
                End If
               
            Next sh
           
        End With
        Sheet6.Range("A5").Resize(lR, 13).Value = Arr
        
        
    
End If
  
  
'Err:
Application.ScreenUpdating = True
End Sub



Private Sub Worksheet_Deactivate()
  Sheet6.Range("A5:M20000").ClearContents
End Sub
Đoạn code trên em test thành công với trường hợp target ""Nhưng khi sửa lại là target = "" thì nó báo lỗi dòng ReDim Anh ạhAnh xem giúp em với
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
PHP:
Đoạn code trên em test thành công với trường hợp target  ""Nhưng khi sửa lại là target = "" thì nó báo lỗi dòng ReDim Anh ạhAnh xem giúp em với[/QUOTE]
Hỏi lại:
- Bạn muốn làm điều gì trong file này?
- Ở sheet RP-TongHop tôi thấy bạn ghi "[B]nhập X tại ô B1 để update OSF[/B]" ---> Vậy khi nhập x vào B1, ta sẽ tìm "cái gì" ở các sheet? ---> Vì thấy trong code có đoạn[B] If SArr(lRow, 21) = Target Then[/B], chẳng ăn nhập gì với chữ "x" cả
-[B] ReDim Preserve[/B] chỉ có thể thay đổi được kích thước của chiều cuối cùng, trong khi bạn lại để đoạn code [B]ReDim Preserve[/B] trong vòng lập và muốn thay đổi chiều thứ nhất, vậy đâu có được
- Trong code có đoạn [B]Sheet5.Range("A5:T65000").ClearContents[/B] mà trong file bạn chẳng có sheet nào là Sheet5 cả
- Cuối code là đoạn [B]Sheet6.Range("A5").Resize(lR, 13).Value = Arr [/B]---> Nếu không tìm thấy gì thì lR sẽ = 0 và đoạn code này chắc chắn báo lỗi, lý ra phải là [B]If lR Then Sheet6.Range("A5").Resize(lR, 13).Value = Arr[/B]
Hic... sai nhiều quá
 
Lần chỉnh sửa cuối:
Upvote 0
Mảng thật tuyệt vời nhưng học và sử dụng nó không đơn giản chút nào
Em mới phát hiện ra lỗi là do khi duyệt qua các sheet nhưng số dòng không giống nhau nên nó bị lỗi dòng ReDim

- Bạn muốn làm điều gì trong file này?

1. Duyệt qua các sheet nếu left(tên sheet,2) <> "RP" (tương đương với sheet1,2,3)
2. Nếu thỏa mãn cells(i,21) (là Cột U - kỳ FC.R) nếu là trông "" thì sau khi mình sẽ update vào sheet tổng hợp


 
Upvote 0
Em làm được rổi nhé
Cám ơn các anh nhiều
 
Upvote 0
Dạo này vợ đòi bỏ, rỗi thời gian sang nghiên cứu món Excel, VBA thấy hay quá, sau khi viết code thì nó không chạy, không biết sai ở đâu

Sub Chanqua()
Dim DL, Thang, Dongdau As Long, Dongcuoi As Long, i As Long
Dongdau = 3
Dongcuoi = [A65000].End(xlUp).Row
DL = Range("A" & (Dongdau) & ":A" & Dongcuoi).Value
Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value
For i = Dongdau To Dongcuoi
Thang(i, 1) = DL(i, 1)
Next i
Range("B" & (Dongdau) & ":B" & Dongcuoi).Value = Thang
End Sub

Ai biết xin chỉ giúp tôi với.
 
Upvote 0
Dạo này vợ đòi bỏ, rỗi thời gian sang nghiên cứu món Excel, VBA thấy hay quá, sau khi viết code thì nó không chạy, không biết sai ở đâu

Sub Chanqua()
Dim DL, Thang, Dongdau As Long, Dongcuoi As Long, i As Long
Dongdau = 3
Dongcuoi = [A65000].End(xlUp).Row
DL = Range("A" & (Dongdau) & ":A" & Dongcuoi).Value
Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value
For i = Dongdau To Dongcuoi
Thang(i, 1) = DL(i, 1)
Next i
Range("B" & (Dongdau) & ":B" & Dongcuoi).Value = Thang
End Sub

Ai biết xin chỉ giúp tôi với.
Bạn đang lẫn lộn giữa chỉ số dòng trên bảng tính và chỉ số "dòng" trong mảng
Chỉ số dòng trên bảng tính với Dongdau bắt đầu từ 3
Chỉ số "dòng" trong mảng bắt đầu từ 1
Vậy làm sao mà gán đây
Có thể sửa lại tí:
Mã:
Sub Chanqua()
  Dim DL, Thang, Dongdau As Long, Dongcuoi As Long, i As Long, [COLOR=#ff0000]n As Long[/COLOR]
  Dongdau = 3
  Dongcuoi = [A65000].End(xlUp).Row
  DL = Range("A" & (Dongdau) & ":A" & Dongcuoi).Value
  Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value
  For i = Dongdau To Dongcuoi
    [COLOR=#ff0000]n = n + 1[/COLOR]
    Thang(n, 1) = DL(n, 1)
  Next i
  Range("B" & (Dongdau) & ":B" & Dongcuoi).Value = Thang
End Sub
Chổ màu đỏ là chổ được thêm vào
Còn nếu là tôi thì tôi viết khác
PHP:
Sub Chanqua()
  Dim DL, Thang, i As Long
  With Range([A3], [A65536].End(xlUp))
    DL = .Value
    ReDim Thang(1 To UBound(DL, 1), 1 To 1)
    For i = 1 To UBound(DL, 1)
      Thang(i, 1) = DL(i, 1)
    Next i
    .Offset(, 1).Value = Thang
  End With
End Sub
 
Upvote 0
Bạn đang lẫn lộn giữa chỉ số dòng trên bảng tính và chỉ số "dòng" trong mảng
Chỉ số dòng trên bảng tính với Dongdau bắt đầu từ 3
Chỉ số "dòng" trong mảng bắt đầu từ 1
Vậy làm sao mà gán đây
Có thể sửa lại tí:
Mã:
Sub Chanqua()
  Dim DL, Thang, Dongdau As Long, Dongcuoi As Long, i As Long, [COLOR=#ff0000]n As Long[/COLOR]
  Dongdau = 3
  Dongcuoi = [A65000].End(xlUp).Row
  DL = Range("A" & (Dongdau) & ":A" & Dongcuoi).Value
  Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value
  For i = Dongdau To Dongcuoi
    [COLOR=#ff0000]n = n + 1[/COLOR]
    Thang(n, 1) = DL(n, 1)
  Next i
  Range("B" & (Dongdau) & ":B" & Dongcuoi).Value = Thang
End Sub
Chổ màu đỏ là chổ được thêm vào
Còn nếu là tôi thì tôi viết khác
PHP:
Sub Chanqua()
  Dim DL, Thang, i As Long
  With Range([A3], [A65536].End(xlUp))
    DL = .Value
    ReDim Thang(1 To UBound(DL, 1), 1 To 1)
    For i = 1 To UBound(DL, 1)
      Thang(i, 1) = DL(i, 1)
    Next i
    .Offset(, 1).Value = Thang
  End With
End Sub

Trong trường hợp này n không nhất thiết phải khai báo giới hạn của nó chạy từ bao nhiêu đến bao nhiêu ?

ở đoạn Code thứ 2 màu xanh ReDim Thang(1 To UBound(DL, 1), 1 To 1) tôi chưa hiểu lắm về nó có nghĩa là vậy?
 
Lần chỉnh sửa cuối:
Upvote 0
Trong trường hợp này n không nhất thiết phải khai báo giới hạn của nó chạy từ bao nhiêu đến bao nhiêu ?

ở đoạn Code thứ 2 màu xanh ReDim Thang(1 To UBound(DL, 1), 1 To 1) tôi chưa hiểu lắm về nó có nghĩa là vậy?
n đương nhiên chạy từ 1 đến khi nào hết vòng lập thì ngưng
ReDim Thang... chẳng qua để chỉnh lại kích thước của mảng Thang sao cho nó bằng với DL (gần giống với Resize ấy)
 
Upvote 0
n đương nhiên chạy từ 1 đến khi nào hết vòng lập thì ngưng
ReDim Thang... chẳng qua để chỉnh lại kích thước của mảng Thang sao cho nó bằng với DL (gần giống với Resize ấy)

Từ code của bác, tôi thắc mắc liệu cách dùng trong bài giải của bác có gì khác nếu viết thành thế này không?

Sub Chanqua()
Dim DL, Thang, Dongdau As Long, Dongcuoi As Long, i As Long
Dongdau = 3
Dongcuoi = [A65000].End(xlUp).Row
DL = Range("A" & (Dongdau) & ":A" & Dongcuoi).Value
Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value
For i = Dongdau To UBound(DL, 1)
Thang(i, 1) = DL(i, 1)
Next i
Range("B" & (Dongdau) & ":B" & Dongcuoi).Value = Thang
End Sub
 
Upvote 0
Từ code của bác, tôi thắc mắc liệu cách dùng trong bài giải của bác có gì khác nếu viết thành thế này không?

Sub Chanqua()
Dim DL, Thang, Dongdau As Long, Dongcuoi As Long, i As Long
Dongdau = 3
Dongcuoi = [A65000].End(xlUp).Row
DL = Range("A" & (Dongdau) & ":A" & Dongcuoi).Value
Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value
For i = Dongdau To UBound(DL, 1)
Thang(i, 1) = DL(i, 1)
Next i
Range("B" & (Dongdau) & ":B" & Dongcuoi).Value = Thang
End Sub
Mấu chốt bài này sai là
Dongdau=3, nếu = 1 thì OK.
Tại vì for i= dongdau to dongcuoi
Mà dongdau=3 => dongcuoi=dongdau-3
Nếu dongcuoi=dongcuoi thì mảng DL kg hiểu DL(dongcuoi) trong khi nó chỉ có dongcuoi - 3 dòng.
 
Upvote 0
Từ code của bác, tôi thắc mắc liệu cách dùng trong bài giải của bác có gì khác nếu viết thành thế này không?

Sub Chanqua()
Dim DL, Thang, Dongdau As Long, Dongcuoi As Long, i As Long
Dongdau = 3
Dongcuoi = [A65000].End(xlUp).Row
DL = Range("A" & (Dongdau) & ":A" & Dongcuoi).Value
Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value
For i = Dongdau To UBound(DL, 1)
Thang(i, 1) = DL(i, 1)
Next i
Range("B" & (Dongdau) & ":B" & Dongcuoi).Value = Thang
End Sub
Bạn nên nhớ rằng khi chuyển bất cứ Range vào sang Array thì chỉ số của phần tử đầu tiên trong Array luôn bắt đầu bằng 1
Ở đây bạn chuyên vùng A3:Ax sang Array DL, với vùng A3:Ax bắt đầu từ dòng 3, nhưng DL lại bắt đầu bằng 1 (cả Thang cũng bắt đầu bằng 1)
Vậy nếu dùng code trên, bạn sẽ bị mất 2 phần tử 1 và 2
Bởi vậy phải sửa thành:
Mã:
Sub Chanqua()
  Dim DL, Thang, Dongdau As Long, Dongcuoi As Long, i As Long
  Dongdau = 3
  Dongcuoi = [A65000].End(xlUp).Row
  DL = Range("A" & (Dongdau) & ":A" & Dongcuoi).Value
  Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value
  For [COLOR=#ff0000][B]i = 1[/B][/COLOR] To UBound(DL, 1)
    Thang(i, 1) = DL(i, 1)
    Next i
  Range("B" & (Dongdau) & ":B" & Dongcuoi).Value = Thang
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Ah, Tôi hiểu rồi.

Thế thì thực chất đoạn ReDim Thang(1 To UBound(DL, 1), 1 To 1) nó chẳng qua thay thế cho đoạn Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value, nhưng Redim có ưu điểm là có tính tự động co dãn để đảm bảo số phần tử của Thang luôn = số phần tử của DL?
 
Lần chỉnh sửa cuối:
Upvote 0
Ah, Tôi hiểu rồi.

Thế thì thực chất đoạn ReDim Thang(1 To UBound(DL, 1), 1 To 1) nó chẳng qua thay thế cho đoạn Thang = Range("B" & (Dongdau) & ":B" & Dongcuoi).Value, nhưng Redim có ưu điểm là có tính tự động co dãn để đảm bảo số phần tử của Thang luôn = số phần tử của DL?

Đã co giãn rồi sao có thể đảm bảo số phần tử của mảng ban đầu bằng với mảng mới được bạn? Muốn bằng hay không do mình quy định khi ReDim thôi bạn à.
 
Upvote 0
Cuối ngày rồi mình có 1 câu hỏi muốn hỏi các bạn ham thích về mảng Array cũng để các bạn hiểu rõ hơn về mảng Array
PHP:
Sub ArrinArr()
Dim Arr As Variant
Arr = Array(Array(Array(4, 5, 6), Array(7, 8, 9), Array(10, 11, 12)), Array(4, Array(13, 14, 15), 6))
'Debug.Print Arr(1)(1)(1)
End Sub
Bạn suy nghĩ trường hợp không dùng Option Base 1 thì truy xuất phần tử trong Array với kiểu truy xuất như dạng này Arr(1)(1)(1) thì giá trị là bao nhiêu, rồi dùng Option Base 1 thì giá trị là bao nhiêu suy nghĩ rồi thì bạn hãy dùng Debug.Print nhen! Các bạn cứ phát triển thêm phần tử trong mảng để hiểu rõ hơn
 
Upvote 0
Cuối ngày rồi mình có 1 câu hỏi muốn hỏi các bạn ham thích về mảng Array cũng để các bạn hiểu rõ hơn về mảng Array
PHP:
Sub ArrinArr()
Dim Arr As Variant
Arr = Array(Array(Array(4, 5, 6), Array(7, 8, 9), Array(10, 11, 12)), Array(4, Array(13, 14, 15), 6))
'Debug.Print Arr(1)(1)(1)
End Sub
Bạn suy nghĩ trường hợp không dùng Option Base 1 thì truy xuất phần tử trong Array với kiểu truy xuất như dạng này Arr(1)(1)(1) thì giá trị là bao nhiêu, rồi dùng Option Base 1 thì giá trị là bao nhiêu suy nghĩ rồi thì bạn hãy dùng Debug.Print nhen! Các bạn cứ phát triển thêm phần tử trong mảng để hiểu rõ hơn
Ẹc... Ẹc... không ngở bạn cũng bắt đầu nghiên cứu đến phần "cao cấp" của mảng đây: Mảng trong mảng ---> Trò này sẽ có nhiều ứng dụng rất hay!
 
Upvote 0
Ẹc... Ẹc... không ngở bạn cũng bắt đầu nghiên cứu đến phần "cao cấp" của mảng đây: Mảng trong mảng ---> Trò này sẽ có nhiều ứng dụng rất hay!
Em xin đưa 1 file mảng trong mảng mình tập làm quen thôi chứ không ứng dụng gì hết, anh Ndu giúp em cho em 1 vài ứng dụng đi nhen

PHP:
Sub ArrayinArray()
Dim arr(3) As Variant
Dim icol As Long, i As Long, j As Long
With Sheets("data")
    For icol = 1 To 8 Step 3
        i = i + 1
        arr(i) = .Range(.Cells(1, icol), .Cells(21, icol)).Resize(, 2).Value
    Next
    For i = 1 To UBound(arr(2))
        If Len(arr(2)(i, 2)) = 10 Then
            j = j + 1
            arr(3)(j, 1) = arr(2)(i, 2)
        End If
    Next i
.Range("i2").Resize(j, 1).Value = arr(3)
End With
End Sub
Trong ví dụ này chủ yếu các giá trị ta nạp chúng vào Array tạm rồi xuất giá trị theo từng lần nạp theo thứ tự dòng cột mà chúng ta muốn xuất ví dụ ta lấy các giá trị có chiều dài bằng 10 của lần nạp thứ 2 của cột thứ 2
 

File đính kèm

Upvote 0
Em xin đưa 1 file mảng trong mảng mình tập làm quen thôi chứ không ứng dụng gì hết, anh Ndu giúp em cho em 1 vài ứng dụng đi nhen
Ứng dùng là bài này nè (vửa đố xong):
http://www.giaiphapexcel.com/forum/showthread.php?60569-HD-giúp-thuật-toán-tìm-cặp-số-liên-tiếp-thỏa-dk!&p=374182#post374182
Tôi làm như sau:
PHP:
Option Base 1
Sub ConsNum(ByVal numArr)
  Dim Dic1, Dic2, ArrItem(1 To 2), Arr(), TG As Double
  Dim k As Long, tmp, lPos As Long, n As Long
  TG = Timer
  Set Dic1 = CreateObject("Scripting.Dictionary")
  Set Dic2 = CreateObject("Scripting.Dictionary")
  For k = LBound(numArr) To UBound(numArr) - 1
    If numArr(k) > 1 And numArr(k + 1) > 1 Then
      If lPos = 0 Then lPos = k
      If Not Dic1.Exists(lPos) Then
        n = n + 1
        Dic1.Add lPos, 2
        Dic2.Add lPos, n
        ReDim Preserve Arr(1 To n)
        Arr(n) = ArrItem
        Arr(n)(1) = lPos
        Arr(n)(2) = 2
      Else
        Dic1.Item(lPos) = Dic1.Item(lPos) + 1
        Arr(Dic2.Item(lPos))(1) = lPos
        Arr(Dic2.Item(lPos))(2) = Dic1.Item(lPos)
      End If
    Else
      lPos = 0
    End If
    tmp = numArr(k)
  Next
  For k = 1 To UBound(Arr)
    Arr(k) = Join(Arr(k), ":")
  Next
  If n Then Range("C1").Value = Join(Arr, " - ")
  MsgBox Timer - TG
End Sub
PHP:
Function Range2Array(ByVal SrcRng As Range)
  Dim Item, sArray, Arr(), n As Long
  sArray = SrcRng.Value
  ReDim Arr(SrcRng.Count)
  For Each Item In SrcRng
    n = n + 1
    Arr(n) = Item
  Next
  Range2Array = Arr
End Function
PHP:
Sub Main()
  Dim i As Long, numArr
  numArr = Range2Array(Range("A1:A10000"))
  ConsNum numArr
End Sub
Xem file đính kèm, dữ liệu nguồn tại cột A
 

File đính kèm

Upvote 0
Tôi vẫn chưa hiểu được hết bản chất của mảng, xin được chỉ giúp chố sai của đoạn Code này

PHP:
Sub loc()
  Dim Vung
        Set Vung = Range([A1], [A65000].End(xlUp))
  i = Count(Vung)
    MsgBox i
   End Sub

Nếu khai báo đoạn Set Vung = Range([A1], [A65000].End(xlUp)) bằng đoạn Vung = Range([A1], [A65000].End(xlUp)) thì có gì là khác nhau?

Xin cảm ơn rất nhiều./.
 
Upvote 0
Tôi vẫn chưa hiểu được hết bản chất của mảng, xin được chỉ giúp chố sai của đoạn Code này

PHP:
Sub loc()
  Dim Vung
        Set Vung = Range([A1], [A65000].End(xlUp))
  i = Count(Vung)
    MsgBox i
   End Sub

Nếu khai báo đoạn Set Vung = Range([A1], [A65000].End(xlUp)) bằng đoạn Vung = Range([A1], [A65000].End(xlUp)) thì có gì là khác nhau?

Xin cảm ơn rất nhiều./.
Theo như mình hiểu thì Vung là mãng nhận giá trị trong vùng đó, còn Set Vung là bao gồm mãng, định dạng v.v...
 
Upvote 0
Tôi vẫn chưa hiểu được hết bản chất của mảng, xin được chỉ giúp chố sai của đoạn Code này

PHP:
Sub loc()
  Dim Vung
        Set Vung = Range([A1], [A65000].End(xlUp))
  i = Count(Vung)
    MsgBox i
   End Sub

Nếu khai báo đoạn Set Vung = Range([A1], [A65000].End(xlUp)) bằng đoạn Vung = Range([A1], [A65000].End(xlUp)) thì có gì là khác nhau?

Xin cảm ơn rất nhiều./.

Bạn chưa đúng cơ bản 2 điều:

1) Khi dùng Set đối với vùng giá trị nào đó của sheet, nó thuộc về biến Range, còn không Set nó như là 1 Variant

2) Trong thủ tục code không có cấu trúc: Count(Vung) mà nếu đã Set Vung as Range thì ta có thể ghi là Vung.Count, với mảng có lẽ ta phải dùng thủ tục Ubound để đếm.

Bạn xem 2 thủ tục ít nhiều sẽ rõ:

Với Vung là một Range:
PHP:
Sub loc1()
    Dim Vung As Range
    Set Vung = Range([A1], [A65000].End(xlUp))
    i = Vung.Count
    MsgBox i
End Sub

Với Vung là một Variant (có thể phát sinh lỗi nếu i bằng 0 hoặc bằng 1):
PHP:
Sub loc2()
    Dim Vung As Variant
    Vung = Range([A1], [A65000].End(xlUp))
    i = UBound(Vung, 1)
    MsgBox i
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Xin hỏi thêm: Làm thế nào để đếm nhanh được số phần tử trong vung không tính ô trống (tức là MsgBox i = 5 thay vì bằng 6 như các đoạn Code trên).
 
Upvote 0
Xin hỏi thêm: Làm thế nào để đếm nhanh được số phần tử trong vung không tính ô trống (tức là MsgBox i = 5 thay vì bằng 6 như các đoạn Code trên).

Thì bạn làm như vầy đi:

PHP:
Sub loc2()
    Dim Vung, i As Long, m As Long
    Vung = Range([A1], [A65000].End(xlUp))
    For i = 1 To UBound(Vung)
        If Vung(i, 1) <> "" Then m = m + 1
    Next i
    MsgBox m
End Sub
 
Upvote 0
Tôi vẫn còn lờ mờ cái này: Chưa phần biệt được khác nhau, cách dùng giữa RangeVariant.
Nhờ bác minhthien321 và mọi người giúp cho.
 
Upvote 0
Tôi vẫn còn lờ mờ cái này: Chưa phần biệt được khác nhau, cách dùng giữa RangeVariant.
Nhờ bác minhthien321 và mọi người giúp cho.

Để giải thích theo kiểu nôm na của mình hiểu thì:

1) Range: là kiểu dữ liệu dựa trên sheet, nó mang tính chất của một Range khi được khai báo

2) Variant: là kiểu dữ liệu bất kỳ, nó bao gồm tất cả các biến được khai như: Integer, Byte, Long, Single, Currency, Decimal, Double...

Nếu Set Vung = [A1:G300] thì nó mang tính chất Range, những thuộc tính của Range như thế nào thì Vung đều có như thế đó.

Nếu Vung = [A1:G300] thì nó như là một mảng, chỉ mang giá trị là Value chứ không có các thuộc tính như Range.
 
Upvote 0
Một đề tài rất hay, nhờ đọc nó em thấy hiểu thêm được rất nhiều điều. Em xin cảm ơn các sư phụ Ptm0412, sư phụ Ndu96081631 rất nhiều.
 
Upvote 0
Xin chỉ rõ hơn 1 chút, tôi vẫn loay hoay phân biệt cách dùng Range và Variant.

Tại sao viết thế này không chạy
PHP:
Sub loc1()
    Dim Vung As Range
    Vung = Range([A1], [A65000].End(xlUp))
    i = Vung.Count
    MsgBox i
End Sub

Đổi thành thế này lại OK
PHP:
Sub loc()
  Dim Vung
        Set Vung = Range([A1], [A65000].End(xlUp))
  i = Count(Vung)
    MsgBox i
   End Sub
lại được.

(Bởi tôi cứ hay nhầm cách sử dụng Count và Ubound), do IQ của tôi tiếp thu chậm quá, xin mọi người giảng giải cho.
---------------------

Ah, tôi hiểu ra thế này, nếu có gì sai nhờ mọi người sửa hộ

Bản chất của Count là đếm số ô, mà Range chứa các ô nên nó là đối tượng của Count. Trong khi Vung trong Code thứ nhất khi khai báo dạng Variant nên nó chỉ là các giá trị "rời rạc" không liên quan đến khái niệm ô nên không phải là đối tượng của Count.

Ubound có tính chất đếm số phần tử trong tập rời rạc nên nó làm việc với Variant (chứ không phải đếm ô nên không làm việc với Range tức là TH khai báo Set).

Khi so sánh, làm phép tính phải sử dụng Variant (chứ không sử dụng trực tiếp Range), chỉ khi ra kết quả cuối cùng gán cho 1 vùng lúc này mới sử dụng Range chăng?
 
Lần chỉnh sửa cuối:
Upvote 0
Xin chỉ rõ hơn 1 chút, tôi vẫn loay hoay phân biệt cách dùng Range và Variant.

Tại sao viết thế này không chạy
PHP:
Sub loc1()
    Dim Vung As Range
    Vung = Range([A1], [A65000].End(xlUp))
    i = Vung.Count
    MsgBox i
End Sub

Đổi thành thế này lại OK
PHP:
Sub loc()
  Dim Vung
        Set Vung = Range([A1], [A65000].End(xlUp))
  i = Count(Vung)
    MsgBox i
   End Sub
lại được.

(Bởi tôi cứ hay nhầm cách sử dụng Count và Ubound), do IQ của tôi tiếp thu chậm quá, xin mọi người giảng giải cho.
Như nhiều lần đã đề cập, SET dùng để khởi tạo 1 biến thuộc Object...
Object (hay đối tượng) là những biến như: Hình vẽ, các đối tượng thuộc thanh Forms, Workbook, Worksheet... vân vân...
Vì đã khai báo ở đầu code Dim Vung As Range nên đương nhiên Vung phải là Object ---> Thế thì nếu không có SET "nó" không chịu (quy định thế thôi)
---------------
COUNT và Ubound hoàn toàn khác nhau.
Count thường là thuộc tính của Range (đếm số cell) trong khi Ubound không phải dùng để đếm. Ubound là 1 số dùng để xác định chỉ số phần tử cuối cùng của 1 mảng
Ví dụ:
Dim Arr(1 to 5)
thì UBound(Arr) sẽ = 5 ---> chính là chỉ số thứ tự cuối cùng của mảng Arr ---> Trùng hợp, số phần tử của Arr cũng = 5
Một ví dụ khác
Dim Arr(5)
Thì UBound(Arr) sẽ = 5 ---> chính là chỉ số thứ tự cuối cùng của mảng Arr nhưng tổng số phần tử của Arr lại = 6 (vì chỉ số đầu tiên của Arr trong trường hợp này bắt đầu bằng 0 chứ không bằng 1 như ví dụ trên)
Ngược với Ubound là Lbound, nó dùng để xác định chỉ số thứ tự đầu tiên của mảng
-----------
So sánh 2 "em" Count và Ubound này có thể mường tượng như khi so sánh hàm ROW và ROWS ấy (ROW là chỉ số dòng trong khi ROWS là tổng số dòng)
 
Lần chỉnh sửa cuối:
Upvote 0
Tức là khi khai báo biến thằng nào chắc chắn là mảng thì khai báo VD: Dim Dic As Range, nếu biết chắc chắn là Long thì khai báo long, còn các cái khác cứ để chung chung không nói gì thì nó tự hiểu là Variant hả thày?
 
Upvote 0
Đúng cả, trừ cái này
Tức là khi khai báo biến thằng nào chắc chắn là mảng thì khai báo VD: Dim Dic As Range
Chắc chắc là mảng thì phải Dim Dic() hoặc Dim Dic hoặc Dim Dic as Variant
Còn nếu chắc chắn là Range thì mới.. As Range chứ
 
Upvote 0
Tức là khi khai báo biến thằng nào chắc chắn là mảng thì khai báo VD: Dim Dic As Range, nếu biết chắc chắn là Long thì khai báo long, còn các cái khác cứ để chung chung không nói gì thì nó tự hiểu là Variant hả thày?
Không đúng
.....thằng nào chắc chắn là mảng thì khai báo VD: Dim Dic As Range...
range không phải là biến kiểu mảng mà là một trong các kiểu biến Object
.....còn các cái khác cứ để chung chung không nói gì thì nó tự hiểu là Variant......
cứ để thế thì biến là empty chứ không phải Variant
Khi bạn khai báo Dim trungvdb thì biến trungvdb là Empty
Nếu bạn gán trungvdb =1 thì trungvdb là Integer
Nếu bạn gán trungvdb ="Concogia" thì trungvdb là String
Nếu bạn gán trungvdb =Range("A1:A100") thì trungvdb là Variant
Nếu bạn gán Set trungvdb =Range("A1:A100") thì trungvdb là Range
Híc
 
Upvote 0
Không đúng

cứ để thế thì biến là empty chứ không phải Variant
Khi bạn khai báo Dim trungvdb thì biến trungvdb là Empty
Nếu bạn gán trungvdb =1 thì trungvdb là Integer
Nếu bạn gán trungvdb ="Concogia" thì trungvdb là String
Nếu bạn gán trungvdb =Range("A1:A100") thì trungvdb là Variant
Nếu bạn gán Set trungvdb =Range("A1:A100") thì trungvdb là Range
Híc

Không đúng (sic)
Không khai báo kiểu thì biến nhận kiểu variant, và giá trị ban đầu là không có (empty)

Cái này là rất, rất, rất căn bản:

Cú pháp khai báo biến:

Dim <VarName> [As <VarType>]
Dim <tên biến> [As <kiểu>]

Kiểu có nhiều loại, trong đó có kiểu variant, kính thưa quan viên hai họ!
trong dấu [...] là có thể bỏ qua, nếu bỏ qua, thì là kiểu variant, kính thưa 2 bác Cò!
 
Lần chỉnh sửa cuối:
Upvote 0
Không đúng (sic)
Không khai báo kiểu thì biến nhận kiểu variant, và giá trị ban đầu là không có (empty)

Cái này là rất, rất, rất căn bản:

Cú pháp khai báo biến:

Dim <VarName> [As <VarType>]
Dim <tên biến> [As <kiểu>]

Kiểu có nhiều loại, trong đó có kiểu variant, kính thưa quan viên hai họ!
trong dấu [...] là có thể bỏ qua, nếu bỏ qua, thì là kiểu variant, kính thưa 2 bác Cò!
Híc
Đúng là nhầm, hổng sao, hột vịt còn lộn mà ( chẳng bao giờ khai báo kiểu biến trong code của mình mà vẫn lộn)
Khi không khai báo thì không có giá trị ban đầu của biến, sau đó muốn gán kiểu quái gì thì gán
Thanks Lão Chết Tiệt
Híc
 
Upvote 0
Còn cái này:

Tức là khi khai báo biến thằng nào chắc chắn là mảng thì khai báo ..., nếu biết chắc chắn là Long thì khai báo long, còn các cái khác cứ để chung chung không nói gì thì nó tự hiểu là Variant hả thày?

Không phải chắc chắn "nó" (biến nào) là String hoặc chắc chắn "nó" là Long; mà là chắc chắn mình muốn sử dụng "nó" (biến nào) là String hay sử dụng biến nào là Long.

Tương tự, ta muốn sử dụng tuỳ ý 1 biến nào đó tương ứng với bất kỳ kiểu dữ liệu nào gán vào, thì khai báo kiểu variant, hoặc không khai báo kiểu.

Ta khai báo, là ta chủ động bắt "nó" là kiểu nào, chứ không phải bị "nó" áp đặt.

Dù là đã hiểu rồi, cũng phải phát biểu cho chính xác.
 
Lần chỉnh sửa cuối:
Upvote 0
Híc...Cảm ơn các thày, thế mà từ trước đến nay tôi toàn hiểu khái niệm Range và Mảng là giống nhau.

Tôi tự hỏi: Khi đã có Range là đủ, sao cần có mảng nữa. Bởi theo cá nhân tôi hiểu, nếu xét về mặt tính chất thì Range rộng hơn mảng (tựa như trong Toán học thì tập hợp R là tập hợp số thực > tập Q là tập hợp số hữu tỷ).
Phải chăng do Mảng có tính "cơ động" hơn là Range?

Nếu có thể xin các thày hướng dẫn cụ thể cho cho chút nữa, đó là bản chất của Rangemảng khác nhau như thế nào, chúng tương tác với nhau ra sao?
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu có thể xin các thày hướng dẫn cụ thể cho cho chút nữa, đó là bản chất của Rangemảng khác nhau như thế nào, chúng tương tác với nhau ra sao?
Range là một vùng trên Sheet còn mảng là 1 vùng ảo được lưu trử trong bộ nhớ củamáy khi ta viết code mà muốn vùng ảo thành vùng thật thì ta phải gán xuống sheet để thấy giá trị của chúng
 
Upvote 0
Híc...Cảm ơn các thày, thế mà từ trước đến nay tôi toàn hiểu khái niệm Range và Mảng là giống nhau.

Tôi tự hỏi: Khi đã có Range là đủ, sao cần có mảng nữa. Bởi theo cá nhân tôi hiểu, nếu xét về mặt tính chất thì Range rộng hơn mảng (tựa như trong Toán học thì tập hợp R là tập hợp số thực > tập Q là tập hợp số hữu tỷ).
Phải chăng do Mảng có tính "cơ động" hơn là Range?

Nếu có thể xin các thày hướng dẫn cụ thể cho cho chút nữa, đó là bản chất của Rangemảng khác nhau như thế nào, chúng tương tác với nhau ra sao?

Range là tập hợp tất cả các giá trị, định dạng, công thức, sự kiện, thuộc tính, v.v... Range là cái ta có thể nhìn thấy trực tiếp trên Sheet.

Mảng là tập hợp các phần tử chứa giá trị. Mảng chứa trong bộ nhớ tạm, chúng ta không thể thấy, tạm gọi là giá trị ảo.

Vì Range bao gồm tất cả các tập hợp trên nên khi xử lý trực tiếp trong Range sẽ bị chậm hơn so với mảng vì mảng chỉ có chứa tập hợp là giá trị. Vì vậy, khi xử lý dữ liệu, người ta thường dùng mảng để xử lý trước rồi gán xuống sheet mà không làm trực tiếp trên sheet sẽ cho tốc độ chậm.

Trên đây là theo sự hiểu biết của mình, hy vọng bạn sẽ hiểu về nó.
 
Upvote 0
Híc...Cảm ơn các thày, thế mà từ trước đến nay tôi toàn hiểu khái niệm Range và Mảng là giống nhau.

Tôi tự hỏi: Khi đã có Range là đủ, sao cần có mảng nữa. Bởi theo cá nhân tôi hiểu, nếu xét về mặt tính chất thì Range rộng hơn mảng (tựa như trong Toán học thì tập hợp R là tập hợp số thực > tập Q là tập hợp số hữu tỷ).
Phải chăng do Mảng có tính "cơ động" hơn là Range?

Nếu có thể xin các thày hướng dẫn cụ thể cho cho chút nữa, đó là bản chất của Rangemảng khác nhau như thế nào, chúng tương tác với nhau ra sao?
Chính vì nó "rộng" hơn (như bạn nói) nên nó phải ôm đồm nhiều thứ, dẫn đến nó sẽ xử lý dữ liệu chậm hơn
Vậy nên, những bài toán liên quan đến xử lý dữ liệu (không quan tâm đến format, chỉ quan tâm giá trị), nếu chuyển về mảng để xử lý sẽ nhanh hơn
Xử lý mảng khó hơn, vì chúng chẳng có bất cứ thuộc tính nào như range nhưng cũng vì thế mà nhanh hơn
Việc chuyển từ Range sang mảng hoặc ngược lại rất đơn giản, chỉ là Arr = Range("...").Value hoặc Range("...").Value = Arr
Lưu ý thêm rằng: mảng do range chuyển vào sẽ luôn là mảng 2 chiều (Range nằm trên 1 "mặt phẳng", đương nhiên phải 2 chiều rồi)
Ẹc... Ẹc...
 
Upvote 0
Chính vì nó "rộng" hơn (như bạn nói) nên nó phải ôm đồm nhiều thứ, dẫn đến nó sẽ xử lý dữ liệu chậm hơn
Vậy nên, những bài toán liên quan đến xử lý dữ liệu (không quan tâm đến format, chỉ quan tâm giá trị), nếu chuyển về mảng để xử lý sẽ nhanh hơn
Xử lý mảng khó hơn, vì chúng chẳng có bất cứ thuộc tính nào như range nhưng cũng vì thế mà nhanh hơn
Việc chuyển từ Range sang mảng hoặc ngược lại rất đơn giản, chỉ là Arr = Range("...").Value hoặc Range("...").Value = Arr
Lưu ý thêm rằng: mảng do range chuyển vào sẽ luôn là mảng 2 chiều (Range nằm trên 1 "mặt phẳng", đương nhiên phải 2 chiều rồi)
Ẹc... Ẹc...
Vì mới bập bẹ về mảng nên câu hỏi hơi bị "ngu":
Ví dụ gán Mảng Arr = Range("A4:E15").Value
Dùng hàm gì để biết mảng 2 chiều Arr có 1 chiều = 12 phần tử, một chiều = 5 phần tử, số phần tử trong mảng là 60?
 
Upvote 0
Vì mới bập bẹ về mảng nên câu hỏi hơi bị "ngu":
Ví dụ gán Mảng Arr = Range("A4:E15").Value
Dùng hàm gì để biết mảng 2 chiều Arr có 1 chiều = 12 phần tử, một chiều = 5 phần tử, số phần tử trong mảng là 60?
Anh dùng hàm Ubound. Thí nghiệm với MsgBox UBound(Arr, 1) và MsgBox UBound(Arr, 2)
 
Upvote 0
Anh dùng hàm Ubound. Thí nghiệm với MsgBox UBound(Arr, 1) và MsgBox UBound(Arr, 2)
Lưu ý cái này nha:
- UBound không phải tổng số phần tử mà là chỉ số thứ tự phần tử cuối cùng
- Tương tự LBound là chỉ số thứ tự phần tử đầu tiên
Với Option Base 0 thì STT phần tử đầu tính từ 0, vì thí tổng số phần tử sẽ = UBound(...) +1
Với mảng gán từ range thì Base luôn = 1 nên khỏi phải cộng thêm 1
Nói thế để mai này khỏi bị nhầm
 
Upvote 0
Sau khi nghiên cứu về mảng, tôi tự làm bài đầu tiên như sau mà chạy không nổi, chẳng biết sai ở đâu, xin hãy chỉ giúp.

PHP:
Sub Loc()
Dim DL As Range, Arr(), KQ(), i As Long, j As Long
DL = Range([A1], [A65000].End(xlUp))
Arr = DL.Value
For i = 1 To UBound(Arr, 1)
j = 1
If Arr(i, 1) <> "" Then
KQ(j, 1) = Arr(i, 1)
j = j + 1
Next i
Range("B1:B10").Value = KQ
End Sub
 
Upvote 0
Sau khi nghiên cứu về mảng, tôi tự làm bài đầu tiên như sau mà chạy không nổi, chẳng biết sai ở đâu, xin hãy chỉ giúp.

PHP:
Sub Loc()
Dim DL As Range, Arr(), KQ(), i As Long, j As Long
DL = Range([A1], [A65000].End(xlUp))
Arr = DL.Value
For i = 1 To UBound(Arr, 1)
j = 1
If Arr(i, 1) <> "" Then
KQ(j, 1) = Arr(i, 1)
j = j + 1
Next i
Range("B1:B10").Value = KQ
End Sub
Bạn phải đặt dòng j = 1 ra ngoài vòng lặp thì mới được. Vì bạn đặt dòng đó trong vòng lặp nên cứ mỗi lần duyệt qua 1 phần tử của mảng Arr thì j lại được gán lại giá trị bằng 1. Vì vậy dữ liệu luôn được gán vào phần tử đầu tiên của mảng KQ
 
Upvote 0
Ngoài lỗi đó ra thì chắc vẫn còn lỗi gì đó anh ah, vì tôi đã sửa như anh nói mà chạy vẫn không được

PHP:
Sub Loc()
Dim DL As Range, Arr(), KQ(), i As Long, j As Long
DL = Range([A1], [A65000].End(xlUp))
Arr = DL.Value
j = 1
For i = 1 To UBound(Arr, 1)
If Arr(i, 1) <> "" Then
KQ(j, 1) = Arr(i, 1)
j = j + 1
Next i
Range("B1:B10").Value = KQ
End Sub
 
Upvote 0
- Biến DL khai báo là Range, và gán giá trị cho nó là 1 Range, thì phải có Set
- Thực ra cũng không cần qua trung gian DL, có thể gán thẳng giá trị cho Arr bằng giá trị của 1 range
- Có If nhưng không có End If
- Array KQ chưa có kích thước.
 
Upvote 0
Ngoài lỗi đó ra thì chắc vẫn còn lỗi gì đó anh ah, vì tôi đã sửa như anh nói mà chạy vẫn không được

PHP:
Sub Loc()
Dim DL As Range, Arr(), KQ(), i As Long, j As Long
DL = Range([A1], [A65000].End(xlUp))
Arr = DL.Value
j = 1
For i = 1 To UBound(Arr, 1)
If Arr(i, 1) <> "" Then
KQ(j, 1) = Arr(i, 1)
j = j + 1
Next i
Range("B1:B10").Value = KQ
End Sub
Sai nhiều quá
Sửa vầy mới đúng:
PHP:
Sub Loc()
  Dim Arr, KQ(), i As Long, j As Long
  Arr = Range([A1], [A65000].End(xlUp)).Value
  ReDim KQ(1 To UBound(Arr, 1), 1 To 1)
  For i = 1 To UBound(Arr, 1)
    If Arr(i, 1) <> "" Then
      j = j + 1
      KQ(j, 1) = Arr(i, 1)
    End If
  Next
  Range("B1").Resize(j).Value = KQ
End Sub
 
Upvote 0
Cảm ơn thày nhiều, thế mà tôi cứ tưởng j chạy đến đâu thì kích thước mảng kết quả sẽ tự thay đổi theo đó?

Xin cho phép hỏi thêm chút nữa là nếu trong Code

PHP:
Sub Loc()
  Dim Arr, KQ(), i As Long, j As Long
  Arr = Range([A1], [A65000].End(xlUp)).Value
  ReDim KQ(1 To UBound(Arr, 1), 1 To 1)
  For i = 1 To UBound(Arr, 1)
    If Arr(i, 1) <> "" Then
      j = j + 1
      KQ(j, 1) = Arr(i, 1)
    End If
  Next
  Range("B1").Resize(j).Value = KQ
End Sub

Bây giờ tôi thay "em Rờ Đim" tức dòng ReDim KQ(1 To UBound(Arr, 1), 1 To 1) bằng Dim KQ(1 To UBound(Arr, 1), 1 To 1) thì sao?
--------------
Nếu ReDim KQ có tính co dãn, tôi hiểu không biết có đúng không: Tức là khai báo tại ban đầu ReDim KQ(1 To UBound(Arr, 1), 1 To 1) nó chỉ là kích thước "tạm thời" (kiểu như dự toán vậy), sau này kích thước mảng KQ khi chạy hết vòng lặp đuợc xác định quyết toán theo thực tế?

(Ví dụ ban đầu KQ ban đầu khai báo ReDim nó tạm thời là mảng 2 chiều có 10 dòng, 1cột tức KQ (10,1), nhưng sau khi bỏ qua 4 ô trống lúc này j = 6 thôi thì lúc này KQ(6,1) mới là kích thước thật?

Nếu có gì sai, xin thày chỉ bảo cho.
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn thày nhiều, thế mà tôi cứ tưởng j chạy đến đâu thì kích thước mảng kết quả sẽ tự thay đổi theo đó?

Xin cho phép hỏi thêm chút nữa là nếu trong Code

PHP:
Sub Loc()
  Dim Arr, KQ(), i As Long, j As Long
  Arr = Range([A1], [A65000].End(xlUp)).Value
  ReDim KQ(1 To UBound(Arr, 1), 1 To 1)
  For i = 1 To UBound(Arr, 1)
    If Arr(i, 1) <> "" Then
      j = j + 1
      KQ(j, 1) = Arr(i, 1)
    End If
  Next
  Range("B1").Resize(j).Value = KQ
End Sub

Bây giờ tôi thay "em Rờ Đim" tức dòng ReDim KQ(1 To UBound(Arr, 1), 1 To 1) bằng Dim KQ(1 To UBound(Arr, 1), 1 To 1) thì sao?
--------------
Nếu ReDim KQ có tính co dãn, tôi hiểu không biết có đúng không: Tức là khai báo tại ban đầu ReDim KQ(1 To UBound(Arr, 1), 1 To 1) nó chỉ là kích thước "tạm thời" (kiểu như dự toán vậy), sau này kích thước mảng KQ khi chạy hết vòng lặp đuợc xác định quyết toán theo thực tế?

(Ví dụ ban đầu KQ ban đầu khai báo ReDim nó tạm thời là mảng 2 chiều có 10 dòng, 1cột tức KQ (10,1), nhưng sau khi bỏ qua 4 ô trống lúc này j = 6 thôi thì lúc này KQ(6,1) mới là kích thước thật?

Nếu có gì sai, xin thày chỉ bảo cho.
Mảng hơi khó "nhai" trong mấy vụ "rờ đim" này đấy
Ví dụ:
Mã:
Dim KQ(1 to 10,  1 to 1)[/B]
sẽ không có vấn đề gì, nhưng nếu viết
Mã:
[/B]
[B]n = 5[/B]
[B]ReDim KQ(1 to n, 1 to 1)[/B][B]
thì VBA nó cóc chịu
Khai báo mảng ban đầu phải là 1 số cụ thể nào đó, không thể cho biến vào được
Ở trường hợp bên dưới, phải viết vầy mới được
Mã:
[/B]
[B]Dim KQ()[/B]
[B]n = 5[/B]
[B]ReDim KQ(1 to n, 1 to 1)[/B][B]
Tức khai báo trước, xong muốn "rờ.." cái gì thì "rờ..."
 
Upvote 0
Mảng hơi khó "nhai" trong mấy vụ "rờ đim" này đấy
Ví dụ:
Mã:
Dim KQ(1 to 10,  1 to 1)
sẽ không có vấn đề gì, nhưng nếu viết
Mã:
[B]n = 5[/B]
[B]ReDim KQ(1 to n, 1 to 1)[/B]
thì VBA nó cóc chịu
Khai báo mảng ban đầu phải là 1 số cụ thể nào đó, không thể cho biến vào được
Ở trường hợp bên dưới, phải viết vầy mới được
Mã:
[B]Dim KQ()[/B]
[B]n = 5[/B]
[B]ReDim KQ(1 to n, 1 to 1)[/B]
Tức khai báo trước, xong muốn "rờ.." cái gì thì "rờ..."

Rắc rối quá nhỉ, thế để cho tổng quát ban đầu sao mình không cho nó lớn hết cỡ đi ví dụ
ReDim KQ(1 to 65536, 1 to 1) chẳng hạn, lúc đó sẽ chẳng cần quan tâm đến cái anh Arr làm chi.
 
Upvote 0
Rắc rối quá nhỉ, thế để cho tổng quát ban đầu sao mình không cho nó lớn hết cỡ đi ví dụ
ReDim KQ(1 to 65536, 1 to 1) chẳng hạn, lúc đó sẽ chẳng cần quan tâm đến cái anh Arr làm chi.
Làm vậy cũng được mà nó sẽ tốn bộ nhớ máy tính bạn ah khi làm việc sẽ chậm hơn
 
Upvote 0

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

Back
Top Bottom