Rút gọn thủ tục xử lý mảng như thế nào?

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,662
Được thích
16,720
Giới tính
Nam
Tôi mới học cách xử lý mảng nên chưa rành về nó lắm, tôi có một thủ tục như sau:

PHP:
Sub Test()
  Dim iArr As Long, sArray, MyArr
  With HocArray
    sArray = Range(.[A4], .[A65536].End(xlUp)).Resize(, 11).Value
    ReDim MyArr(1 To UBound(sArray, 1), 1 To 14)
    For iArr = 1 To UBound(sArray, 1)
      MyArr(iArr, 1) = sArray(iArr, 2)
      MyArr(iArr, 2) = sArray(iArr, 3)
      MyArr(iArr, 3) = sArray(iArr, 4)
      MyArr(iArr, 4) = sArray(iArr, 5)
      MyArr(iArr, 5) = sArray(iArr, 6)
      MyArr(iArr, 6) = sArray(iArr, 7)
      MyArr(iArr, 7) = MyArr(iArr, 1) + MyArr(iArr, 3) + MyArr(iArr, 5)
      MyArr(iArr, 8) = MyArr(iArr, 2) + MyArr(iArr, 4) + MyArr(iArr, 6)
      MyArr(iArr, 9) = sArray(iArr, 8)
      MyArr(iArr, 10) = sArray(iArr, 9)
      MyArr(iArr, 11) = sArray(iArr, 10)
      MyArr(iArr, 12) = sArray(iArr, 11)
      MyArr(iArr, 13) = MyArr(iArr, 8) + MyArr(iArr, 9) + MyArr(iArr, 10) + MyArr(iArr, 11) + MyArr(iArr, 12)
      MyArr(iArr, 14) = sArray(iArr, 1)
    Next
    .[M4].Resize(UBound(MyArr, 1), 14).Value = MyArr
  End With
End Sub


Và từ đó, rút gọn lại như dưới đây:

PHP:
Sub TestRutGon()
  Dim iArr As Long, jArr As Long, sArray, MyArr
  With HocArray
    sArray = Range(.[A4], .[A65536].End(xlUp)).Resize(, 11).Value
    ReDim MyArr(1 To UBound(sArray, 1), 1 To 14)
    For iArr = 1 To UBound(sArray, 1)
      For jArr = 1 To 6
        MyArr(iArr, jArr) = sArray(iArr, jArr + 1)
      Next
      MyArr(iArr, 7) = MyArr(iArr, 1) + MyArr(iArr, 3) + MyArr(iArr, 5)
      MyArr(iArr, 8) = MyArr(iArr, 2) + MyArr(iArr, 4) + MyArr(iArr, 6)
      For jArr = 9 To 12
        MyArr(iArr, jArr) = sArray(iArr, jArr - 1)
      Next
      MyArr(iArr, 13) = MyArr(iArr, 8) + MyArr(iArr, 9) + MyArr(iArr, 10) + MyArr(iArr, 11) + MyArr(iArr, 12)
      MyArr(iArr, 14) = sArray(iArr, 1)
    Next
    .[M4].Resize(UBound(MyArr, 1), 14).Value = MyArr
  End With
End Sub

Xin vui lòng cho hỏi, Với cách rút gọn như trên, không biết đã tối ưu chưa?

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

File đính kèm

Tôi mới học cách xử lý mảng nên chưa rành về nó lắm, tôi có một thủ tục như sau:
PHP:
Sub TestRutGon()
  Dim iArr As Long, jArr As Long, sArray, MyArr
  With HocArray
    sArray = Range(.[A4], .[A65536].End(xlUp)).Resize(, 11).Value
    ReDim MyArr(1 To UBound(sArray, 1), 1 To 14)
    For iArr = 1 To UBound(sArray, 1)
      For jArr = 1 To 6
        MyArr(iArr, jArr) = sArray(iArr, jArr + 1)
      Next
      MyArr(iArr, 7) = MyArr(iArr, 1) + MyArr(iArr, 3) + MyArr(iArr, 5)
      MyArr(iArr, 8) = MyArr(iArr, 2) + MyArr(iArr, 4) + MyArr(iArr, 6)
      For jArr = 9 To 12
        MyArr(iArr, jArr) = sArray(iArr, jArr - 1)
      Next
      MyArr(iArr, 13) = MyArr(iArr, 8) + MyArr(iArr, 9) + MyArr(iArr, 10) + MyArr(iArr, 11) + MyArr(iArr, 12)
      MyArr(iArr, 14) = sArray(iArr, 1)
    Next
    .[M4].Resize(UBound(MyArr, 1), 14).Value = MyArr
  End With
