vba - 调用 Sub 导致 Sub undefined 错误
问题描述
我正在尝试找到一种方法来让我的表格自动扩展,同时防止用户使用公式编辑列。鉴于这是一种很常见的情况,看起来它应该很简单,没有花哨的编码,但我离题了......
我在网上找到了以下代码(向作者道歉,因为我不记得在哪里):
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Sheets("Instructions").Range("autoExpand") Like "Disabled" Then Exit Sub
Dim Tbl As ListObject, Off As Integer, ExitCode As Label
Dim TblFirstRow As Long, TblFirstColumn As Integer
Dim FirstRowAllowed As Long
On Error GoTo ExitCode
Off = 0: If Target.Row > 1 Then Off = -1
Set Tbl = ActiveSheet.ListObjects(1)
TblFirstRow = Tbl.HeaderRowRange.Row
TblFirstColumn = Tbl.HeaderRowRange.Cells(1, 1).Column
OpenClipboard 0
FirstRowAllowed = TblFirstRow
If Target.Row >= FirstRowAllowed And Target.Row <= Tbl.ListRows.Count + TblFirstRow + 1 And _
Target.Column <= Tbl.ListColumns.Count + TblFirstColumn And _
Target.Cells.Offset(Off, 0).Locked = False Then
Unprotect
CloseClipboard
Else
GoTo ExitCode
End If
Exit Sub
ExitCode:
Protect DrawingObjects:=False, Contents:=True, Scenarios:= _
False, UserInterfaceOnly:=True, AllowFormattingCells:=True, AllowFormattingColumns:=True, _
AllowFormattingRows:=True, AllowInsertingRows:=True, AllowSorting:=True, _
AllowFiltering:=True, AllowUsingPivotTables:=True
CloseClipboard
End Sub
该代码效果很好,但我想在同一个工作簿中的多个工作表上使用它,所以我想也许我可以这样做:
在工作表中:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Call table_expand
End Sub
在模块中:
Sub table_expand()
(pasted code from within the Sub above)
End Sub
但是,这不起作用-我得到了
“未定义子”
错误。经过一些谷歌搜索后,问题似乎与缺少或多余的括号有关,但我没有得到任何工作。
我暂时可以将代码粘贴到所有工作表中,但由于我有大约十个,基本上我只是想把它弄干一点......
...我应该认为这是可能的?我确信很明显,我对 VBA 的经验几乎为零,非常感谢您的帮助。
解决方案
我猜您没有将相关信息传递Target
给您的常规宏。所以它不知道该做什么。
像这样的东西:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
myMacro Target
End Sub
在常规模块中:
Sub myMacro(Target As Range)
MsgBox Target.Worksheet.Name & vbLf & Target.Address
End Sub
Target.Sheet
在常规宏中,如果您引用发生事件的工作表,则需要将对工作表的引用更改为或类似的内容。
请注意,在 VBA 中,Call
不是必需的。
此外,正如我在阅读@chrisneilsen 的评论后意识到的那样,您可以使用 Workbook 事件代码,而不是将您的事件代码放在每个工作表上。然后你只需要输入一次。例如:
工作簿代码:
Private Sub Workbook_SheetSelectionChange(ByVal sh As Object, ByVal Target As Range)
Call myMacro(sh, Target)
End Sub
常规模块:
Sub myMacro(sh As Worksheet, Target As Range)
Dim Tbl As ListObject
Set Tbl = sh.ListObjects(1)
Stop
End Sub
或者您可以将所有宏代码放入工作簿代码中;维护您希望发生这种情况的工作表列表并添加测试。
Private Sub Workbook_SheetSelectionChange(ByVal sh As Object, ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Sheets("Instructions").Range("autoExpand") Like "Disabled" Then Exit Sub
Dim Tbl As ListObject, Off As Integer, ExitCode As Label
Dim TblFirstRow As Long, TblFirstColumn As Integer
Dim FirstRowAllowed As Long
On Error GoTo ExitCode
Off = 0: If Target.Row > 1 Then Off = -1
Set Tbl = sh.ListObjects(1)
TblFirstRow = Tbl.HeaderRowRange.Row
TblFirstColumn = Tbl.HeaderRowRange.Cells(1, 1).Column
OpenClipboard 0
FirstRowAllowed = TblFirstRow
If Target.Row >= FirstRowAllowed And Target.Row <= Tbl.ListRows.Count + TblFirstRow + 1 And _
Target.Column <= Tbl.ListColumns.Count + TblFirstColumn And _
Target.Cells.Offset(Off, 0).Locked = False Then
Unprotect
CloseClipboard
Else
GoTo ExitCode
End If
Exit Sub
ExitCode:
Protect DrawingObjects:=False, Contents:=True, Scenarios:= _
False, UserInterfaceOnly:=True, AllowFormattingCells:=True, AllowFormattingColumns:=True, _
AllowFormattingRows:=True, AllowInsertingRows:=True, AllowSorting:=True, _
AllowFiltering:=True, AllowUsingPivotTables:=True
CloseClipboard
End Sub
您的代码在我的系统上运行时会返回错误,因此我假设您的环境不同,因为您在工作表上写道它运行正常。
尤其是:
OpenClipboard
没有定义CloseClipboard
没有定义
并且您将希望Worksheet.Protect
对该活动使用该方法。
推荐阅读
- c - 可能的内存泄漏 valgrind c
- vue.js - 在 v-for 循环中插入动态组件
- node.js - Apple 芯片上的 Firebase admin sdk 无法正常工作
- forms - 如何将表单项与引导程序对齐
- node.js - 我应该在哪个条带事件中更新我的数据库以授予订阅者访问权限
- byte-buddy - Bytebuddy Advice 并不总是在 Java 代理中工作
- material-ui - 设置material-ui文档部分样式的正确方法
- python - 找出一系列整数中的跳过值
- lua - Lua从自我向上移动(Y)5个值?
- mysql - MySQL算法更新银行交易(最终余额)