Tìm hiểu về mảng qua code (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

tueyennhi

Thành viên tích cực
Tham gia
18/10/10
Bài viết
1,192
Được thích
105
Em chào anh chị!

Em tham gia diễn đàn đã lâu, và cũng chỉ dừng lại ở hỏi đáp những vấn đề gặp phải (từ chèn ảnh bằng hàm của thầy Ndu, tổng hợp công nhờ anh SA_DQ, anh Bate rồi bạn Befaint giúp đỡ cùng rất nhiều thành viên khác...

Hôm nay em viết bài này lên mong được học hỏi cái cốt lõi để em có thể tự viết cho mình, cụ thể với code làm việc với mảng em thấy nó thật kỳ diệu. Qua chủ đề này em hy vọng bản thân mình cũng như nhiều người có thể hiểu thêm nhiều điều về mảng


Bài viết sẽ dựa trên code thực tiễn, và qua nó để hiểu cách làm việc code là như thế nào. File đính kèm em lấy từ một thành viên trên diễn đàn mình mà không nhớ tên, xin được lượng thứ :)

Option Explicit

Public Sub GPE()
Dim Dic As Object, Ws As Worksheet, sArr(), dArr(1 To 100, 1 To 4)
Dim I As Long, J As Long, K As Long, Rws As Long, Tem As String
Set Dic = CreateObject("Scripting.Dictionary")
For Each Ws In Worksheets
If Ws.Name <> "Data" Then
sArr = Ws.Range("A4", Ws.Range("A4").End(xlDown)).Resize(, 5).Value
For I = 1 To UBound(sArr)
Tem = sArr(I, 1) & "#" & sArr(I, 2) & "#" & sArr(I, 5)
If Not Dic.Exists(Tem) Then
K = K + 1
Dic.Add Tem, K
dArr(K, 1) = sArr(I, 1)
dArr(K, 2) = sArr(I, 2)
dArr(K, 4) = sArr(I, 5)
End If
Rws = Dic.Item(Tem)
dArr(Rws, 3) = dArr(Rws, 3) + sArr(I, 4)
Next I
End If
Next Ws
With Sheets("Data")
.Range("C5:F100").ClearContents
.Range("C5:F5").Resize(K) = dArr
.Range("A5:F5").Resize(K).Borders.LineStyle = 1
End With
Set Dic = Nothing
End Sub

Mong mọi người giải đáp giúp em hiểu code trên.
 
Lần chỉnh sửa cuối:
Khuyên bạn 2 việc:

1. đem đề tài này hỏi ở thớt "các câu hỏi về mảng trong VBA"

2. bạn cho biết code trên làm cái gì, và vì sao bạn chọn nó rồi mới dễ giải thích. Nếu chỉ muốn học về mảng thì còn nhiều code dễ học hơn.
 
Upvote 0
Khuyên bạn 2 việc:

1. đem đề tài này hỏi ở thớt "các câu hỏi về mảng trong VBA"

2. bạn cho biết code trên làm cái gì, và vì sao bạn chọn nó rồi mới dễ giải thích. Nếu chỉ muốn học về mảng thì còn nhiều code dễ học hơn.

Cảm ơn bạn.

Code trên tổng hợp dữ liệu các sheet vào sheet Data dựa vào ba yếu tố Mã ERP, Diễn giải và đơn vị
Nếu 3 yếu tố trên trùng lặp giữa các sheet thì sẽ được cộng chung lại vào sheet Data, còn nếu 1 trong 3 yếu tố trên khác nhau thì sẽ được ghi dữ liệu riêng. Ví dụ trong sheet 1, 2, 3... Mã ERP đều là 123, Diễn giải là abc và Đơn vị là m thì trong sheet Data sẽ cộng tổng lại ở cột số lượng cho vào sheet Data. Nếu mình nói khó hiểu mong mọi người góp ý.

Mình cũng đã đọc các chủ đề về mảng nhưng không hiểu được nhiều, tuy nhiên mình có thể dựa vào những thứ đã có kèm theo hướng dẫn cụ thể thì có thể biến nó thành cái của mình phục vụ nhiều thứ khác nhau.

Mình nói qua sự hiểu của mình ở đoạn code trên nhé

Dòng lệnh Tem = sArr(I, 1) & "#" & sArr(I, 2) & "#" & sArr(I, 5)
theo mình nghĩ nó là lấy các giá trị ở cột 1, 2 và 5 để làm key

dArr(K, 1) = sArr(I, 1)
dArr(K, 2) = sArr(I, 2)
dArr(K, 4) = sArr(I, 5)

Gán các giá trị đó vào cột 1, 2 và 4 sheet Data

Mình chỉ hiểu có vậy mong mọi người chỉ dạy!
 
Upvote 0
đồng ý với bác chủ thớt là đọc code có sẵn cũng là 1 cách học , nhưng để biến nó thành của mình thì phải có thời gian ngâm cứu !
giống như lái xe phải tìm hiểu đc tính năng của nó trước thì lái mới đảm bảo an toàn ^
---------------------------------------------------------------------
đoạn code này mình rút ra đc mấy ý .
sArr = Ws.Range("A4", Ws.Range("A4").End(xlDown)).Resize(, 5).Value

---------------------------------------------------------------------
1 ) 2 mảng 2 chiều có thể gán cho nhau ,
như ví dụ khai báo mảng và gán trực tiếp ra lưới , từ lưới đọc ngược lại , và lại xuất ra


