cách chia nhóm theo 3 tiêu chí: điểm số, giới tính và số lượng thành viên

Liên hệ QC

hoahongden142917

Thành viên hoạt động
Tham gia
28/5/13
Bài viết
179
Được thích
20
Kính chào các anh chị. Em có 1 file excel muốn thiết lập cho nó tự chia các em học sinh trong lớp thành nhiều nhóm nhỏ với 3 tiêu chí sau: mỗi nhóm có n em (nếu cò dư từ 1 đến 2 em thì cho nó vào bất kì nhóm nào cũng được), mỗi nhóm đều có nam và nữ, phân đều năng lực các em dựa theo điểm số về các nhóm
Phân bổ năng lực theo điểm số:
Từ 8 đến 10 điểm: A
Từ 7,5 đến dưới 8: B
Từ 6,5 đến dưới 7,5: C
Từ 5 đến dưới 6,5: D
Ví dụ: một lớp có tối đa 45 em (theo quy định): giả sử thầy đó chọn n = 5 (có 5 em/nhóm) thì chia ra có 9 nhóm trong đó mỗi nhóm có nam và nữ trộn vào (hoặc là 5 nam, 4 nữ hoặc là 4 nam, 5 nữ, hoặc nếu ít nữ thì chia 6 nam 3 nữ), mỗi nhóm có đủ A, B, C, D hoặc A, A, B, C, D hoặc A, B, B, C, D.
Rất mong được anh chị giúp đỡ, xin cảm ơn ạ.
 

File đính kèm

  • chia nhom.xls
    46 KB · Đọc: 23
Giải pháp
Em đã thử code của anh rồi. Nó cho kết quả nhanh và chính xác số lượng học sinh trên nhóm, điểm số cũng phân phù hợp giữa các nhóm, giới tính cũng tương đối đồng đều. Em chân thành cảm ơn anh HIEUCD. Em cũng chân thành cảm ơn anh HUONGHCKT đã nhiệt tình giúp đỡ cho em. Em cảm ơn các anh chị đã quan tâm đến chủ đề này. Trân trọng.
Điều chỉnh lại phân bổ giới tình và thống kê kết quả
Mã:
Option Explicit
Sub XYZ()
  Dim sh As Worksheet
  Dim arr(), aDiem, aTK(), a, b, c, d, res()
  Dim soHS&, soNhom&, N&, i&, r&, j&, k&, gt&, le&
  Dim soNu&, nMin&, nMax&, t&, hl&, iDC&, tmp$
 
  Set sh = Sheets("8a2")
  arr = sh.Range("D2", sh.Range("E" & Rows.Count).End(xlUp)).Value
  soHS = UBound(arr)
 
  On Error Resume Next
  N = InputBox("Hay...
Chủ đề phân nhóm học sinh này đang hot, nhất là sắp đến mùa tựu trường, và năm nay bộ GD đang lại mở thêm 1 chương mới cho sự nghiệp "đổi mới".
BX mình cũng trong nghề, và mình cũng vừa làm cho bả cái này xong.
 
Upvote 0
Dạng bài này không hề đơn giản, nhất là khi dữ liệu không có tính cân xứng. Thớt cũng không mô tả quy luật ưu tiên trong từng trường hợp cụ thể nên tôi cũng không bàn thêm.
--
Xét trong trường hợp đơn giản nhất như sau:
Lớp có 32 học sinh, trong đó:
- 8 học sinh nữ điểm 9
- 8 học sinh nữ điểm 5
- 8 học sinh nam điểm 9
- 8 học sinh nam điểm 5
Cần chia thành 16 nhóm với mỗi nhóm có 2 học sinh

Dễ thấy với dữ liệu như trên cách chia phù hợp với yêu cầu của đầu bài là học sinh nữ điểm 5 chung nhóm với học sinh nam điểm 9 và học sinh nữ điểm 9 chung nhóm với học sinh nam điểm 5 nhưng code này chưa chia được như vậy.
Chia ngẫu nhiên với dữ liệu ngẫu nhiên khó đáp ứng đồng đều, code mình chỉ xử lý cơ bản còn 2 điểm chưa đều ngẫu nhiên , viết khá rối nên bỏ qua :) vì trong thực tế không quan trọng lắm :p
 
