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

Liên hệ QC

viehoai

Thành viên gắn bó
Tham gia
22/5/09
Bài viết
2,599
Được thích
2,908
Xin các anh chị giúp đỡ Code Gán các giá trị của một Range là các phần tử của Mãng
Ví dụ: Tôi có các giá trị của Range("A1:A10"). Tôi muốn viết code để gán giá trị của các cells từ A1:A10 là các phần tử của Mãng Arr chẳn hạn.
Xin cảm ơn các anh chị
 
Em lại có ví dụ sau để học mảng
- Sheet 1 có dữ liệu từ A1:C10
- Trong một hàng dữ liệu (ví dụ từ A1:C1) chỉ được nhận là trống hết, nếu đã điền, thì phải điền đủ dữ liệu
Ví dụ:
- TH1: Điền hết dữ liệu
Cột A------Cột B----------Cột C
TM..... 09/03/2012--------201203
- TH2: để trống hết
Cột A------Cột B----------Cột C
..............................................

Yêu cầu
Dùng mảng để duyệt những dòng điền dữ liệu không đủ

Em có đoạn code sau như nó báo lỗi "Object required"
PHP:
Sub blank()
Dim sArr()
    sArr = Sheet1.Range("A1:A10").Value
    
    For i = 1 To UBound(sArr) 
        If WorksheetFunction.CountBlank(sArr(i, 1).Resize(, 3)) <> 3 Then
             MsgBox "Sheet1 dong thu" & i & " chua dien du thong tin "
        End If
   Next i
End Sub

Anh/Chị xem giúp em với ạh?
 
Upvote 0
Em lại có ví dụ sau để học mảng
- Sheet 1 có dữ liệu từ A1:C10
- Trong một hàng dữ liệu (ví dụ từ A1:C1) chỉ được nhận là trống hết, nếu đã điền, thì phải điền đủ dữ liệu
Ví dụ:
- TH1: Điền hết dữ liệu
Cột A------Cột B----------Cột C
TM..... 09/03/2012--------201203
- TH2: để trống hết
Cột A------Cột B----------Cột C
..............................................

Yêu cầu
Dùng mảng để duyệt những dòng điền dữ liệu không đủ

Em có đoạn code sau như nó báo lỗi "Object required"
PHP:
Sub blank()
Dim sArr()
    sArr = Sheet1.Range("A1:A10").Value
    
    For i = 1 To UBound(sArr) 
        If WorksheetFunction.CountBlank(sArr(i, 1).Resize(, 3)) <> 3 Then
             MsgBox "Sheet1 dong thu" & i & " chua dien du thong tin "
        End If
   Next i
End Sub

Anh/Chị xem giúp em với ạh?
Đơn giản vì COUNTBLANK chỉ làm việc với Range, không làm việc với mảng đâu
Thêm nữa sArr(i, 1).Resize(, 3) là sai cú pháp ---> Mảng không cho phép Resize (chỉ dùng được Resize với Range mà thôi)
 
Upvote 0
Ẹc
Em sửa lại thành, code chạy veo véo
PHP:
Sub blank()
Dim sArr()
    sArr = Sheet1.Range("A1:C10").Value
    
    For i = 1 To UBound(sArr, 1) ' 1 la chieu thu nhat de phan biet chieu thu 2
        If sArr(i, 1) = "" And sArr(i, 2) = "" And sArr(i, 3) = "" Then
             MsgBox "Sheet1 dong thu" & i & " chua dien du thong tin "
             Exit Sub
        End If
   Next i
End Sub
 
Upvote 0
Ẹc
Em sửa lại thành, code chạy veo véo
PHP:
Sub blank()
Dim sArr()
    sArr = Sheet1.Range("A1:C10").Value
    
    For i = 1 To UBound(sArr, 1) ' 1 la chieu thu nhat de phan biet chieu thu 2
        If sArr(i, 1) = "" And sArr(i, 2) = "" And sArr(i, 3) = "" Then
             MsgBox "Sheet1 dong thu" & i & " chua dien du thong tin "
             Exit Sub
        End If
   Next i
End Sub
Nếu có 20 cột thì bạn AND bằng cách nào đây?
Ẹc... Ẹc...
 
Upvote 0
Hai cách viết sau có hoàn toàn giống nhau không

Em có 2 Code sau
PHP:
Sub loc()
    Dim sArr(), Arr(), i As Long, j As Long
    sArr = Sheet1.Range("A1:A100").Value
    ReDim Arr(1 To UBound(sArr, 1), 1 To 1)
    For i = 1 To UBound(sArr, 1)
        If sArr(i, 1) > 0 Then
            j = j + 1
            Arr(j, 1) = sArr(i, 1)
        Sheet1.[B1].Resize(j).Value = Arr
        End If
    Next