Mã:
Sub test_()


        Dim dArr(5, 5) As Integer
        Dim eArr()
        
        ' gan gia tri vao mang
        dArr(0, 0) = 1
        dArr(1, 1) = 2
        dArr(2, 2) = 3
        dArr(3, 3) = 4
        dArr(4, 4) = 5
        dArr(5, 5) = 6
        
        ' xuat ra luoi excel
        Range("A1:F6") = dArr
        
        'doc tu excel vao lai bo nho
        eArr = Range("A1:F6")         ' hoac [I]Range("A1:F6").Value[/I] cũng duoc
        
        'gan them gia tri
        eArr(1, 5) = 11
        eArr(1, 6) = 22
        eArr(2, 5) = 33
        eArr(2, 6) = 44
        eArr(5, 1) = 55
        eArr(5, 2) = 66
        eArr(6, 1) = 77
        eArr(6, 2) = 88
        
        'xuat lai ra luoi
        Range("A11:F16") = eArr


End Sub

sau khi thử nghiệm mình thấy vị trí bắt đầu của mảng 2 chiều khi đọc vào và xuất ra lệch 1 đơn vị !
----------------------------------------------------------

hàm Resize tính năng của nó cũng hay , có thể coi như 1 range
 
Lần chỉnh sửa cuối:
Upvote 0
Code trên tổng hợp dữ liệu các sheet vào sheet Data dựa vào ba yếu tố Mã ERP, Diễn giải và đơn vị
Nếu 3 yếu tố trên trùng lặp giữa các sheet thì sẽ được cộng chung lại vào sheet Data, còn nếu 1 trong 3 yếu tố trên khác nhau thì sẽ được ghi dữ liệu riêng. Ví dụ trong sheet 1, 2, 3... Mã ERP đều là 123, Diễn giải là abc và Đơn vị là m thì trong sheet Data sẽ cộng tổng lại ở cột số lượng cho vào sheet Data. Nếu mình nói khó hiểu mong mọi người góp ý.

Dòng lệnh Tem = sArr(I, 1) & "#" & sArr(I, 2) & "#" & sArr(I, 5)
theo mình nghĩ nó là lấy các giá trị ở cột 1, 2 và 5 để làm key

dArr(K, 1) = sArr(I, 1)
dArr(K, 2) = sArr(I, 2)
dArr(K, 4) = sArr(I, 5)

Gán các giá trị đó vào cột 1, 2 và 4 sheet Data

Mình chỉ hiểu có vậy mong mọi người chỉ dạy!

Code ở đây dùng tính chất key-value của dictionary để tạo tổng theo key
Dữ liệu thô được đọc vào mảng đầu vào (sArr)
Tổng được ghi vào một mảng kết quả (dArr)

Tem = sArr(I, 1) & "#" & sArr(I, 2) & "#" & sArr(I, 5) ' tạo từ khoá làm key cho dictionary