Upvote 0
Dạng bài này không hề đơn giản, nhất là khi dữ liệu không có tính cân xứng. Thớt cũng không mô tả quy luật ưu tiên trong từng trường hợp cụ thể nên tôi cũng không bàn thêm.
--
Xét trong trường hợp đơn giản nhất như sau:
Lớp có 32 học sinh, trong đó:
- 8 học sinh nữ điểm 9
- 8 học sinh nữ điểm 5
- 8 học sinh nam điểm 9
- 8 học sinh nam điểm 5
Cần chia thành 16 nhóm với mỗi nhóm có 2 học sinh

Dễ thấy với dữ liệu như trên cách chia phù hợp với yêu cầu của đầu bài là học sinh nữ điểm 5 chung nhóm với học sinh nam điểm 9 và học sinh nữ điểm 9 chung nhóm với học sinh nam điểm 5 nhưng code này chưa chia được như vậy.
Tôi cũng đã có suy nghĩ như anh, Do vậy trong code khi tính đến các học sinh nam xếp vào các nhóm tôi đã cho có sort trước phần học lực và chạy code từ cuối mảng lên đầu, tuy nhiên nó vẫn bị không thỏa với từng điều kiện cụ thể, ví dụ chia 45 học sinh thành 11 nhóm (mỗi nhóm 4 hs) thì OK nhưng khi chia mỗi nhóm là 7 thì bạn chủ thớt nói không thỏa.
 
Upvote 0
Sort dữ liệu theo giới tính và năng lực xếp nhóm khá dể
Mã:
Sub XYZ()
  Dim Sh As Worksheet
  Dim arr(), aDiem, a, b, res()
  Dim soHS&, soNhom&, N&, i&, j&, k&, gt&
 
  Set Sh = Sheets("8a2")
  arr = Sh.Range("D2", Sh.Range("E" & Rows.Count).End(xlUp)).Value
  soHS = UBound(arr)
 
  On Error Resume Next
  N = InputBox("Hay nhap so hoc sinh cua 1 nhom vào o bên duoi", "CHIA HOC SINH THEO NHOM")
  If N = 0 Then
    MsgBox " Ban phai nhap sô hoc sinh cua 1 nhóm": Exit Sub
  End If
  If N > soHS Then N = soHS
 
  Randomize
  ReDim res(1 To soHS, 1 To 1)
  ReDim a(1 To 8) 'Chia HS thanh 8 nhom theo Gioi Tinh va Diem
  aDiem = Array(0, 8, 7.5, 6.5, 5)
  For i = 1 To soHS
    If Len(arr(i, 1)) = 2 Then gt = 0 Else gt = 1
    For j = 1 To 4
      If arr(i, 2) >= aDiem(j) Then
        a(j * 2 - gt) = a(j * 2 - gt) & "," & i
        Exit For
      End If
    Next j
  Next i
  a = Split(Join(a, ""), ",") 'xep thu tu HS theo GT va Diem
 
  soNhom = Int(soHS / N) 'Phan nhom HS thanh soNhom
  Do
    Call TaoMangNgauNhien(b, soNhom)
    For j = 1 To soNhom
      k = k + 1
      res(a(k), 1) = b(j)
      If k = soHS Then
        Sh.Range("F2").Resize(soHS) = res
        Exit Sub
      End If
    Next j
  Loop
End Sub

Sub TaoMangNgauNhien(aRnd, ByVal N)
  Dim i&, t&, r&
  ReDim aRnd(1 To N)
  For i = 1 To N
    r = Int(Rnd * N) + 1
    If aRnd(r) = 0 Then t = r Else t = aRnd(r)
    If aRnd(N) = 0 Then aRnd(r) = N Else aRnd(r) = aRnd(N)
    aRnd(N) = t
    N = N - 1
  Next i
End Sub
Em đã thử code của anh rồi. Nó cho kết quả nhanh và chính xác số lượng học sinh trên nhóm, điểm số cũng phân phù hợp giữa các nhóm, giới tính cũng tương đối đồng đều. Em chân thành cảm ơn anh HIEUCD. Em cũng chân thành cảm ơn anh HUONGHCKT đã nhiệt tình giúp đỡ cho em. Em cảm ơn các anh chị đã quan tâm đến chủ đề này. Trân trọng.
 
Upvote 0
Chủ đề phân nhóm học sinh này đang hot, nhất là sắp đến mùa tựu trường, và năm nay bộ GD đang lại mở thêm 1 chương mới cho sự nghiệp "đổi mới".
BX mình cũng trong nghề, và mình cũng vừa làm cho bả cái này xong.
Vậy hả anh. Anh có thể chia sẻ cho em xin file để em học hỏi để áp dụng cho lớp học sinh của em với. Em cảm ơn anh
 
