Sắp xếp lấy TOP 4 theo nhiều điều kiện

Liên hệ QC
Dữ liệu khác code phải khác nhiều. Gởi file với cấu trúc dữ liệu thật, dữ liệu có thể thay thế bằng dữ liệu giả định nếu muốn bảo mật, để viết code 1 lần cuối
Dạ em gửi lại anh file. Nội dung mong muốn em viết ở trong file ak!
Bài đã được tự động gộp:

Dạ em gửi lại anh file. Nội dung mong muốn em viết ở trong file ak!
 

File đính kèm

Lần chỉnh sửa cuối:
Úi chà. Hóa ra là nghề chọn những con số thần kỳ.

Thấy bạn này tâm sự công việc không dùng tới Excel nhưng lại đam mê viết code. Giờ thì đã hiểu động lực đam mê là gì.
...
Đam mê là nhờ làm giùm sao? Chắc là định nghĩa mới. Hồi nào giờ tôi cứ ngỡ người đam mê thì tự làm lấy, chỉ hỏi một vài chỗ vướng mắc.

Động lực là cơn ghiền code của quý vị. Cứ thấy hỏi code là làm tới.

Thớt biết đặc điểm này của dân GPE cho nên cứ thả thẳng ga. Hết ý tưởng này đến sáng kiến khác.

Chú riêng cho tác giả bài #59: kiểu hành động thì giống như một "người quen" trước đây. Chỉ là cách ăn nói thì chưa thấy giống. Nhất là "người quen" kia không có tật xổ Tây.
 
Dạ! Thật lòng không biết nói gì ngoài lời cảm kích ngưỡng mộ Anh, em xin gửi lại file với nội dung mong muốn. Anh bớt chút thời gian xem qua và code giúp.
Trân trọng/
Phải chăng thế này? Hy vọng lần này đúng ý và không phải làm lại.
Nếu bạn ứng dụng nó vào việc tính lô, đề (hay đại loại là đánh bạc..), thì hãy tìm và liên hệ đến đội ngũ làm tín dụng đen, bảo họ giúp nhé. Tin chắc là nhận được sự giúp đỡ vô bờ bến. hihi
 

File đính kèm

Phải chăng thế này? Hy vọng lần này đúng ý và không phải làm lại.
Nếu bạn ứng dụng nó vào việc tính lô, đề (hay đại loại là đánh bạc..), thì hãy tìm và liên hệ đến đội ngũ làm tín dụng đen, bảo họ giúp nhé. Tin chắc là nhận được sự giúp đỡ vô bờ bến. hihi
Cám ơn Anh.
Phải chăng thế này? Hy vọng lần này đúng ý và không phải làm lại.
Nếu bạn ứng dụng nó vào việc tính lô, đề (hay đại loại là đánh bạc..), thì hãy tìm và liên hệ đến đội ngũ làm tín dụng đen, bảo họ giúp nhé. Tin chắc là nhận được sự giúp đỡ vô bờ bến. hihi
Cám ơn Anh đã chiếu cố! Nhưng khi chạy code thì lỗi báo
ReDim S(1 To 100)
For i = 4 To Lr
t = t + 1 .
Em dốt vụ VBA nên không biết chỉnh sao ạ!
 
Mình đoán mò thôi chứ vụ này cũng không xem file nữa.
"Em ngồi im xem các tiền bối để học hỏi vậy" cũng tương đương "Tọa sơn quan hổ chén"
Vào xem cũng đươc mà anh. Nhặt nhạnh được tý kiến thức nào thì hay tí ấy. Trong này toàn thành viên sịn mà em ngưỡng mộ ấy. Hihi.
 