If Not Dic.Exists(Tem) Then ' dictionary chưa có key này, vậy thì thêm vào
' chu trình gồm có:
K = K + 1 ' tăng số dòng (tức là số keys) lên 1 dòng
Dic.Add Tem, K ' ghi chỉ số dòng này vào dictionary
dArr(K, 1) = sArr(I, 1) ' ghi trị mã số, vân vân vào array kết quả
dArr(K, 2) = sArr(I, 2)
dArr(K, 4) = sArr(I, 5) ' xem lưu ý ở dưới
End If
' đến đây thì dic có chứa key và chỉ số tương ứng trong mảng kết quả
' và dArr thì có chứa các trị mã, cùng với con số tổng (nếu mã mới thì con số này là 0)
Rws = Dic.Item(Tem) ' dùng key để truy cập dic, lấy ra chỉ số dòng của key này trong mảng
dArr(Rws, 3) = dArr(Rws, 3) + sArr(I, 4) ' công số vào tổng trong mảng, xem lưu ý bên dưới
Next I
End If
Next Ws
' đến đây thì đã sử lý xong mảng đầu vào.
' mảng đầu ra đã có đẩy đủ các mã duy nhất cùng con số tổng
With Sheets("Data") ' sheet để chép kết quả
.Range("C5:F100").ClearContents ' dọn chỗ trước cho sạch sẽ
.Range("C5:F5").Resize(K) = dArr ' chép mảng đầu ra vào sheet. Resize(K) bảo đảm là sẽ chép K dòng
.Range("A5:F5").Resize(K).Borders.LineStyle = 1 ' chỗ này là đồ trang trí, không đáng nói
End With

Lưu ý: mảng đầu vào có 5 cột, mảng đầu ra có 4 cột, cột chứa số liệu ở đầu vào là 4, cột chứa tổng số liệu đầu ra là 3
Code này viết trên kiểu mà dân lập trình gọi là "số trên trời rớt xuống" (tiếng nghề: magic numbers)
 
Upvote 0
Code ở đây dùng tính chất key-value của dictionary để tạo tổng theo key
Dữ liệu thô được đọc vào mảng đầu vào (sArr)
Tổng được ghi vào một mảng kết quả (dArr)

Tem = sArr(I, 1) & "#" & sArr(I, 2) & "#" & sArr(I, 5) ' tạo từ khoá làm key cho dictionary

If Not Dic.Exists(Tem) Then ' dictionary chưa có key này, vậy thì thêm vào
' chu trình gồm có:
K = K + 1 ' tăng số dòng (tức là số keys) lên 1 dòng
Dic.Add Tem, K ' ghi chỉ số dòng này vào dictionary
dArr(K, 1) = sArr(I, 1) ' ghi trị mã số, vân vân vào array kết quả
dArr(K, 2) = sArr(I, 2)
dArr(K, 4) = sArr(I, 5) ' xem lưu ý ở dưới
End If
' đến đây thì dic có chứa key và chỉ số tương ứng trong mảng kết quả
' và dArr thì có chứa các trị mã, cùng với con số tổng (nếu mã mới thì con số này là 0)
Rws = Dic.Item(Tem) ' dùng key để truy cập dic, lấy ra chỉ số dòng của key này trong mảng
dArr(Rws, 3) = dArr(Rws, 3) + sArr(I, 4) ' công số vào tổng trong mảng, xem lưu ý bên dưới
Next I
End If
Next Ws
' đến đây thì đã sử lý xong mảng đầu vào.
' mảng đầu ra đã có đẩy đủ các mã duy nhất cùng con số tổng
With Sheets("Data") ' sheet để chép kết quả
.Range("C5:F100").ClearContents ' dọn chỗ trước cho sạch sẽ
.Range("C5:F5").Resize(K) = dArr ' chép mảng đầu ra vào sheet. Resize(K) bảo đảm là sẽ chép K dòng
.Range("A5:F5").Resize(K).Borders.LineStyle = 1 ' chỗ này là đồ trang trí, không đáng nói
End With

Lưu ý: mảng đầu vào có 5 cột, mảng đầu ra có 4 cột, cột chứa số liệu ở đầu vào là 4, cột chứa tổng số liệu đầu ra là 3
Code này viết trên kiểu mà dân lập trình gọi là "số trên trời rớt xuống" (tiếng nghề: magic numbers)

Cảm ơn VetMini rất nhiều, cách học thực tế này giúp mình tiến nhanh hơn :). Nhờ Giaiphapexcel mà từ một người chẳng biết excel là gì chỉ nghĩ nó là nhập số và tính cộng trừ nhân chia, ếch đã bò lên được miệng giếng và ngửi thấy mùi VBA ;;;;;;;;;;;
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

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

Back
Top Bottom