Upvote 0
Dạng bài này không hề đơn giản, nhất là khi dữ liệu không có tính cân xứng. Thớt cũng không mô tả quy luật ưu tiên trong từng trường hợp cụ thể nên tôi cũng không bàn thêm.
--
Xét trong trường hợp đơn giản nhất như sau:
Lớp có 32 học sinh, trong đó:
- 8 học sinh nữ điểm 9
- 8 học sinh nữ điểm 5
- 8 học sinh nam điểm 9
- 8 học sinh nam điểm 5
Cần chia thành 16 nhóm với mỗi nhóm có 2 học sinh

Dễ thấy với dữ liệu như trên cách chia phù hợp với yêu cầu của đầu bài là học sinh nữ điểm 5 chung nhóm với học sinh nam điểm 9 và học sinh nữ điểm 9 chung nhóm với học sinh nam điểm 5 nhưng code này chưa chia được như vậy.
em cảm ơn anh. Theo tiêu chí chính là dựa vào điểm (tạm quy ước nó là cơ sở ban đầu để chia theo năng lực), dĩ nhiên cũng phải nam nữ trong nhóm cho hài hòa (vì đó là tôn trọng nữ giới và không khí học tập không căng thẳng). Em cũng thiên về ý định dựa vào điểm số là cái ưu tiên số 1, còn nữ thì tương đối cũng đủ rồi.
Còn nếu chia chính xác như anh nói ở trên thì cũng rất tốt anh ạ. Anh có cách giải quyết nó hả anh
 
Upvote 0
Xin các anh xem giúp về tỉ lệ phân bổ số lượng các em có cùng mức năng lực (ví dụ B cho khoảng điểm 7,5->8), nhóm 1/2/3/4/5 có tỉ lệ phân bổ năng lực B tương ứng là 1/3/1/2/1.
Như vậy em thấy nó phân bổ các em có năng lực B về nhóm 2 tới 3 em, trong khi nhóm 1, nhóm 3 với nhóm 5 chỉ có 1 em có năng lực B.
Các anh chỉnh cái này được chứ ạ.
Em xin cảm ơn
 

File đính kèm

  • chia theo nhom (3) (1).xlsm
    40.1 KB · Đọc: 5
Upvote 0
Em đã thử code của anh rồi. Nó cho kết quả nhanh và chính xác số lượng học sinh trên nhóm, điểm số cũng phân phù hợp giữa các nhóm, giới tính cũng tương đối đồng đều. Em chân thành cảm ơn anh HIEUCD. Em cũng chân thành cảm ơn anh HUONGHCKT đã nhiệt tình giúp đỡ cho em. Em cảm ơn các anh chị đã quan tâm đến chủ đề này. Trân trọng.
Điều chỉnh lại phân bổ giới tình và thống kê kết quả
Mã:
Option Explicit
Sub XYZ()
  Dim sh As Worksheet
  Dim arr(), aDiem, aTK(), a, b, c, d, res()
  Dim soHS&, soNhom&, N&, i&, r&, j&, k&, gt&, le&
  Dim soNu&, nMin&, nMax&, t&, hl&, iDC&, tmp$
 
  Set sh = Sheets("8a2")
  arr = sh.Range("D2", sh.Range("E" & Rows.Count).End(xlUp)).Value
  soHS = UBound(arr)
 
  On Error Resume Next
  N = InputBox("Hay nhap so hoc sinh cua 1 nhom vào o bên duoi", "CHIA HOC SINH THEO NHOM")
  If N = 0 Then
    MsgBox " Ban phai nhap sô hoc sinh cua 1 nhóm": Exit Sub
  End If
  If N > soHS Then N = soHS
  soNhom = Int(soHS / N) 'Phan HS thanh soNhom NHOM
  On Error GoTo 0
 
  Randomize
  ReDim res(1 To soHS, 1 To 2)
  ReDim aTK(1 To soNhom, 0 To 6)
  ReDim a(1 To 8) 'Chia HS thanh 8 nhom theo Gioi Tinh va Diem
  ReDim d(1 To 8) 'Hoc luc
  aDiem = Array(0, 8, 7.5, 6.5, 5)
 
  For i = 1 To soHS 'xep thu tu HS theo GT va Diem
    If Len(arr(i, 1)) = 2 Then
      gt = 0
      soNu = soNu + 1
    Else
      gt = 1
    End If
    For j = 1 To 4
      If arr(i, 2) >= aDiem(j) Then
        a(j * 2 - gt) = a(j * 2 - gt) & "," & i
        d(j * 2 - gt) = d(j * 2 - gt) & "," & j
        Exit For
      End If
    Next j
  Next i
  a = Split(Join(a, ""), ",") 'Mang HS xep thu tu theo GT va Diem
  d = Split(Join(d, ""), ",") 'Mang Loai Hoc luc
  nMin = Int(soNu / soNhom) 'So nu it nhat trong 1 nhom
  If nMin * soNhom = soNu Then nMax = nMin Else nMax = nMin + 1 'So nu nhieu nhat trong 1 nhom

  le = soHS - soNhom * N
  If le > 0 Then 'Chon ngau nhien HS le nhom
    Call TaoMangNgauNhien(c, soHS)
    Call TaoMangNgauNhien(b, soNhom)
    For j = 1 To le
      r = c(j)
      res(a(r), 1) = b(j)
      res(a(r), 2) = d(r)
      If Len(arr(a(r), 1)) = 2 Then aTK(b(j), 2) = aTK(b(j), 2) + 1
      a(r) = Empty
    Next j
  End If

  Do 'Chon ngau nhien HS phan vào các nhóm
    Call TaoMangNgauNhien(b, soNhom)
    For j = 1 To soNhom
      k = k + 1
      If k > soHS Then Exit Do
      If a(k) <> Empty Then
        res(a(k), 1) = b(j)
        res(a(k), 2) = d(k)
        If Len(arr(a(k), 1)) = 2 Then aTK(b(j), 2) = aTK(b(j), 2) + 1
      Else
        j = j - 1
      End If
    Next j
  Loop
 
