Em mới tham gia diễn đàn, đang tập tành VBA. Em có viết code để kiểm tra thời khóa biểu của trường có nhiều phòng chức năng. các bác tham khảo và cho ý kiến để em học hỏi thêm.
Dưới đây là những góp í ban đầu cho chương trình khá công fu của bạn, từ nhỏ nhất
(1) Không nên to màu nền cho cả hàng hay cột; Chỉ nên tô đến cột cuối hay hàgn cuối có dữ liệu mà thôi.
(2) Tên trang tính nên là 'BanGoc' thay vì 'bangoc';
Như rứa với 'TKBMon', 'TKBLop', TKBGV',. . . .
Tên hàm cũng nên là MaGV thay vì 'magv', tên macro cũng vậy, thay vì 'taotkbgv' ta nên xài 'TaoTKBGV'
(3) Xét macro
PHP:
Sub taotkbgv()
Dim TKB(2 To 62, 4 To 22) As String
Dim i As Integer, j As Integer, m As Integer, n As Integer
3 m = 2: n = 3
Sheets("TKBGV").Range("B4:G13").ClearContents
5 Sheets("bangoc").Select '<=|'
For i = 3 To 62
7 n = n + 1
If n > 13 Then
9 n = 4: m = m + 1
End If
11 For j = 4 To 21
'* Da Chuyen Dén Dòng 5'
Cells(i, j).Activate
13 If magv(Cells(i, j).Value) = Range("W2").Value Then
MH = mon(Cells(i, j).Value)
15 LOP = Cells(2, j).Value
PH = PHONG(Cells(i, j).Value)
17 Sheets("tkbgv").Select
Cells(n, m).Value = MH & "_" & PH & "_" & LOP
19 End If
Next j
Next i
End Sub
mình đã sửa vài điểm, có thể là nhỏ với bạn, nhưng với mình là lớn.. .
*) Dòng lệnh 5 mình đem từ trong vòng lặp ra ngoài. Réo gọi nó 1 lần là nó có mặt rồi, chi mà réo hoài làm vậy?!
Khi đó dòng lệnh m ang số 17 nên gộp với dòng dưới liền kề;
(4) Khai báo các biến:
Đọc xong dòng lệnh 18, mình mới biết bạn xài biến n để biểu thị số hàng & m - là cột của ô nào đó;
Vậy sao ngay từ đầu, bạn không dùng là H, D, hay Dg thay cho n có fải ấn tượng hơn không? Hay điều này là fạm huý? Có nhà lập trình chuyên nghiệp trên GPE khuyên chúng ta nên dùng Rw & Col trong những trường hợp này đó nghe!
Riêng mình thì rất hãn hữu xài tên biến với 1 ký tự; vạn bất đắc dĩ thì xài ký tự in hoa; Chi vậy bạn biết không? Tận dụng trình VBE fát hiện lỗi chính tả giúp ta, khi viết câu lệnh.
Các biến MH, PH & LOP nên khai báo tường minh hơn.
(5) Hàm tự tạo của bạn:
Dưới đây mình chỉ nêu 1 hàm trong vài cái của bạn có lỗi na ná nhau, như sau:
PHP:
Public Function magv(s As String) As String
For i = 1 To Len(s)
If Mid(s, i, 1) = "-" Or Mid(s, i, 1) = "_" Then
21
Exit For
End If
Next i
magv = Mid(s, i + 1, 2)
End Function
(*) Tên hàm mình đã nói bên trên;
(*) Tham biến s chí ít nên viết hoa;
(*) Chuyện gì sẽ sẩy ra, 1 khi hàm sẽ không thỏa điều kiện If;
Nói cách khác, bạn chưa lường trước nguy cơ đang rình bạn, 1 khi ai đó xỉn & nhập thiếu dấu gạch dưới hay ngang giửa ("_","-").
Theo mình trong những trường hợp như vậy, hàm nên trả về là 1 chuỗi rỗng;
Thực thi điều đó như vầy:
Chuyển dòng lệnh áp chót lên dòng 21;
Đổi dòng lệnh Exit For thành Exit Function
(6) Bạn nên ghi chú các macro của mình, để ngay chính bạn sau này không tẩu hỏa nhập ma ngay khi đọc đứa con tinh thần của mình!
Thật ra mình cũng tự khoe là mình cũng khá kiên trì với bạn đó chớ bộ, để nói những lời khó nghe như trên!
Public Function mon(s As String) As String '**'
For i = 1 To Len(s)
If Mid(s, i, 1) = "-" Or Mid(s, i, 1) = "_" Then
Exit For
End If
Next i
mon = Left(s, i - 1)
End Function
& hàm:
Mã:
Public Function magv(s As String) As String '<>'
For i = 1 To Len(s)
If Mid(s, i, 1) = "-" Or Mid(s, i, 1) = "_" Then
Exit For
End If
Next i
magv = Mid(s, i + 1, 2) '<>'
End Function
Vì bản thân chúng có giải thuật i chang nhau: Đó là dùng vòng lặp duyệt suốt chiều dài chữ, hễ gặp kí tự qui ước thì xử lý.
Còn mình gợi í bạn dùng hàm IStr("GPE.COM", "C") để làm việc này
Nội dung nó như sau:
PHP:
Function TimMa(Ch As String, Optional GV As Boolean = True) As String
' GV="FALSE" => Mon; GV="TRUE" => MaGV'
Const GG As String = "-": Const GD As String = "_"
Dim VTr As Byte
VTr = InStr(Ch, GD)
If VTr Then GoTo GPE
VTr = InStr(Ch, GG)
If VTr < 1 Then Exit Function
GPE:
If GV Then
TimMa = Mid(Ch, VTr + 1, 2)
Else
TimMa = Left(Ch, VTr - 1)
End If
End Function
Bạn đừng cho là nó dài vậy mà thua 2 cục cưng của bạn về tốc độ đó nhe!
/(/ếu bạn 'OK' mình sẽ giúp bạn cách thay thế vô 2 hàm trên của bạn!
trong chương trình minh không dùng sub taotkbgv thay vào đó mình dùng sub taotkbgMANG
Sub taotkbgvMANG()
Dim TKB(2 To 62, 4 To 21) As String
Dim i As Integer
Dim j As Integer
Dim c As Integer
Dim m As Integer
Dim n As Integer
Dim NHAPMGV As String
Dim TB As Integer
Dim DONG As Integer
Dim SOGV As Integer
Sheets("bangoc").Select
For i = 2 To 62
For j = 4 To 21
Cells(i, j).Activate
TKB(i, j) = Cells(i, j)
Next j
Next i
Sheets("TKBGV").Select
Range("B4:G13").Select
Selection.ClearContents
DONG = 1
For SOGV = 1 To 50
Range("B4:G13").Select
Selection.ClearContents
NHAPMGV = InputBox("NHAP MA GIAO VIEN DE IN", "THONG BAO")
Cells(2, 3).Value = NHAPMGV
m = 2
n = 3
For i = 3 To 62
n = n + 1
If n > 13 Then
n = 4
m = m + 1
End If
For j = 4 To 21
If magv(TKB(i, j)) = NHAPMGV Then
MH = mon(TKB(i, j))
LOP = TKB(2, j)
PH = PHONG(TKB(i, j))
Sheets("tkbgv").Select
Cells(n, m).Value = MH & "_" & PH & "_" & LOP
End If
Next j
Next i
DONG = DONG + 15
Range("A1:G14").Select
Selection.Copy
Cells(DONG, 1).Select
ActiveSheet.Paste
Application.CutCopyMode = False
TB = MsgBox("TIEP TUC?", vbYesNo + vbQuestion, "THONG BAO")
If TB = 7 Then Exit For
'Trong chương trình minh không dùng sub taotkbgv thay vào đó mình dùng sub taotkbgMANG'
Sub taotkbgvMANG()
Dim TKB(2 To 62, 4 To 21) As String
Dim i As Integer, j As Integer, c As Integer, m As Integer
Dim n As Integer, TB As Integer, DONG As Integer, SOGV As Integer
Dim NHAPMGV As String
Sheets("bangoc").Select
For i = 2 To 62
For j = 4 To 21
Cells(i, j).Activate
TKB(i, j) = Cells(i, j)
Next j
Next i
Sheets("TKBGV").Select
Range("B4:G13").Select
Selection.ClearContents
DONG = 1
For SOGV = 1 To 50
Range("B4:G13").Select
Selection.ClearContents
NHAPMGV = InputBox("NHAP MA GIAO VIEN DE IN", "THONG BAO")
Cells(2, 3).Value = NHAPMGV
m = 2: n = 3
For i = 3 To 62
n = n + 1
If n > 13 Then
n = 4: m = m + 1
End If
For j = 4 To 21
If magv(TKB(i, j)) = NHAPMGV Then
MH = mon(TKB(i, j))
LOP = TKB(2, j)
PH = PHONG(TKB(i, j))
Sheets("tkbgv").Select
Cells(n, m).Value = MH & "_" & PH & "_" & LOP
End If
Next j
Next i
DONG = DONG + 15
Range("A1:G14").Select
Selection.Copy
Cells(DONG, 1).Select
ActiveSheet.Paste
Application.CutCopyMode = False
TB = MsgBox("TIEP TUC?", vbYesNo + vbQuestion, "THONG BAO")
If TB = 7 Then Exit For
Next SOGV
End Sub
Thật ra đọc các câu lệnh để hiểu đã khó huống chi sửa;
Hay là vầy đi: Bạn chịu khó mô tả lại chu trình mà macro fải trãi qua & cuối cùng là kết quả bạn cần là như thế nào?