Nhờ rút gọn dùm thủ tục ẩn hiện các Object

  • Thread starter Thread starter BNTT
  • Ngày gửi Ngày gửi
Liên hệ QC

BNTT

Bùi Nguyễn Triệu Tường
Thành viên danh dự
Tham gia
3/7/07
Bài viết
4,946
Được thích
23,208
Nghề nghiệp
Dạy đàn piano
Tôi có đoạn code này:
PHP:
    If MSOHANG.Column(5) <> "" Then
        KT.Visible = True
        xKT.Visible = True
        .....
    Else
        KT.Visible = False
        xKT.Visible = False
        .....
    End If
Hai cái chỗ ..... là còn một lô Object khác, cho ẩn hoặc cho hiện, tùy thuộc vào một điều kiện gì đó (ở đây là MSOHANG.Column(5) <> "")

Cho hỏi, đoạn code đó có thể viết gọn hơn không?

Tôi nhớ có đọc được ở đâu đó, người ta dùng hàm NOT (của VBA), nghĩa là nếu thấy nó đang ẩn thì cho hiện, hoặc nếu thấy đang hiện thì cho ẩn... Nhưng quên mất nó ở đâu rồi.

Nhờ các bạn giúp dùm. Xin cảm ơn.
 
Tôi có đoạn code này:
PHP:
    If MSOHANG.Column(5) <> "" Then
        KT.Visible = True
        xKT.Visible = True
        .....
    Else
        KT.Visible = False
        xKT.Visible = False
        .....
    End If
Hai cái chỗ ..... là còn một lô Object khác, cho ẩn hoặc cho hiện, tùy thuộc vào một điều kiện gì đó (ở đây là MSOHANG.Column(5) <> "")

Cho hỏi, đoạn code đó có thể viết gọn hơn không?

Anh xem đoạn code sau nhé:
Giả sử Object MSOHANG luôn luôn phải được hiện ra:
PHP:
Sub CheckVisible()
Dim Oj As Object
    If MSOHANG.Column(5) <> "" Then
           For Each Oj In UserForm1.Controls
                Oj.Visible = True
           Next
    Else
           For Each Oj In UserForm1.Controls
                Oj.Visible = False
           Next
           MSOHANG.Visible = True
    End If
End Sub
Vậy mấu chốt vấn đề là:
và:
For Each Oj In UserForm.Controls
Oj.Visible = TRUE (FALSE)
Next
Anh xem thêm ví dụ file đính kèm nhé!
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Nói về Not:
Mã:
Dim Oj As Object
              For Each Oj In UserForm1.Controls
                Oj.Visible = Not (MSOHANG.Column(5) = "")
           Next
MSOHANG.Visible = True

Not không phải là hàm nhe, nó là toán tử logic
 
Upvote 0
For Each Oj In UserForm1.Controls
Cái này, sẽ tác dụng với tất cả các Object có trong Userform1 phải không sư phụ?
Vậy thì lỡ như điều kiện không thỏa, thì chả thấy cái gì trong UserForm1 hết? Em chỉ muốn một số cái thôi.

(Cách của Ca_Dafi cũng vậy, phải có thêm một dòng để chừa lại một cái. Vậy nếu muốn ẩn hiện một nửa, chừa lại một nửa, thì hóa ra code vẫn dài thòng à...)

Ở trong đoạn code em gửi lên, điều kiện là: MSOHANG.Column(5) = ""
Nhìn cái này, chắc sư phụ biết ngay MASOHANG là cái gì mà, nó là một cái Combobox, và Column(5) là cột thứ 6 trong Rowsource của nó.

Giả sử, có một số Object đi kèm theo MASOHANG, như Đơn vị tính, Giá, Quy cách...
Ý em là: hễ giá trị trong cột thứ 6 của Rowsource không có (là rỗng) thì không thấy mấy cái Ojbect đi kèm theo.

Có cách nào để Group mấy cái Object vào một nhóm không ? Rồi cho ẩn hiện riêng nhóm này mà thôi ?
 
Upvote 0
Giả sử, có một số Object đi kèm theo MASOHANG, như Đơn vị tính, Giá, Quy cách...
Ý em là: hễ giá trị trong cột thứ 6 của Rowsource không có (là rỗng) thì không thấy mấy cái Ojbect đi kèm theo.

Có cách nào để Group mấy cái Object vào một nhóm không ? Rồi cho ẩn hiện riêng nhóm này mà thôi ?

Anh có thể dựa vào TabIndex để giời hạn control nào "được" ẩn hay hiện. Đại khái như:
PHP:
Private Sub CheckBox1_Click()
Dim Oj As Object
    For Each Oj In UserForm1.Controls
        If Oj.TabIndex >= 10 And Oj.TabIndex <= 15 Then Oj.Visible = Not (MSOHANG.Column(5) = "")
    Next
End Sub
Vì thế, khi tạo các Objects, cái nào đứng gần nhau, cái nào muốn đưa vào 1 group, anh hãy set thuộc tính TabIndex cho chúng có thứ tự gần nhau.
 
Lần chỉnh sửa cuối:
Upvote 0
Cái này, sẽ tác dụng với tất cả các Object có trong Userform1 phải không sư phụ?
1/ Vậy thì lỡ như điều kiện không thỏa, thì chả thấy cái gì trong UserForm1 hết? Em chỉ muốn một số cái thôi.

2/ Có cách nào để Group mấy cái Object vào một nhóm không ? Rồi cho ẩn hiện riêng nhóm này mà thôi ?
1/ Lưu ý : Anh nên đặt tên Object có tính "kĩ thuật" tí : ví dụ như Combobox thì cboMSOHANG ; cmdEXIT ; txtHANGHOA ... Như vậy anh sẽ dễ kiểm soát các Object hơn và đọc code dễ hiểu hơn. Trong trường hợp của anh thì dùng thêm lệnh sau sẽ kiểm soát được các Textbox trên Form:

If UCase(TypeName(
Oj)) = "TEXTBOX" Then ....

Hoặc
If Left(Oj.Name,3) = "txt" Then .....



2/ Trong Control toolbox, có đối tượng Frame có thể giúp anh nhóm các đối tượng lại.

TDN
 
Upvote 0
Cách của tedaynui là đúng (nhất là đề cập đến vấn đề naming convention), cách của ca_dafi là ko tốt vì ko ai đụng đến tabindex trong code cả (kể cả code có chạy).
 
Upvote 0
Cách của tedaynui là đúng (nhất là đề cập đến vấn đề naming convention), cách của ca_dafi là ko tốt vì ko ai đụng đến tabindex trong code cả (kể cả code có chạy).

Không biết em hỏi vậy có spam không? Tuy nhiên sẵn bài này em cũng xin hỏi luôn (vì em cũng đang từng bước học VBA mà thôi):

TabIndex tại sao không xài? Tại sao không tốt? Nhược điểm của nó so với sử dụng Name(hoặc Caption hoặc TypeName) là gì? Hay là vì không ai xài nên nó không tốt?

Theo như yêu cầu bên dưới, trong một Form sẽ có thể có nhiều combobox tương ứng với nhiều textbox (hoặc checkbox, hoặc Image Object ...) thì nếu chỉ dựa vào Left(Oj.Name,3)="txt" (hoặc một giá trị tương tự cho loại Object tương ứng) thì sẽ hide/unhide toàn bộ các textbox (hoặc Object tương ứng) có trên Form (tương tự với TypeName).
 
Lần chỉnh sửa cuối:
Upvote 0

1/ Lưu ý : Anh nên đặt tên Object có tính "kĩ thuật" tí : ví dụ như Combobox thì cboMSOHANG ; cmdEXIT ; txtHANGHOA ... Như vậy anh sẽ dễ kiểm soát các Object hơn và đọc code dễ hiểu hơn. Trong trường hợp của anh thì dùng thêm lệnh sau sẽ kiểm soát được các Textbox trên Form:

If UCase(TypeName(
Oj)) = "TEXTBOX" Then ....

Hoặc
If Left(Oj.Name,3) = "txt" Then .....



2/ Trong Control toolbox, có đối tượng Frame có thể giúp anh nhóm các đối tượng lại.

TDN

Cảm ơn nhiều.
Trong 2 cách của Tedaynui chỉ, mình chọn cách 2, group các object theo từng nhóm (dùng Frame), và sau đó thì chỉ cần set cho Frame.Visible là được, rất nhanh và cũng rất khoa học.

Dùng cách 1 cũng được, nhưng phải sửa hàng loạt tên object lỡ tạo rồi... lười lắm.
 
Upvote 0
Biết sao nói vậy thôi nha, có thể chưa đúng hoặc chưa đủ lắm:
1. TabIndex không ổn định, người sử dụng có thể muốn sửa đổi sau khi chạy thử.
2. Có những controls TabStop = False nhưng vẫn muốn khi ẩn khi hiện
3. Thứ tự sắp xếp controls trên form có thể không giống thứ tự nhập liệu trên form. Ngoài ra CmdButton cũng có TabIndex, và có khi bỏ qua 1 số textbox nhảy ngay vào CmdButton.
 
Upvote 0
Nói về Not:
Mã:
Dim Oj As Object
              For Each Oj In UserForm1.Controls
                Oj.Visible = Not (MSOHANG.Column(5) = "")
           Next
MSOHANG.Visible = True
Not không phải là hàm nhe, nó là toán tử logic

Nên đặt thêm 1 biến kiểu Boolean nữa cho dễ nhìn và chạy nhanh hơn.
PHP:
Dim ABC as Boolean
ABC = Not (MSOHANG.Column(5) = "")
1/ Lưu ý : Anh nên đặt tên Object có tính "kĩ thuật" tí : ví dụ như Combobox thì cboMSOHANG ; cmdEXIT ; txtHANGHOA ... Như vậy anh sẽ dễ kiểm soát các Object hơn và đọc code dễ hiểu hơn. Trong trường hợp của anh thì dùng thêm lệnh sau sẽ kiểm soát được các Textbox trên Form:

If UCase(TypeName(Oj)) = "TEXTBOX" Then ....

Hoặc
If Left(Oj.Name,3) = "txt" Then .....


2/ Trong Control toolbox, có đối tượng Frame có thể giúp anh nhóm các đối tượng lại.

TDN
Việc đặt tên như vậy là rất tốt, vừa định danh rõ ràng, vừa thể hiện tính chất của đối tượng (cmd, txt, cbo . . ). Giúp cho ta điều khiển đích danh hay một nhóm đối tượng dễ dàng.
Và thuận lợi hơn là nếu người khác sửa CodeName của đối tượng thì khi chạy sẽ báo lỗi ngay, nếu dựa vào TabIndex thì khi ai đó (hay ta) thay đổi thì sẽ không biết lỗi để mà sửa.
Hơn nữa NameCode thì không thể thay đổi, còn TabIndex lại rất hay thay đổi (Khi thay đổi trật tự trên Forrm, hoặc thêm bớt 1 Object khác)

Chúc vui
 
Upvote 0
- Lý do 1: "Độc cô" đã nói hộ rồi.
- Lý do 2: Cả thế giới này ko thấy có code như vậy :) (Đơn giản vì logic ở lý do 1)
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom