Tốc độ ẩn hàng không cần thiết VBA

Liên hệ QC

Vo Duy Minh

Thành viên hoạt động
Tham gia
21/3/19
Bài viết
113
Được thích
32
Chào các bạn,

Tôi có lệnh VBA đẻ ẩn hàng các hàng không có thông số (bằng cách đánh dấu cột D số 1 làm ChkCol).
Vấn đề là nếu chỉ có khoảng vài trăm hàng thì lệnh chạy còn chấp nhận được, nhưng khi lên đến 3000 hàng (trong đó có khoảng 2.500 hàng cần ẩn) thì tốc độ quá chậm (có lẽ cả 30 phút không chừng).
Thời đại 4.0 thế thì khó chấp nhận được vì thà ẩn hàng manually thì còn nhanh hơn.
Rất mong được các bạn giúp được lệnh để đẩy nhanh tốc độ xử lý khả quan hơn.
Xin cám ơn các bạn trước.

Sub HideRows_Day()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.Protect UserInterfaceOnly:=True

BeginRow = 8
EndRow = 3000
ChkCol = 4

For RowCnt = BeginRow To EndRow
If Cells(RowCnt, ChkCol).Value = 1 Then
Cells(RowCnt, ChkCol).EntireRow.Hidden = True
Else
Cells(RowCnt, ChkCol).EntireRow.Hidden = False
End If
Next RowCnt
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
Range("b6").Select
ActiveWindow.SmallScroll
End Sub
 
Thử thay đoạn
Mã:
For rowcnt = BeginRow To EndRow
If Cells(rowcnt, ChkCol).Value = 1 Then
Cells(rowcnt, ChkCol).EntireRow.Hidden = True
Else
Cells(rowcnt, ChkCol).EntireRow.Hidden = False
End If
Next rowcnt
bằng đoạn
Mã:
Dim rng As Range
Range("A" & BeginRow).Resize(EndRow - BeginRow + 1).EntireRow.Hidden = True
For rowcnt = BeginRow To EndRow
    If Cells(rowcnt, ChkCol).Value <> 1 Then
        If rng Is Nothing Then
            Set rng = Range("A" & rowcnt)
        Else
            Set rng = Union(rng, Range("A" & rowcnt))
        End If
    End If
Next rowcnt
If Not rng Is Nothing Then rng.EntireRow.Hidden = False
 
Upvote 0
Chào các bạn,

Tôi có lệnh VBA đẻ ẩn hàng các hàng không có thông số (bằng cách đánh dấu cột D số 1 làm ChkCol).
Vấn đề là nếu chỉ có khoảng vài trăm hàng thì lệnh chạy còn chấp nhận được, nhưng khi lên đến 3000 hàng (trong đó có khoảng 2.500 hàng cần ẩn) thì tốc độ quá chậm (có lẽ cả 30 phút không chừng).
Thời đại 4.0 thế thì khó chấp nhận được vì thà ẩn hàng manually thì còn nhanh hơn.
Rất mong được các bạn giúp được lệnh để đẩy nhanh tốc độ xử lý khả quan hơn.
Xin cám ơn các bạn trước.

Sub HideRows_Day()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.Protect UserInterfaceOnly:=True

BeginRow = 8
EndRow = 3000
ChkCol = 4

For RowCnt = BeginRow To EndRow
If Cells(RowCnt, ChkCol).Value = 1 Then
Cells(RowCnt, ChkCol).EntireRow.Hidden = True
Else
Cells(RowCnt, ChkCol).EntireRow.Hidden = False
End If
Next RowCnt
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
Range("b6").Select
ActiveWindow.SmallScroll
End Sub
Câu hỏi đặt ra là Bạn ẩn dòng để làm gì? Có phải bạn muốn lọc dữ liệu theo một điều kiện nào đó? Nếu vậy bạn có thể dùng cách khác: Advanced Filter chẳng hạn
Cuối cùng: nếu bạn vẫn chưa tự làm được, hãy cho file lên đây
 
Upvote 0
Tôi chưa thử xem lệnh của bạn effective thế nào.
Tuy nhiên phản hồi cực nhanh của bạn rất đáng trân trọng.
Chân thành cảm ơn bạn.
Bài đã được tự động gộp:

Chào bạn "batman1"
Tuyệt vời còn hơn real Batman nữa.
Lệnh trước của tôi chạy nửa tiếng chưa xong,
thay bằng lệnh của bạn thì nó chạy trong "3 GIÂY"
Tôi hết sức cảm ơn bạn.
Chúc bạn nhiều sức khỏe và luôn tiếp tục prompt reply và reply effectively.
 
Lần chỉnh sửa cuối:
Upvote 0
thay bằng lệnh của bạn thì nó chạy trong "3 GIÂY"
Tức thao tác trên sheet (EntireRow.Hidden) chỉ làm 2 lần thay cho làm 2993 lần như bạn làm. Mọi thao tác trên sheet rất chậm. Vì thế để đổ vd. 50 000 số lên sheet thì không ai đổ vào từng ô. Phải nhập 50 000 giá trị "đó" vào mảng rồi đổ 1 lần xuống sheet.
 
Upvote 0
Nguyễn Hoàng Nhật Phương? Hình như cô quân nhân này hồi xưa tên là Nguyễn Hoàng Oanh Thơ chứ nhỉ.
 
Upvote 0
Tức thao tác trên sheet (EntireRow.Hidden) chỉ làm 2 lần thay cho làm 2993 lần như bạn làm. Mọi thao tác trên sheet rất chậm. Vì thế để đổ vd. 50 000 số lên sheet thì không ai đổ vào từng ô. Phải nhập 50 000 giá trị "đó" vào mảng rồi đổ 1 lần xuống sheet.

Cám ơn bạn thêm một lần nữa.
Tôi không giỏi gì với VBA, nhưng khái niệm của bạn giúp tôi nắm thêm vấn đề rõ hơn nhiều.
Tôi sẽ cố gắng suy từ đó khi cần thiết với những trường hợp khác.
Dĩ nhiên sau khi HIde thì tôi cũng có Show để bung ra, tốc độ cũng chấp nhận được (khoảng 5 đến 10 giây).
Nhưng không dám làm phiền bạn thêm nữa.
Chúc bạn một buổi tối ngủ ngon.
Một lần nữa, xin cám ơn bạn, tôi vẫn còn sững sở với tốc độ xử lý mà lệnh của bạn giúp tôi.
 
Upvote 0
Nguyễn Hoàng Nhật Phương? Hình như cô quân nhân này hồi xưa tên là Nguyễn Hoàng Oanh Thơ chứ nhỉ.
Con chào Bác Siwtom
Cảm ơn Bác đã quan tâm và nhớ đến con ạ huhu T_T
Dạ vâng Bác, Nhật Phương là tên bé gái nhà con năm nay cháu được 3 tuổi Bác ạ,con muốn thay đổi một chút nên đã nhờ BQT đổi tên.
Bác dạo này có khỏe không ạ?
Oanh Thơ
 
Upvote 0
Con chào Bác Siwtom
Cảm ơn Bác đã quan tâm và nhớ đến con ạ huhu T_T
Dạ vâng Bác, Nhật Phương là tên bé gái nhà con năm nay cháu được 3 tuổi Bác ạ,con muốn thay đổi một chút nên đã nhờ BQT đổi tên.
Bác dạo này có khỏe không ạ?
Oanh Thơ
Cám ơn bạn đã hỏi thăm. Sức khoẻ thì bình thường nhưng hơi "mệt" vì cô Vi. Ở Hà Nội mọi người cũng cố gắng nhé. Đợt này hơi nguy hiểm.
 
Upvote 0
Cám ơn bạn đã hỏi thăm. Sức khoẻ thì bình thường nhưng hơi "mệt" vì cô Vi. Ở Hà Nội mọi người cũng cố gắng nhé. Đợt này hơi nguy hiểm.
Con chào bác Siwtom,
Con cảm ơn Bác đã gửi lời ạ, hic tự nhiên con cảm thấy xúc động ... có thể vì ký ức quá khứ tràn về khi con nhớ đến người ông (đã mất) của mình và con nhớ lại khoảng thời gian khi được Bác giúp đỡ & tận tình chỉ dẫn ...
Con cầu chúc Bác cùng gia đình ở phương xa luôn mạnh khỏe & công tác tốt.
Oanh Thơ.
 
Upvote 0
"công tác tốt" ở trời tây người ta hiếm xài trong giao tiếp lắm!

Tuy nhiên, khi gặp nhau người ta buông câu: "Công việc thế nào?", nhưng chủ iếu gần như là hỏi về sức khỏe.
 
Upvote 0
Thử thay đoạn
Mã:
For rowcnt = BeginRow To EndRow
If Cells(rowcnt, ChkCol).Value = 1 Then
Cells(rowcnt, ChkCol).EntireRow.Hidden = True
Else
Cells(rowcnt, ChkCol).EntireRow.Hidden = False
End If
Next rowcnt
bằng đoạn
Mã:
Dim rng As Range
Range("A" & BeginRow).Resize(EndRow - BeginRow + 1).EntireRow.Hidden = True
For rowcnt = BeginRow To EndRow
    If Cells(rowcnt, ChkCol).Value <> 1 Then
        If rng Is Nothing Then
            Set rng = Range("A" & rowcnt)
        Else
            Set rng = Union(rng, Range("A" & rowcnt))
        End If
    End If
Next rowcnt
If Not rng Is Nothing Then rng.EntireRow.Hidden = False
Bác hay quá, kiểu tư duy sáng tạo như cách viết đoạn code này có học được không ạ?
 
Upvote 0
Chào bạn batman1,
Một lần nữa tôi rất cám ơn bạn đã giúp cho tôi lệnh ẩn hàng không cần thiết. Trước đây tôi cứ phải khổ sở "cân đo đong đếm" để số hàng không vượt quá 3000, vì nhiêu đó có khi mất đến 4, 5 phút mới ẩn hết hàng. Với lệnh của bạn tôi đã đưa số hàng lên đến gần 30.000 mà nó mất chỉ hai ba giây là xong hết.
Thật là tuyệt với, bạn đã giúp tôi giải quyết rất nhiều việc.
Hôm nay tôi xin được bạn giúp thêm một chút.
Tôi muốn viết một lệnh (như lệnh ẩn hàng lần trước), nhưng thay vì chỉ thực hiện với một sheet đang mở (active sheet) thì lệnh được thực thi với những sheet mà tôi khai báo (có thể 5 sheet)
Như lệnh Hiderows dưới đây

Sub HideRows_Day ()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.Protect UserInterfaceOnly:=True

BeginRow = 6
EndRow = 3000
ChkCol = 4

Dim rng As Range
Range("A" & BeginRow).Resize(EndRow - BeginRow + 1).EntireRow.Hidden = True
For rowcnt = BeginRow To EndRow
If Cells(rowcnt, ChkCol).Value <> 1 Then
If rng Is Nothing Then
Set rng = Range("A" & rowcnt)
Else
Set rng = Union(rng, Range("A" & rowcnt))
End If
End If
Next rowcnt
If Not rng Is Nothing Then rng.EntireRow.Hidden = False

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
Range("b6").Select
ActiveWindow.SmallScroll
End Sub

thì cái ActiveSheet chỉ cho ẩn hàng sheet đang mở, nếu mình muốn cùng lúc lệnh sẽ được thực thi với nhiều sheet khác thì sao.

Xin cám ơn bạn trước.
 
Upvote 0
Chào bạn batman1,
Một lần nữa tôi rất cám ơn bạn đã giúp cho tôi lệnh ẩn hàng không cần thiết. Trước đây tôi cứ phải khổ sở "cân đo đong đếm" để số hàng không vượt quá 3000, vì nhiêu đó có khi mất đến 4, 5 phút mới ẩn hết hàng. Với lệnh của bạn tôi đã đưa số hàng lên đến gần 30.000 mà nó mất chỉ hai ba giây là xong hết.
Thật là tuyệt với, bạn đã giúp tôi giải quyết rất nhiều việc.
Hôm nay tôi xin được bạn giúp thêm một chút.
Tôi muốn viết một lệnh (như lệnh ẩn hàng lần trước), nhưng thay vì chỉ thực hiện với một sheet đang mở (active sheet) thì lệnh được thực thi với những sheet mà tôi khai báo (có thể 5 sheet)
Như lệnh Hiderows dưới đây

Sub HideRows_Day ()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.Protect UserInterfaceOnly:=True

BeginRow = 6
EndRow = 3000
ChkCol = 4

Dim rng As Range
Range("A" & BeginRow).Resize(EndRow - BeginRow + 1).EntireRow.Hidden = True
For rowcnt = BeginRow To EndRow
If Cells(rowcnt, ChkCol).Value <> 1 Then
If rng Is Nothing Then
Set rng = Range("A" & rowcnt)
Else
Set rng = Union(rng, Range("A" & rowcnt))
End If
End If
Next rowcnt
If Not rng Is Nothing Then rng.EntireRow.Hidden = False

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
Range("b6").Select
ActiveWindow.SmallScroll
End Sub

thì cái ActiveSheet chỉ cho ẩn hàng sheet đang mở, nếu mình muốn cùng lúc lệnh sẽ được thực thi với nhiều sheet khác thì sao.

Xin cám ơn bạn trước.
Bạn thử tham khảo code dưới nhé:
Rich (BB code):
Sub HideRows_Day()

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.Protect UserInterfaceOnly:=True

BeginRow = 6
EndRow = 3000
ChkCol = 4

Dim sh As Worksheet
Dim rng As Range

    For Each sh In ThisWorkbook.Sheets
        Range("A" & BeginRow).Resize(EndRow - BeginRow + 1).EntireRow.Hidden = True
        For rowcnt = BeginRow To EndRow
        If Cells(rowcnt, ChkCol).Value <> 1 Then
            If rng Is Nothing Then
                Set rng = Range("A" & rowcnt)
            Else
                Set rng = Union(rng, Range("A" & rowcnt))
            End If
        End If
    Next rowcnt
    If Not rng Is Nothing Then rng.EntireRow.Hidden = False
    Next sh

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
Range("b6").Select
ActiveWindow.SmallScroll

End Sub
 
Upvote 0
Code chỉ làm việc trên Active sheet.

EndRow = 3000 => Dữ liệu ít hay nhiều, nó cũng chạy đến đây.

EndRow nên theo dữ liệu của trang tính.

Chắc là thế này ạ:
Mã:
'.................
    BeginRow = 6
    ChkCol = 4
    Dim sh As Worksheet, rng As Range
    For Each sh In ThisWorkbook.Sheets
        EndRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
        sh.Range("A" & BeginRow).Resize(EndRow - BeginRow + 1).EntireRow.Hidden = True
        For rowcnt = BeginRow To EndRow
        If Cells(rowcnt, ChkCol).Value <> 1 Then
            If rng Is Nothing Then
                Set rng = sh.Range("A" & rowcnt)
            Else
                Set rng = Union(rng, sh.Range("A" & rowcnt))
            End If
        End If
    Next rowcnt
    If Not rng Is Nothing Then rng.EntireRow.Hidden = False
    sh.Range("b6").Select
    Next sh
'.................
 
Upvote 0
PHP:
For Each sh In Array("Sheet1", "Sheet2", "Sheet3", "Sheet4") 'Change here
    With Sheets(sh)
        EndRow = .Range("A" & .Rows.Count).End(xlUp).Row
        .Range("A" & BeginRow).Resize(EndRow - BeginRow + 1).EntireRow.Hidden = True
        For rowcnt = BeginRow To EndRow
            If .Cells(rowcnt, ChkCol).Value <> 1 Then
                If rng Is Nothing Then
                    Set rng = .Range("A" & rowcnt)
                Else
                    Set rng = Union(rng, .Range("A" & rowcnt))
                End If
            End If
        Next rowcnt
        If Not rng Is Nothing Then rng.EntireRow.Hidden = False
        Set rng = Nothing
    End With
