Lọc danh sách sinh viên thi lại

Liên hệ QC

Yeuvoyeucon

Thành viên hoạt động
Tham gia
30/10/09
Bài viết
143
Được thích
23
Kính gửi anh chị
Em có một File em lấy ở diễn đàn trước đây nay xem lại code thấy khó hiểu nhờ anh chị làm theo cách khác dễ hiểu hơn với ạ.
- Tại sheet Diem_TChi có danh sách cách sinh viên và kết quả thi các môn. Giờ muốn list ra các sinh viên và môn học mà sinh viên đó phải thi lại với điều kiện điểm tại các cột TKHP <4
 

File đính kèm

  • Danh sach thi lai.xlsm
    69.8 KB · Đọc: 30
Cách hiện hữu là dễ hiểu rồi đó bạn;
Chắc bạn cần diễn dịch sang ngôn ngữ tiếng Việt để hiểu nó chăng?
 
Upvote 0
Kính gửi anh chị
Em có một File em lấy ở diễn đàn trước đây nay xem lại code thấy khó hiểu nhờ anh chị làm theo cách khác dễ hiểu hơn với ạ.
- Tại sheet Diem_TChi có danh sách cách sinh viên và kết quả thi các môn. Giờ muốn list ra các sinh viên và môn học mà sinh viên đó phải thi lại với điều kiện điểm tại các cột TKHP <4
Code ấy là do anh SA_DQ viết đấy, như thế là tối ưu rồi- Dễ hiểu, ngắn gọn và hiệu quả (nhanh, chính xác).
Có phải bạn muốn diễn giải từng dòng code và giải thuật code là gì phải không? Tôi tin là bạn từ từ nghiên cứu là sẽ thấy.
Chúc Khỏe, vui, Thành công và an toàn trong đại dịch
 
Upvote 0
Code đấy không phải của mình đâu;
Phong cách & 1 số cái khác không là của mình mà.
:D :D
$$$$@
hihi. Cháu thấy bác viết hay kiểu này cơ. Nhưng code kia thấy viết thế là ngắn gọn quá rồi mờ
Mã:
aaaa                                       :bbb
                 ccc:                                        ddd
 
Upvote 0
Code đấy không phải của mình đâu;
Phong cách & 1 số cái khác không là của mình mà.
:D :D
$$$$@
Có lẽ tôi nhầm, Xin lỗi anh SA_DQ nhé.
Nhưng chắc chắc là của 1 anh nào đó rất có uy tín trên diễn đàn này viết.
Tôi muốn sửa lại code theo ý riêng là một Sinh viên phải thi lại nhiều môn thì trong Bảng Danh sách SV thi lại môn chỉ hiển thị tên một lần kiểu: (như hình dưới) mà làm mãi không được. Anh em nào có ghé qua, xin cho hướng giải quyết.
Trân trọng
số TTMã SVHọ và tên SVngày tháng năm sinhMôn phải thi lại
1​
DD001Nguyễn Văn A1/1/999Kinh tế
Triết học
Hóa học
Giải phẫu
2​
DD045Hoàng thị N
2/3/1999​
Triết học
3​
DD0056Cao Anh H
4/5/1998​
Kinh tế
Hóa học
Ngoại ngữ
 
Upvote 0
Có lẽ tôi nhầm, Xin lỗi anh SA_DQ nhé.
Nhưng chắc chắc là của 1 anh nào đó rất có uy tín trên diễn đàn này viết.
Tôi muốn sửa lại code theo ý riêng là một Sinh viên phải thi lại nhiều môn thì trong Bảng Danh sách SV thi lại môn chỉ hiển thị tên một lần kiểu: (như hình dưới) mà làm mãi không được. Anh em nào có ghé qua, xin cho hướng giải quyết.
Trân trọng
số TTMã SVHọ và tên SVngày tháng năm sinhMôn phải thi lại
1​
DD001Nguyễn Văn A1/1/999Kinh tế
Triết học
Hóa học
Giải phẫu
2​
DD045Hoàng thị N
2/3/1999​
Triết học
3​
DD0056Cao Anh H
4/5/1998​
Kinh tế
Hóa học
Ngoại ngữ
Em nhớ hình như anh tên là Ba tê ạ. hình thư thế ạ.
Có lẽ tôi nhầm, Xin lỗi anh SA_DQ nhé.
Nhưng chắc chắc là của 1 anh nào đó rất có uy tín trên diễn đàn này viết.
Tôi muốn sửa lại code theo ý riêng là một Sinh viên phải thi lại nhiều môn thì trong Bảng Danh sách SV thi lại môn chỉ hiển thị tên một lần kiểu: (như hình dưới) mà làm mãi không được. Anh em nào có ghé qua, xin cho hướng giải quyết.
Trân trọng
số TTMã SVHọ và tên SVngày tháng năm sinhMôn phải thi lại
1​
DD001Nguyễn Văn A1/1/999Kinh tế
Triết học
Hóa học
Giải phẫu
2​
DD045Hoàng thị N
2/3/1999​
Triết học
3​
DD0056Cao Anh H
4/5/1998​
Kinh tế
Hóa học
Ngoại ngữ
 