End Sub
MyArr là kq của sArray. vậy làm thêm mấy cái for làm gì.
For i=1 to 6
...
For i=9 to 12
...
Sao kg lấy
Arr01=.range...
Arr02=.range...
Và gán xuống luôn. Cái nào cần tính thì for.
 
Upvote 0
MyArr là kq của sArray. vậy làm thêm mấy cái for làm gì.
For i=1 to 6
...
For i=9 to 12
...
Sao kg lấy
Arr01=.range...
Arr02=.range...
Và gán xuống luôn. Cái nào cần tính thì for.
Tôi nghĩ code này chỉ là thí nghiệm để "tập tành" về mảng thôi... Bài toán thực tế có thể khác hơn chứ
-------------------------
Nói chung làm như minhthien của được rồi
 
Upvote 0
MyArr là kq của sArray. vậy làm thêm mấy cái for làm gì.
For i=1 to 6
...
For i=9 to 12
...
Sao kg lấy
Arr01=.range...
Arr02=.range...
Và gán xuống luôn. Cái nào cần tính thì for.

Thật ra nói theo Anh ThuNghi cũng đúng, em đã thử làm như sau:

PHP:
Sub TestMoi()
  Dim MyRng As Range, MyArr1, MyArr2
  With HocArray
    Set MyRng = Range(.[A4], .[A65536].End(xlUp))
    MyArr1 = MyRng.Offset(, 1).Resize(, 6).Value
    MyArr2 = MyRng.Offset(, 7).Resize(, 4).Value
    .[M4].Resize(UBound(MyArr1, 1), 6).Value = MyArr1
    .[U4].Resize(UBound(MyArr2, 1), 4).Value = MyArr2
    .[Z4].Resize(UBound(MyRng.Value, 1), 1).Value = MyRng.Value
    'gán công thúc:
    .[S4].Resize(UBound(MyRng.Value, 1), 1).FormulaR1C1 = "=RC[-6]+RC[-4]+RC[-2]"
    .[T4].Resize(UBound(MyRng.Value, 1), 1).FormulaR1C1 = "=RC[-6]+RC[-4]+RC[-2]"
    .[Y4].Resize(UBound(MyRng.Value, 1), 1).FormulaR1C1 = "=SUM(RC[-5]:RC[-1])"
  End With
End Sub

Xử lý như vậy cũng được phải không?

@ Thầy NDU: Đúng như Thầy nói, em đang tập tành về mảng.
 
Upvote 0
PHP:
Sub TestRutGon()
  Dim iArr As Long, jArr As Long, sArray, MyArr
  With HocArray
    sArray = Range(.[A4], .[A65536].End(xlUp)).Resize(, 11).Value
    ReDim MyArr(1 To UBound(sArray, 1), 1 To 14)
    For iArr = 1 To UBound(sArray, 1)
      For jArr = 1 To 6
        MyArr(iArr, jArr) = sArray(iArr, jArr + 1)
      Next
      MyArr(iArr, 7) = MyArr(iArr, 1) + MyArr(iArr, 3) + MyArr(iArr, 5)
      MyArr(iArr, 8) = MyArr(iArr, 2) + MyArr(iArr, 4) + MyArr(iArr, 6)
      For jArr = 9 To 12
        MyArr(iArr, jArr) = sArray(iArr, jArr - 1)
      Next
      MyArr(iArr, 13) = MyArr(iArr, 8) + MyArr(iArr, 9) + MyArr(iArr, 10) + MyArr(iArr, 11) + MyArr(iArr, 12)
      MyArr(iArr, 14) = sArray(iArr, 1)
    Next
    .[M4].Resize(UBound(MyArr, 1), 14).Value = MyArr
  End With
End Sub

Xin vui lòng cho hỏi, Với cách rút gọn như trên, không biết đã tối ưu chưa?

