具有 400000 行的 Excel 中的组结构级别挂起应用程序

问题描述 投票:0回答:2

我有一个简单的宏,我根据结构级别(1-8)对行进行分组,即创建大纲。当我在有 76k 行的 Excel 上运行宏时,需要一些时间,但可以完成任务。但之后,如果运行宏的行数增加,就会挂起 excel,我必须从任务管理器中终止该进程。

enter image description here

Sub GroupReport()

    'Define Variables
    Dim StartCell As Range
    Dim StartRow As Long
    Dim LevelCol As Integer
    Dim LastRow As Long
    Dim CurrentLevel As Integer 'iterative counter'
    Dim i As Long
    Dim j As Integer
    
    Application.Calculation = xlCalculationManual
    Application.ScreenUpdating = False 

    Set StartCell = Cells(5, 1)
    StartRow = StartCell.Row
    LevelCol = StartCell.Column
    LastRow = ActiveSheet.UsedRange.Rows.Count

    ' Cells.ClearOutline
    
    'inarr = Range(Cells(5, 1), Cells(LastRow, 19))

    For i = StartRow To LastRow
        CurrentLevel = Cells(i, LevelCol)
        Rows(i).Select
        For j = 1 To CurrentLevel - 1
            On Error Resume Next
            Selection.Rows.Group
        Next j
    Next i

    Application.ScreenUpdating = True 

End Sub

我尝试关闭手动计算和屏幕更新来提高性能,但没有多大帮助。我尝试将数据复制到变量数组,但无法理解如何循环它。

我真的很感激任何建议/帮助,使其适用于 4L 的 excel 并提高性能。

excel vba performance freeze
2个回答
0
投票

我会限制与工作表的交互数量,例如Select方法、实际行数而不是UsedRange.Rows.Count,并使用数组来加快处理速度。这是对您的代码的一些接触。

子 My2ndAdjOptimized()

Dim ws As Worksheet
Dim StartRow As Long, LastRow As Long
Dim LevelCol As Long
Dim CurrentLevel As Integer
Dim i As Long, j As Long
Dim LevelArr As Variant

' Define the working sheet
Set ws = ThisWorkbook.ActiveSheet

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

' Start the timer
Dim StartTime As Double
StartTime = Timer

StartRow = 5
LevelCol = 1
LastRow = ws.Cells(ws.Rows.Count, LevelCol).End(xlUp).Row

' Read data into an array
LevelArr = ws.Range(ws.Cells(StartRow, LevelCol), ws.Cells(LastRow, LevelCol)).Value

' Iterate over rows to group them
For i = 1 To UBound(LevelArr, 1)
    CurrentLevel = LevelArr(i, 1)
    For j = 1 To CurrentLevel - 1
        ws.Rows(StartRow + i - 1).Group
    Next j
Next i

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic

' Display runtime
MsgBox "Runtime: " & Round(Timer - StartTime, 2) & " seconds"

结束子


0
投票

我使用 Python 中的 openpyxl 库实现了相同的逻辑,并观察到性能的大幅提升。对于 10,000 行的数据集,该操作只需 1.77 秒即可完成。 这是我的Python代码。

import openpyxl
from time import time

def group_rows_based_on_levels(filename):
    # Load workbook and select active sheet
    wb = openpyxl.load_workbook(filename)
    ws = wb.active
    
    start_time = time()
    
    start_row = 5
    level_col = 1
    
    # Determine the last row with data in the level column
    last_row = ws.max_row

    for i in range(start_row, last_row + 1):
        current_level = ws.cell(row=i, column=level_col).value
        if current_level is not None:
            for _ in range(current_level - 1):
                ws.row_dimensions[i].outlineLevel += 1
                ws.row_dimensions[i].hidden = True

    # Save the changes
    wb.save(filename)
    
    runtime = round(time() - start_time, 2)
    print(f"Runtime: {runtime} seconds")

# Example usage
group_rows_based_on_levels("your_file.xlsx")
© www.soinside.com 2019 - 2024. All rights reserved.