Đào quang Cường
Đào quang Cường
Thảo luận 6 thảo luận
Vỗ tay 0 vỗ tay
Lượt xem 366 lượt xem

Các chút có 1 đoan code phải chạy nhiều lần nhờ các chỉ giúp

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? 


Thảo luận 6 câu trả lời
Lượt xem 366 lượt xem
Vỗ tay vỗ tay
Đào quang Cường 09:12 - Dec 22, 2020

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.

Vỗ tay vỗ tay
Đào quang Cường 14:12 - Dec 22, 2020

Ý 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

Vỗ tay vỗ tay
Đào quang Cường 15:12 - Dec 22, 2020

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.

Vỗ tay vỗ tay
Đào quang Cường 15:12 - Dec 22, 2020
Bạn có thể gửi 1 đoạn code dùng nhiều lần lên phần đặt câu hỏi, mình sẽ làm mẫu giúp bạn chuyển về dạng viết tổng quát.
Vỗ tay vỗ tay
Đào quang Cường 17:12 - Dec 22, 2020

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

Vỗ tay vỗ tay
Đào quang Cường 09:12 - Dec 25, 2020

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ả

Vỗ tay vỗ tay
Câu hỏi liên quan
@ 2020 - Bản quyền của Công ty cổ phần công nghệ giáo dục Gitiho Việt Nam
Giấy chứng nhận Đăng ký doanh nghiệp số: 0109077145, cấp bởi Sở kế hoạch và đầu tư TP. Hà Nội