【问题标题】:Turning off Excel Compatibility Checker for "Significant Loss of Functionality" errors针对“重大功能丧失”错误关闭 Excel 兼容性检查器
【发布时间】:2014-07-07 17:11:27
【问题描述】:

我发现,虽然可以通过代码以编程方式禁用 Excel 的“兼容性检查器”(通过使用 ActiveWorkbook.CheckCompatibility = False,在 SaveAs 调用之前或通过捕获 ActiveWorkbook.BeforeSave 事件在全局范围内),但它没有如果检测到“功能严重丧失”,则似乎不起作用。快速测试方法:

  • 创建一个新的 Excel 2010 工作簿。
  • 选择 A1:A2 并选择条件格式(无所谓)。
  • 选择 A2:A3 并选择不同的条件格式。 A2 应应用两种不同的条件格式。
  • 打开 VBA 编辑器,并将以下代码添加到工作簿模块:

    Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
        ActiveWorkbook.CheckCompatibility = False
    End Sub
    
  • 在代码中放置断点。

  • 返回电子表格,选择文件 > 另存为。代码将立即跳转到断点。如果您单步执行代码,则可以在“立即”窗格中验证 CheckCompatibility 设置。
  • 代码完成后,选择 Excel 97-2003 文件类型并单击“保存”。
  • 兼容性检查器仍然出现。

我怀疑这是因为该错误不是“次要兼容性问题”(参见http://msdn.microsoft.com/en-us/library/office/gg132972(v=office.14).aspx),但我似乎没有采取任何措施来抑制此错误,甚至没有创建注册表项来禁用它。任何人都知道如何抑制检查器,即使“严重”不兼容?

ETA:在不涉及很多不必要的细节的情况下,我试图自动化一个流程,其中打开许多供应商模板,填充数据,根据大量(并且总是略有不同)质量控制集进行处理规则,并保存为 .xls 文件(根据供应商的要求)。因为在无人值守的系统上每两小时会在几十个不同的模板工作簿上发生这种情况,所以我不能简单地取消选中每个工作簿的兼容性要求。我的意思是,我想我可以,但那将成为我的全职工作。我需要能够在运行时关闭任何工作簿的兼容性检查,这是第一次,无需人工干预。

【问题讨论】:

  • 尚未测试,但除了Workbook.CheckCompatibility 之外,还可以尝试Workbook.DoNotPromptForConvert - 请参阅here
  • 您可以尝试使用msdn.microsoft.com/en-us/library/office/… 来自动化用户交互
  • CheckCompatibility 标志也不起作用。似乎在 UI 对话框出现之前触发了“BeforeSave”事件,但兼容性检查正在运行之后该框被关闭。

标签: excel excel-2010 vba


【解决方案1】:

尝试 Application.DisplayAlerts = False 作为解决方法。

【讨论】:

    【解决方案2】:

    创建了一个功能不完全但至少满足我个人需要的解决方法;也许它会成为其他人的起点。请注意,这并不适用于所有情况下的兼容性检查器,只是在自定义格式重叠的情况下。

    简而言之,这将遍历所有活动单元格,并且对于包含条件格式的任何单元格,评估是否应应用自定义格式(以正确的顺序),然​​后手动应用它。最后,所有自定义格式都被删除。这会使工作簿保持格式,但消除了强制显示兼容性检查器的原因。 YMMV。

    Sub FlattenFormats()
        Dim wb As Workbook
        Set wb = ActiveWorkbook
        Dim asheet As Worksheet
        Set asheet = wb.ActiveSheet
    
        Dim cellvalue_regex As New RegExp
        cellvalue_regex.Pattern = "^""(.*)""$"
    
        Dim c As Range
        Dim conds As Collection
    
        For Each c In asheet.UsedRange.SpecialCells(xlCellTypeAllFormatConditions)
            If c.FormatConditions.Count > 0 Then
                Set conds = New Collection
                Dim fc As FormatCondition
                Set fc = Nothing
                For Each fc In c.FormatConditions
                    conds.Add fc
                Next fc
                c.FormatConditions.Delete
    
                Sort conds
    
                Set fc = Nothing
                For Each fc In conds
                    Select Case fc.Type
                        Case XlFormatConditionType.xlCellValue
                            Dim theMatches As MatchCollection
                            Set theMatches = cellvalue_regex.Execute(fc.Formula1)
                            Dim match1 As Match
                            Set match1 = theMatches.Item(0)
                            Dim checkFor As String
                            checkFor = match1.SubMatches(0)
                            If c.Value2 = checkFor Then
                                c.Interior.Color = fc.Interior.Color
                                If fc.StopIfTrue Then
                                    Exit For
                                End If
                            End If
                        Case XlFormatConditionType.xlExpression
                            If Evaluate(fc.Formula1) Then
                                c.Interior.Color = fc.Interior.Color
                                If fc.StopIfTrue Then
                                    Exit For
                                End If
                            End If
                    End Select
                Next fc
            End If
        Next c
    
        ActiveSheet.Cells.FormatConditions.Delete
    End Sub
    
    Private Sub Sort(ByRef c As Collection)
        Dim i As Integer, j As Integer
        Dim temp As FormatCondition
        Dim i_item As FormatCondition, j_item As FormatCondition
    
        For i = 1 To c.Count - 1
            Set i_item = c(i)
    
            For j = i + 1 To c.Count
                Set j_item = c(j)
    
                If i_item.Priority > j_item.Priority Then
                    Set temp = c(j)
                    c.Remove j
                    c.Add temp, temp.Priority, i
                End If
            Next j
        Next i
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-06
      • 2014-03-02
      • 1970-01-01
      • 2020-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多