Dựa vào code của thầy @HieuCD. Mình có chỉnh sửa theo ý muốn của chủ topic. Ai đó có thể chỉ giúp cách tối ưu hoặc giản số lần duyệt với ạ
Mã:
Sub ABC()
Application.ScreenUpdating = False
Dim a$(), b$(), Rng As Range, sRow&, i&, j&, C&, sCol&, x$(), y$()
Set Rng = Sheet1.Range("A4").CurrentRegion
sRow = Rng.Rows.Count
  sCol = Rng.Columns.Count
  ReDim a(1 To sRow, 1 To sCol - 1)
  ReDim x(1 To sRow, 1 To sCol - 1)
  ReDim b(1 To 2, 1 To sCol - 1)
  ReDim y(1 To 2, 1 To sCol - 1)
  For j = sCol - 1 To 1 Step -1
    b(1, j) = "Lien tuc co mau lien tiep " & sCol - j
    y(1, j) = "Khong co mau lien tiep " & sCol - j
  Next
  For i = 1 To sRow
    C = sCol - 1
    For j = sCol - 1 To 1 Step -1
        If Rng(i, sCol - 1).Interior.Color = vbYellow Then
            If Rng(i, j).Interior.Color = vbYellow Then C = C - 1
            If Rng(i, j).Interior.Color <> vbYellow Then
                a(i, C + 1) = Rng(i, sCol)
                If Len(b(2, C + 1)) Then b(2, C + 1) = b(2, C + 1) & "," & a(i, C + 1) Else b(2, C + 1) = a(i, C + 1)
                Exit For
            End If
        Else
            Exit For
        End If
    Next j
  Next i
For i = 1 To sRow
    C = sCol - 1
    For j = sCol - 1 To 1 Step -1
        If Rng(i, sCol - 1).Interior.Pattern = xlNone Then
        If Rng(i, j).Interior.Pattern = xlNone Then C = C - 1
            If Rng(i, j).Interior.Pattern <> xlNone Then
                x(i, C + 1) = Rng(i, sCol)
                If Len(y(2, C + 1)) Then y(2, C + 1) = y(2, C + 1) & "," & x(i, C + 1) Else y(2, C + 1) = x(i, C + 1)
                Exit For
            End If
        Else
            Exit For
        End If
    Next j
Next i
With Sheet1
  .Range("A2").Offset(, sCol + 2).Resize(100000, sCol * 2).ClearContents
  .Range("A2").Offset(, sCol + 2).Resize(2, sCol - 1).Value = b
  .Range("A4").Offset(, sCol + 2).Resize(sRow, sCol - 1).Value = a
  .Range("A2").Offset(, sCol * 2 + 3).Resize(2, sCol - 1).Value = y
  .Range("A4").Offset(, sCol * 2 + 3).Resize(sRow, sCol - 1).Value = x
End With
Application.ScreenUpdating = True
MsgBox "OK"
End Sub
 
Lần chỉnh sửa cuối:
Cám ơn Anh.

Cám ơn Anh đã chiếu cố! Nhưng khi chạy code thì lỗi báo
ReDim S(1 To 100)
For i = 4 To Lr
t = t + 1 .
Em dốt vụ VBA nên không biết chỉnh sao ạ!
Đúng như Anh@ Hoàng Tuấn 868 chuẩn đoán, khai vừa thiếu biến vừa thừa biến.
Bạn thay lại code cũ bằng code này.
Mã:
Option Explicit

Sub XYZ2()
Dim i&, j&, t&, k&, Z&, M&, Comau&, Kmau&, Lr&, Col&
Dim eRng As Range, Sh As Worksheet
Dim Arr(), KQK(), KQM(), SoLan(), TieudeC(), TieudeK()
Dim Dic As Object, Key
Dim Ketqua As Range

Application.ScreenUpdating = False

On Error Resume Next
Set Sh = Sheet1
Lr = Sh.Cells(Rows.Count, 1).End(xlUp).Row

