Mình có các tệp điểm quản lý điểm các môn học của từng học kỳ. Mỗi tệp gồm nhiều môn, mỗi môn ở 1 sheet có cấu trúc giống nhau. Mình muốn lấy điểm tổng kết và điểm thi 8 tuần và HK (ở hai cột) của từng môn đưa sang một tệp khác theo mẫu cho trước. Mình không biết làm thế nào để khi copy điểm tổng kết của một môn nào đó (tên môn là tên sheet) có thể đưa dữ liệu của môn nào đó vào đúng vị trí cột của môn đấy trong tệp tổng hợp (tệp B). Vậy nhờ các bạn xem giúp. Mình có up tệp dữ liệu, tệp mẫu bảng và tệp để chứa code lấy dữ liệu. Rất mong các bạn giúp, mình đang rất cần. Cảm ơn các bạn.
sử dụng hàm sumif(cột có tên học sinh ở sheet phụ; cột có tên học sinh ở sheet chính; điểm số tương ứng ở sheet phụ) vào cột điểm từng bộ môn ứng với sheet tương ứng
Cảm bạn đã hướng dẫn. Ý mình muốn dùng code để làm cho nhiều lớp và kết quả là các điểm tổng kết đó phải được đưa ra một tệp có cấu trúc sẵn để dùng cho chương trình khác đọc dữ liệu vào.
Cảm bạn đã hướng dẫn. Ý mình muốn dùng code để làm cho nhiều lớp và kết quả là các điểm tổng kết đó phải được đưa ra một tệp có cấu trúc sẵn để dùng cho chương trình khác đọc dữ liệu vào.
Về vấn đề này thì em nghĩ là có bước chuyển đổi từ không dấu sang có dấu, sau khi xử lý xong rồi thì lại chuyển ngược lại từ không dấu sang có dấu, bởi vì tên sheet ở đây do phần mềm xuất ra, và nó có liên quan đến vấn đề Import ngược trở lại phần mềm.
Về vấn đề này thì em nghĩ là có bước chuyển đổi từ không dấu sang có dấu, sau khi xử lý xong rồi thì lại chuyển ngược lại từ không dấu sang có dấu, bởi vì tên sheet ở đây do phần mềm xuất ra, và nó có liên quan đến vấn đề Import ngược trở lại phần mềm.
[GPECODE=sql]Sub HLMT_ADO()
On Error GoTo Handle
Dim cn As Object, cat As Object, tbl As Object, strTbl As String, i As Integer
Dim mySQL As String, strFile As Variant
Set cn = CreateObject("ADODB.Connection")
Set cat = CreateObject("ADOX.Catalog")
Set tbl = CreateObject("ADOX.Table")
strFile = Application.GetOpenFilename()
If strFile <> False Then
Application.ScreenUpdating = False
[B7:AV51].ClearContents
With cn
.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strFile & _
";Extended Properties=""Excel 8.0;HDR=No;"";"
cat.ActiveConnection = cn
For i = 0 To cat.Tables.Count - 1
strTbl = Replace(Replace(cat.Tables(i).Name, "$", ""), "'", "")
Cells(5, i + 3).Value = strTbl
Cells(5, i + 21 + i).Value = strTbl
mySQL = "UPDATE [" & strTbl & "$A6:AH50] a " _
& "INNER JOIN " _
& "[Excel 8.0;HDR=No;IMEX=2;DATABASE=" _
& ThisWorkbook.FullName & "].[HK1$a7:AV51] b " _
& "ON a.F1=b.F1 " _
& "SET b.F2=a.F2, b.F" & i + 3 & "=a.F31, b.F" _
& i + 21 + i & "=a.F33, b.F" & i + 22 + i & "=a.F34"
.Execute mySQL
Next
.Close
End With
Application.ScreenUpdating = True
End If
Set cn = Nothing: Set cat = Nothing: Set tbl = Nothing
Exit Sub
Handle:
MsgBox Err.Description
Cảm ơn bạn Hai Lúa Miền Tây và các bạn đã quân tâm và giúp mình. Mình vừa test thử thì thấy chương trình chạy được rồi. Dữ liệu lấy vào không bị nhầm lẫn giữa các môn. Xong có một vấn đề bạn có thể chỉnh tiếp giúp mình được không?
- Đó là Bạn có thể cập nhật dữ liệu vào đúng cột ở mẫu bảng tổng kết được không. Vì đây là thứ tự môn do chương trình dùng để xếp loại học kỳ qui định rồi giờ cập nhật làm xáo trộn đi sẽ dẫn tới khi import vào chương trình kia nó sẽ hiểu nhầm điểm của môn này với môn khác (rất nguy hiểm do chương trình xếp loại nó căn cứ vào vị trí của cột dữ liệu để đọc tương ứng vào chứ nó không thông minh để có thể nhận biết điểm đang đọc là của môn nào để đưa vào đúng môn trong nó). Về vấn đề VBA mình không được học nên không hiểu cách làm như thế nào nhưng mình thiết nghĩ một giải thuật như thế này bạn xem có được không nhé (có gì đừng cười là không làm được còn lắm chuyện nhé). Tên môn học là cố định trong trường theo mẫu bảng tổng hợp rồi (tuy nhiên với từng khối lại có một số môn không học trong học kỳ đó) nên bạn có thể đọc tên môn học theo thứ tự ở mẫu bảng tổng hợp rồi dò tìm tên sheet nào trong tệp dữ liệu mà trùng với tên môn học đang xét thì đọc dữ liệu vào đúng vị trí cột trong bảng tổng hợp, nếu không tìm thấy có nghĩa là môn học này lớp đó không được học thì bỏ qua chuyển sang cột khác tức là môn khác.
- Bạn có thể chỉnh để code này có thể chạy với bất kỳ lớp nào và với học kỳ nào được không vì mình thử với tệp của lớp khác thì nó không chạy.
Rất mong bạn giúp đỡ, mình đang rất cần để chuẩn bị làm điểm cuối năm. Cảm ơn bạn và các bạn đã quan tâm.
Cảm ơn bạn Hai Lúa Miền Tây và các bạn đã quân tâm và giúp mình. Mình vừa test thử thì thấy chương trình chạy được rồi. Dữ liệu lấy vào không bị nhầm lẫn giữa các môn. Xong có một vấn đề bạn có thể chỉnh tiếp giúp mình được không?
- Đó là Bạn có thể cập nhật dữ liệu vào đúng cột ở mẫu bảng tổng kết được không. Vì đây là thứ tự môn do chương trình dùng để xếp loại học kỳ qui định rồi giờ cập nhật làm xáo trộn đi sẽ dẫn tới khi import vào chương trình kia nó sẽ hiểu nhầm điểm của môn này với môn khác (rất nguy hiểm do chương trình xếp loại nó căn cứ vào vị trí của cột dữ liệu để đọc tương ứng vào chứ nó không thông minh để có thể nhận biết điểm đang đọc là của môn nào để đưa vào đúng môn trong nó). Về vấn đề VBA mình không được học nên không hiểu cách làm như thế nào nhưng mình thiết nghĩ một giải thuật như thế này bạn xem có được không nhé (có gì đừng cười là không làm được còn lắm chuyện nhé). Tên môn học là cố định trong trường theo mẫu bảng tổng hợp rồi (tuy nhiên với từng khối lại có một số môn không học trong học kỳ đó) nên bạn có thể đọc tên môn học theo thứ tự ở mẫu bảng tổng hợp rồi dò tìm tên sheet nào trong tệp dữ liệu mà trùng với tên môn học đang xét thì đọc dữ liệu vào đúng vị trí cột trong bảng tổng hợp, nếu không tìm thấy có nghĩa là môn học này lớp đó không được học thì bỏ qua chuyển sang cột khác tức là môn khác.
- Bạn có thể chỉnh để code này có thể chạy với bất kỳ lớp nào và với học kỳ nào được không vì mình thử với tệp của lớp khác thì nó không chạy.
Rất mong bạn giúp đỡ, mình đang rất cần để chuẩn bị làm điểm cuối năm. Cảm ơn bạn và các bạn đã quan tâm.
Việc duyệt qua tiêu đề cột của file mẫu theo thứ tự của bạn tôi đã có suy nghĩ đến, thế nhưng do tên cột và tên sheet có khác nhau nên không thể dùng theo cách này. Ví dụ bạn dò và so sánh tên sheet và tên cột của những môn sau đây: Vật lý, Địa lý, Anh văn, GD CD, CN...
Vâng đúng là có một số môn tên sheet và tên môn gõ không thống nhất. Mình đã chỉnh lại tên môn ở mẫu đúng với tên của môn trên nhãn của sheet. Bạn giúp mình tiếp nhé (theo cách duyệt tên môn theo thứ tự trên mẫu). Mình up lại dữ liệu đã chỉnh. Cảm ơn bạn.
File đính kèm
Lấy điểm TK HK (da chinh ten mon giong ten sheet).rar
Vâng đúng là có một số môn tên sheet và tên môn gõ không thống nhất. Mình đã chỉnh lại tên môn ở mẫu đúng với tên của môn trên nhãn của sheet. Bạn giúp mình tiếp nhé (theo cách duyệt tên môn theo thứ tự trên mẫu). Mình up lại dữ liệu đã chỉnh. Cảm ơn bạn.
[GPECODE=sql]Sub HLMT_ADO1()
On Error GoTo Handle
Dim cn As Object, cat As Object, tbl As Object, strTbl As String, i As Integer, iC As Integer
Dim mySQL As String, strFile As Variant
Set cn = CreateObject("ADODB.Connection")
Set cat = CreateObject("ADOX.Catalog")
Set tbl = CreateObject("ADOX.Table")
strFile = Application.GetOpenFilename()
If strFile <> False Then
Application.ScreenUpdating = False
[B7:AV51].ClearContents
With cn
.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strFile & _
";Extended Properties=""Excel 8.0;HDR=No;"";"
cat.ActiveConnection = cn
For i = 0 To cat.Tables.Count - 1
strTbl = strTbl & "," & Replace(Replace(cat.Tables(i).Name, "$", ""), "'", "")
Next
For iC = 1 To 13
If InStr(strTbl, Cells(5, iC + 2)) > 0 Then
mySQL = "UPDATE [" & Cells(5, iC + 2) & "$A6:AH50] a " _
& "INNER JOIN " _
& "[Excel 8.0;HDR=No;IMEX=2;DATABASE=" _
& ThisWorkbook.FullName & "].[HK1$a7:AV51] b " _
& "ON a.F1=b.F1 " _
& "SET b.F2=a.F2, b.F" & iC + 2 & "=a.F31, b.F" _
& iC + 19 + iC & "=a.F33, b.F" & iC + 20 + iC & "=a.F34"
.Execute mySQL
End If
Next
.Close
End With
Application.ScreenUpdating = True
End If
Set cn = Nothing: Set cat = Nothing: Set tbl = Nothing
Exit Sub
Handle:
MsgBox Err.Description
Cảm ơn bạn mình chạy thử thấy điểm môn này đưa vào cột môn đó trong bảng tổng hợp đúng rồi. Nhưng nếu muốn chạy cho lớp khác thì phải chỉnh thế nào vì mình chạy với lớp khác nó không chạy? Mình muốn chỉ với code này có thể chạy với bat kỳ tệp của lớp nào và học kỳ nào đề được mà không phải tạo mỗi lớp một tệp như thế này (trường mình có nhiều lớp). Phiền bạn xem giúp mình với. Cảm ơn bạn nhiều.
Cảm ơn bạn mình chạy thử thấy điểm môn này đưa vào cột môn đó trong bảng tổng hợp đúng rồi. Nhưng nếu muốn chạy cho lớp khác thì phải chỉnh thế nào vì mình chạy với lớp khác nó không chạy? Mình muốn chỉ với code này có thể chạy với bat kỳ tệp của lớp nào và học kỳ nào đề được mà không phải tạo mỗi lớp một tệp như thế này (trường mình có nhiều lớp). Phiền bạn xem giúp mình với. Cảm ơn bạn nhiều.
Thế nếu mình muốn lấy tên của tệp dữ liệu điểm thì phải dùng lệnh gì? đặt ở chỗ nào? và nếu sau khi tổng hợp mình muốn copy sheet kết quả lưu ra thành một tệp mới thì thêm lệnh gì vào đâu? Bạn chỉ mình với.
Mình đã chỉnh lại code để có thể chạy với bất kỳ lớp; với HK nào cũng được và lưu sheet kết quả ra một tệp riêng được rồi. Nhưng nếu mình ẩn các sheet kết quả bằng thuộc tính Visible = -2 ở tệp chứa code, trong code trước khi update dữ liệu vào tệp sheet kết quả mình có phải bỏ thuộc tính ẩn và sau khi copy sheet đó ra thành tệp mới thì lại phải đặt lại thuộc tính ẩn cho nó. Vậy thì lệnh mở và đóng thuộc tính ẩn của sheet kết quả đặt ở chỗ nào trong code của bạn? Mìnnh đặt thử vào trước lệnh copy nhưng nó lại có tác dụng với sheet ở tệp mới mà không có tác dụng với sheet ở tệp chứa code. Cảm ơn bạn
Thế nếu mình muốn lấy tên của tệp dữ liệu điểm thì phải dùng lệnh gì? đặt ở chỗ nào? và nếu sau khi tổng hợp mình muốn copy sheet kết quả lưu ra thành một tệp mới thì thêm lệnh gì vào đâu? Bạn chỉ mình với.
Mình đã chỉnh lại code để có thể chạy với bất kỳ lớp; với HK nào cũng được và lưu sheet kết quả ra một tệp riêng được rồi. Nhưng nếu mình ẩn các sheet kết quả bằng thuộc tính Visible = -2 ở tệp chứa code, trong code trước khi update dữ liệu vào tệp sheet kết quả mình có phải bỏ thuộc tính ẩn và sau khi copy sheet đó ra thành tệp mới thì lại phải đặt lại thuộc tính ẩn cho nó. Vậy thì lệnh mở và đóng thuộc tính ẩn của sheet kết quả đặt ở chỗ nào trong code của bạn? Mìnnh đặt thử vào trước lệnh copy nhưng nó lại có tác dụng với sheet ở tệp mới mà không có tác dụng với sheet ở tệp chứa code. Cảm ơn bạn
Option Explicit
Sub CopySheet(hk)
Application.DisplayAlerts = False
Sheets(hk).Unprotect Password:=12345
Sheets(hk).Copy
End Sub
Sub HLMT_ADO1()
On Error GoTo Handle
Dim cn As Object, cat As Object, tbl As Object, strTbl As String, i As Integer, iC As Integer, ten, vtri, sohk, hk, tentruong
Dim mySQL As String, strFile As Variant
Set cn = CreateObject("ADODB.Connection")
Set cat = CreateObject("ADOX.Catalog")
Set tbl = CreateObject("ADOX.Table")
strFile = Application.GetOpenFilename()
Workbooks.Open strFile
sohk = Right(Cells(2, 5), 1)
tentruong = Cells(1, 1)
ActiveWindow.Close
hk = "HK" & sohk
If strFile <> False Then
vtri = 0
For i = 1 To Len(strFile)
If Mid(strFile, i, 1) = "\" Then vtri = i
Next
ten = Right(strFile, Len(strFile) - vtri)
Sheets(hk).Activate
Application.ScreenUpdating = False
[B7:AV51].ClearContents
With cn
.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strFile & _
";Extended Properties=""Excel 8.0;HDR=No;"";"
cat.ActiveConnection = cn
For i = 0 To cat.Tables.Count - 1
strTbl = strTbl & "," & Replace(Replace(cat.Tables(i).Name, "$", ""), "'", "")
Next
For iC = 1 To 14
If InStr(strTbl, Cells(5, iC + 2)) > 0 Then
mySQL = "UPDATE [" & Cells(5, iC + 2) & "$A6:AH50] a " _
& "INNER JOIN " _
& "[Excel 8.0;HDR=No;IMEX=2;DATABASE=" _
& ThisWorkbook.FullName & "].[" & hk & "$a7:AV51] b " _
& "ON a.F1=b.F1 " _
& "SET b.F2=a.F2, b.F" & iC + 2 & "=a.F3" & sohk & ", b.F" _
& iC + 19 + iC & "=a.F33, b.F" & iC + 20 + iC & "=a.F34"
.Execute mySQL
End If
Next
.Close
End With
Application.ScreenUpdating = True
Call CopySheet(hk)
Cells(1, 1) = tentruong
Cells(3, 3) = "Cua tep du lieu ''" & ten & "''"
[A1:AV55].Locked = True
Sheets(hk).Protect Password:=12345
ActiveWorkbook.SaveAs ThisWorkbook.Path & "\Bang TB cac mon " & ten
ActiveWindow.Close
MsgBox "Da ket xuat xong diem TB cac mon " & hk & " cua tep du lieu ''" & ten & "''"
End If
Set cn = Nothing: Set cat = Nothing: Set tbl = Nothing
Exit Sub
Handle:
MsgBox Err.Description
End Sub
Trong tệp chứa code mình có 3 sheet một sheet chứa nút lệnh chạy code, hai sheet kia chứa hai mẫu bảng tổng hợp điểm ứng với HK1 và HK2. Bạn xem có thể tinh chỉnh giúp mình cho hợp lý hơn và có thể ẩn hai sheet chứa muẫ bảng tổng kết đi để khi sử dụng cho gọn. Cảm ơn bạn.
Option Explicit
Sub CopySheet(hk)
Application.DisplayAlerts = False
Sheets(hk).Unprotect Password:=12345
Sheets(hk).Copy
End Sub
Sub HLMT_ADO1()
On Error GoTo Handle
Dim cn As Object, cat As Object, tbl As Object, strTbl As String, i As Integer, iC As Integer, ten, vtri, sohk, hk, tentruong
Dim mySQL As String, strFile As Variant
Set cn = CreateObject("ADODB.Connection")
Set cat = CreateObject("ADOX.Catalog")
Set tbl = CreateObject("ADOX.Table")
strFile = Application.GetOpenFilename()
Workbooks.Open strFile
sohk = Right(Cells(2, 5), 1)
tentruong = Cells(1, 1)
ActiveWindow.Close
hk = "HK" & sohk
If strFile <> False Then
vtri = 0
For i = 1 To Len(strFile)
If Mid(strFile, i, 1) = "\" Then vtri = i
Next
ten = Right(strFile, Len(strFile) - vtri)
Sheets(hk).Activate
Application.ScreenUpdating = False
[B7:AV51].ClearContents
With cn
.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strFile & _
";Extended Properties=""Excel 8.0;HDR=No;"";"
cat.ActiveConnection = cn
For i = 0 To cat.Tables.Count - 1
strTbl = strTbl & "," & Replace(Replace(cat.Tables(i).Name, "$", ""), "'", "")
Next
For iC = 1 To 14
If InStr(strTbl, Cells(5, iC + 2)) > 0 Then
mySQL = "UPDATE [" & Cells(5, iC + 2) & "$A6:AH50] a " _
& "INNER JOIN " _
& "[Excel 8.0;HDR=No;IMEX=2;DATABASE=" _
& ThisWorkbook.FullName & "].[" & hk & "$a7:AV51] b " _
& "ON a.F1=b.F1 " _
& "SET b.F2=a.F2, b.F" & iC + 2 & "=a.F3" & sohk & ", b.F" _
& iC + 19 + iC & "=a.F33, b.F" & iC + 20 + iC & "=a.F34"
.Execute mySQL
End If
Next
.Close
End With
Application.ScreenUpdating = True
Call CopySheet(hk)
Cells(1, 1) = tentruong
Cells(3, 3) = "Cua tep du lieu ''" & ten & "''"
[A1:AV55].Locked = True
Sheets(hk).Protect Password:=12345
ActiveWorkbook.SaveAs ThisWorkbook.Path & "\Bang TB cac mon " & ten
ActiveWindow.Close
MsgBox "Da ket xuat xong diem TB cac mon " & hk & " cua tep du lieu ''" & ten & "''"
End If
Set cn = Nothing: Set cat = Nothing: Set tbl = Nothing
Exit Sub
Handle:
MsgBox Err.Description
End Sub
Trong tệp chứa code mình có 3 sheet một sheet chứa nút lệnh chạy code, hai sheet kia chứa hai mẫu bảng tổng hợp điểm ứng với HK1 và HK2. Bạn xem có thể tinh chỉnh giúp mình cho hợp lý hơn và có thể ẩn hai sheet chứa muẫ bảng tổng kết đi để khi sử dụng cho gọn. Cảm ơn bạn.
[GPECODE=sql]Sub HLMT_ADO1()
On Error GoTo Handle
Dim cn As Object, cat As Object, tbl As Object, strTbl As String, i As Integer, iC As Integer, ten, vtri, sohk, hk, tentruong
Dim mySQL As String, strFile As Variant
Set cn = CreateObject("ADODB.Connection")
Set cat = CreateObject("ADOX.Catalog")
Set tbl = CreateObject("ADOX.Table")
strFile = Application.GetOpenFilename()
Workbooks.Open strFile
sohk = Right(Cells(2, 5), 1)
tentruong = Cells(1, 1)
ActiveWindow.Close
hk = "HK" & sohk
If strFile <> False Then
vtri = 0
For i = 1 To Len(strFile)
If Mid(strFile, i, 1) = "\" Then vtri = i
Next
ten = Right(strFile, Len(strFile) - vtri)
'MsgBox " ten " & ten
Application.ScreenUpdating = False
Sheets(hk).Visible = xlSheetVisible
Sheets(hk).Activate
[B7:AV51].ClearContents
With cn
.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strFile & _
";Extended Properties=""Excel 8.0;HDR=No;"";"
cat.ActiveConnection = cn
For i = 0 To cat.Tables.Count - 1
strTbl = strTbl & "," & Replace(Replace(cat.Tables(i).Name, "$", ""), "'", "")
Next
For iC = 1 To 14 '13
If InStr(strTbl, Cells(5, iC + 2)) > 0 Then
mySQL = "UPDATE [" & Cells(5, iC + 2) & "$A6:AH50] a " _
& "INNER JOIN " _
& "[Excel 8.0;HDR=No;IMEX=2;DATABASE=" _
& ThisWorkbook.FullName & "].[" & hk & "$a7:AV51] b " _
& "ON a.F1=b.F1 " _
& "SET b.F2=a.F2, b.F" & iC + 2 & "=a.F3" & sohk & ", b.F" _
& iC + 19 + iC & "=a.F33, b.F" & iC + 20 + iC & "=a.F34"
.Execute mySQL
End If
Next
.Close
End With
Call CopySheet(hk)
Cells(1, 1) = tentruong
Cells(3, 3) = "Cua tep du lieu ''" & ten & "''"
[A1:AV55].Locked = True
Sheets(hk).Protect Password:=12345
ActiveWorkbook.SaveAs ThisWorkbook.Path & "\Bang TB cac mon " & ten
ActiveWindow.Close
Sheets(hk).Visible = xlSheetVeryHidden
Application.ScreenUpdating = True
MsgBox "Da ket xuat xong diem TB cac mon " & hk & " cua tep du lieu ''" & ten & "''"
End If
Set cn = Nothing: Set cat = Nothing: Set tbl = Nothing
Exit Sub
Handle:
MsgBox Err.Description
End Sub
[/GPECODE]
Bạn Set thuộc tính của 2 sheet (HK1,HK2) là xlSheetVeryHidden
Hai lúa Miền Tây ơi bây giờ tệp dữ liệu của mình có một chút thay đổi thế này đó là các môn Thể dục, Âm nhạc, Mỹ Thuật dữ liệu của nó không phải là các số như những môn khác mà là Đ hoặc CĐ. Như vậy thì đoạn code trên không chạy được với các môn này nó báo data type mismatch criteria expression. Bạn có thể chỉnh lại giúp mình không? Cảm ơn bạn. Mình gửi tệp dữ liệu lên bạn chạy và chỉnh hộ mình với.