End Sub

PHP:
Sub loc()
    Dim sArr(), Arr(), i As Long, j As Long
    sArr = Sheet1.Range("A1:A100").Value
    ReDim Arr(1 To UBound(sArr, 1), 1 To 1)
    For i = 1 To UBound(sArr, 1)
        If sArr(i, 1) > 0 Then
            j = j + 1
            Arr(j, 1) = sArr(i, 1)
        End If
    Next
    Sheet1.[B1].Resize(j).Value = Arr
End Sub

Em xin hỏi nó có giống nhau hoàn toàn về mọi phương diện tính toán không?

(Em test thấy kết quả như nhau)
 
Upvote 0
Em có 2 Code sau
PHP:
Sub loc()
    Dim sArr(), Arr(), i As Long, j As Long
    sArr = Sheet1.Range("A1:A100").Value
    ReDim Arr(1 To UBound(sArr, 1), 1 To 1)
    For i = 1 To UBound(sArr, 1)
        If sArr(i, 1) > 0 Then
            j = j + 1
            Arr(j, 1) = sArr(i, 1)
        Sheet1.[B1].Resize(j).Value = Arr
        End If
    Next
End Sub

PHP:
Sub loc()
    Dim sArr(), Arr(), i As Long, j As Long
    sArr = Sheet1.Range("A1:A100").Value
    ReDim Arr(1 To UBound(sArr, 1), 1 To 1)
    For i = 1 To UBound(sArr, 1)
        If sArr(i, 1) > 0 Then
            j = j + 1
            Arr(j, 1) = sArr(i, 1)
        End If
    Next
    Sheet1.[B1].Resize(j).Value = Arr
End Sub

Em xin hỏi nó có giống nhau hoàn toàn về mọi phương diện tính toán không?

(Em test thấy kết quả như nhau)
Kết quả giống nhau nhưng code thứ 2 sẽ nhanh hơn:
- Code thứ nhất, cứ lập 1 lần thì gán dữ liệu vào sheet
- Code thứ hai, làm xong vòng lập mới gán 1 lần vào sheet
------------
Hãy test với dữ liệu 10000 dòng trở lên để cảm nhận sự khác nhau về tốc độ 2 code nhé
 
Upvote 0
Hai code trên giống nhau về việc xử lý dữ liệu nguồn cho ra dữ liệu kết quả (có tính toán gì đâu?)

Nhưng khác nhau ở trình tự gán xuống sheet.
Code 1: Mỗi vòng lặp thoả điều kiện sẽ gán xuống 1 lần, lần sau ghi đè lên lần trước, lần 1 chỉ có 1 ô có dữ liệu, còn toàn là gán ô trống, lần sau ít ô trống hơn, và lần cuối là dữ liệu kết quả đầy đủ nhất.
Code 2: Chỉ gán xuống sheet 1 lần khi kết quả đã đầy đủ.
 
Upvote 0
Nhờ các pác giải thích dùm đoạn code trong bài tổng hợp số liệu

Em chưa hiểu được dòng lệnh With .Resize(.Rows.Count - 1, .Columns.Count - 1) trong Code

PHP:
Option Explicit
Private Sub Worksheet_Activate()
  Dim Sh As Worksheet
  Application.ScreenUpdating = False
  Range("A2:C10000").ClearContents
  For Each Sh In Worksheets
    If Sh.Name <> "Tonghop" Then
      With Sh.Range("A1").CurrentRegion.Offset(1, 1)
        With .Resize(.Rows.Count - 1, .Columns.Count - 1)
          Range("B65536").End(xlUp)(2).Resize(.Rows.Count, .Columns.Count).Value = .Value
        End With
      End With
    End If
  Next Sh
  Range("A1").SpecialCells(4).Value = Evaluate("=Row(R1:R1000)")
  Application.ScreenUpdating = True
End Sub

Nhờ các bác giúp em hiểu về nó
Em xin cảm ơn
 
Upvote 0
Em chưa hiểu được dòng lệnh With .Resize(.Rows.Count - 1, .Columns.Count - 1) trong Code
Nhờ các bác giúp em hiểu về nó
Em xin cảm ơn

Resize nó giống như bạn dùng phím shift với các phím mũi tên lên xuống trái phải vậy đó bạn muốn kéo bao nhiêu cột, dòng thì nhấn phím lên xuống trái phải theo ý muốn, bạn tìm mấy bài của chú SA có nói kỹ về đó lắm Thuộc tính Resize của đối tượng Range trong VBA
 
