知识库 KB0204

有些 Excel 文件使用数据链接时速度很慢

问题

若 Excel 文件包含 Excel 数据链接(请参阅 21. Excel 数据链接)和过多的单元格样式,可能开始滚动时会很慢,Excel 似乎停止响应。

若 Excel 文件包含的单元格样式超过大约 3000 种,可能会发生此问题。您可以在即时窗口中使用以下 VBA 命令检查单元格样式的数量:

print Activeworkbook.Styles.Count

对此进行检查的详细步骤如下:

  1. Alt+F11 打开 VBA 编辑器。
  2. 前往即时窗口。若该窗口不可见,您可以单击视图即时窗口以显示该窗口。
  3. 输入以下命令,然后按 Enter
    print Activeworkbook.Styles.Count

解决方案:清理受影响的工作簿

  • 将您的工作表复制到新的工作簿中

    Office 2013 和更新版本中,默认情况下,在工作簿之间复制工作表会导致无法累计未使用的单元格样式:

    • 选择工作簿中的所有表格,方式为按住 SHIFT 键,然后单击第一个和最后一个工作表
    • 右键单击选择对象:移动或复制...到工作簿:(新工作簿)然后选中创建副本确定
    • 以新名称保存新工作簿

    Office 2007 和 2010 中,若将工作表复制到新工作簿中,会复制所有未使用的单元格样式。若要防止出现此情况,请先激活以下修补程序:

    若您的 Office 版本已完全更新,则可能已安装此修补程序。但是,您还必须激活此修复,其方式可以是使用 Microsoft 提供的 Fix it 解决方案,也可以是在注册表中按照以下 Microsoft 文章的说明而执行:

    若激活修补程序无效,请应用以上 Microsoft 文章中解决方案部分提及的更新。

  • 使用清理工具清理您的工作簿

    使用 Microsoft 在 KB213904 中建议的清理工具。使用 XLStyles 工具,单击获取 Excel 文件,选中将所有单元格样式强制设为“常规”,然后单击处理文件。Excel 打开清理后的文件时,使用新名称保存该文件。

  • 使用 VBA 宏从工作簿中删除自定义单元格样式

    使用 Alt+F11 打开 VBA 编辑器。选择您的工作簿,然后单击插入模块。然后粘贴以下宏的其中之一,按 F5 运行该宏:

    DeleteCustomStyles() 会删除您工作簿中的所有自定义单元格样式。

    Sub DeleteCustomStyles()
    Dim st As Style
    Dim i, i_cust As Long
    i_cust = 0
    For i = (ActiveWorkbook.Styles.Count) To 1 Step -1
    	With ActiveWorkbook.Styles(i)
    		If .BuiltIn = False Then
    			On Error Resume Next
    			.Locked = False
    			On Error GoTo 0
    			If Not .Locked Then
    				.Delete
    				i_cust = i_cust + 1
    			End If
    		End If
    	End With
    	If (i Mod 100) = 0 Then Debug.Print i
    Next
    MsgBox "Styles deleted: " & i_cust & " styles" & Chr(13) & "Styles left: " & ActiveWorkbook.Styles.Count
    End Sub

    Remove_Styles() 会只删除您工作簿中未使用的自定义单元格样式。它与以上宏类似,但是运行可能需要很长时间。该宏由 Microsoft Office 支持提供。

    Option Explicit
    Dim st_array() As String
    Dim i_x As Long
    Sub Remove_Styles()
    Dim stname As String
    Dim ustname As String
    Dim uc As Range
    Dim retval As Boolean
    Dim ust As Style
    Dim sh As Worksheet
    i_x = 0
    For Each sh In ActiveWorkbook.Worksheets
        For Each uc In sh.UsedRange
            stname = uc.Style.Name
            retval = Check_Array(stname)
            If retval = False Then
            ReDim Preserve st_array(i_x)
            st_array(i_x) = stname
            i_x = i_x + 1
            End If
        Next uc
    Next sh
    For Each ust In ActiveWorkbook.Styles
        If ust.BuiltIn = False Then
            ustname = ust.Name
            retval = Delete_Styles(ustname)
            On Error Resume Next
            If retval = True Then ust.Delete
            On Error GoTo 0
        End If
    Next ust
    End Sub
    Function Delete_Styles(stylename As String) As Boolean
    Delete_Styles = True
    Dim i_y As Long
    For i_y = 0 To i_x - 1
        If st_array(i_y) = stylename Then Delete_Styles = False
    Next i_y
    End Function
    Function Check_Array(stylename As String) As Boolean
    Check_Array = False
    Dim i_y As Long
    For i_y = 0 To i_x - 1
        If st_array(i_y) = stylename Then Check_Array = True
    Next i_y
    End Function

最佳解决方案是防止粘贴未使用的单元格样式,但是需要 Microsoft 修复 Excel 2007 和更新版本中的 Bug。到目前为止,Microsoft 认为商业影响尚未高到足以提供此修复。若贵公司有 Microsoft Office 支持合同,而且您希望联系 Microsoft 请求修复,可以参阅 Microsoft 案例编号 113012810172527。

说明

有些 .xlsx 工作簿因 Excel 中的 Bug 和有问题的代码设计而包含大量(数万种)单元格样式。促成因素还包括报告工具,这些工具有时会生成许多不必要的单元格样式。

分享