Xin cảm ơn rất nhiều!
Em xin góp chút ý kiến, em nghĩ mình đưa thêm vòng lặp vào thì sẽ rút gắn được đoạn code hơn vì khì nhiều không lẽ mình cộng cộng dài thòn cũng hơn kỳ. Em nghĩ đang học với mảng như anh minhthien là quá Pro. Thanks anh đã có nhữ bài tập về mảng hay
PHP:
Sub TestRutGon()
  Dim iArr As Long, jArr As Long, sArray, MyArr
  With HocArray
    sArray = Range(.[A4], .[A65536].End(xlUp)).Resize(, 11).Value
    ReDim MyArr(1 To UBound(sArray, 1), 1 To 14)
    For iArr = 1 To UBound(sArray, 1)
      For jArr = 1 To 6
        MyArr(iArr, jArr) = sArray(iArr, jArr + 1)
      Next
      For jArr = 1 To 6 Step 2
      MyArr(iArr, 7) = MyArr(iArr, 7) + MyArr(iArr, jArr)
      MyArr(iArr, 8) = MyArr(iArr, 8) + MyArr(iArr, jArr + 1)
      Next
      For jArr = 9 To 12
        MyArr(iArr, jArr) = sArray(iArr, jArr - 1)
      Next
      For jArr = 9 To 12
      MyArr(iArr, 13) = MyArr(iArr, 13) + MyArr(iArr, jArr)
      Next
      MyArr(iArr, 13) = MyArr(iArr, 13) + MyArr(iArr, 8)
    MyArr(iArr, 14) = sArray(iArr, 1)
    Next
    .[M4].Resize(UBound(MyArr, 1), 14).Value = MyArr
  End With
End Sub
 
Upvote 0
Thật ra nói theo Anh ThuNghi cũng đúng, em đã thử làm như sau:

PHP:
Sub TestMoi()
  Dim MyRng As Range, MyArr1, MyArr2
  With HocArray
    Set MyRng = Range(.[A4], .[A65536].End(xlUp))
    MyArr1 = MyRng.Offset(, 1).Resize(, 6).Value
    MyArr2 = MyRng.Offset(, 7).Resize(, 4).Value
    .[M4].Resize(UBound(MyArr1, 1), 6).Value = MyArr1
    .[U4].Resize(UBound(MyArr2, 1), 4).Value = MyArr2
    .[Z4].Resize(UBound(MyRng.Value, 1), 1).Value = MyRng.Value
    'gán công thúc:
    .[S4].Resize(UBound(MyRng.Value, 1), 1).FormulaR1C1 = "=RC[-6]+RC[-4]+RC[-2]"
    .[T4].Resize(UBound(MyRng.Value, 1), 1).FormulaR1C1 = "=RC[-6]+RC[-4]+RC[-2]"
    .[Y4].Resize(UBound(MyRng.Value, 1), 1).FormulaR1C1 = "=SUM(RC[-5]:RC[-1])"
  End With
End Sub

.
Bạn gán công thức , nếu dữ liệu nhiều sẽ bị chậm .
Nên tính toán trên mảng rồi gán vào sheet nhanh hơn
 
Upvote 0
Bạn gán công thức , nếu dữ liệu nhiều sẽ bị chậm .
Nên tính toán trên mảng rồi gán vào sheet nhanh hơn

Vâng, mình biết là vậy, nhưng tất cả những gì liên quan đến mảng trong bài này mình học hết! theo bạn, ngoài cách mình xử lý trên mảng (đã làm ở bài đầu) thì còn cách nào khác nữa không ạ?

Xin cảm ơn.
 
Upvote 0
Mình thấy vẫn thế nào ấy, tại sao lại không dùng 1 mảng thôi đỡ tổn bộ nhớ. Việc sử lý cũng nhanh, đơn giản không kém.
Các bạn thử code sau xem sao:

Mã:
Sub SeaArr()
Dim Mg, i, j
  With HocArray
    Mg = Range(.[A4], .[A65536].End(xlUp)).Resize(, 14).Value
    For i = 1 To UBound(Mg, 1)
    Mg(i, 14) = Mg(i, 1)
    For j = 12 To 9 Step -1
    Mg(i, j) = Mg(i, j - 1)
    Next j
    For j = 1 To 6
    Mg(i, j) = Mg(i, j + 1)
    Next j
    Mg(i, 7) = Mg(i, 1) + Mg(i, 3) + Mg(i, 5)
    Mg(i, 8) = Mg(i, 2) + Mg(i, 4) + Mg(i, 6)
    Mg(i, 13) = Mg(i, 8) + Mg(i, 9) + Mg(i, 10) + Mg(i, 11) + Mg(i, 12)
    Next i
    .[M4].Resize(UBound(Mg, 1), 14).Value = Mg
  End With
End Sub
 
Upvote 0
MinhThien nên khai báo rõ biến sArray, MyArr nhé, như vậy code sẽ ngon 1 chút!
 
Upvote 0
Vâng, mình biết là vậy, nhưng tất cả những gì liên quan đến mảng trong bài này mình học hết! theo bạn, ngoài cách mình xử lý trên mảng (đã làm ở bài đầu) thì còn cách nào khác nữa không ạ?

Xin cảm ơn.
Mình góp ý một tí về bố trí dữ liệu , điều này sẽ cải thiện khi lập trình , bạn xem file
 

File đính kèm

