Các thầy cho hỏi chút, có 1 đoan code phải chạy nhiều lần nhờ các thầy chỉ giúp cho ngắn gọn hơn không?
Bạn tìm hiểu về vòng lặp nhé, trong chương 10. Việc sử dụng vòng lặp sẽ giúp code ngắn gọn hơn, tư duy lập trình tốt hơn.
Ý em là: nó dùng rời rạc khác nhau từng chỗ í. Một đoạn code chỗ này dùng, chỗ khác lại phải copy lại dùng tiếp, chỗ khác nữa lại copy lại dùng tiếp ấy
Bạn có thể tham khảo về bài viết này:
https://gitiho.com/blog/tim-hieu-ve-c...
Câu trả lời cho câu hỏi của bạn là về Function - hàm tự tạo trong VBA. Nhưng cách viết Function là dạng viết tổng quát, thông qua các biến => Khi sử dụng sẽ truyền tham số để hàm tự tính ra kết quả (hoặc chạy lại 1 thủ tục).
Bạn có thể sử dụng function như 1 hàm trong excel, hoặc sử dụng trong các đoạn code khác.
Bạn có thể tham khảo về function tìm dòng cuối (có trong file bài giảng) là 1 ví dụ về cách viết tổng quát. Khi dùng bạn chỉ cần khai báo thêm tìm dòng cuối ở Sheet nào, theo cột nào mà không cần viết lại toàn bộ cú pháp.
Sub Bieutg()
Dim bt1, bt2, btT As Date
'tinh thoi gian bieu tong
btT = Ekd.Range("b16").Value - Ekd.Range("b15").Value
Ekd.Range("C16").Value = Hour(btT) * 60 + Minute(btT)
'tinh thoi gian bieu 2
' Tinh cho 9:30 - 11:30
If Ekd.Range("b15").Value < "0.395833333" And _
Ekd.Range("b16").Value > "0.395833333" And _
Ekd.Range("b16") < "0.479166667" Then
bt2 = Ekd.Range("b16").Value - "0.395833333"
Ekd.Range("d16").Value = Hour(bt2) * 60 + Minute(bt2)
Ekd.Range("e16").Value = Ekd.Range("C16").Value - Ekd.Range("d16").Value
ElseIf Ekd.Range("b15").Value < "0.395833333" And _
Ekd.Range("b16").Value > "0.395833333" And _
Ekd.Range("b16") > "0.479166667" Then
bt2 = "0.479166667" - "0.395833333"
Ekd.Range("d16").Value = Hour(bt2) * 60 + Minute(bt2)
Ekd.Range("e16").Value = Ekd.Range("C16").Value - Ekd.Range("d16").Value
ElseIf Ekd.Range("b15").Value > "0.395833333" And _
Ekd.Range("b15").Value < "0.479166667" And _
Ekd.Range("b16") > "0.479166667" Then
bt2 = "0.479166667" - Ekd.Range("b15").Value
Ekd.Range("d16").Value = Hour(bt2) * 60 + Minute(bt2)
Ekd.Range("e16").Value = Ekd.Range("C16").Value - Ekd.Range("d16").Value
ElseIf Ekd.Range("b15").Value > "0.395833333" And _
Ekd.Range("b16") < "0.479166667" Then
Ekd.Range("d16").Value = Ekd.Range("c16").Value
Ekd.Range("e16").Value = Ekd.Range("C16").Value - Ekd.Range("d16").Value
' Tinh cho 17:00 - 20:00
ElseIf Ekd.Range("b15").Value < "0.708333333" And _
Ekd.Range("b16").Value > "0.708333333" And _
Ekd.Range("b16") < "0.833333333" Then
bt2 = Ekd.Range("b16").Value - "0.708333333"
Ekd.Range("d16").Value = Hour(bt2) * 60 + Minute(bt2)
Ekd.Range("e16").Value = Ekd.Range("C16").Value - Ekd.Range("d16").Value
ElseIf Ekd.Range("b15").Value < "0.708333333" And _
Ekd.Range("b16").Value > "0.708333333" And _
Ekd.Range("b16") > "0.833333333" Then
bt2 = "0.833333333" - "0.708333333"
Ekd.Range("d16").Value = Hour(bt2) * 60 + Minute(bt2)
Ekd.Range("e16").Value = Ekd.Range("C16").Value - Ekd.Range("d16").Value
ElseIf Ekd.Range("b15").Value > "0.708333333" And _
Ekd.Range("b15").Value < "0.833333333" And _
Ekd.Range("b16") > "0.833333333" Then
bt2 = "0.833333333" - Ekd.Range("b15").Value
Ekd.Range("d16").Value = Hour(bt2) * 60 + Minute(bt2)
Ekd.Range("e16").Value = Ekd.Range("C16").Value - Ekd.Range("d16").Value
ElseIf Ekd.Range("b15").Value > "0.708333333" And _
Ekd.Range("b16") < "0.833333333" Then
bt2 = "0.833333333" - "0.708333333"
Ekd.Range("d16").Value = Ekd.Range("c16").Value
Ekd.Range("e16").Value = Ekd.Range("C16").Value - Ekd.Range("d16").Value
Else: bt2 = 0
Ekd.Range("d16").Value = Hour(bt2) * 60 + Minute(bt2)
Ekd.Range("e16").Value = Ekd.Range("C16").Value - Ekd.Range("d16").Value
End If
End Sub
Đây ạ, e muốn sub cho ra kết quả bt2 để tính tiếp, biến đầu vào để xác định bt2 là ô b15, b16
Chào bạn,
mình có xem code và nhận thấy như sau:
- Các cấu trúc IF của bạn là xét những logic khác nhau (liên tiếp theo 1 trình tự) nên về bản chất cần thể hiện đầy đủ những logic này, không viết gọn hơn được (không sợ code dài đâu, chỉ sợ code thiếu).
- Code đưa về dạng viết tổng quát (function / sub tổng quát) là dạng code dùng đi dùng lại nhiều lần cho 1 lệnh (hình dung là 1 câu lệnh sẽ dùng lặp lại nhiều lần trong các thủ tục khác). Ví dụ như trường hợp của bạn ô B15, B16 có thể nằm ở nhiều sheet, tại các sheet khác có thể nằm ở ô khác, mỗi sheet cần tính 1 lần thì sẽ viết code dạng tổng quát để chỉ cần khai báo riêng ô đó thôi:
Sub Bieutg(sh As Worksheet, rng1 As String, rng2 As String)
'sh la sheet Ekd, rng1 la B15, rng2 la B16
Dim bt1, bt2, btT As Date
'tinh thoi gian bieu tong
btT = sh.Range(rng2).Value - sh.Range(rng1).Value 'B16 - B15
sh.Range(rng2).Offset(0, 1).Value = Hour(btT) * 60 + Minute(btT) 'C16
'tinh thoi gian bieu 2
' Tinh cho 9:30 - 11:30
If sh.Range(rng1).Value < "0.395833333" And sh.Range(rng2).Value > "0.395833333" And sh.Range(rng2).Value < "0.479166667" Then
bt2 = sh.Range(rng2).Value - "0.395833333"
sh.Range(rng2).Offset(0, 2).Value = Hour(bt2) * 60 + Minute(bt2) 'D16
sh.Range(rng2).Offset(0, 3).Value = sh.Range(rng2).Offset(0, 1).Value - sh.Range(rng2).Offset(0, 2).Value 'E16=C16-D16
ElseIf sh.Range(rng1).Value < "0.395833333" And sh.Range(rng2).Value > "0.395833333" And sh.Range(rng2).Value > "0.479166667" Then
bt2 = "0.479166667" - "0.395833333"
sh.Range(rng2).Offset(0, 2).Value = Hour(bt2) * 60 + Minute(bt2)
sh.Range(rng2).Offset(0, 3).Value = sh.Range(rng2).Offset(0, 1).Value - sh.Range(rng2).Offset(0, 2).Value
...
Else
...
End If
End Sub
Khi đó để dùng code này, bạn chỉ cần gọi lệnh
Call Bieutg(Sheets("Sheet1"), "B15", "B16")
trong đó:
- sh là tên sheet => ví dụ là Sheets("Sheet1")
- rng1 là tọa độ vùng ô => ô B15
-rng2 là tọa độ vùng ô => ô B16
là sẽ có kết quả