DieuChinhTiep:
  For i = 1 To soNhom 'Dieu chinh so nu
    If aTK(i, 2) < nMin Or aTK(i, 2) > nMax Then 'Nhom dieu chinh Tang HS Nu
      t = soHS + 1
      For r = 1 To soNhom
        If t > aTK(r, 2) Then
          t = aTK(r, 2)
          iDC = r 'nhom co so Nu it nhat
        End If
      Next r
      t = 0
      For r = 1 To soNhom
        If t < aTK(r, 2) Then
          t = aTK(r, 2)
          k = r 'nhom co so nu nhieu nhat
        End If
      Next r
      tmp = Empty
TroLai:
      For r = 1 To soHS
        If res(r, 1) = i And Len(arr(r, 1)) <> 2 Then 'Nhom dieu chinh Tang HS Nu và HS Nam
          hl = res(r, 2) 'Hoc luc
          If InStr(1, tmp, hl) = 0 Then
            tmp = tmp & hl
            For c = 1 To soHS
              If Len(arr(c, 1)) = 2 And res(c, 1) = k And res(c, 2) = hl Then 'HS Nu và nhom co Nu nhieu nhat và cung Hoc luc
                t = res(c, 1)
                res(c, 1) = res(r, 1)
                res(r, 1) = t
                aTK(iDC, 2) = aTK(iDC, 2) + 1
                aTK(t, 2) = aTK(t, 2) - 1
                GoTo DieuChinhTiep
              End If
            Next c
            If c > soHS Then GoTo TroLai
          End If
        End If
      Next r
    End If
  Next i
  sh.Range("F2").Resize(soHS, 2) = res
  Call ThongKe(sh, res, aTK, soHS) 'Bang Thong ke ket qua phan nhom
End Sub

Sub ThongKe(sh, res, aTK, soHS)
'aTK co 7 Cot:Nhom, So Hoc Sinh, So Nu, Hoc luc A, B, C, D
  Dim i&, r&, c&
  For i = 1 To soHS
    r = res(i, 1)
    c = res(i, 2) + 2
    aTK(r, 1) = aTK(r, 1) + 1
    aTK(r, c) = aTK(r, c) + 1
  Next i
  For i = 1 To UBound(aTK)
    aTK(i, 0) = i
  Next i
  sh.Range("I2").Resize(soHS, 7).ClearContents
  sh.Range("I2").Resize(UBound(aTK), 7) = aTK
End Sub

Sub TaoMangNgauNhien(aRnd, ByVal N)
  Dim i&, t&, r&
  ReDim aRnd(1 To N)
  For i = 1 To N
    r = Int(Rnd * N) + 1
    If aRnd(r) = 0 Then t = r Else t = aRnd(r)
    If aRnd(N) = 0 Then aRnd(r) = N Else aRnd(r) = aRnd(N)
    aRnd(N) = t
    N = N - 1
  Next i
End Sub
 
