Tư vấn rút gọn code

Liên hệ QC

lmtuyen

Thành viên chính thức
Tham gia
14/3/09
Bài viết
71
Được thích
12
CHÀO CÁC BẠN
Mình có đoạn code bên dưới, Dùng If nhiều quá, các bạn tư vấn có thể rút ngắn lại ah. Mình suy nghỉ dùng Mảng, làm thử vẫn chưa được

Private Sub CommandButton1_Click()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Sheet1")
If CheckBox1.Value = True Then
s1 = "A"
End If
If CheckBox2.Value = True Then
s2 = "B"
End If

If CheckBox3.Value = True Then
s3 = "C"
End If

If CheckBox4.Value = True Then
s4 = "D"
End If

If CheckBox5.Value = True Then
S5 = "E"
End If
If CheckBox6.Value = True Then
S6 = "F"
End If
'-----------------
sh.Range("d1").Value = Application.WorksheetFunction.TextJoin(",", True, s1, s2)

sh.Range("d4").Value = Application.WorksheetFunction.TextJoin(",", True, s3, s4, S5, S6)
End Sub
 
Mình chưa rõ có giúp được không, nhưng bạn thử gửi file lên xem sao.
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu các checkbox gắn trên sheet
Nếu s1 đến s5 là ô trên sheet hoặc textbox trên sheet
- Gán LinkedCell cho các checkbox ở chỗ nào đó (ví dụ ô A1 cho checkbox1)
- s1 = if(A1,"A","")
Khỏi code, khỏi băn khoăn code dài, khỏi nhấn command button
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu các checkbox gắn trên sheet
Nếu s1 đến s5 là ô trên sheet hoặc textbox trên sheet
- Gán LinkedCell cho các checkbox ở chỗ nào đó (ví dụ ô A1 cho checkbox1)
- s1 = if(A1,"A","")
Khỏi code, khỏi băn khoăn code dài
Dạ Em chào Thầy

Checkbox em làm nhập liệu trên Form ah, thấy code kỳ kỳ mà tìm chưa ra cái hay hơn.
Capture.JPG
Bài đã được tự động gộp:

Mình chưa rõ có giúp được không, nhưng bạn thử gửi file lên xem sao.
Thank Bạn, mình có đính kèm file bài trước ah
 
Upvote 0
Code bạn thực chất cũng không cần rút gọn làm gì có chăng "If CheckBox1.Value = True Then" chuyển thành "If CheckBox1.Value Then" cũng có nghĩa y nhau.
Nhưng có vấn đề tiềm ẩn là nếu s1, s2, s3, s4, S5, S6 là biến toàn cục, code bạn phải làm dài ra (chẳng hạn thêm Else... hoặc cài đặt lại giá trị) nếu không sẽ dễ sai logic ở lần chạy CommandButton1_Click() thứ 2 nếu lỡ bấm một trong những cái checkbox. Cách đơn giản nhất là dùng chúng như biến cục bộ.
 
Lần chỉnh sửa cuối:
Upvote 0
sh.Range("d1").Value = Application.WorksheetFunction.TextJoin(",", True, IIF(CheckBox1.Value, "A", ""), IIF(CheckBox2.Value, "B", ""))

sh.Range("d4").Value = Application.WorksheetFunction.TextJoin(",", True, IIF(CheckBox3.Value, "C", ""), IIF(CheckBox4.Value, "D", ""), _
IIF(CheckBox5.Value, "E", ""), IIF(CheckBox6.Value, "F", ""))
 
Upvote 0
Chào các bạn, phiền các bạn giúp tôi rút gọn đoạn code dưới với:
Mã:
...
            If gioihan_min > 1 And gioihan_max > 1 Then gioihan_b = True
            If loc_x > 0 Then gioihan_a = True
            loc_1 = "*" & UCase(loc_1) & "*"
            loc_3 = "*" & UCase(loc_3) & "*": k = 0: izi = izi
            For i = 1 To r
                If UCase(Duieu(i, 3)) Like loc_3 Then
                    If UCase(Duieu(i, 5)) Like loc_1 Then
                        If Not gioihan_a Then
                           If Not gioihan_b Then
                                k = k + 1: izi = k
                                For j = 1 To c
                                    n = ary(2, j)
                                    If n > 0 Then
                                        dArr(k, j) = Duieu(i, n)
                                    End If
                                Next j
                                dArr(k, 1) = link
                                dArr(k, 2) = izi
                            Else
                                If Duieu(i, 4) >= gioihan_min Then
                                    If Duieu(i, 4) <= gioihan_max Then
                                        k = k + 1: izi = k
                                        For j = 1 To c
                                            n = ary(2, j)
                                            If n > 0 Then
                                                dArr(k, j) = Duieu(i, n)
                                            End If
                                        Next j
                                        dArr(k, 1) = link
                                        dArr(k, 2) = izi
                                    End If
                                End If
                            End If
                        Else
                            If Duieu(i, 8) = loc_xThen
                                If Not gioihan_b Then
                                    k = k + 1: izi = k
                                    For j = 1 To c
                                        n = ary(2, j)
                                        If n > 0 Then
                                            dArr(k, j) = Duieu(i, n)
                                        End If
                                    Next j
                                    dArr(k, 1) = link
                                    dArr(k, 2) = izi
                                Else
                                    If Duieu(i, 4) >= gioihan_min Then
                                        If Duieu(i, 4) <= gioihan_max Then
                                            k = k + 1: izi = k
                                            For j = 1 To c
                                                n = ary(2, j)
                                                If n > 0 Then
                                                    dArr(k, j) = Duieu(i, n)
                                                End If
                                            Next j
                                            izi(k, 1) = link
                                            dArr(k, 2) = izi
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            Next i
...
Cảm ơn.
 
Upvote 0
Chào các bạn, phiền các bạn giúp tôi rút gọn đoạn code dưới với:
Mã:
...
            If gioihan_min > 1 And gioihan_max > 1 Then gioihan_b = True
            If loc_x > 0 Then gioihan_a = True
            loc_1 = "*" & UCase(loc_1) & "*"
            loc_3 = "*" & UCase(loc_3) & "*": k = 0: izi = izi
            For i = 1 To r
                If UCase(Duieu(i, 3)) Like loc_3 Then
                    If UCase(Duieu(i, 5)) Like loc_1 Then
                        If Not gioihan_a Then
                           If Not gioihan_b Then
                                k = k + 1: izi = k
                                For j = 1 To c
                                    n = ary(2, j)
                                    If n > 0 Then
                                        dArr(k, j) = Duieu(i, n)
                                    End If
                                Next j
                                dArr(k, 1) = link
                                dArr(k, 2) = izi
                            Else
                                If Duieu(i, 4) >= gioihan_min Then
                                    If Duieu(i, 4) <= gioihan_max Then
                                        k = k + 1: izi = k
                                        For j = 1 To c
                                            n = ary(2, j)
                                            If n > 0 Then
                                                dArr(k, j) = Duieu(i, n)
                                            End If
                                        Next j
                                        dArr(k, 1) = link
                                        dArr(k, 2) = izi
                                    End If
                                End If
                            End If
                        Else
                            If Duieu(i, 8) = loc_xThen
                                If Not gioihan_b Then
                                    k = k + 1: izi = k
                                    For j = 1 To c
                                        n = ary(2, j)
                                        If n > 0 Then
                                            dArr(k, j) = Duieu(i, n)
                                        End If
                                    Next j
                                    dArr(k, 1) = link
                                    dArr(k, 2) = izi
                                Else
                                    If Duieu(i, 4) >= gioihan_min Then
                                        If Duieu(i, 4) <= gioihan_max Then
                                            k = k + 1: izi = k
                                            For j = 1 To c
                                                n = ary(2, j)
                                                If n > 0 Then
                                                    dArr(k, j) = Duieu(i, n)
                                                End If
                                            Next j
                                            izi(k, 1) = link
                                            dArr(k, 2) = izi
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            Next i
...
Cảm ơn.
Nhìn như cái bản đồ ấy bạn nhỉ? Mình chưa thử nhiều điều kiện như này.
 
Upvote 0
Mấy cái IF lồng nhau nếu không có ELSE thì có thể dùng AND để giảm bớt các lệch IF. Chẳng hạn:
Mã:
IF A>3 THEN
    IF B<9 THEN

        ....

    END IF
END IF
Rút gọn thành
Mã:
IF A>3 AND B<9 THEN
        ....
END IF
Giảm bớt lồng để nhìn đỡ phức tạp hơn chứ không hẳn là luôn luôn nhanh hơn đâu nhé.
 
Upvote 0
Mấy cái IF lồng nhau nếu không có ELSE thì có thể dùng AND để giảm bớt các lệch IF. Chẳng hạn:
Mã:
IF A>3 THEN
    IF B<9 THEN

        ....

    END IF
END IF
Rút gọn thành
Mã:
IF A>3 AND B<9 THEN
        ....
END IF
Giảm bớt lồng để nhìn đỡ phức tạp hơn chứ không hẳn là luôn luôn nhanh hơn đâu nhé.
Cảm ơn bạn đã góp ý, tôi thấy nó đang bị bó buộc 2 điều kiện này nếu TRUE hoặc FALSE dẫn đến code dài gấp 2 lần
...
If Not gioihan_a Then
If Not gioihan_b Then
...
Có hướng nào để xử lý không bạn?
 
Upvote 0
Code rác rưởi. Viết lại đi chứ sửa làm gì.

Vả lại, đưa lên một đoạn code mà không nói nó làm gì thì biết chỗ nào dư mà cắt bớt?
Trừ cái chỗ dư quá hiển nhiên như sau:
loc_3 = "*" & UCase(loc_3) & "*": k = 0: izi = izi

Ngay cả chỗ này, nhìn chướng mắt nhưng biết đâu nó có lý do của nó:
If loc_x > 0 Then gioihan_a = True
Nếu If không thoả thì gioihan_a giữ giá trị trước đó. Có thấy phần code trước đó đâu mà biết để sửa?

Đoạn này được lặp lại nhiều lần. Nếu chấp nhận code khó hiểu thì có thể thay bằng lệnh GoSub.
k = k + 1: izi = k
For j = 1 To c
n = ary(2, j)
If n > 0 Then
dArr(k, j) = Duieu(i, n)
End If
Next j
dArr(k, 1) = link
dArr(k, 2) = izi
GoSub FILL_ARRAY

Gần chỗ End Sub

Exit Sub ' thoát sub chính, nếu không code sẽ bước vào sub con
' ' --------------------
' start of sub con
FILL_ARRAY:
k = k + 1: izi = k
For j = 1 To c
n = ary(2, j)
If n > 0 Then dArr(k, j) = Duieu(i, n)
Next j
dArr(k, 1) = link
dArr(k, 2) = izi
Return ' hết sub con
' ' --------------------
End Sub ' sub chính
 
Upvote 0
Code rác rưởi. Viết lại đi chứ sửa làm gì.

Vả lại, đưa lên một đoạn code mà không nói nó làm gì thì biết chỗ nào dư mà cắt bớt?
Trừ cái chỗ dư quá hiển nhiên như sau:


Ngay cả chỗ này, nhìn chướng mắt nhưng biết đâu nó có lý do của nó:

Nếu If không thoả thì gioihan_a giữ giá trị trước đó. Có thấy phần code trước đó đâu mà biết để sửa?

Đoạn này được lặp lại nhiều lần. Nếu chấp nhận code khó hiểu thì có thể thay bằng lệnh GoSub.

GoSub FILL_ARRAY

Gần chỗ End Sub

Exit Sub ' thoát sub chính, nếu không code sẽ bước vào sub con
' ' --------------------
' start of sub con
FILL_ARRAY:
k = k + 1: izi = k
For j = 1 To c
n = ary(2, j)
If n > 0 Then dArr(k, j) = Duieu(i, n)
Next j
dArr(k, 1) = link
dArr(k, 2) = izi
Return ' hết sub con
' ' --------------------
End Sub ' sub chính
cảm ơn bạn, tôi chỉ hỏi phương pháp như bạn đã chỉ, không bàn chuyện code đúng hay sai vì tôi chỉ trích một đoạn không đầy đủ.
 
Upvote 0
Tôi biết bạn sẽ không màng đúng hay sai.
Tôi nêu ra chỗ rác rưởi là để khuyến cáo các thành viên khác.
 
Upvote 0
Chào các bạn, phiền các bạn giúp tôi rút gọn đoạn code dưới với:

Cảm ơn.
Trong trường đoạn Code mà bạn trích dẫn mình thấy có 4 điệp khúc sau:
PHP:
                                K = K + 1:          iZi = K
                                For J = 1 To C
                                    N = aRy(2, J)
                                    If N > 0 Then
                                        dArr(K, J) = DLieu(I, N)
                                    End If
                                Next J
                                iZi(K, 1) = link
                                dArr(K, 2) = iZi
Bạn cố viết đoạn điệp khúc này thành 1 macro con xem sao; Dù sao thì viết vậy sẽ dễ nhìn & kiểm soát hơn tẹo nào đó
Chúc vui vẻ đến với mọi người!
 
Upvote 0
Chào các bạn, phiền các bạn giúp tôi rút gọn đoạn code dưới với:
Mã:
...
            If gioihan_min > 1 And gioihan_max > 1 Then gioihan_b = True
            If loc_x > 0 Then gioihan_a = True
            loc_1 = "*" & UCase(loc_1) & "*"
            loc_3 = "*" & UCase(loc_3) & "*": k = 0: izi = izi
            For i = 1 To r
                If UCase(Duieu(i, 3)) Like loc_3 Then
                    If UCase(Duieu(i, 5)) Like loc_1 Then
                        If Not gioihan_a Then
                           If Not gioihan_b Then
                                k = k + 1: izi = k
                                For j = 1 To c
                                    n = ary(2, j)
                                    If n > 0 Then
                                        dArr(k, j) = Duieu(i, n)
                                    End If
                                Next j
                                dArr(k, 1) = link
                                dArr(k, 2) = izi
                            Else
                                If Duieu(i, 4) >= gioihan_min Then
                                    If Duieu(i, 4) <= gioihan_max Then
                                        k = k + 1: izi = k
                                        For j = 1 To c
                                            n = ary(2, j)
                                            If n > 0 Then
                                                dArr(k, j) = Duieu(i, n)
                                            End If
                                        Next j
                                        dArr(k, 1) = link
                                        dArr(k, 2) = izi
                                    End If
                                End If
                            End If
                        Else
                            If Duieu(i, 8) = loc_xThen
                                If Not gioihan_b Then
                                    k = k + 1: izi = k
                                    For j = 1 To c
                                        n = ary(2, j)
                                        If n > 0 Then
                                            dArr(k, j) = Duieu(i, n)
                                        End If
                                    Next j
                                    dArr(k, 1) = link
                                    dArr(k, 2) = izi
                                Else
                                    If Duieu(i, 4) >= gioihan_min Then
                                        If Duieu(i, 4) <= gioihan_max Then
                                            k = k + 1: izi = k
                                            For j = 1 To c
                                                n = ary(2, j)
                                                If n > 0 Then
                                                    dArr(k, j) = Duieu(i, n)
                                                End If
                                            Next j
                                            izi(k, 1) = link
                                            dArr(k, 2) = izi
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            Next i
...
Cảm ơn.
Kiểm tra lại
Mã:
      If gioihan_min > 1 And gioihan_max > 1 Then gioihan_b = True
      If loc_x > 0 Then gioihan_a = True
      loc_1 = "*" & UCase(loc_1) & "*"
      loc_3 = "*" & UCase(loc_3) & "*": k = 0: izi = izi
      For i = 1 To r
        If UCase(Duieu(i, 3)) Like loc_3 Then '1
          If UCase(Duieu(i, 5)) Like loc_1 Then '2
            If Not gioihan_a Then '3
              Call DEF(gioihan_b, gioihan_min, gioihan_max, i, k, ary, darr, dulieu, link)
            Else '3
              If Duieu(i, 8) = loc_x Then '4
                Call DEF(gioihan_b, gioihan_min, gioihan_max, i, k, ary, darr, dulieu, link)
              End If '4
            End If '3
          End If '2
        End If '1
      Next i
Mã:
Private Sub DEF(gioihan_b, gioihan_min, gioihan_max, i, k, ary, darr, dulieu, link)
  If Not gioihan_b Then
    Call ABC(i, k, ary, darr, dulieu, link)
  Else
    If Duieu(i, 4) >= gioihan_min Then
      If Duieu(i, 4) <= gioihan_max Then
        Call ABC(i, k, ary, darr, dulieu, link)
      End If
    End If
  End If
End Sub

Private Sub ABC(i, k, ary, darr, dulieu, link)
  Dim j&, izi, n
  k = k + 1: izi = k
  For j = 1 To c
    n = ary(2, j)
    If n > 0 Then darr(k, j) = Duieu(i, n)
  Next j
  darr(k, 1) = link
  darr(k, 2) = izi
End Sub
 
Upvote 0
Cái phần code chung nó đụng chạm nhiều biến quá. Dựng cái dãy tham để truyền (paramater list) hụt cả hơi.
Không nhìn thấy code chính, ông nội ai biết làm cách nào cho bớt đám rườm rà ấy, phải giữ nguyên bản thôi.
Bản thân tôi không thích dùng Gosub, Goto,... Nhưng tôi chấp nhận đây là trường hợp đặc biệt mà dùng hàm con nội hữu hiệu hơn.

Hàm con nội là một đoạn code nằm bên rong hàm mẹ nó, bắt đầu bằng một label, và kết thúc bằng một lệnh Return.
Vì code hoàn toàn nội cho nên nó sử dụng biến nội của hàm mẹ. Và những biến nó tạo ra trở thành biến của hàm nội. Nói cách khác, biến do hàm con nội tạo ra sẽ trở thành biến của hàm mẹ, khong bị nhuỷ bỏ khi Return.
Túm lại, lệnh Gosub gần giống như lệnh Goto, bảo VBA save lại địa chỉ dòng kế tiếp, nhảy đến dòng lệnh kế tiếp cái Label, tiếp tục chạy cho đến khi gặp Return thì nhảy trở về cái địa chỉ dòng đã được saved. Ngoài cái việc "nhớ chỗ để về" này, Gosub gần như in hệt Goto.

Thôgn thường thì người ta đặt hàm con nội ngay cuối code hàm mẹ.
Và vì vậy, trước cái Label hàm con, phải có dòng EXIT SUB để tránh bước vào code hàm con.
Lưu ý: lệnh Return chỉ bảo code trở về chỗ cũ thôi. Lệnh End Sub mới là lệnh báo VBA "đây là hết tầm vực của hàm mẹ, code đi sau lệnh này không liên quan gì đếnn hàm mẹ nữa".
 
Upvote 0
Web KT
Back
Top Bottom