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

下面的代码片段更改了单元格的数据validation状态,并在Excel-2003工作表不受保护时运行。 但是,当我保护工作表时,macros不会运行并引发运行时错误

运行时错误“-2147417848(80010108)”:

方法“添加”对象“validation”失败

我曾尝试包装的代码

Me.unprotect ... Me.protect 

但是这不能正常工作。 那么,如何在表单被保护而没有上面的运行时错误的情况下,如何修改下面的代码来工作(即让代码修改解锁的单元格的validation)?

更新

我原来的工作书是Excel 2003.我在Excel 2007中testing了@ eJames解决scheme,下面是Workbook_Open的定义

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

工作表受保护时,代码仍然失败,并显示以下运行时错误

运行时错误“1004”:应用程序定义或对象定义的错误

谢谢,Azim


代码片段

 'cell to add drop down validation list' dim myNamedRange as String dim modifyCell as Range modifyCell = ActiveCell.Offset(0,1) ' set list values based on some conditions not defined for brevitity' If myCondition then myNamedRange = "range1" Else myNamedRange = "range2" End If With modifyCell.Validation .Delete 'Run time error occurs on the next line' .Add Type:=xlValidateList, AlertStyle:=xlValidAltertStop, _ Operator:=xlBetween, Formula1:="=" & myNamedRange ... ' skipping more property setting code ' ... End With 

如果我正确地理解了这个问题,你将成为保护工作表的人。 如果是这样的话,你可以使用下面的VBA:

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

这里的关键部分是“userinterfaceonly:= true”。 当工作表受此标志集的保护时,VBAmacros仍然可以进行更改。

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

编辑:感谢兰斯罗伯茨他build议使用Workbook_Activate而不是Workbook_Open

编辑:由于上述似乎没有工作,你可能不得不包装你的VBA代码的失败部分与解除/保护命令。 如果你这样做的话,我也会用一个error handling程序来包装整个macros,这样在发生错误之后,这个表不会被保护。

 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。 他们经历了许多相同的步骤,得出了同样的结论。 至less你并不孤单!

我不确定这是否是一个通用的解决scheme,但是当我最近遇到这个错误时,我只需要在执行Validation.Add之前做一个MywkSheet.Activate。 所以:

 ' set list values based on some conditions not defined for brevitity' If myCondition then myNamedRange = "range1" Else myNamedRange = "range2" End If ''-------------------------------------------------- Sheets("mysheet").Activate ''-------------------------------------------------- With modifyCell.Validation .Delete 'Run time error occurs on the next line' .Add Type:=xlValidateList, AlertStyle:=xlValidAltertStop, _ Operator:=xlBetween, Formula1:="=" & myNamedRange ... ' skipping more property setting code ' ... End With 

在我的情况下,ScreenUpdating已经closures了,所以用户从来不会看到纸张来回切换。 HTH。