Upvote 0
...Tôi muốn sửa lại code theo ý riêng là một Sinh viên phải thi lại nhiều môn thì trong Bảng Danh sách SV thi lại môn chỉ hiển thị tên một lần kiểu: (như hình dưới) mà làm mãi không được. Anh em nào có ghé qua, xin cho hướng giải quyết.
...
Cái dạng bạn muốn trông đẹp nhưng chỉ để ngắm.
Dạng này không hổ trợ filter và pivot cho nên hầu như không thể dùng làm dữ liệu để phân tích. Ví dụ, tôi muốn xem môn Kinh Tế có những học sinh nào thi lại thì phải dùng công thức khủng hay lại phải viết code VBA.

Chú: nếu bạn thực sự chỉ muốn "code chơi cho vui" thì copy lại cái code trong file kia, đăng lên đây, nếu được tôi sẽ mách cho cách làm. (Bản thân tôi kỵ mở file xlsm để xem code)
 
Upvote 0
Bảng dịch VBA đó sang phong cách của mình đây, xin mời tham khảo:

PHP:
Public Sub s_GPE()
 Dim sArr(), dArr(), I As Long, J As Long, W As Long, N As Long, Rws As Long, lCol As Integer
 Dim StrC As String
 
 lCol = Sheets("Diem_TChi").[B10].CurrentRegion.Columns.Count
 Rws = Sheets("Diem_TChi").[B10].CurrentRegion.Rows.Count
 sArr = Sheets("Diem_TChi").[A7].Resize(Rws, lCol).Value
 ReDim dArr(1 To Rws * 6, 1 To 6)
 Sheets("Thi_lai").[A5].Resize(Rws, 6).Value = dArr()
 For I = 4 To Rws
    For J = 13 To lCol Step 4
        If sArr(I, J) < 4 Then
            W = W + 1:                          dArr(W, 1) = W
            For N = 2 To 5
                dArr(W, N) = sArr(I, N)
            Next N
                                                'Mon = Split(sArr(1, J), "_")(1)  '
            dArr(W, 6) = Mon(sArr(1, J))        'Left(Mon, Len(Mon) - 4)  '
        End If
    Next J
 Next I
 With Sheets("Thi_lai")
    .Range("A5").Resize(W, 6) = dArr()
 End With
End Sub
Mã:
Function Mon(StrC As Variant) As String
 Mon = Split(StrC, "_")(1)
 Mon = Left(Mon, Len(Mon) - 4)
End Function
 
Upvote 0
Cái dạng bạn muốn trông đẹp nhưng chỉ để ngắm.
Dạng này không hổ trợ filter và pivot cho nên hầu như không thể dùng làm dữ liệu để phân tích. Ví dụ, tôi muốn xem môn Kinh Tế có những học sinh nào thi lại thì phải dùng công thức khủng hay lại phải viết code VBA.

Chú: nếu bạn thực sự chỉ muốn "code chơi cho vui" thì copy lại cái code trong file kia, đăng lên đây, nếu được tôi sẽ mách cho cách làm. (Bản thân tôi kỵ mở file xlsm để xem code)
Cảm ơn anh đã đọc bài và có ý kiến đóng góp.
đây code của bài chủ thớt đăng, tôi tải lại và đưa lên đây. Xin anh quan tâm và chỉ hướng giải quyết theo mong muốn như ở bài #8 đã nêu. Tôi muốn có thêm được một bài học thêm về mảng và cũng là để có hướng giải quyết các bài tương tự (nếu có).
Mã:
Option Explicit