Upvote 0
Cám ơn bác nmhung49, về thuộc tính Resize thì em có biết nhưng em thắc mắc là tại sao nó mở rộng ra số dòng và số cột With .Resize(.Rows.Count - 1, .Columns.Count - 1) , tức là đoạn em bôi đen đấy ah.

Bởi em thấy dòng ngay trên nó
PHP:
With Sh.Range("A1").CurrentRegion.Offset(1, 1)
đã là toàn bộ vùng cần Copy sang rồi, sao còn mở rộng thêm làm gì nữa nhỉ?
 
Upvote 0
Bạn phải căn cứ vào đoạn code này mới đúng
PHP:
With .Resize(.Rows.Count - 1, .Columns.Count - 1) 
      Range("B65536").End(xlUp)(2).Resize(.Rows.Count, .Columns.Count).Value = .Value 
End With

Tức là vùng bạn muốn paste giá trị copy phải bằng vùng bạn copy nếu bạn không resize bằng vùng bạn copy thì khi paste sẽ thiếu

Bạn có thể thí nghiệm đoạn code này bạn hiểu rõ
PHP:
Sub Rest()
     Range("E4:F10").Value = Range("A4:C10").Value
End Sub

Mà cái Topic này thắc mắc về mảng bạn nên post vào topic những thắc mắc về code nhen. Thân chào!!!
 
Upvote 0
Xin hỏi mảng Gom trong Code sau có ý nghĩa thế nào

Em xem ví dụ đính kèm mà vẫn chưa hiểu Mảng Gom nhằm để làm gì, xin được giải thích giúp

PHP:
Public Sub SapXep()
    Dim Vung, I, Gom, Mg(), K, d
    Set d = CreateObject("scripting.dictionary")
    Vung = Range([A2], [A50000].End(xlUp)).Resize(, 3)
    ReDim Mg(1 To UBound(Vung) * 3, 1 To 1)
        For I = 1 To UBound(Vung)
            Gom = Vung(I, 1) & Vung(I, 2)
                If Not d.exists(Vung(I, 1)) And Not d.exists(Gom) Then
                    K = K + 1
                    d.Add Vung(I, 1), K
                    Mg(K, 1) = Vung(I, 1)
                    K = K + 1
                    d.Add Gom, K
                    Mg(K, 1) = Vung(I, 2)
                    K = K + 1
                    Mg(K, 1) = Vung(I, 3)
                ElseIf d.exists(Vung(I, 1)) And Not d.exists(Gom) Then
                    K = K + 1
                    d.Add Gom, K
                    Mg(K, 1) = Vung(I, 2)
                    K = K + 1
                    Mg(K, 1) = Vung(I, 3)
                Else
                    K = K + 1
                    Mg(K, 1) = Vung(I, 3)
                End If
        Next I
    [F2:F10000].ClearContents
    [F2].Resize(K) = Mg
End Sub
 

File đính kèm

  • Sap xep.xls
    33 KB · Đọc: 52
Upvote 0
Tại sao mảng 1 chiều không chứa được biến?

Tôi có thủ tục sau:

