如何在MS-Excel中避免工作表被保护时的运行时错误?

12 浏览
0 Comments

如何在MS-Excel中避免工作表被保护时的运行时错误?

下面的代码片段用于改变单元格的数据验证状态,并且在Excel-2003的工作表未受保护时运行。然而,当我保护工作表时,宏不会运行并引发运行时错误:\n

\n运行时错误\'-2147417848 (80010108)\':\n对象\'Validation\'的方法\'Add\'失败\n

\n我尝试将代码包装在以下代码中:\n

Me.unprotect
...
Me.protect

\n但是这并不能正常工作。那么,我应该如何修改下面的代码,使其在工作表受保护的情况下(即使代码修改了解锁单元格的验证)运行而不会出现上述运行时错误?\n更新\n我的原始工作簿是Excel 2003。我在Excel 2007中使用以下定义测试了@eJames的解决方案:\n

Sub WorkBook_Open()
    Me.Worksheets("MainTable").Protect  contents:=True, userinterfaceonly:=True 
End Sub

\n当工作表受保护时,该代码仍然会出现以下运行时错误:\n

\n运行时错误\'1004\':\n 应用程序定义或对象定义错误\n

\n谢谢,Azim\n


\n代码片段\n

'要添加下拉验证列表的单元格'
dim myNamedRange as String
dim modifyCell as Range 
set modifyCell = ActiveCell.Offset(0,1) 
'根据某些条件设置列表值,为了简洁起见未定义'
If myCondition then
   myNamedRange = "range1"
Else
   myNamedRange = "range2"
End If
With modifyCell.Validation
   .Delete
   '运行时错误发生在下一行'
   .Add Type:=xlValidateList, AlertStyle:=xlValidAltertStop, _
        Operator:=xlBetween, Formula1:="=" & myNamedRange
   ... 
   '跳过更多属性设置代码'
   ...
End With

0
0 Comments

当在MS-Excel中保护工作表时,如何避免运行时错误?

问题的出现原因是,对于VBA能够编辑受保护的工作表,该工作表必须使用"UserInterfaceOnly"参数设置为True进行保护。然而,当工作簿被保存时,UserInterfaceOnly参数不会被保存,因此如果关闭并重新打开工作簿,就会发生错误。

下面是一种解决方法:

1. 创建一个子程序,用于保护所有工作表并将UserInterfaceOnly参数设置为True。我将其分为ProtectSheet和ProtectAll两个子程序:

Sub ProtectSheet(SheetName As String)
    Dim pswd As String
    pswd = "pass" ' 你应该从安全的地方获取密码,而不是硬编码
    ThisWorkbook.Worksheets(SheetName).Protect Password:=pswd, DrawingObjects:=True, Contents:=True, Scenarios:=True, _
        UserInterfaceOnly:=True, AllowFormattingCells:=False, AllowFormattingColumns:=False, _
        AllowFormattingRows:=False, AllowInsertingColumns:=False, AllowInsertingRows:=False, _
        AllowInsertingHyperlinks:=False, AllowDeletingColumns:=False, AllowDeletingRows:=False, _
        AllowSorting:=False, AllowFiltering:=False, AllowUsingPivotTables:=False
End Sub
Sub ProtectAll()
    Dim ws As Worksheet
    For Each ws In ThisWorkbook.Worksheets
        ProtectSheet (ws.Name)
    Next ws
End Sub

2. 在ThisWorkbook中,当工作簿打开时,保护所有工作表:

Private Sub Workbook_Open()
    Call ProtectAll ' 使用UserInterfaceOnly设置为true来保护所有工作表,以便VBA可以进行编辑
End Sub

通过以上方法,可以解决在MS-Excel中保护工作表时出现的运行时错误。

0
0 Comments

在MS-Excel中,当工作表被保护时,如何避免运行时错误?

最近我遇到这个错误时,我发现只需要在Validation.Add之前执行MywkSheet.Activate就可以解决。所以:

'根据某些条件设置列表值,为了简洁起见,未定义'
If myCondition then
   myNamedRange = "range1"
Else
   myNamedRange = "range2"
End If
''--------------------------------------------------
Sheets("mysheet").Activate
''--------------------------------------------------
With modifyCell.Validation
   .Delete
   '运行时错误发生在下一行'
   .Add Type:=xlValidateList, AlertStyle:=xlValidAltertStop, _
        Operator:=xlBetween, Formula1:="=" & myNamedRange
   ... 
   '跳过更多属性设置代码'
   ...
End With

在我的情况下,ScreenUpdating已经关闭,所以用户看不到工作表来回切换。希望对你有帮助。

0
0 Comments

在MS-Excel中,当工作表被保护时,如何避免运行时错误?

问题的原因是,工作表被保护后,无法以普通方式修改其内容,而只有VBA宏可以进行更改。为了解决这个问题,可以使用以下VBA代码:

myWorksheet.Protect contents:=True, userinterfaceonly:=True

这里的关键部分是"userinterfaceonly:=true"。当工作表以此标志被保护时,VBA宏仍然可以进行更改操作。

将这段代码放入`WorkBook_Activate`事件中,以便在每次激活工作簿时自动保护工作表并设置标志。

编辑:感谢Lance Roberts的建议,使用`Workbook_Activate`而不是`Workbook_Open`。

如果上述方法无法解决问题,则可能需要将VBA代码的失败部分用解锁/锁定命令包裹起来。如果这样做,还建议将整个宏包裹在错误处理程序中,以防止在发生错误后工作表保持解锁状态:

Sub MyMacro
    On Error Goto HandleError
    ...
    myWorksheet.unprotect
    With ModifyCell.Validation
        ...
    End With
    myWorksheet.protect contents:=True, userinterfaceonly:=True
    ...
Goto SkipErrorHandler
HandleError:
    myWorksheet.protect contents:=True, userinterfaceonly:=True
    ... some code to present the error message to the user
SkipErrorHandler:
End Sub

在PCreview的论坛上有一个讨论线程,他们经历了类似的步骤,并得出了相同的结论。至少你不是一个人!

感谢提供链接,Remou。虽然我还没有遇到这个问题,但至少现在我知道发生了什么!

是的,你正确理解了我的问题;我是保护工作表的人。我尝试了你的解决方案(在Excel 2007中),当工作表被保护时出现了运行时错误'1004'。

你是在运行`myWorksheet.protect`后出现这个错误吗?

是的,我在运行`myWorksheet.protect`后出现了这个错误。我取消了工作表的保护,保存文件,关闭它,再次打开它,打开事件保护工作表,然后运行宏引发了错误。

你确定该单元格没有被锁定吗?(在单元格属性中未选中锁定)?我假设答案是肯定的,但我还是要确认一下! 🙂

我在答案中添加了一个可能的解决方法。我不确定为什么原始解决方案不起作用,但也许这个方法能帮到你。

谢谢eJames。在`Workbook_Open`事件中保护工作表并将代码包裹在保护和解保护的块中似乎起作用了。

我刚刚通过多个工作表的激活和取消激活以及`Workbook_Open`事件来学习了一种麻烦的方法,所以我不得不转向`Workbook_Activate`事件。由于这似乎是关于此主题的最全面的帖子,你可能也想进行编辑。

非常感谢你的提示。非常非常有用。

0