Public Sub s_Gpe()
Const CoLs As Long = 36
Dim sArr(), dArr(), I As Long, J As Long, K As Long, N As Long, R As Long, Mon As String
sArr = Sheets("Diem_TChi").Range("A7", Sheets("Diem_TChi").Range("A10").End(xlDown)).Resize(, CoLs).Value
R = UBound(sArr)
ReDim dArr(1 To R * 6, 1 To 6)
For I = 4 To R
For J = 13 To CoLs Step 4
If sArr(I, J) < 4 Then
K = K + 1
dArr(K, 1) = K
For N = 2 To 5
dArr(K, N) = sArr(I, N)
Next N
Mon = Split(sArr(1, J), "_")(1)
dArr(K, 6) = Left(Mon, Len(Mon) - 4)
End If
Next J
Next I
With Sheets("Thi_lai")
.Range("A5").Resize(K, 6) = dArr
End With
End Sub
Cảm ơn anh nhiều!
 
Upvote 0
Tôi muốn sửa lại code theo ý riêng là một Sinh viên phải thi lại nhiều môn thì trong Bảng Danh sách SV thi lại môn chỉ hiển thị tên một lần kiểu: (như hình dưới) mà làm mãi không được. Anh em nào có ghé qua, xin cho hướng giải quyết.
Trân trọng
số TTMã SVHọ và tên SVngày tháng năm sinhMôn phải thi lại
1​
DD001Nguyễn Văn A1/1/999Kinh tế
Triết học
Hóa học
Giải phẫu
2​
DD045Hoàng thị N
2/3/1999​
Triết học
3​
DD0056Cao Anh H
4/5/1998​
Kinh tế
Hóa học
Ngoại ngữ
Cho em gop vui với. Có thiếu sót gì mong mọi người sửa giúp. Coi như học hỏi thêm
Mã:
Sub ABC()
    Dim Arr(), Res(), Dic As Object, I&, J&, iKey, iRow&, K&, N&
    Set Dic = CreateObject("Scripting.dictionary")
    With Sheets("Diem_TChi")
        iRow = .Range("B" & Rows.Count).End(3).Row
        If iRow < 10 Then Exit Sub
        Arr = .Range("A7:AM" & iRow).Value
    End With
    ReDim Res(1 To UBound(Arr, 1) * 6, 1 To 6)
    For I = 4 To UBound(Arr, 1)
        For J = 13 To 36 Step 4
            iKey = Arr(I, 2)
            If Arr(I, J) < 4 Then
                K = K + 1
                If Dic.exists(iKey) = False Then
                    N = N + 1
                    Dic.Add (iKey), iKey
                    Res(K, 1) = N: Res(K, 2) = iKey: Res(K, 3) = Arr(I, 3)
                    Res(K, 4) = Arr(I, 4): Res(K, 5) = Arr(I, 5)
                End If
                Res(K, 6) = Left(Split(Arr(1, J), "_")(1), Len(Split(Arr(1, J), "_")(1)) - 4)
            End If
        Next
    Next
    With Sheets("Thi_lai")
        .Range("I5").Resize(1000, 6).ClearContents
        If K Then .Range("I5").Resize(K, 6) = Res
    End With
End Sub
 
Upvote 0
Cho em gop vui với. Có thiếu sót gì mong mọi người sửa giúp. Coi như học hỏi thêm
Mã:
Sub ABC()
    Dim Arr(), Res(), Dic As Object, I&, J&, iKey, iRow&, K&, N&
    Set Dic = CreateObject("Scripting.dictionary")
    With Sheets("Diem_TChi")
        iRow = .Range("B" & Rows.Count).End(3).Row
        If iRow < 10 Then Exit Sub
        Arr = .Range("A7:AM" & iRow).Value
    End With
    ReDim Res(1 To UBound(Arr, 1) * 6, 1 To 6)
    For I = 4 To UBound(Arr, 1)
        For J = 13 To 36 Step 4
            iKey = Arr(I, 2)
            If Arr(I, J) < 4 Then
                K = K + 1
                If Dic.exists(iKey) = False Then
                    N = N + 1
                    Dic.Add (iKey), iKey
                    Res(K, 1) = N: Res(K, 2) = iKey: Res(K, 3) = Arr(I, 3)
                    Res(K, 4) = Arr(I, 4): Res(K, 5) = Arr(I, 5)
                End If
                Res(K, 6) = Left(Split(Arr(1, J), "_")(1), Len(Split(Arr(1, J), "_")(1)) - 4)
            End If
        Next
    Next
    With Sheets("Thi_lai")
        .Range("I5").Resize(1000, 6).ClearContents
        If K Then .Range("I5").Resize(K, 6) = Res
    End With
End Sub
Anh cho em hỏi đoạn này có ý nghĩa thế nào ạ
Res(K, 6) = Left(Split(Arr(1, J), "_")(1), Len(Split(Arr(1, J), "_")(1)) - 4)
Đặc biệt, Cách viết (1) là thế nào ạ.
 
Upvote 0
Anh cho em hỏi đoạn này có ý nghĩa thế nào ạ
Res(K, 6) = Left(Split(Arr(1, J), "_")(1), Len(Split(Arr(1, J), "_")(1)) - 4)
Đặc biệt, Cách viết (1) là thế nào ạ.
Bạn đọc code của thầy trước viết ấy sẽ hiểu tại sao nó ra thế. Mình chỉ chế cháo thêm 1 chút thôi. Cái đó là để lấy tên môn học đó
 
Upvote 0
Bạn đọc code của thầy trước viết ấy sẽ hiểu tại sao nó ra thế. Mình chỉ chế cháo thêm 1 chút thôi. Cái đó là để lấy tên môn học đó
Dạ, đọc code anh em hiểu hiểu. Dễ hiểu hơn thầy viết. Em chỉ thấy lạ cách viết hàm chỗ lấy tên học ạ. EM chưa nhìn thấy cách viết kiểu thế bao giờ ? nó là cách viết theo lý thuyết nào anh nhỉ ? nhất là cái chỗ (1)
 
Upvote 0
Dạ, đọc code anh em hiểu hiểu. Dễ hiểu hơn thầy viết. Em chỉ thấy lạ cách viết hàm chỗ lấy tên học ạ. EM chưa nhìn thấy cách viết kiểu thế bao giờ ? nó là cách viết theo lý thuyết nào anh nhỉ ? nhất là cái chỗ (1)
Cái hàm split ấy. Nó sẽ tách cái môn học bạn đầu của bạn làm 2 phần tử (0) và (1). Cái phần tử (1) ấy là tên môn học. Dùng hàm left ấy xử lí các kí tự dư thừa ấy mà
 
Upvote 0
Ở GPE này người ta dùng Dictionary dễ quá cho nên quên mất kỹ thuật căn bản của so sánh từng dòng.
Dùng mã SV để dò. Nếu mã giống trước đó thì chép "", giản dị vậy thôi.

Const COTMASV = 2
Dim maSV As String, nuSTT As Long
maSV = "???"

For I = 4 To R
For J = 13 To CoLs Step 4
If sArr(I, J) < 4 Then
K = K + 1
' dArr(K, 1) = K
If sArr(I, COTMASV) <> maSV Then
nuSTT = nuSTT + 1
dArr(K, 1) = nuSTT
For N = 2 To 5
dArr(K, N) = ""
Next N
maSV = sArr(i, COTMASV)
Else
For N = 2 To 5
dArr(K, N) = sArr(I, N)
Next N
End If

Mon = Split(sArr(1, J), "_")(1)
dArr(K, 6) = Left(Mon, Len(Mon) - 4)
End If
Next J
Next I
 
Lần chỉnh sửa cuối:
Upvote 0
Ở GPE này người ta dùng Dictionary dễ quá cho nên quên mất kỹ thuật căn bản của so sánh từng dòng.
Dùng mã SV để dò. Nếu mã giống trước đó thì chép "", giản dị vậy thôi.

Const COTMASV = 2
Dim maSV As String, khacSV As Boolean, nuSTT As Long
maSV = "???"

For I = 4 To R
For J = 13 To CoLs Step 4
If sArr(I, J) < 4 Then
K = K + 1
' dArr(K, 1) = K
If sArr(I, COTMASV) <> maSV Then
nuSTT = nuSTT + 1
dArr(K, 1) = nuSTT
For N = 2 To 5
dArr(K, N) = ""
Next N
maSV = sArr(i, COTMASV)
Else
For N = 2 To 5
dArr(K, N) = sArr(I, N)
Next N
End If

Mon = Split(sArr(1, J), "_")(1)
dArr(K, 6) = Left(Mon, Len(Mon) - 4)
End If
Next J
Next I
Đúng là cháu viết xong. Thấy dùng dic nó cứ thừa thừa cái gì ạ. Trót viết rồi. Nên khỏi sửa luôn. Hihi
 
Upvote 0
Web KT
Back
Top Bottom