Nhờ sửa giúp code UserForm

Liên hệ QC

Cát Lượng

Thành viên tiêu biểu
Tham gia
14/11/18
Bài viết
403
Được thích
66
Em chạy code Userform có tên là "bangquanlysheet' xuất hiện lỗi và bảng giao diện hiện ra (khoanh đỏ) không tác động vào được.
Em xin được nhờ sự giúp đỡ của các anh chị ạ!
file anh.png
 

File đính kèm

  • File mau.xlsm
    2 MB · Đọc: 15
Bạn thử thay
Mã:
SheetName = Mid(SheetList.List(SheetList.ListIndex), (InStr(SheetList.List(SheetList.ListIndex), vbTab) + 1))
bằng
Mã:
SheetName = VBA.Mid(SheetList.List(SheetList.ListIndex), (InStr(SheetList.List(SheetList.ListIndex), vbTab) + 1))
Bài đã được tự động gộp:

Chọn Tools -> References -> nhìn xem có thằng nào được chọn mà ở đầu có MISSING không. Nếu có thì tên nó là gi.
Em làm theo thầy hướng dẫn, nhưng khi chọn -> References thì References không chọn được ạ!
(Video em đính ở dưới nhờ thầy xem giúp)
 

File đính kèm

  • bai 1.rar
    2 MB · Đọc: 5
Upvote 0
Em làm theo thầy hướng dẫn, nhưng khi chọn -> References thì References không chọn được ạ!
Tôi viết có 2 ý, tách biệt nhau:

1. Sửa Mid thành VBA.Mid rồi chạy code từ đầu. Còn lỗi không?

2. Xem trong References. Muốn xem References thì trước hết phải kết thúc chạy code. Đang debug thì làm sao xem được References?
 
Upvote 0
Tôi viết có 2 ý, tách biệt nhau:

1. Sửa Mid thành VBA.Mid rồi chạy code từ đầu. Còn lỗi không?

2. Xem trong References. Muốn xem References thì trước hết phải kết thúc chạy code. Đang debug thì làm sao xem được References?
Dạ em cám ơn thầy, em sửa theo ý thầy: Sửa Mid thành VBA và mở qua phần mềm thì code Userform đó đã chạy được rồi ạ!
Em cám ơn các thầy!
Chúc các thầy sức khỏe và thành công!
 
Upvote 0
Dạ em cám ơn thầy, em sửa theo ý thầy: Sửa Mid thành VBA và mở qua phần mềm thì code Userform đó đã chạy được rồi ạ!
Em cám ơn các thầy!
Chúc các thầy sức khỏe và thành công!
Ấy, cái sửa Mid thành VBA.Mid chỉ là lấy lá che "cục c*" thôi. Không nhìn thấy nó nữa nhưng nó vẫn còn đó. Thử thêm VBA chỉ là để xem thế nào thôi.
Nó phải có nguyên nhân từ đâu đó.
Bạn có kiểm tra MISSING không? Có những thằng nào có MISSING?
 
Upvote 0
Ấy, cái sửa Mid thành VBA.Mid chỉ là lấy lá che "cục c*" thôi. Không nhìn thấy nó nữa nhưng nó vẫn còn đó. Thử thêm VBA chỉ là để xem thế nào thôi.
Nó phải có nguyên nhân từ đâu đó.
Bạn có kiểm tra MISSING không? Có những thằng nào có MISSING?
À vâng đúng rồi, em vừa chi tiết thì mới chỉ ẩn và hiện được các sheet còn 3 nút Delete, Sort A-Z, Sort A-Z chưa có tác dụng
Khi tác động vào 3 nút đó ở bảng giao diện hiện ra vẫn báo lỗi ạ! (hình thứ 1)
Những Missing được chọn như hình thứ 2
Nhờ thầy giúp em tiếp ạ!
12.pngco missing.png
 
Upvote 0
À vâng đúng rồi, em vừa chi tiết thì mới chỉ ẩn và hiện được các sheet còn 3 nút Delete, Sort A-Z, Sort A-Z chưa có tác dụng
Khi tác động vào 3 nút đó ở bảng giao diện hiện ra vẫn báo lỗi ạ! (hình thứ 1)
Những Missing được chọn như hình thứ 2
Nhờ thầy giúp em tiếp ạ!
View attachment 209003View attachment 209004
Thì nếu Mid đã bị dính chưởng thì các hàm khác của VBA bạn dùng cũng thế. Tức thay vì UCase thì VBA.UCase. Và cứ thế cho các hàm khác.

Nhưng đây không phải là giải pháp. Chỉ là lấy lá che ...

Cái MISSING kia là có xung đột về phiên bản (không tương thích). Có 2 trường hợp.

1. Nếu bắt buộc phải dùng control trong thư viện MISSING kia thì phải tải thư viện thích hợp về cài lại. Tìm đọc trên GPE về Miscosoft Windows Common Controls.

2. Nếu không cần tới thư viện kia, tức không dùng tới các controls trong nó thì đơn giản là bỏ chọn mục bị MISSING.

Tôi không dò nhưng cảm giác là bạn không cần thư viện MISSING kia.

Lưu ý: trong Module7 trên dòng Sub quanly thừa dòng Option Explicit. Xóa dòng này đi và lưu lại tập tin.

Thao tác tiếp như sau: Tools -> References -> bỏ chọn mục MISSING -> OK -> menu Debug -> chọn Compile VBAProject.

Nếu không thấy thông báo gì thì thư viện MISSING kia không dùng đến và xóa nó là rất tốt, không cần phải tải phiên bản phù hợp và cài.

Tôi tin rằng sau khi xóa MISSING và OK rồi lưu lại tập tin thì bây giờ chạy code sẽ không còn lỗi cho dù không thêm VBA vào từng hàm Mid, UCase, ...
 
Upvote 0
Thì nếu Mid đã bị dính chưởng thì các hàm khác của VBA bạn dùng cũng thế. Tức thay vì UCase thì VBA.UCase. Và cứ thế cho các hàm khác.

Nhưng đây không phải là giải pháp. Chỉ là lấy lá che ...

Cái MISSING kia là có xung đột về phiên bản (không tương thích). Có 2 trường hợp.

1. Nếu bắt buộc phải dùng control trong thư viện MISSING kia thì phải tải thư viện thích hợp về cài lại. Tìm đọc trên GPE về Miscosoft Windows Common Controls.

2. Nếu không cần tới thư viện kia, tức không dùng tới các controls trong nó thì đơn giản là bỏ chọn mục bị MISSING.

Tôi không dò nhưng cảm giác là bạn không cần thư viện MISSING kia.

Lưu ý: trong Module7 trên dòng Sub quanly thừa dòng Option Explicit. Xóa dòng này đi và lưu lại tập tin.

Thao tác tiếp như sau: Tools -> References -> bỏ chọn mục MISSING -> OK -> menu Debug -> chọn Compile VBAProject.

Nếu không thấy thông báo gì thì thư viện MISSING kia không dùng đến và xóa nó là rất tốt, không cần phải tải phiên bản phù hợp và cài.

Tôi tin rằng sau khi xóa MISSING và OK rồi lưu lại tập tin thì bây giờ chạy code sẽ không còn lỗi cho dù không thêm VBA vào từng hàm Mid, UCase, ...
Em có làm như thầy hướng dẫn:
- Đã Sửa Mid thành VBA.
- Thao tác tiếp như sau: Tools -> References -> bỏ chọn mục MISSING -> OK -> menu Debug -> chọn Compile VBAProject.
Sau đó chạy code thì em thấy:
1. Các thao tác trên các nút closedelete đã ok và không có vấn đề gì.
2. Trên 2 nút "Sort A-Z ""Sort Z-A " đã có tác dụng nhưng vẫn hiện thông báo (như hình 01 và 02 )
Nhờ thầy giúp em tiếp ạ!
a1.pnga2.png
 
Upvote 0
Em có làm như thầy hướng dẫn:
- Đã Sửa Mid thành VBA.
- Thao tác tiếp như sau: Tools -> References -> bỏ chọn mục MISSING -> OK -> menu Debug -> chọn Compile VBAProject.
Như thế là đã loại được nguyên nhân. Sửa Mid, UCase thành VBA.Mid, VBA.UCase chỉ là cách đối phó. Khi bạn đã loại nguyên nhân tận gốc rồi thì không việc gì phải thêm VBA nữa. Chả nhẽ trong code có 1000 chỗ dùng hàm VBA thì cũng cần cù thêm 1000 VBA?
Sau đó chạy code thì em thấy:
1. Các thao tác trên các nút closedelete đã ok và không có vấn đề gì.
2. Trên 2 nút "Sort A-Z ""Sort Z-A " đã có tác dụng nhưng vẫn hiện thông báo (như hình 01 và 02 )
Còn lỗi hiện hành là do code của bạn sai.

Trong Sub SortList có
Mã:
If Sheets(i).Visible = False Then
        
            HiddenSheets(i) = Sheets(i).Name
            Sheets(i).Visible = True
            
End If
Như vậy những sheet có xlSheetVeryHidden (=2) sẽ không thỏa điều kiện vì 2 trong VBA là TRUE (0 là FALSE, mọi giá trị <> 0 đều là TRUE). Lúc đó sheet có xlSheetVeryHidden sẽ không được hiển thị trước khi sắp xếp nên sau đó sẽ có lỗi vì sheet có xlSheetVeryHidden không thể Move được.

Cụ thể khi sảy ra lỗi như thông báo ở dòng
Mã:
Worksheets(j).Move Before:=Worksheets(i)
thì chính Worksheets(j) (nó là sheet PAGE_NULL) có xlSheetVeryHidden. Do trước đó không thỏa điều kiện nên nó không được gỡ bỏ very hidden nên khi MOVE thì có lỗi.

Tôi sửa thành.

1.
Mã:
Sub SortList(Order As Integer)
Dim i As Long
Dim j As Long
Dim HiddenSheets() As String
    Application.ScreenUpdating = False
    
    ReDim HiddenSheets(1 To Sheets.Count)
    
    For i = 1 To Sheets.Count
        If Sheets(i).Visible = xlSheetVeryHidden Then
            HiddenSheets(i) = Sheets(i).Name
            Sheets(i).Visible = xlSheetHidden
        End If
    Next i

    For i = 1 To Worksheets.Count - 1
        For j = i + 1 To Worksheets.Count
            If Order = Ascending Then
                If UCase(Worksheets(j).Name) < UCase(Worksheets(i).Name) Then
                    Worksheets(j).Move Before:=Worksheets(i)
                End If
            Else
                If UCase(Worksheets(j).Name) > UCase(Worksheets(i).Name) Then
                   Worksheets(j).Move Before:=Worksheets(i)
                End If
            End If
         Next j
    Next i
    
    For i = 1 To Sheets.Count
        If Len(HiddenSheets(i)) Then Sheets(HiddenSheets(i)).Visible = xlSheetVeryHidden
    Next i
        
    PopulateList
    
    Sheets(1).Activate
    
    Application.ScreenUpdating = True
End Sub

2. Khi kiểm tra Visible thì không được dùng TRUE / FALSE mà phải dùng xlSheetVisible,

xlSheetHidden và xlSheetVeryHidden

Vd. trong Sub PopulateList có
Mã:
If Sheets(counter).Visible = False Then
        
            HiddenPrefix = "H"
Không biết dụng ý của bạn thế nào. Nếu tôi đoán được ý thì điều kiện chỉ đúng khi sheet có

xlSheetHidden. Còn nếu sheet có xlVeryHidden thì điều kiện không thỏa. Rõ ràng chỗ này có

thể khác với dụng ý của bạn.

Trong VBA chỉ có 0 (xlSheetHidden) là FALSE còn -1 (xlSheetVisible) và 2

(xlSheetVeryHidden) đều là TRUE.

Vậy hãy sửa
Mã:
If Sheets(counter).Visible = False Then
thành
Mã:
If Sheets(counter).Visible <> xlSheetVisible Then
 
Upvote 0
Như thế là đã loại được nguyên nhân. Sửa Mid, UCase thành VBA.Mid, VBA.UCase chỉ là cách đối phó. Khi bạn đã loại nguyên nhân tận gốc rồi thì không việc gì phải thêm VBA nữa. Chả nhẽ trong code có 1000 chỗ dùng hàm VBA thì cũng cần cù thêm 1000 VBA?

Còn lỗi hiện hành là do code của bạn sai.

Trong Sub SortList có
Mã:
If Sheets(i).Visible = False Then
       
            HiddenSheets(i) = Sheets(i).Name
            Sheets(i).Visible = True
           
End If
Như vậy những sheet có xlSheetVeryHidden (=2) sẽ không thỏa điều kiện vì 2 trong VBA là TRUE (0 là FALSE, mọi giá trị <> 0 đều là TRUE). Lúc đó sheet có xlSheetVeryHidden sẽ không được hiển thị trước khi sắp xếp nên sau đó sẽ có lỗi vì sheet có xlSheetVeryHidden không thể Move được.

Cụ thể khi sảy ra lỗi như thông báo ở dòng
Mã:
Worksheets(j).Move Before:=Worksheets(i)
thì chính Worksheets(j) (nó là sheet PAGE_NULL) có xlSheetVeryHidden. Do trước đó không thỏa điều kiện nên nó không được gỡ bỏ very hidden nên khi MOVE thì có lỗi.

Tôi sửa thành.

1.
Mã:
Sub SortList(Order As Integer)
Dim i As Long
Dim j As Long
Dim HiddenSheets() As String
    Application.ScreenUpdating = False
   
    ReDim HiddenSheets(1 To Sheets.Count)
   
    For i = 1 To Sheets.Count
        If Sheets(i).Visible = xlSheetVeryHidden Then
            HiddenSheets(i) = Sheets(i).Name
            Sheets(i).Visible = xlSheetHidden
        End If
    Next i

    For i = 1 To Worksheets.Count - 1
        For j = i + 1 To Worksheets.Count
            If Order = Ascending Then
                If UCase(Worksheets(j).Name) < UCase(Worksheets(i).Name) Then
                    Worksheets(j).Move Before:=Worksheets(i)
                End If
            Else
                If UCase(Worksheets(j).Name) > UCase(Worksheets(i).Name) Then
                   Worksheets(j).Move Before:=Worksheets(i)
                End If
            End If
         Next j
    Next i
   
    For i = 1 To Sheets.Count
        If Len(HiddenSheets(i)) Then Sheets(HiddenSheets(i)).Visible = xlSheetVeryHidden
    Next i
       
    PopulateList
   
    Sheets(1).Activate
   
    Application.ScreenUpdating = True
End Sub

2. Khi kiểm tra Visible thì không được dùng TRUE / FALSE mà phải dùng xlSheetVisible,

xlSheetHidden và xlSheetVeryHidden

Vd. trong Sub PopulateList có
Mã:
If Sheets(counter).Visible = False Then
       
            HiddenPrefix = "H"
Không biết dụng ý của bạn thế nào. Nếu tôi đoán được ý thì điều kiện chỉ đúng khi sheet có

xlSheetHidden. Còn nếu sheet có xlVeryHidden thì điều kiện không thỏa. Rõ ràng chỗ này có

thể khác với dụng ý của bạn.

Trong VBA chỉ có 0 (xlSheetHidden) là FALSE còn -1 (xlSheetVisible) và 2

(xlSheetVeryHidden) đều là TRUE.

Vậy hãy sửa
Mã:
If Sheets(counter).Visible = False Then
thành
Mã:
If Sheets(counter).Visible <> xlSheetVisible Then
Thật tuyệt vời thầy cao thủ quá!
Em làm như thầy hướng dẫn và không còn lỗi nào.
Thầy có thể bớt chút thời gian giúp em một chút nữa (vấn đề ngoài luồng): em muốn thêm một dấu tích Ẩn/hiện đồng loạt các Sheet
Khi tích vào đó sẽ hiện và không tích vào đó sẽ ẩn tất cả các sheet (trừ sheet hiện hành).
Em cũng mới tìm hiểu được mấy hôm về VBA nên nhiều câu hỏi còn ngây ngô, mong sự giúp đỡ của các thầy.
Em cám ơn ạ!
binh minh.png
 
Upvote 0
Thầy có thể bớt chút thời gian giúp em một chút nữa (vấn đề ngoài luồng): em muốn thêm một dấu tích Ẩn/hiện đồng loạt các Sheet
Khi tích vào đó sẽ hiện và không tích vào đó sẽ ẩn tất cả các sheet (trừ sheet hiện hành).
Code thì tôi nghĩ không khó, nhưng tôi chưa chắc là bạn đã suy nghĩ thấu đáo.

Nếu muốn như bạn thì bạn luôn chỉ có 2 trạng thái: hoặc tất cả các sheet đều hiện hoặc chỉ 1 sheet hiện. Tai sao?

CheckBox (với Caption = "Hide") chỉ có 2 trạng thái là chọn - ứng với "ẩn hết chỉ trừ 1", hoặc bỏ chọn - hiện hết.
Theo lôgíc trong UserForm_Initialize code phải tự thiết lập trạng thái của CheckBox để phản ánh thực trạng trên Sheet. Tôi cho vd., trước khi mở Form thì mọi sheet đều hiện. Nếu bạn chọn CheckBox (ẩn hết chỉ trừ 1) thì chỉ có 1 sheet hiển thị. Bây giờ bạn đóng Form. Ở lần mở tiếp theo thì code bắt buộc phải thiết lập CheckBox là chọn để nó phản ánh đúng thực trạng đang có trên sheet.

Code chỉ có thể thiết lập CheckBox là chọn (ẩn hết chỉ trừ 1) hoặc bỏ chọn (hiện hết). Vậy thì sẽ không bao giờ bạn có thể dùng tay hoặc code khác để hiện thêm 1 sheet sau khi "ẩn hết chỉ trừ 1", hoặc ẩn 1 sheet sau khi hiện tất cả. Bởi lúc đó khi mở Form code không biết sẽ phải thiết lập ChcekBox thế nào. Thiết lập chọn, tức ẩn hết chỉ trừ 1, hay bỏ chọn, tức hiện hết, thì rõ ràng cả 2 trạng thái đó đều không phản ánh đúng thực trạng trên sheet.

Cũng có thể yêu cầu là bất luận thực trạng trên sheet thế nào khi hiện Form thì code mở hết các sheet và CheckBox bỏ chọn, hoặc code ẩn hết chỉ trừ 1 và CheckBox được chọn.

Tóm lại tôi không biết bạn đã suy nghĩ thấu đáo chưa. Và bạn muốn kịch bản nào: khi CheckBox được chọn thì sao, khi bỏ chọn thì sao, khi mở Form thì có thay đổi thực trạng các sheet không, nếu có thì thay đổi thế nào, và ứng với thực trạng đó thì CheckBox sẽ phải như thế nào.

Hãy mô tả kỹ. Vì tôi là người không thích viết đi sửa lại.
 
Upvote 0
Code thì tôi nghĩ không khó, nhưng tôi chưa chắc là bạn đã suy nghĩ thấu đáo.

Nếu muốn như bạn thì bạn luôn chỉ có 2 trạng thái: hoặc tất cả các sheet đều hiện hoặc chỉ 1 sheet hiện. Tai sao?

CheckBox (với Caption = "Hide") chỉ có 2 trạng thái là chọn - ứng với "ẩn hết chỉ trừ 1", hoặc bỏ chọn - hiện hết.
Theo lôgíc trong UserForm_Initialize code phải tự thiết lập trạng thái của CheckBox để phản ánh thực trạng trên Sheet. Tôi cho vd., trước khi mở Form thì mọi sheet đều hiện. Nếu bạn chọn CheckBox (ẩn hết chỉ trừ 1) thì chỉ có 1 sheet hiển thị. Bây giờ bạn đóng Form. Ở lần mở tiếp theo thì code bắt buộc phải thiết lập CheckBox là chọn để nó phản ánh đúng thực trạng đang có trên sheet.

Code chỉ có thể thiết lập CheckBox là chọn (ẩn hết chỉ trừ 1) hoặc bỏ chọn (hiện hết). Vậy thì sẽ không bao giờ bạn có thể dùng tay hoặc code khác để hiện thêm 1 sheet sau khi "ẩn hết chỉ trừ 1", hoặc ẩn 1 sheet sau khi hiện tất cả. Bởi lúc đó khi mở Form code không biết sẽ phải thiết lập ChcekBox thế nào. Thiết lập chọn, tức ẩn hết chỉ trừ 1, hay bỏ chọn, tức hiện hết, thì rõ ràng cả 2 trạng thái đó đều không phản ánh đúng thực trạng trên sheet.

Cũng có thể yêu cầu là bất luận thực trạng trên sheet thế nào khi hiện Form thì code mở hết các sheet và CheckBox bỏ chọn, hoặc code ẩn hết chỉ trừ 1 và CheckBox được chọn.

Tóm lại tôi không biết bạn đã suy nghĩ thấu đáo chưa. Và bạn muốn kịch bản nào: khi CheckBox được chọn thì sao, khi bỏ chọn thì sao, khi mở Form thì có thay đổi thực trạng các sheet không, nếu có thì thay đổi thế nào, và ứng với thực trạng đó thì CheckBox sẽ phải như thế nào.

Hãy mô tả kỹ. Vì tôi là người không thích viết đi sửa lại.
Dạ vâng, em cám ơn sự hướng dẫn rất cụ thể và tận tình của thầy.
Em nhờ thầy thiết kế giúp em một nút (khoanh đỏ như hình em đăng bài #31).
Và chi tiết hơn được diễn giải như sau:
Khi em CheckBox vào đó các sheet sẽ bị ẩn hết (trừ sheet hiện hành không bị ẩn) và những sheet khi bị ẩn thì mình có thể dùng tay thao tác trực tiếp trên giao diện (bỏ "H" để sheet lên hiện bình thường) và khi bỏ CheckBox ở nút khoanh đỏ đi thì các sheet được hiện hết lên.
Thao tác như trên sẽ thuận tiện rất nhiều khi quản lý sheet, vì khi muốn ẩn không phải CheckBox vào từng cái sheet một để ẩn.
Xin ý kiến và sự giúp đỡ của thầy.
 
Upvote 0
Bạn vẫn không hiểu tôi nói gì?
những sheet khi bị ẩn thì mình có thể dùng tay thao tác trực tiếp trên giao diện (bỏ "H" để sheet lên hiện bình thường)
1. Giả sử bạn check vào thì các sheet ẩn hết chỉ trừ 1. Bây giờ bạn định làm như thế nào để bỏ H cho 1 hoặc vài sheet? Bạn phải nói để tôi còn viết code cho phù hợp.

2. Giả sử trường hợp 1 sau khi ẩn hết chỉ trừ 1 bạn mở thêm 1 sheet nữa, nói theo cách nói của bạn là bỏ H. Vậy có 2 sheet hiện. Bây giờ bạn đóng Form thì ở lần mở Form sau CheckBox phải ở trạng thái nào? Ở trạng thái được check thì không phản ánh đúng thực trạng trên sheet. Vì check có nghĩa là chỉ có 1 sheet hiện trong khi trên sheet là có 2 sheet hiện. Mà nếu cho ở trạng thái bỏ check thì cũng không phản ánh thực trạng. Vì bỏ check đồng nghĩa với việc hiện hết trong khi trên sheet chỉ có 2 sheet hiện.
 
Upvote 0
Bạn vẫn không hiểu tôi nói gì?

1. Giả sử bạn check vào thì các sheet ẩn hết chỉ trừ 1. Bây giờ bạn định làm như thế nào để bỏ H cho 1 hoặc vài sheet? Bạn phải nói để tôi còn viết code cho phù hợp.

2. Giả sử trường hợp 1 sau khi ẩn hết chỉ trừ 1 bạn mở thêm 1 sheet nữa, nói theo cách nói của bạn là bỏ H. Vậy có 2 sheet hiện. Bây giờ bạn đóng Form thì ở lần mở Form sau CheckBox phải ở trạng thái nào? Ở trạng thái được check thì không phản ánh đúng thực trạng trên sheet. Vì check có nghĩa là chỉ có 1 sheet hiện trong khi trên sheet là có 2 sheet hiện. Mà nếu cho ở trạng thái bỏ check thì cũng không phản ánh thực trạng. Vì bỏ check đồng nghĩa với việc hiện hết trong khi trên sheet chỉ có 2 sheet hiện.
Vâng, thầy nói em mới vỡ ra .
Khi bỏ check thì các sheet ẩn hết chỉ trừ 1 sheet hiện hành, thì lúc này các sheet bị ẩn đều có ký hiệu "H" bình thường như khi ẩn thủ công
Khi check vào nút khoanh đỏ thì hiện hết các sheet đồng nghĩa các ký hiệu H đầu dòng ô bên trái đều bị ẩn
Ý em muốn là hiện hay ẩn bằng check vào nút khoanh đỏ thì đều có ẩn hay xuất hiện ký tự H.
Em so sánh với công cụ lọc trong Excel:
Check vào nút khoanh đỏ giống như tích vào "chọn tất cả" trong bộ cụ lọc
Bỏ Check ở nút khoanh đỏ giống như bỏ tích ở "chọn tất cả" trong bộ cụ lọc
Còn chọn "H" ở đầu dòng giống như bỏ tích ở chọn các nội dung nào đó trong bộ lọc
Bỏ chọn H ở đầu (muốn hiện) dòng giống như chọn tích vào nội dung nào đó trong bộ lọc
Nút khoanh đỏ giống như nút "chọn tất cả" trong bộ lọc , nó có 03 trạng thái : khi Check vào nó sẽ hiện các sheet lên, bỏ Check nó sẽ ẩn đồng loạt các Sheet, sau đó dùng thủ công đê ẩn, hay hiện Sheet nào thì nút đỏ sẽ xuất hiện trang thái nữa (dấu chấm vuông tô đậm)
Em diễn đạt có thể hơi lủng củng... hi, mong hồi âm và chỉ bảo của thầy!
cd.png
 
Lần chỉnh sửa cuối:
Upvote 0
Nút khoanh đỏ giống như nút "chọn tất cả" trong bộ lọc , nó có 03 trạng thái : khi Check vào nó sẽ hiện các sheet lên, bỏ Check nó sẽ ẩn đồng loạt các Sheet, sau đó dùng thủ công đê ẩn, hay hiện Sheet nào thì nút đỏ sẽ xuất hiện trang thái nữa (dấu chấm vuông tô đậm)
Thì ý tôi là CheckBox chỉ có 2 trạng thái, không có trạng thái tương ứng với "dấu chấm vuông tô đậm". Ý thức cho bạn thế thôi.

CheckBox hiện tất cả nếu chọn, và ẩn hết trừ Active khi bỏ chọn.
Tôi sửa lại các Sub khác, nhưng cố gắng sửa ít nhất vì bạn đã quen với code cũ.

Thay toàn bộ code cũ trong Form bằng code sau.
Mã:
' http://www.excel.webkynang.vn
'

Option Explicit

Const Ascending As Integer = 1
Const Descending As Integer = 0

Private Sub CheckBox1_Change()
Dim k As Long, state As XlSheetVisibility, sh As Worksheet
    Application.ScreenUpdating = False
    
    If CheckBox1.Value Then
        state = xlSheetVisible
    Else
        state = xlSheetHidden
    End If
    Set sh = ActiveSheet
    For k = 1 To Worksheets.Count
        If Not Worksheets(k) Is sh Then
            Worksheets(k).Visible = state
        End If
    Next k
    PopulateList
    Application.ScreenUpdating = True
End Sub

Private Sub CloseForm_Click()
    Unload Me
End Sub

Private Sub DeleteSheets_Click()
Dim i As Integer
Dim MySheet As String
      Application.DisplayAlerts = False
      For i = 0 To SheetList.ListCount - 1
          If SheetList.Selected(i) Then
              On Error Resume Next
              Sheets(Mid(SheetList.List(i), InStr(SheetList.List(i), vbTab) + 1)).Delete
              If Err.Number = 1004 Then
                MsgBox "Khong the xoa tat ca cac sheet trong file", vbOKOnly + vbCritical
              End If
              On Error GoTo 0
          End If
      Next i
      Application.DisplayAlerts = True
      PopulateList
End Sub

Private Sub SheetList_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim SheetName As String
    SheetName = Mid(SheetList.List(SheetList.ListIndex), (InStr(SheetList.List(SheetList.ListIndex), vbTab) + 1))
    If Sheets(SheetName).Visible = xlSheetVisible Then
        On Error Resume Next
        Sheets(SheetName).Visible = xlSheetHidden
        If Err.Number = 1004 Then
            MsgBox "Khong the an het tat ca cac sheet", vbOKOnly + vbCritical
        Else
            SheetList.List(SheetList.ListIndex) = "H" & vbTab & SheetName
        End If
        On Error GoTo 0
    Else
        Sheets(SheetName).Visible = xlSheetVisible
        SheetList.List(SheetList.ListIndex) = "" & vbTab & SheetName
    End If
    Sheets(1).Activate
End Sub

Sub SortList(Order As Integer)
Dim i As Long
Dim j As Long
Dim HiddenSheets() As String
    Application.ScreenUpdating = False
    
    ReDim HiddenSheets(1 To Sheets.Count)
    
    For i = 1 To Sheets.Count
        If Sheets(i).Visible = xlSheetVeryHidden Then
            HiddenSheets(i) = Sheets(i).Name
            Sheets(i).Visible = xlSheetHidden
        End If
    Next i

    For i = 1 To Worksheets.Count - 1
        For j = i + 1 To Worksheets.Count
            If Order = Ascending Then
                If UCase(Worksheets(j).Name) < UCase(Worksheets(i).Name) Then
                    Worksheets(j).Move Before:=Worksheets(i)
                End If
            Else
                If UCase(Worksheets(j).Name) > UCase(Worksheets(i).Name) Then
                   Worksheets(j).Move Before:=Worksheets(i)
                End If
            End If
         Next j
    Next i
    
    For i = 1 To Sheets.Count
        If Len(HiddenSheets(i)) Then Sheets(HiddenSheets(i)).Visible = xlSheetVeryHidden
    Next i
    PopulateList
    Sheets(1).Activate
    
    Application.ScreenUpdating = True
End Sub

Private Sub SortAZ_Click()
    SortList Ascending
End Sub

Private Sub SortZA_Click()
    SortList Descending
End Sub

Sub PopulateList()
Dim counter As Long
Dim HiddenPrefix As String
    SheetList.Clear
    For counter = 1 To Sheets.Count
        If Sheets(counter).Visible <> xlSheetVisible Then
            HiddenPrefix = "H"
        Else
            HiddenPrefix = ""
        End If
        SheetList.AddItem HiddenPrefix & vbTab & Sheets(counter).Name
    Next counter
End Sub

Private Sub UserForm_Initialize()
    bangquanlysheet.Caption = ActiveWorkbook.Name
    PopulateList
End Sub
 
Upvote 0
Thì ý tôi là CheckBox chỉ có 2 trạng thái, không có trạng thái tương ứng với "dấu chấm vuông tô đậm". Ý thức cho bạn thế thôi.

CheckBox hiện tất cả nếu chọn, và ẩn hết trừ Active khi bỏ chọn.
Tôi sửa lại các Sub khác, nhưng cố gắng sửa ít nhất vì bạn đã quen với code cũ.

Thay toàn bộ code cũ trong Form bằng code sau.
Mã:
' http://www.excel.webkynang.vn
'

Option Explicit

Const Ascending As Integer = 1
Const Descending As Integer = 0

Private Sub CheckBox1_Change()
Dim k As Long, state As XlSheetVisibility, sh As Worksheet
    Application.ScreenUpdating = False
   
    If CheckBox1.Value Then
        state = xlSheetVisible
    Else
        state = xlSheetHidden
    End If
    Set sh = ActiveSheet
    For k = 1 To Worksheets.Count
        If Not Worksheets(k) Is sh Then
            Worksheets(k).Visible = state
        End If
    Next k
    PopulateList
    Application.ScreenUpdating = True
End Sub

Private Sub CloseForm_Click()
    Unload Me
End Sub

Private Sub DeleteSheets_Click()
Dim i As Integer
Dim MySheet As String
      Application.DisplayAlerts = False
      For i = 0 To SheetList.ListCount - 1
          If SheetList.Selected(i) Then
              On Error Resume Next
              Sheets(Mid(SheetList.List(i), InStr(SheetList.List(i), vbTab) + 1)).Delete
              If Err.Number = 1004 Then
                MsgBox "Khong the xoa tat ca cac sheet trong file", vbOKOnly + vbCritical
              End If
              On Error GoTo 0
          End If
      Next i
      Application.DisplayAlerts = True
      PopulateList
End Sub

Private Sub SheetList_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim SheetName As String
    SheetName = Mid(SheetList.List(SheetList.ListIndex), (InStr(SheetList.List(SheetList.ListIndex), vbTab) + 1))
    If Sheets(SheetName).Visible = xlSheetVisible Then
        On Error Resume Next
        Sheets(SheetName).Visible = xlSheetHidden
        If Err.Number = 1004 Then
            MsgBox "Khong the an het tat ca cac sheet", vbOKOnly + vbCritical
        Else
            SheetList.List(SheetList.ListIndex) = "H" & vbTab & SheetName
        End If
        On Error GoTo 0
    Else
        Sheets(SheetName).Visible = xlSheetVisible
        SheetList.List(SheetList.ListIndex) = "" & vbTab & SheetName
    End If
    Sheets(1).Activate
End Sub

Sub SortList(Order As Integer)
Dim i As Long
Dim j As Long
Dim HiddenSheets() As String
    Application.ScreenUpdating = False
   
    ReDim HiddenSheets(1 To Sheets.Count)
   
    For i = 1 To Sheets.Count
        If Sheets(i).Visible = xlSheetVeryHidden Then
            HiddenSheets(i) = Sheets(i).Name
            Sheets(i).Visible = xlSheetHidden
        End If
    Next i

    For i = 1 To Worksheets.Count - 1
        For j = i + 1 To Worksheets.Count
            If Order = Ascending Then
                If UCase(Worksheets(j).Name) < UCase(Worksheets(i).Name) Then
                    Worksheets(j).Move Before:=Worksheets(i)
                End If
            Else
                If UCase(Worksheets(j).Name) > UCase(Worksheets(i).Name) Then
                   Worksheets(j).Move Before:=Worksheets(i)
                End If
            End If
         Next j
    Next i
   
    For i = 1 To Sheets.Count
        If Len(HiddenSheets(i)) Then Sheets(HiddenSheets(i)).Visible = xlSheetVeryHidden
    Next i
    PopulateList
    Sheets(1).Activate
   
    Application.ScreenUpdating = True
End Sub

Private Sub SortAZ_Click()
    SortList Ascending
End Sub

Private Sub SortZA_Click()
    SortList Descending
End Sub

Sub PopulateList()
Dim counter As Long
Dim HiddenPrefix As String
    SheetList.Clear
    For counter = 1 To Sheets.Count
        If Sheets(counter).Visible <> xlSheetVisible Then
            HiddenPrefix = "H"
        Else
            HiddenPrefix = ""
        End If
        SheetList.AddItem HiddenPrefix & vbTab & Sheets(counter).Name
    Next counter
End Sub

Private Sub UserForm_Initialize()
    bangquanlysheet.Caption = ActiveWorkbook.Name
    PopulateList
End Sub
Cảm ơn thầy nhiều, thật tuyệt!
Mọi thứ đã ổn, em xin phép làm phiền thầy chút xíu nữa, giờ giao diện Add - in này có cách nào cho lên dải Riboon để khi thao tác cho dễ không vậy thầy.
 
Upvote 0
Cảm ơn thầy nhiều, thật tuyệt!
Mọi thứ đã ổn, em xin phép làm phiền thầy chút xíu nữa, giờ giao diện Add - in này có cách nào cho lên dải Riboon để khi thao tác cho dễ không vậy thầy.
Nhìn cái file hóa ra Chủ Topic với cái người này là một người
 
Upvote 0
Cảm ơn thầy nhiều, thật tuyệt!
Mọi thứ đã ổn, em xin phép làm phiền thầy chút xíu nữa, giờ giao diện Add - in này có cách nào cho lên dải Riboon để khi thao tác cho dễ không vậy thầy.
Thế bạn mường tượng thế nào thì nói rõ chứ tôi có đi guốc trong đầu bạn đâu?

Chỉ là việc khởi động Form mà là khó?

Còn nếu là ứng dụng thì để tác động lên bất cứ tập tin nào đang mở hay chỉ tác động lên tập tin cụ thể? Vì nếu cụ thể như tập tin của bạn thì cứ để trong tập tin thôi. Làm cái Button hoặc phím tắt để hiện Form.
 
Upvote 0
Nhìn cái file hóa ra Chủ Topic với cái người này là một người
Gần chứ không phải 1 Nhất Chi Lan ạ!
Bài đã được tự động gộp:

Thế bạn mường tượng thế nào thì nói rõ chứ tôi có đi guốc trong đầu bạn đâu?

Chỉ là việc khởi động Form mà là khó?

Còn nếu là ứng dụng thì để tác động lên bất cứ tập tin nào đang mở hay chỉ tác động lên tập tin cụ thể? Vì nếu cụ thể như tập tin của bạn thì cứ để trong tập tin thôi. Làm cái Button hoặc phím tắt để hiện Form.
À vâng, đúng rồi dùng phím tắt cũng tốt, em cám ơn Thầy!
 
Upvote 0
Nhìn cái file hóa ra Chủ Topic với cái người này là một người
Hồi xưa có Nhất Chi Mai ghé qua một tí rồi lui vào làm việc ở hậu trường.
Không biết Nhất Chi Lan là "hàng" thật hay hàng tậu ở Thái về ***. Không biết Nhất Chi Lan có là chị (em) của Nhất Chi Mai không. Nhưng cả Mai và Lan đều đẹp.

***: ở trên GPE có nhiều người đeo mặt nạ không phản ánh trung thực "nội dung", thậm chí có người có 4, 5 mặt nạ. Vì thế câu hỏi là có nguyên do của nó.
 
Upvote 0
Web KT
Back
Top Bottom