保存后VBA代码崩溃 - 说情况出现在XML“运行时错误'429'

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

我为我工作的公司制作了一份工作表,以帮助定制定制设计。几个月前,我制作了一个宏,可以将部件保存到文本文件中,如果我们想引用相同的设计,可以在以后提取。一切都很完美,直到有一天我打开它并得到错误信息

We found a problem with some content in 'File.xlsm'. Do you want us to try 
to recover as much as we can?

当我单击是时,它会显示宏完全未格式化的工作表,并说它只能通过修复或删除以下部分来打开文件

Repaired Part: /xl/worksheets/sheet3.xml part.

这很奇怪,因为我使用的唯一xml代码只是在加载保存的设计名称时创建一个下拉菜单。自最终修订代码以来,除了已保存的设计数量之外,没有任何变化。我作为按钮绑定到宏的框已被删除,并且此工作表的代码都不起作用。我现在查看代码时显示的是Sheet_Thumbnails

所有其他宏工作,其他表完全正常。当我尝试在这张表上运行代码时,我得到了

Run-time error '429':

ActiveX component can't create object

这必须是在编译时,因为我甚至无法调试发生这种情况的地方。当我看到这个错误时,我得到的最佳答案是,当从其他地方调用文件或对象时,我没有使用“New”关键字。但我查看了我的代码,并没有看到任何适用的地方。幸运的是,一位同事将我们服务器上的副本保存到她的计算机上,所以我有一个备份,但是当我打开它并运行宏然后保存并重新打开时,同样的崩溃就会发生。

这是xml的代码:

Sub MakeList(ByRef r As Range, ByRef Config As String)

r.Clear
If Not Config = "" Then
    r.Select
        With Selection.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Formula1:=Config
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = ""
        .InputMessage = ""
        .ErrorMessage = ""
        .ShowInput = True
        .ShowError = True
        End With
    End If
End Sub

谁能帮我?我完全失去了为什么会发生这种情况以及为什么会一直发生这种情况。它是验证部分吗?为什么会在工作几个月后发生?

先感谢您。

编辑1

导出所有代码并创建新工作簿并没有解决问题。

感谢Profex,问题已经找到并且正在验证中。基本上我的一个列表太长了。验证中使用的公式不应超过255个字符。即使Excel没有对此进行任何警告,当我创建下拉菜单时,虽然它会填充列表中的每个项目,但在保存关闭和重新打开后,显然这会破坏编码的表单。所以现在问题在于如何将值添加到下拉菜单中而不清除并使用更长的列表重新初始化。我应该发布一个新问题吗?

excel vba excel-vba
2个回答
0
投票

在Excel中,单元格验证列表具有8191个字符限制(这对用户来说无论如何都是太长了)。

保存/重新打开时,超过254个字符的任何内容都将损坏文件。

这与我过去创建的动态验证列表类似:

它使用你的MakeList()子程序,并需要另一个GetList()函数来获取指定单元格的验证列表。

由于此代码位于Workbook模块中,因此我还添加了另一个名为IsSheetTheOneICareAboutWithValidations()的函数。如果在特定表单模块中使用WorksSheet_SelectionChange事件,则不需要这样做;但你必须将m_ValidationCellm_ValidationList的范围改为Public

此代码未经测试,并进入ThisWorkbook模块:

Option Explicit

Private m_ValidationCell As Excel.Range
Private m_ValidationList As String

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    If Not m_ValidationCell Is Nothing Then
        m_ValidationList = m_ValidationCell.Validation.Value
        m_ValidationCell.Validation.Delete
    End If
End Sub

Private Sub Workbook_AfterSave(ByVal Success As Boolean)
    If m_ValidationList <> vbNullString Then
        With m_ValidationCell.Validation
            .Add Type:=xlValidateList, Formula1:=ValidationList
        End With
        m_ValidationList = vbNullString
    End If
End Sub

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    If Not m_ValidationCell Is Nothing Then
        m_ValidationCell.Validation.Delete
        Set m_ValidationCell = Nothing
    End If

    If IsSheetTheOneICareAboutWithValidations(Sh) Then
        ' Since we're changing the Validation each time there is a new Selection;
        ' It's the Active Cell that matters, not the Target range
        '   Add a validation list to any cell in column 4, after the header (in row 1).
        If ActiveCell.Column = 4 And ActiveCell.Row > 1 Then
            List = GetList(ActiveCell)
            MakeList ActiveCell, List
            ' Should probably add this next line to you MakeList() function
            Set m_ValidationCell = ActiveCell
        End If
    End If
End Sub

Private Function GetList(Target As Range) As String
    GetList = vbNullString ' or whatever you want
End Function

Private Function IsSheetTheOneICareAboutWithValidations(Sh As Object) As Boolean
    IsSheetTheOneICareAboutWithValidations = (Sh.Name = "Pricing")
End Function

0
投票

复苏

看起来你只是有一个糟糕的保存。有时它只会破坏文件,你可以做的事情不多,其他希望你有备份。

右键单击文件夹>属性>以前的版本


如果您没有备份,可能只是将所有内容移动到新文件。

  • 创建一个新工作簿
  • 从第一张纸中选择所有单元格(单击A左侧的1)
  • 按Ctrl + C复制
  • 选择新工作簿/工作表中的所有单元格
  • 按Ctrl + V粘贴
  • 重复所有工作表

在VB方面,你可以将Forms / Modules / Classes从Old文件拖到New文件中。

问题

您是否知道所有新Office文档都只是ZIP文件...

继续,将文件重命名为File.xlsm.zip

在文件中你会看到一个文件夹结构应该有... /xl/worksheets/sheet3.xml

这就是excel抱怨的!该文件丢失或错误。

我不知道你是怎么称呼Makelist的,所以我无法验证你传递的范围R是否有效。

请从您的代码中删除Select/Selection。您无需在Excel的前端GUI中选择任何内容来访问/更改单元格。你也没有检查R是否是Nothing

Sub MakeList(ByRef r As Range, ByRef Config As String)
If Not r Is Nothing then 
    r.Clear
    If Not Config = "" Then    
        With r.Validation
            ...
        End With     
    End If 
End If 
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.