Nhờ tăng tốc code nạp dữ liệu điểm từ 16800 dòng vào 4200 HS chia thành 4 môn theo mã phách

Liên hệ QC

titanic20072007

Thành viên thường trực
Tham gia
10/7/07
Bài viết
213
Được thích
8
Nghề nghiệp
Giáo viên
Chào các bạn. Mình có viết code cùi nạp dữ liệu điểm bài KT từ tệp KQ có 16800 bài (gồm 4 môn) vào tệp tổng hợp theo mã bài và mã phòng chia theo môn. Chạy OK, tuy nhiên chạy lâu quá. Nhờ các bạn tăng tốc giúp hoặc có cách nào để chạy nhanh hơn. Cảm ơn.
 

File đính kèm

  • Du lieu.xls
    4.4 MB · Đọc: 45
Chạy OK, tuy nhiên chạy lâu quá.
Bạn dùng mảng là nhanh rồi, tuy nhiên trong code: khi dã lấy được dữ liệu , vòng lặp J vẫn chạy tiếp mà không thoát.

1. Nên thoát vòng J khi đã lấy dữ liệu.

2. Hoặc viết lại chỉ dùng 2 vòng lặp:

- Vòng 1 dùng Dictionary để nạp chỉ số dòng của mảng.

- Vòng 2 nạp Điểm.
 
Upvote 0
Chào các bạn. Mình có viết code cùi nạp dữ liệu điểm bài KT từ tệp KQ có 16800 bài (gồm 4 môn) vào tệp tổng hợp theo mã bài và mã phòng chia theo môn. Chạy OK, tuy nhiên chạy lâu quá. Nhờ các bạn tăng tốc giúp hoặc có cách nào để chạy nhanh hơn. Cảm ơn.
Bạn thử.
Mã:
Sub laydulieu()
    Dim arr, i As Long, lr As Long, dic As Object, dk As String, k As Integer
    Set dic = CreateObject("scripting.dictionary")
    With Sheet7
         lr = .Range("B" & Rows.Count).End(xlUp).Row
         arr = .Range("B6:F" & lr).Value
         For i = 1 To UBound(arr)
             dk = arr(i, 1)
             If Not dic.exists(dk) Then
                dic.Add dk, Array(arr(i, 3), arr(i, 5))
             End If
         Next i
   End With
   With Sheet8
        lr = .Range("D" & Rows.Count).End(xlUp).Row
        arr = .Range("I7:X" & lr).Value
        For k = 1 To UBound(arr, 2) Step 4
            For i = 1 To UBound(arr)
                dk = arr(i, k)
                If dic.exists(dk) Then
                   arr(i, k + 2) = dic.Item(dk)(0)
                   arr(i, k + 3) = dic.Item(dk)(1)
                Else
                   arr(i, k + 2) = Empty
                   arr(i, k + 3) = Empty
                End If
           Next i
       Next k
       .Range("I7:X" & lr).Value = arr
   End With
End Sub
 
Upvote 0
Bình thường thì mọi người theo một quy luật bất thành văn khi duyệt mảng nhiều chiều: i cho dòng và j cho cột.

Không ai bắt buộc bạn phải theo luật này. Nhưng mục đích của những luật bất thành văn là để cho code dễ đọc hơn.
Thêm nữa, đây là công việc điểm thi. Code loại này theo đúng quy trình làm việc thì phải đi qua đồng nghiệp (trong nghề gọi là peer review, kiểm soát những chỗ sơ sót)

Không ai bắt buộc bạn phải ăn cơm bằng đầu nhỏ hơn của cặp đũa. Nhưng nếu bạn dọn cơm cho khách, xếp đũa quay đầu nhọn ra ngoài thì họ sẽ hơi "khựng"
 
Upvote 0
Bạn thử.
Mã:
Sub laydulieu()
    Dim arr, i As Long, lr As Long, dic As Object, dk As String, k As Integer
    Set dic = CreateObject("scripting.dictionary")
    With Sheet7
         lr = .Range("B" & Rows.Count).End(xlUp).Row
         arr = .Range("B6:F" & lr).Value
         For i = 1 To UBound(arr)
             dk = arr(i, 1)
             If Not dic.exists(dk) Then
                dic.Add dk, Array(arr(i, 3), arr(i, 5))
             End If
         Next i
   End With
   With Sheet8
        lr = .Range("D" & Rows.Count).End(xlUp).Row
        arr = .Range("I7:X" & lr).Value
        For k = 1 To UBound(arr, 2) Step 4
            For i = 1 To UBound(arr)
                dk = arr(i, k)
                If dic.exists(dk) Then
                   arr(i, k + 2) = dic.Item(dk)(0)
                   arr(i, k + 3) = dic.Item(dk)(1)
                Else
                   arr(i, k + 2) = Empty
                   arr(i, k + 3) = Empty
                End If
           Next i
       Next k
       .Range("I7:X" & lr).Value = arr
   End With