Mã:
Sub FillArray()
    Dim MyRng As Range, n As Long, i As Long
    Set MyRng = Range(Source.[A2], Source.[A100].End(xlUp))
    n = MyRng.Rows.Count - 1
    [SIZE=3][COLOR=#0000cd][B]Dim ArrKhoiLuong([/B][/COLOR][COLOR=#ff0000][B]n[/B][/COLOR][COLOR=#0000CD][B]) As String[/B][/COLOR][/SIZE]
    For i = 0 To n
        ArrKhoiLuong(i) = MyRng(i + 1).Value
    Next
End Sub

Nếu như n = 3 và ghi là Dim ArrKhoiLuong(3) As String thì được, còn để vào n thì báo lỗi.
 
Upvote 0
Em xem ví dụ đính kèm mà vẫn chưa hiểu Mảng Gom nhằm để làm gì, xin được giải thích giúp

Nhìn thấy thủ tục của bạn, theo tôi, GOM không phải là mảng, mà là giá trị được ghép với nhau để tạo thành Key mà thôi.
 
Upvote 0
Tại sao mảng 1 chiều không chứa được biến?

Tôi có thủ tục sau:

Mã:
Sub FillArray()
    Dim MyRng As Range, n As Long, i As Long
    Set MyRng = Range(Source.[A2], Source.[A100].End(xlUp))
    n = MyRng.Rows.Count - 1
    [SIZE=3][COLOR=#0000cd][B]Dim ArrKhoiLuong([/B][/COLOR][COLOR=#ff0000][B]n[/B][/COLOR][COLOR=#0000CD][B]) As String[/B][/COLOR][/SIZE]
    For i = 0 To n
        ArrKhoiLuong(i) = MyRng(i + 1).Value
    Next
End Sub

Nếu như n = 3 và ghi là Dim ArrKhoiLuong(3) As String thì được, còn để vào n thì báo lỗi.
Trời!
Cái này nói nhiều lần rồi còn gì
Mảng không thể khai báo kiểu đó được! Muốn gì thì cứ Dim trước, xong sẽ ReDim (hoặc ReDim Preserve) sau đó theo biến
Ví dụ
Mã:
Dim ArrKhoiLuong()
ReDim ArrKhoiLuong(n)
 
Upvote 0
Trời!
Cái này nói nhiều lần rồi còn gì
Mảng không thể khai báo kiểu đó được! Muốn gì thì cứ Dim trước, xong sẽ ReDim (hoặc ReDim Preserve) sau đó theo biến
Ví dụ
Mã:
Dim ArrKhoiLuong()
ReDim ArrKhoiLuong(n)

Uh hen, lâu lâu bị "tẩu hỏa nhập ma", lập đi lập lại thành thói quen, giờ cái cơ bản lại không nhớ! Cám ơn Thầy nha.
 
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

Anh Hùng ơi
Tại sao khi em paste code này và F5 nó ra giá trị = 14 tại Immediate window
Anh giải thích giúp em nhé
 
Upvote 0
Anh Hùng ơi
Tại sao khi em paste code này và F5 nó ra giá trị = 14 tại Immediate window
Anh giải thích giúp em nhé

Thì 14 đúng rồi!
Arr(0) = Array(Array(4, 5, 6), Array(7, 8, 9), Array(10, 11, 12))
Arr(1) = Array(4, Array(13, 14, 15), 6)
===>
Arr(1)(0) = 4
Arr(1)(1) = Array(13, 14, 15)
Arr(1)(2) = 6
===>
Arr(1)(1)(0) = 13
Arr(1)(1)(1) = 14
Arr(1)(1)(2) = 15
-------------
Đương nhiên kết quả trên dựa trên Option Base 0. Nếu là Option Base 1 thì kết quả sẽ khác
 
Lần chỉnh sửa cuối:
Upvote 0
Nhưng anh Ndu đã giải thích có chỗ này bị lỗi anh Ndu sửa lại dùng em chỗ Arr(1)(1)(0) = 15 thành Arr(1)(1)(2) = 15 nhen. Còn dùng Option Base 1 thì sẽ khác rồi bạn cứ nghiên cứu từ từ nhen
 
Upvote 0
nho giup do

Nhờ các anh chị giúp em giải quyết bài toán này ( em có kèm file)
Em có dùng hàm if(and( nhưng chỉ dùng được có 7 lần….. vì em là thanh viên mới nên không biết tìm bài giải của các anh chị ở đâu trên diễn đàn nữa, vui lòng gửi bài giúp em qua mail :quachcongluanadong@gmail.com ( và chỉ giúp em cách tìm bài được đăng ở đâu luôn các anh chị nhé…..để lần sau tự em tìm. Thanks!

Nếu A6> 0 thì AG6=4 nếu A6<1 thì AG6=5
Nếu A6>0, B6<1thì AH6=5, nếu A6<1,B6<1 thì AH6=7, nếu B6>0 thì AH6=4
Nếu A6<1,B6<1,C6<1 thì AI6=10, nếu A6>0,B6<1,C6<1 thì AI6=7, nếu B6>0,C6<1 thì AI6=5, nếu C6>0 thi AI6=4
Tương tự ……
Nếu A6<1,B6<1,C6<1……..AD6<1 thì Bj6=3000, nếu A6>0,B6<1,C6<1……..AD6<1 thì BJ6=2900, nếu B6>0,C6<1,D6<1……..AD6<1 thì BJ6=2700,nếu C6>0,D6<1,E6<1,F6<1……..AD6<1 thì BJ6=2500,
neu D6>0,E6<1,F6<1G6<1……..AD6<1 thì BJ6=2000, điều kiện tương tự như vậy đến khi AD>0 thì BJ6=4.
Nếu từ A6 đến AE6 đều <1 thì AG6=4 và lập lại điều kiện như trên









 

File đính kèm

  • Book1.xls
    15 KB · Đọc: 15
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom