viết code giúp chức năng sort dữ liệu có điều kiện

Liên hệ QC

Thuy.Vuong

Thành viên mới
Tham gia
25/12/21
Bài viết
24
Được thích
0
Giới tính
Nữ
Em chào anh chị!
Em có một file cần lọc dữ liệu theo cấp độ ưu tiên, khi nhấn vào nút "Lọc Dữ Liệu" thì dữ liệu từ cột A4 đến đến cột AE sẽ được sắp xếp theo cấp độ ưu tiên như em đã để số thứ tự 1(F2), 2(H2), 3(J2), 4(P2), 5(O2), kiểu sắp xếp là từ A-Z, nếu cột là số thì sắp xêp từ bé đến lớn, hiện tại thì em đang sử dụng chức năng sort của excel như hình ảnh bên dưới , nhưng khi cần thiết thập thêm mức độ ưu tiên cho các cột khác thì rất dễ bị nhầm lẫn mất kiểm soát không thể nhớ được là đã sort hay chưa, vì vậy rất mong a chị viết code giúp em vấn đề này.

Capture.PNG
 

File đính kèm

  • Loc Du Lieu.xlsb
    33.5 KB · Đọc: 23
Em chào anh chị!
Em có một file cần lọc dữ liệu theo cấp độ ưu tiên, khi nhấn vào nút "Lọc Dữ Liệu" thì dữ liệu từ cột A4 đến đến cột AE sẽ được sắp xếp theo cấp độ ưu tiên như em đã để số thứ tự 1(F2), 2(H2), 3(J2), 4(P2), 5(O2), kiểu sắp xếp là từ A-Z, nếu cột là số thì sắp xêp từ bé đến lớn, hiện tại thì em đang sử dụng chức năng sort của excel như hình ảnh bên dưới , nhưng khi cần thiết thập thêm mức độ ưu tiên cho các cột khác thì rất dễ bị nhầm lẫn mất kiểm soát không thể nhớ được là đã sort hay chưa, vì vậy rất mong a chị viết code giúp em vấn đề này.