End Sub
Cảm ơn snow25. Mình test thấy code chạy rất nhanh nhưng chạy khoảng 300 HS đầu mỗi môn điểm nạp vào đúng còn lại những HS sau điểm không đúng. Bạn xem lại giúp với.
 
Upvote 0
Bạn dùng mảng là nhanh rồi, tuy nhiên trong code: khi dã lấy được dữ liệu , vòng lặp J vẫn chạy tiếp mà không thoát.

1. Nên thoát vòng J khi đã lấy dữ liệu.

2. Hoặc viết lại chỉ dùng 2 vòng lặp:

- Vòng 1 dùng Dictionary để nạp chỉ số dòng của mảng.

- Vòng 2 nạp Điểm.
Mình chưa nghiên cứu Dic nên không hiểu về nó đành viết kiểu này. Mình đã thử dùng 1 vòng lặp ngoài lấy mã bên KQ, một vòng lặp để lấy mã bên tổng hợp để so sánh. Mỗi lần lặp so sánh cả 4 môn luôn nhưng tốc độ chạy vẫn rất chậm.
 
Upvote 0
Cảm ơn snow25. Mình test thấy code chạy rất nhanh nhưng chạy khoảng 300 HS đầu mỗi môn điểm nạp vào đúng còn lại những HS sau điểm không đúng. Bạn xem lại giúp với.
Bạn thử nhé.Mình dùng Dictionary bạn tham khảo.Mình đã sửa chỗ điều kiện để kiểm tra.
Mã:
Sub laydulieu()
    Dim arr, i As Long, lr As Long, dic As Object, dk As String, k As Integer
    Set dic = CreateObject("scripting.dictionary")
    With Sheet7
         lr = .Range("B" & Rows.Count).End(xlUp).Row
         arr = .Range("B6:F" & lr).Value
         For i = 1 To UBound(arr)
             dk = arr(i, 1) & "#" & arr(i, 2)
             If Not dic.exists(dk) Then
                dic.Add dk, Array(arr(i, 3), arr(i, 5))
             End If
         Next i
   End With
   With Sheet8
        lr = .Range("D" & Rows.Count).End(xlUp).Row
        arr = .Range("I7:X" & lr).Value
        For k = 1 To UBound(arr, 2) Step 4
            For i = 1 To UBound(arr)
                dk = arr(i, k) & "#" & arr(i, k + 1)
                If dic.exists(dk) Then
                   arr(i, k + 2) = dic.Item(dk)(0)
                   arr(i, k + 3) = dic.Item(dk)(1)
                Else
                   arr(i, k + 2) = Empty
                   arr(i, k + 3) = Empty
                End If
           Next i
       Next k
       .Range("I7:X" & lr).Value = arr
   End With
End Sub
 
Upvote 0
Bạn thử nhé.Mình dùng Dictionary bạn tham khảo.Mình đã sửa chỗ điều kiện để kiểm tra.
Mã:
Sub laydulieu()
    Dim arr, i As Long, lr As Long, dic As Object, dk As String, k As Integer
    Set dic = CreateObject("scripting.dictionary")
    With Sheet7
         lr = .Range("B" & Rows.Count).End(xlUp).Row
         arr = .Range("B6:F" & lr).Value
         For i = 1 To UBound(arr)
             dk = arr(i, 1) & "#" & arr(i, 2)
             If Not dic.exists(dk) Then
                dic.Add dk, Array(arr(i, 3), arr(i, 5))
             End If
         Next i
   End With
   With Sheet8
        lr = .Range("D" & Rows.Count).End(xlUp).Row
        arr = .Range("I7:X" & lr).Value
        For k = 1 To UBound(arr, 2) Step 4
            For i = 1 To UBound(arr)
                dk = arr(i, k) & "#" & arr(i, k + 1)
                If dic.exists(dk) Then
                   arr(i, k + 2) = dic.Item(dk)(0)
                   arr(i, k + 3) = dic.Item(dk)(1)
                Else
                   arr(i, k + 2) = Empty
                   arr(i, k + 3) = Empty
                End If
           Next i
       Next k
       .Range("I7:X" & lr).Value = arr
   End With
End Sub
Mình mới kiểm tra thấy đã khớp dữ liệu. Mình sẽ kiểm tra tiếp, có gì mình sẽ nhờ bạn giúp đỡ tiếp. Cảm ơn bạn nhiều.
 
Upvote 0
Chào các bạn. Mình có viết code cùi nạp dữ liệu điểm bài KT từ tệp KQ có 16800 bài (gồm 4 môn) vào tệp tổng hợp theo mã bài và mã phòng chia theo môn. Chạy OK, tuy nhiên chạy lâu quá. Nhờ các bạn tăng tốc giúp hoặc có cách nào để chạy nhanh hơn. Cảm ơn.
Bạn xem kết quả có đúng ý không? Thử không dùng vòng lặp xem có chạy nhanh hơn không?
Tôi thêm phần đánh số thứ tự và tô viềng để trang trí.
Lưu ý:
1/ Sheet Diem_K9 bạn có thể thêm đến 30000 dòng dữ liệu cũng không thành vấn đề.
2/ Sheet KQ chấm_K9 tôi sửa cấu trúc lại một tí để thuận tiện cho việc lấy dữ liệu. Khi nhấn nút nó xóa dữ liệu cũ và gán lại dữ liệu mới.

Sau khi xem lại nội dung thì tiêu đề bài viết bạn ghi chưa rỏ ràng, có thể sửa tiêu đề là "Giúp lấy dữ liệu 4 vùng từ sheet Diem_K9 và gán lặp xuống 4 cột B: E của sheet KQ chấm_K9".
Sau khi xem lại tiêu đề bài viết thì hình như tôi làm đã làm ngược theo yêu cầu thì phải? Hay là tôi hiểu sai.
 

File đính kèm

  • Tranpose Du lieu.xls
    1.5 MB · Đọc: 5
Lần chỉnh sửa cuối:
Upvote 0
Bạn xem kết quả có đúng ý không? Thử không dùng vòng lặp xem có chạy nhanh hơn không?
Tôi thêm phần đánh số thứ tự và tô viềng để trang trí.
Lưu ý:
1/ Sheet Diem_K9 bạn có thể thêm đến 30000 dòng dữ liệu cũng không thành vấn đề.
2/ Sheet KQ chấm_K9 tôi sửa cấu trúc lại một tí để thuận tiện cho việc lấy dữ liệu. Khi nhấn nút nó xóa dữ liệu cũ và gán lại dữ liệu mới.

Sau khi xem lại nội dung thì tiêu đề bài viết bạn ghi chưa rỏ ràng, có thể sửa tiêu đề là "Giúp lấy dữ liệu 4 vùng từ sheet Diem_K9 và gán lặp xuống 4 cột B: E của sheet KQ chấm_K9".
Sau khi xem lại tiêu đề bài viết thì hình như tôi làm đã làm ngược theo yêu cầu thì phải? Hay là tôi hiểu sai.
Bạn làm ngược vấn đề rồi. Mình cần lấy từ sheet KQ chấm vào sheet Điểm. Bạn sủa lại được không?
 
Upvote 0
Chào các bạn. Mình có viết code cùi nạp dữ liệu điểm bài KT từ tệp KQ có 16800 bài (gồm 4 môn) vào tệp tổng hợp theo mã bài và mã phòng chia theo môn. Chạy OK, tuy nhiên chạy lâu quá. Nhờ các bạn tăng tốc giúp hoặc có cách nào để chạy nhanh hơn. Cảm ơn.
Thử code siêu tốc và siêu liều
Mã:
Sub UongThuocLieu()
  Dim sArr(), j&, fRow&, fCol&
  Const sRow& = 4200
  fRow = 6: fCol = 11
  Application.ScreenUpdating = False
  For j = 1 To 4
    Sheet8.Cells(7, fCol).Resize(sRow) = Sheet7.Cells(fRow, 4).Resize(sRow).Value2
    Sheet8.Cells(7, fCol + 1).Resize(sRow) = Sheet7.Cells(fRow, 6).Resize(sRow).Value2
    fRow = fRow + sRow
    fCol = fCol + 4
  Next j
  Application.ScreenUpdating = True
End Sub
 
Upvote 0
Thử code siêu tốc và siêu liều
Mã:
Sub UongThuocLieu()
  Dim sArr(), j&, fRow&, fCol&
  Const sRow& = 4200
  fRow = 6: fCol = 11
  Application.ScreenUpdating = False
  For j = 1 To 4
    Sheet8.Cells(7, fCol).Resize(sRow) = Sheet7.Cells(fRow, 4).Resize(sRow).Value2
    Sheet8.Cells(7, fCol + 1).Resize(sRow) = Sheet7.Cells(fRow, 6).Resize(sRow).Value2
    fRow = fRow + sRow
    fCol = fCol + 4
  Next j
  Application.ScreenUpdating = True
End Sub
Cảm ơn HieuCD code rất gọn mà chạy nhanh. Không dùng mảng, Dic sao chạy nhanh thế nhỉ. Trong code không có lệnh kiểm tra so khớp mã bài, mã phòng liệu có nhầm điểm của HS này sang HS khác không. Mình sẽ test kỹ.
 
Upvote 0
Thử code siêu tốc và siêu liều
Mã:
Sub UongThuocLieu()
  Dim sArr(), j&, fRow&, fCol&
  Const sRow& = 4200
  fRow = 6: fCol = 11
  Application.ScreenUpdating = False
  For j = 1 To 4
    Sheet8.Cells(7, fCol).Resize(sRow) = Sheet7.Cells(fRow, 4).Resize(sRow).Value2
    Sheet8.Cells(7, fCol + 1).Resize(sRow) = Sheet7.Cells(fRow, 6).Resize(sRow).Value2
    fRow = fRow + sRow
    fCol = fCol + 4
  Next j
  Application.ScreenUpdating = True
End Sub
Liều thật :eek:
 
Upvote 0
Cảm ơn HieuCD code rất gọn mà chạy nhanh. Không dùng mảng, Dic sao chạy nhanh thế nhỉ. Trong code không có lệnh kiểm tra so khớp mã bài, mã phòng liệu có nhầm điểm của HS này sang HS khác không. Mình sẽ test kỹ.
Nhầm là chắc, khi dữ liệu kiểu khác...
Nhưng có mấy tỉnh nhầm kiểu điểm tăng thế , lo chi
 
Upvote 0
Thử code siêu tốc và siêu liều
Mã:
Sub UongThuocLieu()
  Dim sArr(), j&, fRow&, fCol&
  Const sRow& = 4200
  fRow = 6: fCol = 11
  Application.ScreenUpdating = False
  For j = 1 To 4
    Sheet8.Cells(7, fCol).Resize(sRow) = Sheet7.Cells(fRow, 4).Resize(sRow).Value2
    Sheet8.Cells(7, fCol + 1).Resize(sRow) = Sheet7.Cells(fRow, 6).Resize(sRow).Value2
    fRow = fRow + sRow
    fCol = fCol + 4
  Next j
  Application.ScreenUpdating = True
End Sub
sRow là hằng. Resize liên tục code trông không rõ. Lấy trọn 1 lần vào range rồi dùng Offset dễ kiểm soát hơn.
...
Set rgS = Sheet7.Cells(6, "D").Resize(sRow) ' bắt đầu phần được chép từ ô D6
Set rgD = Sheet8.Cells(7, "K").Resize(sRow) ' bắt đầu phần chép từ ô K7
For i = 1 To 4
rgD = rgS.Value2
rgD.Offset( , 1) = rgS.Offset( , 2).Value2
Set rgD = rgD.Offset( , 4) ' phần chép kế tiếp là qua phải 4 cột
Set rgS = rgS.Offset( sRow ) ' phần được chép ké tiếp là xuống sRow hàng
Next i
 
Upvote 0
Chào các bạn. Mình có viết code cùi nạp dữ liệu điểm bài KT từ tệp KQ có 16800 bài (gồm 4 môn) vào tệp tổng hợp theo mã bài và mã phòng chia theo môn. Chạy OK, tuy nhiên chạy lâu quá. Nhờ các bạn tăng tốc giúp hoặc có cách nào để chạy nhanh hơn. Cảm ơn.

Bạn làm được chưa? nếu chưa thì dùng file đính kèm.
file này chạy bằng dictionary.
 

File đính kèm

  • Copy of Du lieu.xls
    5.7 MB · Đọc: 8
Upvote 0
Web KT
Back
Top Bottom