Upvote 0
Em xin góp chút ý kiến, em nghĩ mình đưa thêm vòng lặp vào thì sẽ rút gắn được đoạn code hơn vì khì nhiều không lẽ mình cộng cộng dài thòn cũng hơn kỳ. Em nghĩ đang học với mảng như anh minhthien là quá Pro. Thanks anh đã có nhữ bài tập về mảng hay
Mã:
Sub TestRutGon()
  Dim iArr As Long, jArr As Long, sArray, MyArr
  With HocArray
    sArray = Range(.[A4], .[A65536].End(xlUp)).Resize(, 11).Value
    ReDim MyArr(1 To UBound(sArray, 1), 1 To 14)
    For iArr = 1 To UBound(sArray, 1)
      For jArr = 1 To 6
        MyArr(iArr, jArr) = sArray(iArr, jArr + 1)
      Next
      For jArr = 1 To 6 Step 2
      MyArr(iArr, 7) = MyArr(iArr, 7) + MyArr(iArr, jArr)
      MyArr(iArr, 8) = MyArr(iArr, 8) + MyArr(iArr, jArr + 1)
      Next
      For jArr = 9 To 12
        MyArr(iArr, jArr) = sArray(iArr, jArr - 1)
      Next
      For jArr = 9 To 12
      MyArr(iArr, 13) = MyArr(iArr, 13) + MyArr(iArr, jArr)
      Next
      [COLOR=#ff0000][B]MyArr(iArr, 13) = MyArr(iArr, 13) + MyArr(iArr, 8)[/B][/COLOR]
    MyArr(iArr, 14) = sArray(iArr, 1)
    Next
    .[M4].Resize(UBound(MyArr, 1), 14).Value = MyArr
  End With
End Sub

Làm như em là quá hay rồi, nhưng hơi thừa 1 dòng:

Mã:
Sub TestRutGon2()
  Dim iArr As Long, jArr As Long, sArray, MyArr, TG As Double
  TG = Timer
  With HocArray
    sArray = Range(.[A4], .[A65536].End(xlUp)).Resize(, 11).Value
    ReDim MyArr(1 To UBound(sArray, 1), 1 To 14)
    For iArr = 1 To UBound(sArray, 1)
      For jArr = 1 To 6
        MyArr(iArr, jArr) = sArray(iArr, jArr + 1)
      Next
      
      For jArr = 1 To 6 Step 2
        MyArr(iArr, 7) = MyArr(iArr, 7) + MyArr(iArr, jArr)
        MyArr(iArr, 8) = MyArr(iArr, 8) + MyArr(iArr, jArr + 1)
      Next
        
      For jArr = 9 To 12
        MyArr(iArr, jArr) = sArray(iArr, jArr - 1)
      Next
        
      For jArr =[COLOR=#ff0000][B] 8 [/B][/COLOR]To 12
        MyArr(iArr, 13) = MyArr(iArr, 13) + MyArr(iArr, jArr)
      Next
      
      MyArr(iArr, 14) = sArray(iArr, 1)
    Next
    .[M4].Resize(UBound(MyArr, 1), 14).Value = MyArr
  End With
  MsgBox Timer - TG
End Sub

Chuyển cho nó lên 8 luôn vì đã tính 8 ở trên rồi mà phải không?
 
Upvote 0
Upvote 0
Một cách nữa để bạn tham khảo :

Sub TestRutGon()
Dim iArr As Long, jArr As Long, Arr1, Arr2
With HocArray
jArr = .[A65536].End(xlUp).Row
Arr1 = .Range("B4:I" & jArr).Value
Arr2 = .Range("H4:L" & jArr).Value
For iArr = 1 To UBound(Arr1, 1)
Arr1(iArr, 7) = Arr1(iArr, 1) + Arr1(iArr, 3) + Arr1(iArr, 5)
Arr1(iArr, 8) = Arr1(iArr, 2) + Arr1(iArr, 4) + Arr1(iArr, 6)
Arr2(iArr, 5) = Arr1(iArr, 8) + Arr2(iArr, 1) + Arr2(iArr, 2) + Arr2(iArr, 3) + Arr2(iArr, 4)
Next
.Range("M4:T" & jArr).Value = Arr1
.Range("U4:Y" & jArr).Value = Arr2
.Range("Z4:Z" & jArr).Value = .Range("A4:A" & jArr).Value
End With
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Học rút gọn mảng bài 2

Mã:
Sub TestPivot2()
  Dim iRow As Long, iCol1 As Long, iCol2 As Long, sArray, MyArr, TG As Double
  TG = Timer
    sArray = Range(Sheet1.[J6], Sheet1.[J65536].End(xlUp)).Resize(, 21).Value
    ReDim MyArr(1 To UBound(sArray, 1), 1 To 15)
    For iRow = 1 To UBound(sArray, 1)
[COLOR=#008000]'--------------------------------------------------------------------------------
'      MyArr(iRow, 1) = sArray(iRow, 2) + sArray(iRow, 8)
'      MyArr(iRow, 2) = sArray(iRow, 3) + sArray(iRow, 9)
'      MyArr(iRow, 3) = sArray(iRow, 4) + sArray(iRow, 10)
'      MyArr(iRow, 4) = sArray(iRow, 5) + sArray(iRow, 11)
'      MyArr(iRow, 5) = sArray(iRow, 8) + sArray(iRow, 12)
'      MyArr(iRow, 6) = sArray(iRow, 7) + sArray(iRow, 13)
'      Rut gon:[/COLOR]
      For iCol1 = 1 To 6
        MyArr(iRow, iCol1) = sArray(iRow, iCol1 + 1) + sArray(iRow, iCol1 + 7)
      Next
[COLOR=#008000]'--------------------------------------------------------------------------------
'      MyArr(iRow, 7) = MyArr(iRow, 1) + MyArr(iRow, 3) + MyArr(iRow, 5)
'      MyArr(iRow, 8) = MyArr(iRow, 2) + MyArr(iRow, 4) + MyArr(iRow, 6)
'      Rut gon:[/COLOR]
      For iCol1 = 1 To 6 Step 2
        MyArr(iRow, 7) = MyArr(iRow, 7) + MyArr(iRow, iCol1)
        MyArr(iRow, 8) = MyArr(iRow, 8) + MyArr(iRow, iCol1 + 1)
      Next
[COLOR=#008000]'--------------------------------------------------------------------------------
'      MyArr(iRow, 9) = sArray(iRow, 15)
'      MyArr(iRow, 10) = sArray(iRow, 17)
'      MyArr(iRow, 11) = sArray(iRow, 19)
'      MyArr(iRow, 12) = sArray(iRow, 21)
'      Rut gon:[/COLOR]
     [COLOR=#ff0000][B] iCol2 = 13
      For iCol1 = 9 To 12
        iCol2 = iCol2 + 2
        MyArr(iRow, iCol1) = sArray(iRow, iCol2)
      Next[/B][/COLOR]
[COLOR=#008000]'--------------------------------------------------------------------------------
'      MyArr(iRow, 13) = MyArr(iRow, 8) + MyArr(iRow, 9) + MyArr(iRow, 10) + MyArr(iRow, 11) + MyArr(iRow, 12)
'      Rut gon:[/COLOR]
      For iCol1 = 8 To 12
        MyArr(iRow, 13) = MyArr(iRow, 13) + MyArr(iRow, iCol1)
      Next
[COLOR=#008000]'--------------------------------------------------------------------------------[/COLOR]
      MyArr(iRow, 14) = sArray(iRow, 1)
    Next
    Sheet2.[A3].Resize(UBound(MyArr, 1), 14).Value = MyArr
  MsgBox Timer - TG
End Sub


Thắc mắc chỗ này:

Mã:
    MyArr(iRow, 9) = sArray(iRow, 15)
    MyArr(iRow, 10) = sArray(iRow, 17)
    MyArr(iRow, 11) = sArray(iRow, 19)
    MyArr(iRow, 12) = sArray(iRow, 21)

Thì làm thế này lại cho kết quả đúng:

Mã:
    iCol2 = 13
    For iCol1 = 9 To 12
      iCol2 = iCol2 + 2
      MyArr(iRow, iCol1) = sArray(iRow, iCol2)
    Next

Nhưng làm thế này lại cho kết quả sai:

Mã:
    For iCol1 = 9 To 12
      For iCol2 = 15 To 21 Step 2
        MyArr(iRow, iCol1) = sArray(iRow, iCol2)
      Next
    Next

Làm ơn giải thích dùm vấn đề trên ạ!

Trân trọng cảm ơn!
 

File đính kèm

Upvote 0
Ở đây nó chạy vòng lặp trong trước , và kết thúc tất cả sẽ là sArray(iRow, 21)
 
Upvote 0
Ở đây nó chạy vòng lặp trong trước , và kết thúc tất cả sẽ là sArray(iRow, 21)

Uh, như vậy là sự kết thúc của nó luôn ở bên trong trước, mình hiểu rồi, cám ơn bạn.

Viết thế này:

Mã:
     [B] iCol2 = [COLOR=#ff0000]15[/COLOR][/B]
      For iCol1 = 9 To 12
        MyArr(iRow, iCol1) = sArray(iRow, iCol2)
       [COLOR=#0000cd][B] iCol2 = iCol2 + 2[/B][/COLOR]
      Next

So với thế này:

Mã:
      [B]iCol2 = [COLOR=#ff0000]13[/COLOR][/B]
      For iCol1 = 9 To 12
       [COLOR=#0000cd][B] iCol2 = iCol2 + 2[/B][/COLOR]
        MyArr(iRow, iCol1) = sArray(iRow, iCol2)
      Next

Thì cách viết ở trên nó dễ hiểu hơn đúng không, cũng là giá trị đó, nhưng nó có gốc là 15 thì dễ hiểu hơn là 13, nếu tính thì nó tính ít hơn 1 lần nữa!
 
Upvote 0
Mã:
     [B] iCol2 = [COLOR=#ff0000]15[/COLOR][/B]
      For iCol1 = 9 To 12
        MyArr(iRow, iCol1) = sArray(iRow, iCol2)
       [COLOR=#0000cd][B] iCol2 = iCol2 + 2[/B][/COLOR]
      Next

So với thế này:

Mã:
      [B]iCol2 = [COLOR=#ff0000]13[/COLOR][/B]
      For iCol1 = 9 To 12
       [COLOR=#0000cd][B] iCol2 = iCol2 + 2[/B][/COLOR]
        MyArr(iRow, iCol1) = sArray(iRow, iCol2)
      Next
Sao thấy phức tạp hóa quá.
PHP:
 Sub thu()
For i = 1 To 4
  MsgBox 8 + i & "-" & 13 + 2 * i
Next i
End Sub
 
Upvote 0
Sao thấy phức tạp hóa quá.
PHP:
 Sub thu()
For i = 1 To 4
  MsgBox 8 + i & "-" & 13 + 2 * i
Next i
End Sub

À, em hiểu rồi, do mình tùy biến sao cho hợp lý đúng không anh! Cám ơn Anh.

PHP:
      For iCol = 1 To 4
        MyArr(iRow, iCol + 8) = sArray(iRow, iCol * 2 + 13)
      Next
 
Upvote 0
Gọn hơn

For iCol1 = 9 To 12
MyArr(iRow,iCol1) = sArray(iRow, 2* iCol1-3)
Next
 
Upvote 0
Web KT

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

Back
Top Bottom