Next sh
 
Upvote 0
Bạn thử tham khảo code dưới nhé:
Rich (BB code):
Sub HideRows_Day()

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.Protect UserInterfaceOnly:=True

BeginRow = 6
EndRow = 3000
ChkCol = 4

Dim sh As Worksheet
Dim rng As Range

    For Each sh In ThisWorkbook.Sheets
        Range("A" & BeginRow).Resize(EndRow - BeginRow + 1).EntireRow.Hidden = True
        For rowcnt = BeginRow To EndRow
        If Cells(rowcnt, ChkCol).Value <> 1 Then
            If rng Is Nothing Then
                Set rng = Range("A" & rowcnt)
            Else
                Set rng = Union(rng, Range("A" & rowcnt))
            End If
        End If
    Next rowcnt
    If Not rng Is Nothing Then rng.EntireRow.Hidden = False
    Next sh

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
Range("b6").Select
ActiveWindow.SmallScroll

End Sub


Cám ơn bạn đã phản hồi rất nhanh chóng.
Vấn đề của tôi là trong workbook thì có nhiều sheets, nhưng tôi chỉ muốn một số sheets cùng loại trong đó mà thôi (đều có Endrow = 3000), còn những sheets khác thì không bị ảnh hưởng.
Tôi cũng vừa thử dùng lệnh bạn vừa gửi nhưng nó vẫn không ảnh hưởng đến các sheets khác, cũng chỉ hide sheet đang mở mà thôi.
 
Upvote 0
Code chỉ làm việc trên Active sheet.

EndRow = 3000 => Dữ liệu ít hay nhiều, nó cũng chạy đến đây.

EndRow nên theo dữ liệu của trang tính.
Cảm ơn @phuocam@NHN_Phương ! Lại được học thêm kiến thức của mọi người chia sẻ!

Cám ơn bạn đã phản hồi rất nhanh chóng.
Vấn đề của tôi là trong workbook thì có nhiều sheets, nhưng tôi chỉ muốn một số sheets cùng loại trong đó mà thôi (đều có Endrow = 3000), còn những sheets khác thì không bị ảnh hưởng.
Tôi cũng vừa thử dùng lệnh bạn vừa gửi nhưng nó vẫn không ảnh hưởng đến các sheets khác, cũng chỉ hide sheet đang mở mà thôi.
Bạn tham khảo 2 bài viết trên của @phuocam@NHN_Phương nhé.
 
Upvote 0
PHP:
For Each sh In Array("Sheet1", "Sheet2", "Sheet3", "Sheet4") 'Change here
    With Sheets(sh)
        EndRow = .Range("A" & .Rows.Count).End(xlUp).Row
        .Range("A" & BeginRow).Resize(EndRow - BeginRow + 1).EntireRow.Hidden = True
        For rowcnt = BeginRow To EndRow
            If .Cells(rowcnt, ChkCol).Value <> 1 Then
                If rng Is Nothing Then
                    Set rng = .Range("A" & rowcnt)
                Else
                    Set rng = Union(rng, .Range("A" & rowcnt))
                End If
            End If
        Next rowcnt
        If Not rng Is Nothing Then rng.EntireRow.Hidden = False
        Set rng = Nothing
    End With
Next sh

Chào bạn @phuocam
Tôi thử dùng code bạn gửi, nhưng không được. Nó báo "Subscript out of range"
Tôi vẫn còn nhớ tên của bạn, trước đây bạn đã giúp tôi viết một hàm excel, tôi đã ứng dụng hướng dẫn của bạn và đã giải quyết được rất nhiều cho công việc của tôi.
Một lần nữa, rất cám ơn bạn.
 
Upvote 0
Web KT

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

Back
Top Bottom