Upvote 0
Giải pháp
Điều chỉnh lại phân bổ giới tình và thống kê kết quả
Mã:
Option Explicit
Sub XYZ()
  Dim sh As Worksheet
  Dim arr(), aDiem, aTK(), a, b, c, d, res()
  Dim soHS&, soNhom&, N&, i&, r&, j&, k&, gt&, le&
  Dim soNu&, nMin&, nMax&, t&, hl&, iDC&, tmp$
 
  Set sh = Sheets("8a2")
  arr = sh.Range("D2", sh.Range("E" & Rows.Count).End(xlUp)).Value
  soHS = UBound(arr)
 
  On Error Resume Next
  N = InputBox("Hay nhap so hoc sinh cua 1 nhom vào o bên duoi", "CHIA HOC SINH THEO NHOM")
  If N = 0 Then
    MsgBox " Ban phai nhap sô hoc sinh cua 1 nhóm": Exit Sub
  End If
  If N > soHS Then N = soHS
  soNhom = Int(soHS / N) 'Phan HS thanh soNhom NHOM
  On Error GoTo 0
 
  Randomize
  ReDim res(1 To soHS, 1 To 2)
  ReDim aTK(1 To soNhom, 0 To 6)
  ReDim a(1 To 8) 'Chia HS thanh 8 nhom theo Gioi Tinh va Diem
  ReDim d(1 To 8) 'Hoc luc
  aDiem = Array(0, 8, 7.5, 6.5, 5)
 
  For i = 1 To soHS 'xep thu tu HS theo GT va Diem
    If Len(arr(i, 1)) = 2 Then
      gt = 0
      soNu = soNu + 1
    Else
      gt = 1
    End If
    For j = 1 To 4
      If arr(i, 2) >= aDiem(j) Then
        a(j * 2 - gt) = a(j * 2 - gt) & "," & i
        d(j * 2 - gt) = d(j * 2 - gt) & "," & j
        Exit For
      End If
    Next j
  Next i
  a = Split(Join(a, ""), ",") 'Mang HS xep thu tu theo GT va Diem
  d = Split(Join(d, ""), ",") 'Mang Loai Hoc luc
  nMin = Int(soNu / soNhom) 'So nu it nhat trong 1 nhom
  If nMin * soNhom = soNu Then nMax = nMin Else nMax = nMin + 1 'So nu nhieu nhat trong 1 nhom

  le = soHS - soNhom * N
  If le > 0 Then 'Chon ngau nhien HS le nhom
    Call TaoMangNgauNhien(c, soHS)
    Call TaoMangNgauNhien(b, soNhom)
    For j = 1 To le
      r = c(j)
      res(a(r), 1) = b(j)
      res(a(r), 2) = d(r)
      If Len(arr(a(r), 1)) = 2 Then aTK(b(j), 2) = aTK(b(j), 2) + 1
      a(r) = Empty
    Next j
  End If

  Do 'Chon ngau nhien HS phan vào các nhóm
    Call TaoMangNgauNhien(b, soNhom)
    For j = 1 To soNhom
      k = k + 1
      If k > soHS Then Exit Do
      If a(k) <> Empty Then
        res(a(k), 1) = b(j)
        res(a(k), 2) = d(k)
        If Len(arr(a(k), 1)) = 2 Then aTK(b(j), 2) = aTK(b(j), 2) + 1
      Else
        j = j - 1
      End If
    Next j
  Loop
 
DieuChinhTiep:
  For i = 1 To soNhom 'Dieu chinh so nu
    If aTK(i, 2) < nMin Or aTK(i, 2) > nMax Then 'Nhom dieu chinh Tang HS Nu
      t = soHS + 1
      For r = 1 To soNhom
        If t > aTK(r, 2) Then
          t = aTK(r, 2)
          iDC = r 'nhom co so Nu it nhat
        End If
      Next r
      t = 0
      For r = 1 To soNhom
        If t < aTK(r, 2) Then
          t = aTK(r, 2)
          k = r 'nhom co so nu nhieu nhat
        End If
      Next r
      tmp = Empty
TroLai:
      For r = 1 To soHS
        If res(r, 1) = i And Len(arr(r, 1)) <> 2 Then 'Nhom dieu chinh Tang HS Nu và HS Nam
          hl = res(r, 2) 'Hoc luc
          If InStr(1, tmp, hl) = 0 Then
            tmp = tmp & hl
            For c = 1 To soHS
              If Len(arr(c, 1)) = 2 And res(c, 1) = k And res(c, 2) = hl Then 'HS Nu và nhom co Nu nhieu nhat và cung Hoc luc
                t = res(c, 1)
                res(c, 1) = res(r, 1)
                res(r, 1) = t
                aTK(iDC, 2) = aTK(iDC, 2) + 1
                aTK(t, 2) = aTK(t, 2) - 1
                GoTo DieuChinhTiep
              End If
            Next c
            If c > soHS Then GoTo TroLai
          End If
        End If
      Next r
    End If
  Next i
  sh.Range("F2").Resize(soHS, 2) = res
  Call ThongKe(sh, res, aTK, soHS) 'Bang Thong ke ket qua phan nhom
End Sub

Sub ThongKe(sh, res, aTK, soHS)
'aTK co 7 Cot:Nhom, So Hoc Sinh, So Nu, Hoc luc A, B, C, D
  Dim i&, r&, c&
  For i = 1 To soHS
    r = res(i, 1)
    c = res(i, 2) + 2
    aTK(r, 1) = aTK(r, 1) + 1
    aTK(r, c) = aTK(r, c) + 1
  Next i
  For i = 1 To UBound(aTK)
    aTK(i, 0) = i
  Next i
  sh.Range("I2").Resize(soHS, 7).ClearContents
  sh.Range("I2").Resize(UBound(aTK), 7) = aTK
End Sub

Sub TaoMangNgauNhien(aRnd, ByVal N)
  Dim i&, t&, r&
  ReDim aRnd(1 To N)
  For i = 1 To N
    r = Int(Rnd * N) + 1
    If aRnd(r) = 0 Then t = r Else t = aRnd(r)
    If aRnd(N) = 0 Then aRnd(r) = N Else aRnd(r) = aRnd(N)
    aRnd(N) = t
    N = N - 1
  Next i
End Sub
Em cảm ơn anh. Em đã chạy thử thì phát hiện rằng khi mình chia nhóm theo số chia hết thì tốt. Nhưng khi mình chia nhóm theo số dư (6 em/nhóm thì dư 3 em) nó bổ 3 em đó vào nhóm 1, 3, và 5 nên nó bị 3 em loại a vào nhóm 1, trong khi chỉ có 1 em loại a ở nhóm 2. Tương tự cũng có 3 em loại d ở nhóm 3 trong khi chỉ có 1 em loại d ở nhóm 1.
Cách em khắc phục là em nhập số 6 em/nhóm cho chạy code như vậy 3 lần thì nó mới bổ đều ra.
Em cảm ơn anh
 

File đính kèm

  • Screenshot 2023-08-13 064338.png
    Screenshot 2023-08-13 064338.png
    165 KB · Đọc: 9
Lần chỉnh sửa cuối:
Upvote 0
EM CẢM ƠN ANH. EM ĐÃ TEST THÌ PHÁT HIỆN RẰNG KHI MÌNH CHIA NHÓM THEO SỐ CHIA HẾT THÌ TỐT. NHƯNG KHI MÌNH CHIA NHÓM THEO SỐ DƯ (6 EM/NHÓM THÌ DƯ 3 EM) NÓ BỔ 3 EM ĐÓ VÀO NHÓM 1, 3, VÀ 5 NÊN NÓ BỊ 3 EM LOẠI A VÀO NHÓM 1, TRONG KHI CHỈ CÓ 1 EM LOẠI A Ở NHÓM 2. TƯƠNG TỰ CŨNG CÓ 3 EM LOẠI D Ở NHÓM 3 TRONG KHI CHỈ CÓ 1 EM LOẠI D Ở NHÓM 1.
CÁCH EM KHẮC PHỤC LÀ EM NHẬP SỐ 6 EM/NHÓM CHO CHẠY CODE NHƯ VẬY 3 LẦN THÌ NÓ MỚI BỔ ĐỀU RA.
EM CẢM ƠN ANH
Bạn nên chuyển về chữ thường, Nội quy diễn đàn có quy định không được viết hoa toàn bộ bài viết.

II. Hình thức của bài viết:
3. Không được viết hoa và/hoặc sử dụng màu đỏ trong cả bài viết. Màu đỏ chỉ dành cho người điều hành diễn đàn.
 