ReDim KQM(1 To Lr - 3, 1 To 100)
ReDim KQK(1 To Lr - 3, 1 To 100)
ReDim TieudeC(1 To 1, 1 To 100)
ReDim TieudeK(1 To 1, 1 To 100)
For i = 4 To Lr
t = t + 1
Set eRng = Sh.Range(Cells(i, 1), Cells(i, Sh.Range("A" & i).End(xlToRight).Column))
Col = eRng.Columns.Count
    For j = Col To 1 Step -1
        If eRng(1, j) <> Empty Then
            If eRng(1, j).Interior.Color = vbYellow Then
                Comau = Comau + 1
            Else
               Kmau = Kmau + 1
                If Comau >= 1 Then Exit For
            End If
        End If
    Next j
        TieudeC(1, Comau) = "Liên tuc có màu liên tiêp " & Comau
        TieudeK(1, Kmau - 1) = "Liên tuc không có màu liên tiêp " & Kmau - 1
            KQM(t, Comau) = eRng(1, Col)
            KQK(t, Kmau - 1) = eRng(1, Col)
    If Comau > M Then M = Comau
       Comau = 0: Kmau = 0: Set Rng = Nothing
Next i

Sh.[J1].Resize(10000, 1000).ClearContents
Sh.[J1].Resize(1, M) = TieudeC
Sh.[J1].Resize(2, M).Interior.Color = vbYellow
Sh.[J1].Offset(0, M).Resize(1, M) = TieudeK
Sh.[J4].Resize(t, M) = KQM
Sh.[J4].Offset(0, M).Resize(t, M) = KQK

Arr = Sh.Range("J4", "J4").Resize(t, M * 2).Value
ReDim SoLan(1 To 1, 1 To UBound(Arr))

For i = 1 To UBound(Arr, 2)
Set Dic = CreateObject("Scripting.Dictionary")
    For j = 1 To UBound(Arr, 1)
        If Arr(j, i) <> Empty Then
            Key = Arr(j, i)
            If Not Dic.Exists(Key) Then
            k = k + 1: Dic.Add (Key), k
                If SoLan(1, i) = Empty Then SoLan(1, i) = Key Else SoLan(1, i) = SoLan(1, i) & "," & Key
            End If
        End If
    Next j
    Set Dic = Nothing
Next i
Sh.[J2].Resize(1, UBound(Arr)) = SoLan
Application.ScreenUpdating = True
MsgBox "OK!", vbInformation, "THÔNG BÁO"
End Sub
Nên tham khảo các code khác nữa nhé.
Bài đã được tự động gộp:

Chắc chắn kết quả chưa đúng ý thớt :D
Tôi thuộc tip người chậm hiểu nên không thể đoán đúng ý của chủ thớt, nhiều khi cứ code mò thôi. Ngay cả cái lỗi code bạn ấy đưa lên
" ...ReDim S(1 To 100)
For i = 4 To Lr
t = t + 1...."
Lỗi dòng nào? có bảng thông báo gì không? Cũng không nên cũng phải đoán đó là gì?
Tôi cũng nhắc bạn đó tham khảo các code khác. và vẫn nói bạn đó nếu sử dụng file tôi làm giúp bạn ấy vào mục đích chơi lô đề, đánh bạc... thì hãy chủ động liên hệ với đội ngũ làm tín dụng đen để được hỗ trợ, trợ giúp vô tư, vô bờ bến
 
Lần chỉnh sửa cuối:
File bài #63, rút bớt vòng for (Chưa kiểm lại kỹ không biết có lỗi gì không)
Mã:
Option Explicit

Sub Count_Color_NoColor()
Dim Rng As Range, I&, J&, R&, C&, Cols&, iColor&, NoColor&, colorArr$(), noColorArr$()
'--------------------------- Nhap lieu dau vao
Const MyColor = vbYellow
Const MyNoColor = xlNone
Const iR& = 3 'Dòng phía tren moi bang
Set Rng = Sheets("Sheet1").Range("A4:H26") 'Dong du lieu bat dau >=4
'----------------------------
R = Rng.Rows.Count: C = Rng.Columns.Count
Cols = C - 2 'Cot arr can offset
ReDim colorArr(1 To R + iR, 1 To Cols)
ReDim noColorArr(1 To R + iR, 1 To Cols)
For I = 1 To Cols
    colorArr(1, I) = "Lien tuc co mau lien tiep " & Cols + 1 - I
    noColorArr(1, I) = "Khong co mau lien tiep " & Cols + 1 - I