View attachment 271843
Dùng bộ thu Macro, tùy chỉnh thêm dòng cuối "eRow"
Mã:
Sub ABC()
    Dim eRow As Long
    eRow = Worksheets("ABS").Range("D" & Rows.Count).End(xlUp).Row
    If eRow < 5 Then MsgBox ("Khong co du lieu!"): Exit Sub
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("F4:F" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("H4:H" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("J4:J" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("P4:P" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("O4:O" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("ABS").Sort
        .SetRange Range("A3:AR" & eRow) 'Sort tu cot A toi cot AR
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub
 
Upvote 0
Dùng bộ thu Macro, tùy chỉnh thêm dòng cuối "eRow"
Mã:
Sub ABC()
    Dim eRow As Long
    eRow = Worksheets("ABS").Range("D" & Rows.Count).End(xlUp).Row
    If eRow < 5 Then MsgBox ("Khong co du lieu!"): Exit Sub
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("F4:F" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("H4:H" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("J4:J" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("P4:P" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("ABS").Sort.SortFields.Add Key:=Range("O4:O" & eRow), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("ABS").Sort
        .SetRange Range("A3:AR" & eRow) 'Sort tu cot A toi cot AR
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub
A HieuCD ơi code chạy rồi a nhé, nhưng mà mỗi lần muốn thay đổi thứ tự ưu tiên, phải mở code ra sửa mà sửa thì dễ nhầm lẫn lắm ạ, thay vì phải mở code, a có thể viết giúp em chỉ cần thay đổi thứ tự ưu tiên ở các ô
1(F2), 2(H2), 3(J2), 4(P2), 5(O2) được không ạ ví dụ như em muốn đổi thứ tự ưu tiên 1(O2) và 5(F2) sau đó nhấn nút thứ tự ưu tiên sẽ được cập nhật lại
 
Upvote 0
A HieuCD ơi code chạy rồi a nhé, nhưng mà mỗi lần muốn thay đổi thứ tự ưu tiên, phải mở code ra sửa mà sửa thì dễ nhầm lẫn lắm ạ, thay vì phải mở code, a có thể viết giúp em chỉ cần thay đổi thứ tự ưu tiên ở các ô
1(F2), 2(H2), 3(J2), 4(P2), 5(O2) được không ạ ví dụ như em muốn đổi thứ tự ưu tiên 1(O2) và 5(F2) sau đó nhấn nút thứ tự ưu tiên sẽ được cập nhật lại
A HieuCD ơi code chạy rồi a nhé, nhưng mà mỗi lần muốn thay đổi thứ tự ưu tiên, phải mở code ra sửa mà sửa thì dễ nhầm lẫn lắm ạ, thay vì phải mở code, a có thể viết giúp em chỉ cần thay đổi thứ tự ưu tiên ở các ô
1(F2), 2(H2), 3(J2), 4(P2), 5(O2) được không ạ ví dụ như em muốn đổi thứ tự ưu tiên 1(O2) và 5(F2) sau đó nhấn nút thứ tự ưu tiên sẽ được cập nhật lại
Nhập thứ tự ưu tiên vào A2:AE2, số dương sort A->Z số âm sort Z->A
Mã:
Option Explicit
Sub XYZ()
  Dim aDK(), arr(), eRow&, sRow&, sCol&, j&, c, ord
  With Worksheets("ABS")
    eRow = .Range("D" & Rows.Count).End(xlUp).Row
    If eRow < 5 Then MsgBox ("Khong co du lieu!"): Exit Sub
    sRow = eRow - 3
    aDK = .Range("A2:AE2").Value 'Vung dieu kien sort
    Call dkSort(aDK, arr, sCol)
    If sCol > 0 Then
      .Sort.SortFields.Clear
      For j = 1 To sCol
        If arr(1, j) <> Empty Then
          If arr(2, j) > 0 Then ord = 1 Else ord = 2
          .Sort.SortFields.Add Key:=Range(arr(1, j)).Resize(sRow), _
          SortOn:=xlSortOnValues, Order:=ord, DataOption:=xlSortNormal
        End If
      Next j
      With ActiveWorkbook.Worksheets("ABS").Sort
        .SetRange Range("A3:AR" & eRow) 'Sort tu cot A toi cot AR
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
      End With
    End If
  End With
End Sub

Private Sub dkSort(aDK, arr, sCol)
  Dim j&, c, cAbs&
  For j = 1 To UBound(aDK, 2)
    c = aDK(1, j)
    If c <> Empty And IsNumeric(c) Then
      cAbs = Abs(c)
      If sCol < cAbs Then
        sCol = cAbs
        ReDim Preserve arr(1 To 2, 1 To sCol)
      End If
      arr(1, cAbs) = Cells(4, j).Address(0, 0)
      arr(2, cAbs) = c
    End If
  Next j
End Sub
 
Upvote 0
Nhập thứ tự ưu tiên vào A2:AE2, số dương sort A->Z số âm sort Z->A
Mã:
Option Explicit
Sub XYZ()
  Dim aDK(), arr(), eRow&, sRow&, sCol&, j&, c, ord
  With Worksheets("ABS")
    eRow = .Range("D" & Rows.Count).End(xlUp).Row
    If eRow < 5 Then MsgBox ("Khong co du lieu!"): Exit Sub
    sRow = eRow - 3
    aDK = .Range("A2:AE2").Value 'Vung dieu kien sort
    Call dkSort(aDK, arr, sCol)
    If sCol > 0 Then
      .Sort.SortFields.Clear
      For j = 1 To sCol
        If arr(1, j) <> Empty Then
          If arr(2, j) > 0 Then ord = 1 Else ord = 2
          .Sort.SortFields.Add Key:=Range(arr(1, j)).Resize(sRow), _
          SortOn:=xlSortOnValues, Order:=ord, DataOption:=xlSortNormal
        End If
      Next j
      With ActiveWorkbook.Worksheets("ABS").Sort
        .SetRange Range("A3:AR" & eRow) 'Sort tu cot A toi cot AR
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
      End With
    End If
  End With
End Sub

Private Sub dkSort(aDK, arr, sCol)
  Dim j&, c, cAbs&
  For j = 1 To UBound(aDK, 2)
    c = aDK(1, j)
    If c <> Empty And IsNumeric(c) Then
      cAbs = Abs(c)
      If sCol < cAbs Then
        sCol = cAbs
        ReDim Preserve arr(1 To 2, 1 To sCol)
      End If
      arr(1, cAbs) = Cells(4, j).Address(0, 0)
      arr(2, cAbs) = c
    End If
  Next j
End Sub
em cám ơn a nhé, để em copy về chạy
Bài đã được tự động gộp:

Từ đầu đến giờ không thấy bóng dáng một câu cảm ơn nào cho người giúp nhỉ.
vâng, giờ em mới đọc tin của a HieuCD, không cám ơn không được ấy hihihi, cám ơn tất cả các anh nhé
 
Upvote 0
Nhập thứ tự ưu tiên vào A2:AE2, số dương sort A->Z số âm sort Z->A
Mã:
Option Explicit
Sub XYZ()
  Dim aDK(), arr(), eRow&, sRow&, sCol&, j&, c, ord
  With Worksheets("ABS")
    eRow = .Range("D" & Rows.Count).End(xlUp).Row
    If eRow < 5 Then MsgBox ("Khong co du lieu!"): Exit Sub
    sRow = eRow - 3
    aDK = .Range("A2:AE2").Value 'Vung dieu kien sort
    Call dkSort(aDK, arr, sCol)
    If sCol > 0 Then
      .Sort.SortFields.Clear
      For j = 1 To sCol
        If arr(1, j) <> Empty Then
          If arr(2, j) > 0 Then ord = 1 Else ord = 2
          .Sort.SortFields.Add Key:=Range(arr(1, j)).Resize(sRow), _
          SortOn:=xlSortOnValues, Order:=ord, DataOption:=xlSortNormal
        End If
      Next j
      With ActiveWorkbook.Worksheets("ABS").Sort
        .SetRange Range("A3:AR" & eRow) 'Sort tu cot A toi cot AR
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
      End With
    End If
  End With
End Sub

Private Sub dkSort(aDK, arr, sCol)
  Dim j&, c, cAbs&
  For j = 1 To UBound(aDK, 2)
    c = aDK(1, j)
    If c <> Empty And IsNumeric(c) Then
      cAbs = Abs(c)
      If sCol < cAbs Then
        sCol = cAbs
        ReDim Preserve arr(1 To 2, 1 To sCol)
      End If
      arr(1, cAbs) = Cells(4, j).Address(0, 0)
      arr(2, cAbs) = c
    End If
  Next j
End Sub
A HieuCD ơi
em xin lỗi em làm phiền anh tí xíu ạ,
sau một thời gian chạy em mới hiểu hết được vấn đề phát sinh cần a giúp đỡ thêm.
với code hiện tại đã sắp xếp giống như chức năng sort trong excel rồi nhưng giờ em muốn sắp xếp thêm các điều kiện nữa.
cụ thể như sau
1. khi nhấn nút sắp xếp các ô ở dòng thứ 2 sẽ sắp xếp giống như thứ tự ưu tiên em đang để hiện tại em đánh số từ 1 đến 5 theo chức năng sort
2. các "ITEM CODE" giống nhau ở cột K sẽ được sắp xếp liền nhau theo điều kiện
- Nếu các "ITEM CODE" đó có cùng "MACHINE" ở cột P nhưng khác ngày "FINAL D" ở cột G thì ưu tiên lấy ngày từ bé đến lớn sao cho tổng ở cột T của "ITEM CODE" đó <=5
Vi dụ dòng số 16, 23, 60, 61, 62, 63, 64 có cùng "ITEM CODE" = CB602675B nhưng lại khác ngày ở cột G thì ưu tiên lấy ngày từ bé bắt đầu từ dòng 16 23, 60, 61, 62, đến dòng 63 vì có ở cột T = 1.56 thỏa mãn điều kiện <=5, không lấy dòng 64 vì tổng ở cột T > 5.
- sau khi sắp xếp xong đánh số thứ tự ở cột A bắt đầu từ dòng số 4, điền 1 2 3 4 5... đến hết các dòng có dữ liệu.

3.
Công thức ở cột M và N nó cứ nhảy lung tung ô tham chiếu gây nhẫm lẫn sai số, mỗi lần nhấn nút sắp xếp a viết code giúp em làm sao vẫn giữ được đúng ô tham chiếu với
 

File đính kèm

  • sort.xlsb
    756 KB · Đọc: 5
Lần chỉnh sửa cuối:
Upvote 0
A HieuCD ơi
em xin lỗi em làm phiền anh tí xíu ạ,
sau một thời gian chạy em mới hiểu hết được vấn đề phát sinh cần a giúp đỡ thêm.
với code hiện tại đã sắp xếp giống như chức năng sort trong excel rồi nhưng giờ em muốn sắp xếp thêm các điều kiện nữa.
cụ thể như sau
1. khi nhấn nút sắp xếp các ô ở dòng thứ 2 sẽ sắp xếp giống như thứ tự ưu tiên em đang để hiện tại em đánh số từ 1 đến 5 theo chức năng sort
2. các "ITEM CODE" giống nhau ở cột K sẽ được sắp xếp liền nhau theo điều kiện
- Nếu các "ITEM CODE" đó có cùng "MACHINE" ở cột P nhưng khác ngày "FINAL D" ở cột G thì ưu tiên lấy ngày từ bé đến lớn sao cho tổng ở cột T của "ITEM CODE" đó <=5
Vi dụ dòng số 16, 23, 60, 61, 62, 63, 64 có cùng "ITEM CODE" = CB602675B nhưng lại khác ngày ở cột G thì ưu tiên lấy ngày từ bé bắt đầu từ dòng 16 23, 60, 61, 62, đến dòng 63 vì có ở cột T = 1.56 thỏa mãn điều kiện <=5, không lấy dòng 64 vì tổng ở cột T > 5.
- sau khi sắp xếp xong đánh số thứ tự ở cột A bắt đầu từ dòng số 4, điền 1 2 3 4 5... đến hết các dòng có dữ liệu.

3.
Công thức ở cột M và N nó cứ nhảy lung tung ô tham chiếu gây nhẫm lẫn sai số, mỗi lần nhấn nút sắp xếp a viết code giúp em làm sao vẫn giữ được đúng ô tham chiếu với
3/ Công thức cột M và N xóa bỏ tên sheet hiện hành: "PFL_PRINT!"
2/ Vụ nầy quá khó vì nhiều thứ còn mập mờ không biết kết quả có hình dáng gì, làm tay thêm kết quả thật chuẩn không được sai sót và gởi lại
 
Upvote 0
3/ Công thức cột M và N xóa bỏ tên sheet hiện hành: "PFL_PRINT!"
2/ Vụ nầy quá khó vì nhiều thứ còn mập mờ không biết kết quả có hình dáng gì, làm tay thêm kết quả thật chuẩn không được sai sót và gởi lại
Dạ em ngồi nghĩ làm sao để diễn tả cho a hiểu được, em làm thủ công như file đính kèm, cột K được sắp xếp theo như mô tả ở bài 8

Các "ITEM CODE" giống nhau ở cột K sẽ được sắp xếp liền nhau theo điều kiện
- Nếu các "ITEM CODE" đó có cùng "MACHINE" ở cột P nhưng khác ngày "FINAL D" ở cột G thì ưu tiên lấy ngày từ bé đến lớn sao cho tổng ở cột T của "ITEM CODE" đó <=5
Vi dụ dòng số 16, 23, 60, 61, 62, 63, 64 có cùng "ITEM CODE" = CB602675B nhưng lại khác ngày ở cột G thì ưu tiên lấy ngày từ bé bắt đầu từ dòng 16 23, 60, 61, 62, đến dòng 63 vì có ở cột T = 1.56 thỏa mãn điều kiện <=5, không lấy dòng 64 vì tổng ở cột T > 5.

Tương tự như cho các "MATERIAL CODE" giống nhau ở Q ẽ được sắp xếp liền nhau theo điều kiện

- Nếu các "MATERIAL CODE" đó có cùng "MACHINE" ở cột P nhưng khác ngày "FINAL D" ở cột G thì ưu tiên lấy ngày từ bé đến lớn sao cho tổng ở cột T của "MATERIAL CODE" đó <=5

chủ yếu nhất là nếu khác ngày ở cột G thì mới phải tính toán sắp xếp như vậy, còn cùng ngày thì mặc định là sắp xếp liền nhau.
- sau khi sắp xếp xong đánh số thứ tự ở cột A bắt đầu từ dòng số 4, điền 1 2 3 4 5... đến hết các dòng có dữ liệu, thứ tự lặp lại theo "MACHINE" ở cột P

a xem giúp em ạ, nếu em diễn tả khó hiểu quá a cứ code theo các hiểu của a xong rồi sửa tiếp được không ạ.
 

File đính kèm

  • sort.xlsb
    752.5 KB · Đọc: 12
Upvote 0
Dạ em ngồi nghĩ làm sao để diễn tả cho a hiểu được, em làm thủ công như file đính kèm, cột K được sắp xếp theo như mô tả ở bài 8

Các "ITEM CODE" giống nhau ở cột K sẽ được sắp xếp liền nhau theo điều kiện
- Nếu các "ITEM CODE" đó có cùng "MACHINE" ở cột P nhưng khác ngày "FINAL D" ở cột G thì ưu tiên lấy ngày từ bé đến lớn sao cho tổng ở cột T của "ITEM CODE" đó <=5
Vi dụ dòng số 16, 23, 60, 61, 62, 63, 64 có cùng "ITEM CODE" = CB602675B nhưng lại khác ngày ở cột G thì ưu tiên lấy ngày từ bé bắt đầu từ dòng 16 23, 60, 61, 62, đến dòng 63 vì có ở cột T = 1.56 thỏa mãn điều kiện <=5, không lấy dòng 64 vì tổng ở cột T > 5.

Tương tự như cho các "MATERIAL CODE" giống nhau ở Q ẽ được sắp xếp liền nhau theo điều kiện

- Nếu các "MATERIAL CODE" đó có cùng "MACHINE" ở cột P nhưng khác ngày "FINAL D" ở cột G thì ưu tiên lấy ngày từ bé đến lớn sao cho tổng ở cột T của "MATERIAL CODE" đó <=5

chủ yếu nhất là nếu khác ngày ở cột G thì mới phải tính toán sắp xếp như vậy, còn cùng ngày thì mặc định là sắp xếp liền nhau.
- sau khi sắp xếp xong đánh số thứ tự ở cột A bắt đầu từ dòng số 4, điền 1 2 3 4 5... đến hết các dòng có dữ liệu, thứ tự lặp lại theo "MACHINE" ở cột P

a xem giúp em ạ, nếu em diễn tả khó hiểu quá a cứ code theo các hiểu của a xong rồi sửa tiếp được không ạ.
Chạy sub XYZ . . .
Mã:
Option Explicit
Sub XYZ()
  Dim aDK(), arr(), eRow&, sRow&, sCol&, j&, c, ord
 
  Application.ScreenUpdating = False
  With Worksheets("PFL_PRINT")
    eRow = .Range("D" & Rows.Count).End(xlUp).Row
    If eRow < 5 Then MsgBox ("Khong co du lieu!"): Exit Sub
    sRow = eRow - 3
    aDK = .Range("A2:AF2").Value 'Vung dieu kien sort
    Call dkSort(aDK, arr, sCol)
    If sCol > 0 Then
      .Sort.SortFields.Clear
      For j = 1 To sCol
        If arr(1, j) <> Empty Then
          If arr(2, j) > 0 Then ord = 1 Else ord = 2
          .Sort.SortFields.Add Key:=Range(arr(1, j)).Resize(sRow), _
          SortOn:=xlSortOnValues, Order:=ord, DataOption:=xlSortNormal
        End If
      Next j
      With ActiveWorkbook.Worksheets("PFL_PRINT").Sort
        .SetRange Range("A3:AS" & eRow) 'Sort tu cot A toi cot AS
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
      End With
    End If
  End With
  Call SortItem(sRow)
  Application.ScreenUpdating = True
End Sub

Sub SortItem(sRow)
  Dim sArr(), arr(), dic As Object, iKey$, i&, ik&, tmp#
 
  ReDim arr(1 To sRow, 1 To 2)
  Set dic = CreateObject("scripting.dictionary")
  With Worksheets("PFL_PRINT")
    sArr = .Range("K4:T4").Resize(sRow).Value
    For i = 1 To sRow
      arr(i, 1) = i
      iKey = sArr(i, 1) & "|" & sArr(i, 6)
      If dic.exists(iKey) = False Then
        dic.Add iKey, i
        arr(i, 2) = sArr(i, 10)
      Else
        ik = dic.Item(iKey)
        If arr(ik, 2) < 5 Then
          tmp = arr(ik, 2) + sArr(i, 10)
          If tmp <= 5 Then
            arr(i, 1) = ik
            arr(i, 2) = tmp
          End If
        End If
      End If
    Next i
    .Range("AT4").Resize(sRow).Value = arr
    .Range("A4:AT4").Resize(sRow).Sort .Range("AT4"), 1, Header:=xlNo
    .Range("AT4").Resize(sRow).ClearContents
  End With
End Sub

Private Sub dkSort(aDK, arr, sCol)
  Dim j&, c, cAbs&
  For j = 1 To UBound(aDK, 2)
    c = aDK(1, j)
    If c <> Empty And IsNumeric(c) Then
      cAbs = Abs(c)
      If sCol < cAbs Then
        sCol = cAbs
        ReDim Preserve arr(1 To 2, 1 To sCol)
      End If
      arr(1, cAbs) = Cells(4, j).Address(0, 0)
      arr(2, cAbs) = c
    End If
  Next j
End Sub
 
Upvote 0
Chạy sub XYZ . . .
Mã:
Option Explicit
Sub XYZ()
  Dim aDK(), arr(), eRow&, sRow&, sCol&, j&, c, ord
 
  Application.ScreenUpdating = False
  With Worksheets("PFL_PRINT")
    eRow = .Range("D" & Rows.Count).End(xlUp).Row
    If eRow < 5 Then MsgBox ("Khong co du lieu!"): Exit Sub
    sRow = eRow - 3
    aDK = .Range("A2:AF2").Value 'Vung dieu kien sort
    Call dkSort(aDK, arr, sCol)
    If sCol > 0 Then
      .Sort.SortFields.Clear
      For j = 1 To sCol
        If arr(1, j) <> Empty Then
          If arr(2, j) > 0 Then ord = 1 Else ord = 2
          .Sort.SortFields.Add Key:=Range(arr(1, j)).Resize(sRow), _
          SortOn:=xlSortOnValues, Order:=ord, DataOption:=xlSortNormal
        End If
      Next j
      With ActiveWorkbook.Worksheets("PFL_PRINT").Sort
        .SetRange Range("A3:AS" & eRow) 'Sort tu cot A toi cot AS
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
      End With
    End If
  End With
  Call SortItem(sRow)
  Application.ScreenUpdating = True
End Sub

Sub SortItem(sRow)
  Dim sArr(), arr(), dic As Object, iKey$, i&, ik&, tmp#
 
  ReDim arr(1 To sRow, 1 To 2)
  Set dic = CreateObject("scripting.dictionary")
  With Worksheets("PFL_PRINT")
    sArr = .Range("K4:T4").Resize(sRow).Value
    For i = 1 To sRow
      arr(i, 1) = i
      iKey = sArr(i, 1) & "|" & sArr(i, 6)
      If dic.exists(iKey) = False Then
        dic.Add iKey, i
        arr(i, 2) = sArr(i, 10)
      Else
        ik = dic.Item(iKey)
        If arr(ik, 2) < 5 Then
          tmp = arr(ik, 2) + sArr(i, 10)
          If tmp <= 5 Then
            arr(i, 1) = ik
            arr(i, 2) = tmp
          End If
        End If
      End If
    Next i
    .Range("AT4").Resize(sRow).Value = arr
    .Range("A4:AT4").Resize(sRow).Sort .Range("AT4"), 1, Header:=xlNo
    .Range("AT4").Resize(sRow).ClearContents
  End With
End Sub

Private Sub dkSort(aDK, arr, sCol)
  Dim j&, c, cAbs&
  For j = 1 To UBound(aDK, 2)
    c = aDK(1, j)
    If c <> Empty And IsNumeric(c) Then
      cAbs = Abs(c)
      If sCol < cAbs Then
        sCol = cAbs
        ReDim Preserve arr(1 To 2, 1 To sCol)
      End If
      arr(1, cAbs) = Cells(4, j).Address(0, 0)
      arr(2, cAbs) = c
    End If
  Next j
End Sub
em cám ơn anh nhé, em sẽ kiểm tra kĩ xem nó chạy thế nào ạ
 
Upvote 0
Chạy sub XYZ . . .
Mã:
Option Explicit
Sub XYZ()
  Dim aDK(), arr(), eRow&, sRow&, sCol&, j&, c, ord
 
  Application.ScreenUpdating = False
  With Worksheets("PFL_PRINT")
    eRow = .Range("D" & Rows.Count).End(xlUp).Row
    If eRow < 5 Then MsgBox ("Khong co du lieu!"): Exit Sub
    sRow = eRow - 3
    aDK = .Range("A2:AF2").Value 'Vung dieu kien sort
    Call dkSort(aDK, arr, sCol)
    If sCol > 0 Then
      .Sort.SortFields.Clear
      For j = 1 To sCol
        If arr(1, j) <> Empty Then
          If arr(2, j) > 0 Then ord = 1 Else ord = 2
          .Sort.SortFields.Add Key:=Range(arr(1, j)).Resize(sRow), _
          SortOn:=xlSortOnValues, Order:=ord, DataOption:=xlSortNormal
        End If
      Next j
      With ActiveWorkbook.Worksheets("PFL_PRINT").Sort
        .SetRange Range("A3:AS" & eRow) 'Sort tu cot A toi cot AS
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
      End With
    End If
  End With
  Call SortItem(sRow)
  Application.ScreenUpdating = True
End Sub

Sub SortItem(sRow)
  Dim sArr(), arr(), dic As Object, iKey$, i&, ik&, tmp#
 
  ReDim arr(1 To sRow, 1 To 2)
  Set dic = CreateObject("scripting.dictionary")
  With Worksheets("PFL_PRINT")
    sArr = .Range("K4:T4").Resize(sRow).Value
    For i = 1 To sRow
      arr(i, 1) = i
      iKey = sArr(i, 1) & "|" & sArr(i, 6)
      If dic.exists(iKey) = False Then
        dic.Add iKey, i
        arr(i, 2) = sArr(i, 10)
      Else
        ik = dic.Item(iKey)
        If arr(ik, 2) < 5 Then
          tmp = arr(ik, 2) + sArr(i, 10)
          If tmp <= 5 Then
            arr(i, 1) = ik
            arr(i, 2) = tmp
          End If
        End If
      End If
    Next i
    .Range("AT4").Resize(sRow).Value = arr
    .Range("A4:AT4").Resize(sRow).Sort .Range("AT4"), 1, Header:=xlNo
    .Range("AT4").Resize(sRow).ClearContents
  End With
End Sub

Private Sub dkSort(aDK, arr, sCol)
  Dim j&, c, cAbs&
  For j = 1 To UBound(aDK, 2)
    c = aDK(1, j)
    If c <> Empty And IsNumeric(c) Then
      cAbs = Abs(c)
      If sCol < cAbs Then
        sCol = cAbs
        ReDim Preserve arr(1 To 2, 1 To sCol)
      End If
      arr(1, cAbs) = Cells(4, j).Address(0, 0)
      arr(2, cAbs) = c
    End If
  Next j
End Sub
Chưa chắc xyz đã kết thúc.
 
Upvote 0
...
a xem giúp em ạ, nếu em diễn tả khó hiểu quá a cứ code theo các hiểu của a xong rồi sửa tiếp được không ạ.
Có lẽ bạn rủ bác viết code ở trên ra đâu đó tra đổi ý tưởng, tiện thể làm mẹt thịt chó & vài xị đế, chắc cuối bữa là ra hết ngay thôi :D:D:D
 
Upvote 0
Web KT

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

Back
Top Bottom