Upvote 1
EM CẢM ƠN ANH. EM ĐÃ TEST THÌ PHÁT HIỆN RẰNG KHI MÌNH CHIA NHÓM THEO SỐ CHIA HẾT THÌ TỐT. NHƯNG KHI MÌNH CHIA NHÓM THEO SỐ DƯ (6 EM/NHÓM THÌ DƯ 3 EM) NÓ BỔ 3 EM ĐÓ VÀO NHÓM 1, 3, VÀ 5 NÊN NÓ BỊ 3 EM LOẠI A VÀO NHÓM 1, TRONG KHI CHỈ CÓ 1 EM LOẠI A Ở NHÓM 2. TƯƠNG TỰ CŨNG CÓ 3 EM LOẠI D Ở NHÓM 3 TRONG KHI CHỈ CÓ 1 EM LOẠI D Ở NHÓM 1.
CÁCH EM KHẮC PHỤC LÀ EM NHẬP SỐ 6 EM/NHÓM CHO CHẠY CODE NHƯ VẬY 3 LẦN THÌ NÓ MỚI BỔ ĐỀU RA.
EM CẢM ƠN ANH
Do chọn ngẫu nhiên nên kết quả hên xui, xử lý tương tự như giới tính cũng được nhưng làm code rối thêm, chịu khó bấm code đến khi thỏa thì dừng :p
Lưu ý không nên viết in toàn bộ
 
Upvote 0
Bạn nên chuyển về chữ thường, Nội quy diễn đàn có quy định không được viết hoa toàn bộ bài viết.

II. Hình thức của bài viết:
3. Không được viết hoa và/hoặc sử dụng màu đỏ trong cả bài viết. Màu đỏ chỉ dành cho người điều hành diễn đàn.
Dạ vâng. Em đang đi chợ. Về tới em mở máy lên chỉnh lại ạ. Em cảm ơn anh
 
Upvote 0
Do chọn ngẫu nhiên nên kết quả hên xui, xử lý tương tự như giới tính cũng được nhưng làm code rối thêm, chịu khó bấm code đến khi thỏa thì dừng :p
Lưu ý không nên viết in toàn bộ
em vận hành một thời gian thì phát hiện có 1 quy luật bị lỗi ạ: "Nếu số học sinh dư > số nhóm" thì nó debug ạ. Cụ thể khi tổng số học sinh 29 em mà ta chia mỗi nhóm 6 em thì dư 5 em. Ta thấy 5 em dư đó giá trị số 5>4 (4 nhóm) nên báo lỗi debug.
 
Upvote 0
em vận hành một thời gian thì phát hiện có 1 quy luật bị lỗi ạ: "Nếu số học sinh dư > số nhóm" thì nó debug ạ. Cụ thể khi tổng số học sinh 29 em mà ta chia mỗi nhóm 6 em thì dư 5 em. Ta thấy 5 em dư đó giá trị số 5>4 (4 nhóm) nên báo lỗi debug.
Trường hợp nầy lấy 4 nhóm hay 5 nhóm?
Định trước số em cho 1 nhóm không ổn, thường là xác định số nhóm trước từ đó mới tính số em 1 nhóm
 
Upvote 0
Code phân nhóm theo giới tính và học lực tương đối đều hơn, thêm bẩy lỗi không phân nhóm được theo số học sinh chọn trước
Mã:
Option Explicit
Sub PhanNhom()
  Dim sh As Worksheet
  Dim arr(), aDiem, aTK(), a, b, c, NN, res()
  Dim soHS&, soNhom&, HSle&, N&, i&, r&, j&, k&, nhom&
  Dim soNu&, nMin&, nMax&, t&, hl&, iDC&, tmp
 
  Set sh = Sheets("8a2")
  arr = sh.Range("D2", sh.Range("E" & Rows.Count).End(xlUp)).Value
  soHS = UBound(arr)
 
  On Error Resume Next
  N = InputBox("Hay nhap so hoc sinh cua 1 nhom vào o bên duoi", "CHIA HOC SINH THEO NHOM")
  If N = 0 Then
    MsgBox " Ban phai nhap sô hoc sinh cua 1 nhóm": Exit Sub
  End If
  If N > soHS Then N = soHS
  soNhom = Int(soHS / N) 'Phan HS thanh soNhom NHOM
  HSle = soHS Mod N
  If HSle > soNhom Then
    soNhom = Int(soHS / (N - 1)) 'Phan HS thanh soNhom NHOM
    HSle = soHS Mod (N - 1)
    If HSle = 0 Or HSle > soNhom Then
      MsgBox ("Khong the chia nhom co " & N & " hoc sinh")
      Exit Sub
    End If
  End If
  On Error GoTo 0
 
  Randomize
  ReDim res(1 To soHS, 1 To 2)
  ReDim aTK(1 To soNhom, 0 To 6)
  ReDim a(1 To 4) 'Chia HS thanh 4 nhom theo Hoc luc
  aDiem = Array(0, 8, 7.5, 6.5, 5)
 
  For i = 1 To soHS 'xep thu tu HS theo Hoc luc
    If Len(arr(i, 1)) = 2 Then soNu = soNu + 1
    For j = 1 To 4
      If arr(i, 2) >= aDiem(j) Then
        a(j) = a(j) & "," & i 'Thu tu dong
        res(i, 2) = j 'Hoc luc
        Exit For
      End If
    Next j
  Next i
  For i = 1 To 4
    If a(i) <> Empty Then
      b = Split(a(i), ",")
      tmp = Empty
      Call TaoMangNgauNhien(NN, UBound(b))
      For j = 1 To UBound(b)
        tmp = tmp & "," & b(NN(j))
      Next j
      a(i) = tmp
    End If
  Next i
  a = Split(Join(a, ""), ",") 'Mang STT HS xep thu tu theo Hoc luc
  nMin = Int(soNu / soNhom) 'So nu it nhat trong 1 nhom
  If nMin * soNhom = soNu Then nMax = nMin Else nMax = nMin + 1 'So nu nhieu nhat trong 1 nhom

  Do 'Chia HS vào các nhóm
    Call TaoMangNgauNhien(NN, soNhom)
    For j = 1 To soNhom
      nhom = NN(j) 'Thu tu nhom
      k = k + 1
      If k > soHS Then Exit Do
      r = a(k) 'Thu tu dong du lieu goc
      res(r, 1) = nhom
      If Len(arr(r, 1)) = 2 Then aTK(nhom, 2) = aTK(nhom, 2) + 1
    Next j
  Loop