Next
For I = 1 To R
    iColor = 0: NoColor = 0
    For J = C - 1 To 2 Step -1
        If Rng(I, J).Interior.Color = MyColor Then
            If NoColor = 0 Then iColor = iColor + 1 Else Exit For
        ElseIf Rng(I, J).Interior.Pattern = MyNoColor Then
            If iColor = 0 Then NoColor = NoColor + 1 Else Exit For
        End If
    Next
    If iColor Then
        J = Cols + 1 - iColor
        colorArr(I + iR, J) = Rng(I, C).Text
        colorArr(2, J) = IIf(colorArr(2, J) = "", Rng(I, C).Text, colorArr(2, J) & "," & Rng(I, C).Text)
    Else
        J = Cols + 1 - NoColor
        noColorArr(I + iR, J) = Rng(I, C).Text
        noColorArr(2, J) = IIf(noColorArr(2, J) = "", Rng(I, C).Text, noColorArr(2, J) & "," & Rng(I, C).Text)
    End If
Next
Rng(1, C).Offset(-iR, 2).Resize(R + iR, Cols) = colorArr
Rng(1, C).Offset(-iR, Cols + 3).Resize(R + iR, Cols) = noColorArr
End Sub
 
File bài #63, rút bớt vòng for (Chưa kiểm lại kỹ không biết có lỗi gì không)
...
Trên tinh thần chia sẻ, học hỏi, bạn nên cho biết rút bớt vòng for thì được gì. Ví dụ, tiết kiệm được x lần con tính abc; tiết kiệm y lần chạy những dòng code def...
Tôi nói không phải do bắt bẻ. Chuyện tiết kiệm số lần tính là một trong những chỉ tiêu của refactor code.

Thỉnh thoảng có mấy người ở đây thách đố "giảm số vòng lặp" mà không thấy đưa mục đích gì.
 
Trên tinh thần chia sẻ, học hỏi, bạn nên cho biết rút bớt vòng for thì được gì. Ví dụ, tiết kiệm được x lần con tính abc; tiết kiệm y lần chạy những dòng code def...
Tôi nói không phải do bắt bẻ. Chuyện tiết kiệm số lần tính là một trong những chỉ tiêu của refactor code.

Thỉnh thoảng có mấy người ở đây thách đố "giảm số vòng lặp" mà không thấy đưa mục đích gì.
Thực ra em cũng không biết giải thích sao, em suy nghĩ kiểu như nếu đi chợ mà ra chợ xem hàng xong, nếu có món mình cần mua thì chạy về nhà lấy tiền ra để mua. Thay vào đó ta đem tiền đi từ đầu thì đỡ mệt. Vậy thôi bác :D, trong bài này em cũng chưa xem kỹ bài các bạn, chỉ là em nêu ra một cách làm khác giảm bớt vòng lặp đi thôi. Có vấn đề gì nhờ bác chỉ thêm!
 
Thực ra em cũng không biết giải thích sao, em suy nghĩ kiểu như nếu đi chợ mà ra chợ xem hàng xong, nếu có món mình cần mua thì chạy về nhà lấy tiền ra để mua. Thay vào đó ta đem tiền đi từ đầu thì đỡ mệt. Vậy thôi bác :D, trong bài này em cũng chưa xem kỹ bài các bạn, chỉ là em nêu ra một cách làm khác giảm bớt vòng lặp đi thôi. Có vấn đề gì nhờ bác chỉ thêm!
Tôi lười mở file bài #63 ra để xem code mà so sánh. Để dịp khác vậy.

Đại khái 1 cách so sánh:
For i = 1 To SoDong
For j = 1 To SoCot
a(i, j) = etCetera
Next j
Next i
Gom lại thành 1 vòng lặp:
For i = 1 To SoDong*SoCot
a((i-1)\SoCot+1, ((i-1) Mod SoCot)+1) = etCetera
Next i
Code ngắn hơn. Giảm được 1 vòng lặp, tức là giảm được SoDong lần đếm j từ 1 đến SoCot. Nói cách khác là giảm được SoDong*SoCot lần đếm trị j.
Ngược lại, mất SoDong*SoCot lần tính hai chỉ số mảng.
Số lần code gán etCetera như nhau. Số lần Goto (Next tức là Goto For) như nhau.
Như vậy, trước mắt là lỗ. Bởi con toán tính chỉ số phức tạp hơn con toán tăng 1 nhiều.

Vậy thì giảm từ 2 xuống 1 vòng lặp còn khác nhau những gì?
Câu trả lời sẽ hơi lạ đối với người mới viết code.
Khi ta có lệnh Exit For.
1 vòng lặp Exit là hết luôn.
2 vòng lặp Exit vòng trong vẫn còn vòng ngoài. Muốn hết luôn thì phải có code test và Exit lần nữa.
Như vậy, người ta có thể chọn loại Exit mà áp dụng 1 hay 2 vòng lặp.

Những điểm khác nhau còn lại thuộc về dạng cao cấp. Điển hình khi lệnh khởi vòng lặp có biểu thức gọi các hàm người dùng khác.
 
Dạ em gửi lại anh file. Nội dung mong muốn em viết ở trong file ak!
Bài đã được tự động gộp:
Chạy code . . .
Mã:
Sub XYZ()
  Dim sh As Worksheet, a$(), b$(), rng As Range
  Dim sRow&, Col&, i&, j&, c&, dC&, bYellow As Boolean
  Const sCol& = 20 'So cot ket qua
 
  Set sh = Sheets("Sheet1")
  Set rng = sh.Range("A4", sh.Range("X" & Rows.Count).End(xlUp))
  sRow = rng.Rows.Count: Col = rng.Columns.Count - 1
  ReDim a(1 To sRow, 1 To 2 * sCol + 2)
  ReDim b(1 To 1, 1 To 2 * sCol + 2)
  For i = 1 To sRow
    c = sCol + 1
    If rng(i, Col).Interior.Color = vbYellow Then
      bYellow = True
      dC = 0
    Else
      bYellow = False
      dC = sCol + 2
    End If
    For j = Col To 1 Step -1
      If (rng(i, j).Interior.Color = vbYellow) = bYellow Then
        c = c - 1
      Else
        If c >= 1 Then
          c = c + dC
          a(i, c) = rng(i, Col + 1)
          If InStr(1, b(1, c), a(i, c)) = 0 Then
            If Len(b(1, c)) Then b(1, c) = b(1, c) & "," & a(i, c) Else b(1, c) = a(i, c)
          End If
          Exit For
        End If
      End If
    Next j
  Next i
  sh.Range("Z2:BO10000").Clear
  sh.Range("Z4").Resize(sRow, 2 * sCol + 2) = a
  sh.Range("Z2").Resize(, 2 * sCol + 2) = b
End Sub
 
Vô bờ bến thì không có vấn đề gì. Nhưng dân không biết đọc code thì làm sao biết là code vô tư?
Tôi chỉ muốn nhắc bạn ấy là nếu sử dụng file tôi để tính toán lô đề, cờ bạc gửi thì hãy cảnh giác (có thể sẽ phải ra đê để ở...). Vì có thể sẽ không đem lại kết quả sau cùng như mong muốn.
Còn bạn ấy có hiểu hay không hiểu thì bạn ấy cứ đọc hết các bài thì cũng có thể hiểu được code vô tư hay không vô tư.
 
Đúng như Anh@ Hoàng Tuấn 868 chuẩn đoán, khai vừa thiếu biến vừa thừa biến.
Bạn thay lại code cũ bằng code này.
Mã:
Option Explicit

Sub XYZ2()
Dim i&, j&, t&, k&, Z&, M&, Comau&, Kmau&, Lr&, Col&
Dim eRng As Range, Sh As Worksheet
Dim Arr(), KQK(), KQM(), SoLan(), TieudeC(), TieudeK()
Dim Dic As Object, Key
Dim Ketqua As Range

Application.ScreenUpdating = False

On Error Resume Next
Set Sh = Sheet1
Lr = Sh.Cells(Rows.Count, 1).End(xlUp).Row

ReDim KQM(1 To Lr - 3, 1 To 100)
ReDim KQK(1 To Lr - 3, 1 To 100)
ReDim TieudeC(1 To 1, 1 To 100)
ReDim TieudeK(1 To 1, 1 To 100)
For i = 4 To Lr
t = t + 1
Set eRng = Sh.Range(Cells(i, 1), Cells(i, Sh.Range("A" & i).End(xlToRight).Column))
Col = eRng.Columns.Count
    For j = Col To 1 Step -1
        If eRng(1, j) <> Empty Then
            If eRng(1, j).Interior.Color = vbYellow Then
                Comau = Comau + 1
            Else
               Kmau = Kmau + 1
                If Comau >= 1 Then Exit For
            End If
        End If
    Next j
        TieudeC(1, Comau) = "Liên tuc có màu liên tiêp " & Comau
        TieudeK(1, Kmau - 1) = "Liên tuc không có màu liên tiêp " & Kmau - 1
            KQM(t, Comau) = eRng(1, Col)
            KQK(t, Kmau - 1) = eRng(1, Col)
    If Comau > M Then M = Comau
       Comau = 0: Kmau = 0: Set Rng = Nothing
Next i

Sh.[J1].Resize(10000, 1000).ClearContents
Sh.[J1].Resize(1, M) = TieudeC
Sh.[J1].Resize(2, M).Interior.Color = vbYellow
Sh.[J1].Offset(0, M).Resize(1, M) = TieudeK
Sh.[J4].Resize(t, M) = KQM
Sh.[J4].Offset(0, M).Resize(t, M) = KQK

Arr = Sh.Range("J4", "J4").Resize(t, M * 2).Value
ReDim SoLan(1 To 1, 1 To UBound(Arr))

For i = 1 To UBound(Arr, 2)
Set Dic = CreateObject("Scripting.Dictionary")
    For j = 1 To UBound(Arr, 1)
        If Arr(j, i) <> Empty Then
            Key = Arr(j, i)
            If Not Dic.Exists(Key) Then
            k = k + 1: Dic.Add (Key), k
                If SoLan(1, i) = Empty Then SoLan(1, i) = Key Else SoLan(1, i) = SoLan(1, i) & "," & Key
            End If
        End If
    Next j
    Set Dic = Nothing
Next i
Sh.[J2].Resize(1, UBound(Arr)) = SoLan
Application.ScreenUpdating = True
MsgBox "OK!", vbInformation, "THÔNG BÁO"
End Sub
Nên tham khảo các code khác nữa nhé.
Bài đã được tự động gộp:


Tôi thuộc tip người chậm hiểu nên không thể đoán đúng ý của chủ thớt, nhiều khi cứ code mò thôi. Ngay cả cái lỗi code bạn ấy đưa lên
" ...ReDim S(1 To 100)
For i = 4 To Lr
t = t + 1...."
Lỗi dòng nào? có bảng thông báo gì không? Cũng không nên cũng phải đoán đó là gì?
Tôi cũng nhắc bạn đó tham khảo các code khác. và vẫn nói bạn đó nếu sử dụng file tôi làm giúp bạn ấy vào mục đích chơi lô đề, đánh bạc... thì hãy chủ động liên hệ với đội ngũ làm tín dụng đen để được hỗ trợ, trợ giúp vô tư, vô bờ bến
Dạ mong anh bỏ quá cho, không biết nói gì ngoài Cảm ơn Anh. Chúc Anh luôn mạnh khoẻ và Thành đạt!!!
 
Web KT

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

Back
Top Bottom