DieuChinhTiep:
  For i = 1 To soNhom 'Dieu chinh so nu
    If aTK(i, 2) < nMin Or aTK(i, 2) > nMax Then 'Nhom dieu chinh Tang Giam HS Nu
      tmp = soHS + 1
      For r = 1 To soNhom
        If tmp > aTK(r, 2) Then
          tmp = aTK(r, 2)
          iDC = r 'nhom co so Nu it nhat
        End If
      Next r
      tmp = 0
      For r = 1 To soNhom
        If tmp < aTK(r, 2) Then
          tmp = aTK(r, 2)
          k = r 'nhom co so nu nhieu nhat
        End If
      Next r
      tmp = Empty
TroLai:
      For r = 1 To soHS
        If res(r, 1) = iDC And Len(arr(r, 1)) <> 2 Then 'Nhom dieu chinh Tang HS Nu và giam HS Nam
          hl = res(r, 2) 'Hoc luc
          If InStr(1, tmp, hl) = 0 Then
            tmp = tmp & hl
            For c = 1 To soHS
              If Len(arr(c, 1)) = 2 And res(c, 1) = k And res(c, 2) = hl Then 'HS Nu và nhom co Nu nhieu nhat và cung Hoc luc
                t = res(c, 1)
                res(c, 1) = res(r, 1)
                res(r, 1) = t
                aTK(iDC, 2) = aTK(iDC, 2) + 1
                aTK(t, 2) = aTK(t, 2) - 1
                GoTo DieuChinhTiep
              End If
            Next c
            If c > soHS Then GoTo TroLai
          End If
        End If
      Next r
    End If
  Next i
  sh.Range("F2").Resize(soHS, 2) = res
  Call ThongKe(sh, res, aTK, soHS) 'Bang Thong ke ket qua phan nhom
End Sub

Sub ThongKe(sh, res, aTK, soHS)
'aTK co 7 Cot:Nhom, So Hoc Sinh, So Nu, Hoc luc A, B, C, D
  Dim i&, r&, c&
  For i = 1 To soHS
    r = res(i, 1)
    c = res(i, 2) + 2
    aTK(r, 1) = aTK(r, 1) + 1
    aTK(r, c) = aTK(r, c) + 1
  Next i
  For i = 1 To UBound(aTK)
    aTK(i, 0) = i
  Next i
  sh.Range("I2").Resize(soHS, 7).ClearContents
  sh.Range("I2").Resize(UBound(aTK), 7) = aTK
End Sub

Sub TaoMangNgauNhien(aRnd, ByVal N)
  Dim i&, t&, r&
  ReDim aRnd(1 To N)
  For i = 1 To N
    r = Int(rnd * N) + 1
    If aRnd(r) = Empty Then t = r Else t = aRnd(r)
    If aRnd(N) = Empty Then aRnd(r) = N Else aRnd(r) = aRnd(N)
    aRnd(N) = t
    N = N - 1
  Next i
End Sub
 
Upvote 0
Web KT

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

Back
Top Bottom