Excel VBA - 如何在代码编辑器中打开行号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40731182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Excel VBA - How to Turn On Line Numbers in Code Editor
提问by Sohel
Please kindly help: how do I turn on the line numbers in Excel VBA code editor? I am using Excel 2013 version.
请帮助:如何在 Excel VBA 代码编辑器中打开行号?我正在使用 Excel 2013 版本。
Thank you.
谢谢你。
回答by hymced
Here is my code to add line numbers in the VBE IDE. It is an improvement of the solution provided hereby Excel MVP mikerickson. I have worked on this, because in some rare cases I have already met, VBE can't enter in debug mode, for example when you have a .ReplaceLine method in your code. Indeed, you can't enter in debug mode once it has been executed, so Erl might be usefully for debug (instead of Debug.Print). I have added several feature such as:
这是我在 VBE IDE 中添加行号的代码。它是对Excel MVP mikerickson在此处提供的解决方案的改进。我已经解决了这个问题,因为在我已经遇到的一些极少数情况下,VBE 无法进入调试模式,例如当您的代码中有 .ReplaceLine 方法时。事实上,一旦它被执行,你就不能进入调试模式,所以 Erl 可能对调试很有用(而不是 Debug.Print)。我添加了几个功能,例如:
- possibility to either add line numbers as labels:
10: Dim foo as baror as single numbers seperated from code by a tab:10 Dim foo as bar- possibility to add line numbers to End of procedures statements, and to match the indent of the procedure declaration lines to its End statement line once numberered. Or not.
- possibility of add line numbers to empty lines or not
- [WIP] possibility to add line numbers to a specific procedure in a module
- [WIP] match all indentations of code lines with line numbers to match the indent of the last line indented. If last line is
200: End Sub, the line30: With ActiveSheetwill be re-indented as30: ActiveSheet- [WIP] add of a VBE IDE command to directly make the calls with the current module/proc as a parameter
- 添加行号作为标签的可能性:
10: Dim foo as bar或作为由选项卡与代码分隔的单个数字:10 Dim foo as bar- 可以将行号添加到 End of Procedures 语句,并在编号后将过程声明行的缩进与其 End 语句行相匹配。或不。
- 是否可以将行号添加到空行
- [WIP] 可以将行号添加到模块中的特定过程
- [WIP] 将代码行的所有缩进与行号匹配,以匹配最后缩进的行的缩进。如果最后一行是
200: End Sub,则该行将30: With ActiveSheet重新缩进为30: ActiveSheet- [WIP] 增加一个 VBE IDE 命令,直接以当前模块/进程为参数进行调用
Public Enum vbLineNumbers_LabelTypes
vbLabelColon ' 0
vbLabelTab ' 1
End Enum
Public Enum vbLineNumbers_ScopeToAddLineNumbersTo
vbScopeAllProc ' 1
vbScopeThisProc ' 2
End Enum
Sub AddLineNumbers(ByVal wbName As String, _
ByVal vbCompName As String, _
ByVal LabelType As vbLineNumbers_LabelTypes, _
ByVal AddLineNumbersToEmptyLines As Boolean, _
ByVal AddLineNumbersToEndOfProc As Boolean, _
ByVal Scope As vbLineNumbers_ScopeToAddLineNumbersTo, _
Optional ByVal thisProcName As String)
' USAGE RULES
' DO NOT MIX LABEL TYPES FOR LINE NUMBERS! IF ADDING LINE NUMBERS AS COLON TYPE, ANY LINE NUMBERS AS VBTAB TYPE MUST BE REMOVE BEFORE, AND RECIPROCALLY ADDING LINE NUMBERS AS VBTAB TYPE
Dim i As Long
Dim j As Long
Dim procName As String
Dim startOfProcedure As Long
Dim lengthOfProcedure As Long
Dim endOfProcedure As Long
Dim strLine As String
With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule
.CodePane.Window.Visible = False
If Scope = vbScopeAllProc Then
For i = 1 To .CountOfLines
strLine = .Lines(i, 1)
procName = .ProcOfLine(i, vbext_pk_Proc) ' Type d'argument ByRef incompatible ~~> Requires VBIDE library as a Reference for the VBA Project
If procName <> vbNullString Then
startOfProcedure = .ProcStartLine(procName, vbext_pk_Proc)
bodyOfProcedure = .ProcBodyLine(procName, vbext_pk_Proc)
countOfProcedure = .ProcCountLines(procName, vbext_pk_Proc)
prelinesOfProcedure = bodyOfProcedure - startOfProcedure
'postlineOfProcedure = ??? not directly available since endOfProcedure is itself not directly available.
lengthOfProcedure = countOfProcedure - prelinesOfProcedure ' includes postlinesOfProcedure !
'endOfProcedure = ??? not directly available, each line of the proc must be tested until the End statement is reached. See below.
If endOfProcedure <> 0 And startOfProcedure < endOfProcedure And i > endOfProcedure Then
GoTo NextLine
End If
If i = bodyOfProcedure Then InProcBodyLines = True
If bodyOfProcedure < i And i < startOfProcedure + countOfProcedure Then
If Not (.Lines(i - 1, 1) Like "* _") Then
InProcBodyLines = False
PreviousIndentAdded = 0
If Trim(strLine) = "" And Not AddLineNumbersToEmptyLines Then GoTo NextLine
If IsProcEndLine(wbName, vbCompName, i) Then
endOfProcedure = i
If AddLineNumbersToEndOfProc Then
Call IndentProcBodyLinesAsProcEndLine(wbName, vbCompName, LabelType, endOfProcedure)
Else
GoTo NextLine
End If
End If
If LabelType = vbLabelColon Then
If HasLabel(strLine, vbLabelColon) Then strLine = RemoveOneLineNumber(.Lines(i, 1), vbLabelColon)
If Not HasLabel(strLine, vbLabelColon) Then
temp_strLine = strLine
.ReplaceLine i, CStr(i) & ":" & strLine
new_strLine = .Lines(i, 1)
If Len(new_strLine) = Len(CStr(i) & ":" & temp_strLine) Then
PreviousIndentAdded = Len(CStr(i) & ":")
Else
PreviousIndentAdded = Len(CStr(i) & ": ")
End If
End If
ElseIf LabelType = vbLabelTab Then
If Not HasLabel(strLine, vbLabelTab) Then strLine = RemoveOneLineNumber(.Lines(i, 1), vbLabelTab)
If Not HasLabel(strLine, vbLabelColon) Then
temp_strLine = strLine
.ReplaceLine i, CStr(i) & vbTab & strLine
PreviousIndentAdded = Len(strLine) - Len(temp_strLine)
End If
End If
Else
If Not InProcBodyLines Then
If LabelType = vbLabelColon Then
.ReplaceLine i, Space(PreviousIndentAdded) & strLine
ElseIf LabelType = vbLabelTab Then
.ReplaceLine i, Space(4) & strLine
End If
Else
End If
End If
End If
End If
NextLine:
Next i
ElseIf AddLineNumbersToEmptyLines And Scope = vbScopeThisProc Then
End If
.CodePane.Window.Visible = True
End With
End Sub
Function IsProcEndLine(ByVal wbName As String, _
ByVal vbCompName As String, _
ByVal Line As Long) As Boolean
With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule
If Trim(.Lines(Line, 1)) Like "End Sub*" _
Or Trim(.Lines(Line, 1)) Like "End Function*" _
Or Trim(.Lines(Line, 1)) Like "End Property*" _
Then IsProcEndLine = True
End With
End Function
Sub IndentProcBodyLinesAsProcEndLine(ByVal wbName As String, ByVal vbCompName As String, ByVal LabelType As vbLineNumbers_LabelTypes, ByVal ProcEndLine As Long)
Dim procName As String
Dim startOfProcedure As Long
Dim endOfProcedure As Long
With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule
procName = .ProcOfLine(ProcEndLine, vbext_pk_Proc)
bodyOfProcedure = .ProcBodyLine(procName, vbext_pk_Proc)
endOfProcedure = ProcEndLine
strEnd = .Lines(endOfProcedure, 1)
j = bodyOfProcedure
Do Until Not .Lines(j - 1, 1) Like "* _" And j <> bodyOfProcedure
strLine = .Lines(j, 1)
If LabelType = vbLabelColon Then
If Mid(strEnd, Len(CStr(endOfProcedure)) + 1 + 1 + 1, 1) = " " Then
.ReplaceLine j, Space(Len(CStr(endOfProcedure)) + 1) & strLine
Else
.ReplaceLine j, Space(Len(CStr(endOfProcedure)) + 2) & strLine
End If
ElseIf LabelType = vbLabelTab Then
If endOfProcedure < 1000 Then
.ReplaceLine j, Space(4) & strLine
Else
Debug.Print "This tool is limited to 999 lines of code to work properly."
End If
End If
j = j + 1
Loop
End With
End Sub
Sub RemoveLineNumbers(ByVal wbName As String, ByVal vbCompName As String, ByVal LabelType As vbLineNumbers_LabelTypes)
Dim i As Long
With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule
For i = 1 To .CountOfLines
procName = .ProcOfLine(i, vbext_pk_Proc)
If procName <> vbNullString Then
If i = .ProcBodyLine(procName, vbext_pk_Proc) Then InProcBodyLines = True
LenghtBefore = Len(.Lines(i, 1))
If Not .Lines(i - 1, 1) Like "* _" Then
InProcBodyLines = False
.ReplaceLine i, RemoveOneLineNumber(.Lines(i, 1), LabelType)
Else
If IsInProcBodyLines Then
' do nothing
Else
.ReplaceLine i, Mid(.Lines(i, 1), RemovedChars_previous_i + 1)
End If
End If
LenghtAfter = Len(.Lines(i, 1))
LengthBefore_previous_i = LenghtBefore
LenghtAfter_previous_i = LenghtAfter
RemovedChars_previous_i = LengthBefore_previous_i - LenghtAfter_previous_i
If Trim(.Lines(i, 1)) Like "End Sub*" Or Trim(.Lines(i, 1)) Like "End Function" Or Trim(.Lines(i, 1)) Like "End Property" Then
LenOfRemovedLeadingCharacters = LenghtBefore - LenghtAfter
procName = .ProcOfLine(i, vbext_pk_Proc)
bodyOfProcedure = .ProcBodyLine(procName, vbext_pk_Proc)
j = bodyOfProcedure
strLineBodyOfProc = .Lines(bodyOfProcedure, 1)
Do Until Not strLineBodyOfProc Like "* _"
j = j + 1
strLineBodyOfProc = .Lines(j, 1)
Loop
LastLineBodyOfProc = j
strLastLineBodyOfProc = strLineBodyOfProc
strLineEndOfProc = .Lines(i, 1)
For k = bodyOfProcedure To j
.ReplaceLine k, Mid(.Lines(k, 1), 1 + LenOfRemovedLeadingCharacters)
Next k
i = i + (j - bodyOfProcedure)
GoTo NextLine
End If
Else
' GoTo NextLine
End If
NextLine:
Next i
End With
End Sub
Function RemoveOneLineNumber(ByVal aString As String, ByVal LabelType As vbLineNumbers_LabelTypes)
RemoveOneLineNumber = aString
If LabelType = vbLabelColon Then
If aString Like "#:*" Or aString Like "##:*" Or aString Like "###:*" Then
RemoveOneLineNumber = Mid(aString, 1 + InStr(1, aString, ":", vbTextCompare))
If Left(RemoveOneLineNumber, 2) Like " [! ]*" Then RemoveOneLineNumber = Mid(RemoveOneLineNumber, 2)
End If
ElseIf LabelType = vbLabelTab Then
If aString Like "# *" Or aString Like "## *" Or aString Like "### *" Then RemoveOneLineNumber = Mid(aString, 5)
If aString Like "#" Or aString Like "##" Or aString Like "###" Then RemoveOneLineNumber = ""
End If
End Function
Function HasLabel(ByVal aString As String, ByVal LabelType As vbLineNumbers_LabelTypes) As Boolean
If LabelType = vbLabelColon Then HasLabel = InStr(1, aString & ":", ":") < InStr(1, aString & " ", " ")
If LabelType = vbLabelTab Then
HasLabel = Mid(aString, 1, 4) Like "# " Or Mid(aString, 1, 4) Like "## " Or Mid(aString, 1, 4) Like "### "
End If
End Function
Function RemoveLeadingSpaces(ByVal aString As String) As String
Do Until Left(aString, 1) <> " "
aString = Mid(aString, 2)
Loop
RemoveLeadingSpaces = aString
End Function
Function WhatIsLineIndent(ByVal aString As String) As String
i = 1
Do Until Mid(aString, i, 1) <> " "
i = i + 1
Loop
WhatIsLineIndent = i
End Function
Function HowManyLeadingSpaces(ByVal aString As String) As String
HowManyLeadingSpaces = WhatIsLineIndent(aString) - 1
End Function
You can make calls like this :
您可以这样拨打电话:
Sub AddLineNumbers_vbLabelColon()
AddLineNumbers wbName:="EvaluateCall.xlsm", vbCompName:="ModLineNumbers_testDest", LabelType:=vbLabelColon, AddLineNumbersToEmptyLines:=True, AddLineNumbersToEndOfProc:=True, Scope:=vbScopeAllProc
End Sub
Sub AddLineNumbers_vbLabelTab()
AddLineNumbers wbName:="EvaluateCall.xlsm", vbCompName:="ModLineNumbers_testDest", LabelType:=vbLabelTab, AddLineNumbersToEmptyLines:=True, AddLineNumbersToEndOfProc:=True, Scope:=vbScopeAllProc
End Sub
Sub RemoveLineNumbers_vbLabelColon()
RemoveLineNumbers wbName:="EvaluateCall.xlsm", vbCompName:="ModLineNumbers_testDest", LabelType:=vbLabelColon
End Sub
Sub RemoveLineNumbers_vbLabelTab()
RemoveLineNumbers wbName:="EvaluateCall.xlsm", vbCompName:="ModLineNumbers_testDest", LabelType:=vbLabelTab
End Sub
And as a reminder, here as some compile rules about about line numbers:
提醒一下,这里有一些关于行号的编译规则:
- not allowed before a Sub/Function declaration statement
- not allowed outside of a proc
- not allowed on a line following a line continuation character "_" (underscore)
- not allowed to have more than one label/line number per code line ~~> Existing labels other than line numbers must be tested otherwise a compile error will occur trying to force a line number.
- not allowed to use characters that already have a special VBA meaning ~~> Allowed characters are [a-Z], [0-9], é, è, ?, ù, , £, § and even ":" alone !
- compiler will trim any space before a label ~~> So if there is a label, the first char of the line is the first char of the label, it cannot be a space.
- appending a line number with a colon will result in having a space inserted between the ":" and the fist next char if there is none
- when appending a line number with a tab/space, there must be at least one space between the last digit and the first next char, compiler won't add it as it does for a label with a colon separator
- the .ReplaceLine method will overide the compile rules without displaying any compile error as it does in design mode when selecting a new line or when manually relaunching compilation
- the compiler is 'quicker than the VBA environment/system': for example, just after a line number with colon and without any space has been inserted with .ReplaceLine, if the .Lines property is called to get the new string, the space (between the colon character and the first character of the string) is already appended in that string !
- it is not possible to enter debug mode after a .ReplaceLine has been called (from within or outside the module it is editting), not till the code is running, and execution reset.
- 不允许在 Sub/Function 声明语句之前
- 不允许在 proc 之外
- 不允许在行继续符“_”(下划线)之后的行中
- 每个代码行不允许有多个标签/行号~~> 必须测试除行号以外的现有标签,否则在尝试强制行号时会发生编译错误。
- 不允许使用已经具有特殊 VBA 含义的字符~~> 允许使用的字符有 [aZ]、[0-9]、é、è、?、ù、 、£、§ 甚至“:”!
- 编译器会修剪标签前的任何空格~~> 所以如果有标签,那一行的第一个字符就是标签的第一个字符,不能是空格。
- 用冒号附加行号将导致在“:”和第一个下一个字符之间插入一个空格,如果没有
- 使用制表符/空格附加行号时,最后一位数字和下一个字符之间必须至少有一个空格,编译器不会像添加冒号分隔符的标签那样添加它
- .ReplaceLine 方法将覆盖编译规则,而不会像在设计模式下选择新行或手动重新启动编译时那样显示任何编译错误
- 编译器“比 VBA 环境/系统更快”:例如,在用 .ReplaceLine 插入带冒号且没有任何空格的行号之后,如果调用 .Lines 属性来获取新字符串,则空格(在冒号字符和字符串的第一个字符之间)已附加到该字符串中!
- 在 .ReplaceLine 被调用(从它正在编辑的模块内部或外部)之后,不可能进入调试模式,直到代码运行,并且执行重置。
回答by a.t.
Short answerfor excel 2016, have not tried it in 2013 yet.
excel 2016 的简短回答,2013 年还没有尝试过。
Do Once:
做一次:
- Paste the large code from final
Module2in this answer in your workbook. - Paste the code for final
Module3in this answer, in your workbook. - Paste the code for final
Module4in this answer, in your workbook. - Then paste the line
Global allow_for_line_addition As Stringthis is just so that you can automatically add linenumbers` above/in the first line of every module. - Delete all empty lines at the end of each module (so no lose enters after the last
end sub,end functionorEnd Propertyof a module). - In the VBA editor, while not running a code, and not being in "break"-mode:click tools>references>mark: `Microsoft Visual Basic for Applications Extensibility 5.3"
- 将最终
Module2答案中的大代码粘贴到您的工作簿中。 - 将此答案中的final代码粘贴到
Module3您的工作簿中。 - 将此答案中的final代码粘贴到
Module4您的工作簿中。 - 然后粘贴这行
Global allow_for_line_addition As String,这样您就可以自动在每个模块的第一行上方/中添加 linenumbers`。 - 删除在每个模块的端部的所有空行(后最后所以没有输进入
end sub,end function或者End Property一个模块的)。 - 在 VBA 编辑器中,在未运行代码且未处于“中断”模式时:单击工具>参考>标记:`Microsoft Visual Basic for Applications Extensibility 5.3"
Do every time you have modified your code:
每次修改代码时都执行以下操作:
- *Run the code for final
Module3to remove line numbers to all the modules in your workbook. - *Run the code for final
Module4to add line numbers to all the modules in your workbook.
- *运行final的代码
Module3以删除工作簿中所有模块的行号。 - * 运行final代码
Module4以将行号添加到工作簿中的所有模块。
(*because sometimes you get an error if you cut lines out or move them around (e.g. put line 2440:above line 2303:). By removing and re-adding them, the line numbering is automatically correct again)
(*因为有时如果你剪掉或移动它们(例如放在line 2440:上面line 2303:),你会得到一个错误。通过删除和重新添加它们,行号会自动再次正确)
Long answer(including learning steps and attempts) - to me it was not straightforward to implement hymced`s answer, so I documented the steps necessary to add line numbers to a module in the VBA code editor (*and remove them again). I followed the following steps to get it working.
长答案(包括学习步骤和尝试) - 对我来说,实现 hymced 的答案并不简单,所以我记录了在 VBA 代码编辑器中向模块添加行号所需的步骤(*并再次删除它们)。我按照以下步骤使其工作。
- From this linkI have learned that a vbcomponent can be a module.
- I Copyied the first code given, into temporary
Module2, and the second code given by hymced into temporaryModule3. Then modified the first line of the 2nd code in temporary
Module3to:AddLineNumbers wbName:="Book1.xlsm", vbCompName:="Module1", LabelType:=vbLabelColon, AddLineNumbersToEmptyLines:=True, AddLineNumbersToEndOfProc:=True, Scope:=vbScopeAllProcI got an error at line:
procName = .ProcOfLine(i, vbext_pk_Proc) ` Type d`argument ByRef incompatible ~~> Requires VBIDE library as a Reference for the VBA ProjectSo I read I had to enable the VBIDE library.
So I stopped the code, clicked tools>references, and could not find the VBIDE library.
On this forumI found the VBIDE is enabled by adding a reference to the VBA extensibility library:
- 从这个链接我了解到 vbcomponent 可以是一个模块。
- 我Copyied给出的,成第一编码临时
Module2和hymced到由给定的所述第二代码临时Module3。 然后临时修改第二行代码的第一行
Module3:AddLineNumbers wbName:="Book1.xlsm", vbCompName:="Module1", LabelType:=vbLabelColon, AddLineNumbersToEmptyLines:=True, AddLineNumbersToEndOfProc:=True, Scope:=vbScopeAllProc我在行中遇到错误:
procName = .ProcOfLine(i, vbext_pk_Proc) ` Type d`argument ByRef incompatible ~~> Requires VBIDE library as a Reference for the VBA Project所以我读到我必须启用 VBIDE 库。
于是我把代码停了下来,点击工具>引用,找不到VBIDE库。
在这个论坛上,我发现通过添加对 VBA 扩展库的引用来启用 VBIDE:
Click on Tools-References in the VBE, and scroll down and tick the entry for Microsoft Visual Basic for Applications Extensibility 5.3.
单击 VBE 中的 Tools-References,向下滚动并勾选 Microsoft Visual Basic for Applications Extensibility 5.3 条目。
So after doing that the first error disapeared and it did not highlight any line but gave the it gave the error "Invalid procedure call or argument".
因此,在这样做之后,第一个错误消失了,它没有突出显示任何行,而是给出了错误“过程调用或参数无效”。
Since I am still not sure about the vbCompName, I thought it might need to know the sub in stead of the module so I tried to modify the 2nd code in temporary
Module3to:AddLineNumbers wbName:="Book1.xlsm", vbCompName:="learn", LabelType:=vbLabelColon, AddLineNumbersToEmptyLines:=True, AddLineNumbersToEndOfProc:=True, Scope:=vbScopeAllProcThat highlighted the line:
With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule
由于我仍然不确定 vbCompName,我认为它可能需要知道 sub 而不是模块,所以我尝试将第二个代码临时修改
Module3为:AddLineNumbers wbName:="Book1.xlsm", vbCompName:="learn", LabelType:=vbLabelColon, AddLineNumbersToEmptyLines:=True, AddLineNumbersToEndOfProc:=True, Scope:=vbScopeAllProc这突出了这一行:
With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule
saying: subscript out of range. (So I also tried: Module1.learnand Module1:learn, yielding the subscript out of range-error.
说:subscript out of range。(所以我也试过:Module1.learnand Module1:learn,产生subscript out of range-error.
As it turns out,
事实证明,
AddLineNumbers wbName:="Book1.xlsm", vbCompName:="Module1", LabelType:=vbLabelColon, AddLineNumbersToEmptyLines:=True, AddLineNumbersToEndOfProc:=True, Scope:=vbScopeAllProc
is the right way to call the replacing sub if the sub you want to provide with line numbers is located in a module named Module1. The first error describes occurs, but it does add the line numbers to the code (except for first line containing sub ...and the last line containing end sub.Tested in Module1named sub learn()of the excel 2016 workbook named Book1.xlsm. For completeness learnconsists of:
如果您要提供行号的 sub 位于名为Module1. 第一个错误描述发生,但它确实将行号添加到代码中(除了第一行包含sub ...和最后一行包含end sub.Tested in Module1namedsub learn()的 excel 2016 工作簿名为Book1.xlsm。完整性learn包括:
Sub learn()
ThisWorkbook.Worksheets("Sheet1").Activate
Range("A1").Activate
Range("A1").Select
Range("A1").Value = Range("A1").Value + 1
End Sub
However, on the way back, removing the line numbers, it yielded an error because it asks .lines(0,1) of procNamein Sub AddLineNumbers...
然而,在返回的路上,删除行号,它产生了一个错误,因为它要求 .lines(0,1) of procNameinSub AddLineNumbers...
So I modified it to exclude the .lines(0,1) by putting the changed code below into final
Module2:Public Enum vbLineNumbers_LabelTypes vbLabelColon ' 0 vbLabelTab ' 1 End Enum Public Enum vbLineNumbers_ScopeToAddLineNumbersTo vbScopeAllProc ' 1 vbScopeThisProc ' 2 End Enum Sub AddLineNumbers(ByVal wbName As String, _ ByVal vbCompName As String, _ ByVal LabelType As vbLineNumbers_LabelTypes, _ ByVal AddLineNumbersToEmptyLines As Boolean, _ ByVal AddLineNumbersToEndOfProc As Boolean, _ ByVal Scope As vbLineNumbers_ScopeToAddLineNumbersTo, _ Optional ByVal thisProcName As String) ' USAGE RULES ' DO NOT MIX LABEL TYPES FOR LINE NUMBERS! IF ADDING LINE NUMBERS AS COLON TYPE, ANY LINE NUMBERS AS VBTAB TYPE MUST BE REMOVE BEFORE, AND RECIPROCALLY ADDING LINE NUMBERS AS VBTAB TYPE Dim i As Long Dim j As Long Dim procName As String Dim startOfProcedure As Long Dim lengthOfProcedure As Long Dim endOfProcedure As Long Dim strLine As String With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule .CodePane.Window.Visible = False If Scope = vbScopeAllProc Then For i = 1 To .CountOfLines - 1 strLine = .Lines(i, 1) procName = .ProcOfLine(i, vbext_pk_Proc) ' Type d'argument ByRef incompatible ~~> Requires VBIDE library as a Reference for the VBA Project If procName <> vbNullString Then startOfProcedure = .ProcStartLine(procName, vbext_pk_Proc) bodyOfProcedure = .ProcBodyLine(procName, vbext_pk_Proc) countOfProcedure = .ProcCountLines(procName, vbext_pk_Proc) prelinesOfProcedure = bodyOfProcedure - startOfProcedure 'postlineOfProcedure = ??? not directly available since endOfProcedure is itself not directly available. lengthOfProcedure = countOfProcedure - prelinesOfProcedure ' includes postlinesOfProcedure ! 'endOfProcedure = ??? not directly available, each line of the proc must be tested until the End statement is reached. See below. If endOfProcedure <> 0 And startOfProcedure < endOfProcedure And i > endOfProcedure Then GoTo NextLine End If If i = bodyOfProcedure Then inprocbodylines = True If bodyOfProcedure < i And i < startOfProcedure + countOfProcedure Then If Not (.Lines(i - 1, 1) Like "* _") Then inprocbodylines = False PreviousIndentAdded = 0 If Trim(strLine) = "" And Not AddLineNumbersToEmptyLines Then GoTo NextLine If IsProcEndLine(wbName, vbCompName, i) Then endOfProcedure = i If AddLineNumbersToEndOfProc Then Call IndentProcBodyLinesAsProcEndLine(wbName, vbCompName, LabelType, endOfProcedure) Else GoTo NextLine End If End If If LabelType = vbLabelColon Then If HasLabel(strLine, vbLabelColon) Then strLine = RemoveOneLineNumber(.Lines(i, 1), vbLabelColon) If Not HasLabel(strLine, vbLabelColon) Then temp_strLine = strLine .ReplaceLine i, CStr(i) & ":" & strLine new_strLine = .Lines(i, 1) If Len(new_strLine) = Len(CStr(i) & ":" & temp_strLine) Then PreviousIndentAdded = Len(CStr(i) & ":") Else PreviousIndentAdded = Len(CStr(i) & ": ") End If End If ElseIf LabelType = vbLabelTab Then If Not HasLabel(strLine, vbLabelTab) Then strLine = RemoveOneLineNumber(.Lines(i, 1), vbLabelTab) If Not HasLabel(strLine, vbLabelColon) Then temp_strLine = strLine .ReplaceLine i, CStr(i) & vbTab & strLine PreviousIndentAdded = Len(strLine) - Len(temp_strLine) End If End If Else If Not inprocbodylines Then If LabelType = vbLabelColon Then .ReplaceLine i, Space(PreviousIndentAdded) & strLine ElseIf LabelType = vbLabelTab Then .ReplaceLine i, Space(4) & strLine End If Else End If End If End If End If NextLine: Next i ElseIf AddLineNumbersToEmptyLines And Scope = vbScopeThisProc Then End If .CodePane.Window.Visible = True End With End Sub Function IsProcEndLine(ByVal wbName As String, _ ByVal vbCompName As String, _ ByVal Line As Long) As Boolean With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule If Trim(.Lines(Line, 1)) Like "End Sub*" _ Or Trim(.Lines(Line, 1)) Like "End Function*" _ Or Trim(.Lines(Line, 1)) Like "End Property*" _ Then IsProcEndLine = True End With End Function Sub IndentProcBodyLinesAsProcEndLine(ByVal wbName As String, ByVal vbCompName As String, ByVal LabelType As vbLineNumbers_LabelTypes, ByVal ProcEndLine As Long) Dim procName As String Dim startOfProcedure As Long Dim endOfProcedure As Long With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule procName = .ProcOfLine(ProcEndLine, vbext_pk_Proc) bodyOfProcedure = .ProcBodyLine(procName, vbext_pk_Proc) endOfProcedure = ProcEndLine strEnd = .Lines(endOfProcedure, 1) j = bodyOfProcedure Do Until Not .Lines(j - 1, 1) Like "* _" And j <> bodyOfProcedure strLine = .Lines(j, 1) If LabelType = vbLabelColon Then If Mid(strEnd, Len(CStr(endOfProcedure)) + 1 + 1 + 1, 1) = " " Then .ReplaceLine j, Space(Len(CStr(endOfProcedure)) + 1) & strLine Else .ReplaceLine j, Space(Len(CStr(endOfProcedure)) + 2) & strLine End If ElseIf LabelType = vbLabelTab Then If endOfProcedure < 1000 Then .ReplaceLine j, Space(4) & strLine Else Debug.Print "This tool is limited to 999 lines of code to work properly." End If End If j = j + 1 Loop End With End Sub Sub RemoveLineNumbers(ByVal wbName As String, ByVal vbCompName As String, ByVal LabelType As vbLineNumbers_LabelTypes) Dim i As Long With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule 'MsgBox ("nr of lines = " & .CountOfLines & vbNewLine & "Procname = " & procName) 'MsgBox ("nr of lines REMEMBER MUST BE LARGER THAN 7! = " & .CountOfLines) For i = 1 To .CountOfLines procName = .ProcOfLine(i, vbext_pk_Proc) If procName <> vbNullString Then If i > 1 Then 'MsgBox ("Line " & i & " is a body line " & .ProcBodyLine(procName, vbext_pk_Proc)) If i = .ProcBodyLine(procName, vbext_pk_Proc) Then inprocbodylines = True If .Lines(i - 1, 1) <> "" Then 'MsgBox (.Lines(i - 1, 1)) End If If Not .Lines(i - 1, 1) Like "* _" Then 'MsgBox (inprocbodylines) inprocbodylines = False 'MsgBox ("recoginized a line that should be substituted: " & i) 'MsgBox ("about to replace " & .Lines(i, 1) & vbNewLine & " with: " & RemoveOneLineNumber(.Lines(i, 1), LabelType) & vbNewLine & " with label type: " & LabelType) .ReplaceLine i, RemoveOneLineNumber(.Lines(i, 1), LabelType) Else If IsInProcBodyLines Then ' do nothing 'MsgBox (i) Else .ReplaceLine i, Mid(.Lines(i, 1), RemovedChars_previous_i + 1) End If End If End If Else ' GoTo NextLine End If NextLine: Next i End With End Sub Function RemoveOneLineNumber(ByVal aString As String, ByVal LabelType As vbLineNumbers_LabelTypes) RemoveOneLineNumber = aString If LabelType = vbLabelColon Then If aString Like "#:*" Or aString Like "##:*" Or aString Like "###:*" Or aString Like "####:*" Then RemoveOneLineNumber = Mid(aString, 1 + InStr(1, aString, ":", vbTextCompare)) If Left(RemoveOneLineNumber, 2) Like " [! ]*" Then RemoveOneLineNumber = Mid(RemoveOneLineNumber, 2) End If ElseIf LabelType = vbLabelTab Then If aString Like "# *" Or aString Like "## *" Or aString Like "### *" Or aString Like "#### *" Then RemoveOneLineNumber = Mid(aString, 5) If aString Like "#" Or aString Like "##" Or aString Like "###" Or aString Like "####" Then RemoveOneLineNumber = "" End If End Function Function HasLabel(ByVal aString As String, ByVal LabelType As vbLineNumbers_LabelTypes) As Boolean If LabelType = vbLabelColon Then HasLabel = InStr(1, aString & ":", ":") < InStr(1, aString & " ", " ") If LabelType = vbLabelTab Then HasLabel = Mid(aString, 1, 4) Like "# " Or Mid(aString, 1, 4) Like "## " Or Mid(aString, 1, 4) Like "### " Or Mid(aString, 1, 5) Like "#### " End If End Function Function RemoveLeadingSpaces(ByVal aString As String) As String Do Until Left(aString, 1) <> " " aString = Mid(aString, 2) Loop RemoveLeadingSpaces = aString End Function Function WhatIsLineIndent(ByVal aString As String) As String i = 1 Do Until Mid(aString, i, 1) <> " " i = i + 1 Loop WhatIsLineIndent = i End Function Function HowManyLeadingSpaces(ByVal aString As String) As String HowManyLeadingSpaces = WhatIsLineIndent(aString) - 1 End Function
所以我修改它以通过将下面更改的代码放入final来排除 .lines(0,1)
Module2:Public Enum vbLineNumbers_LabelTypes vbLabelColon ' 0 vbLabelTab ' 1 End Enum Public Enum vbLineNumbers_ScopeToAddLineNumbersTo vbScopeAllProc ' 1 vbScopeThisProc ' 2 End Enum Sub AddLineNumbers(ByVal wbName As String, _ ByVal vbCompName As String, _ ByVal LabelType As vbLineNumbers_LabelTypes, _ ByVal AddLineNumbersToEmptyLines As Boolean, _ ByVal AddLineNumbersToEndOfProc As Boolean, _ ByVal Scope As vbLineNumbers_ScopeToAddLineNumbersTo, _ Optional ByVal thisProcName As String) ' USAGE RULES ' DO NOT MIX LABEL TYPES FOR LINE NUMBERS! IF ADDING LINE NUMBERS AS COLON TYPE, ANY LINE NUMBERS AS VBTAB TYPE MUST BE REMOVE BEFORE, AND RECIPROCALLY ADDING LINE NUMBERS AS VBTAB TYPE Dim i As Long Dim j As Long Dim procName As String Dim startOfProcedure As Long Dim lengthOfProcedure As Long Dim endOfProcedure As Long Dim strLine As String With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule .CodePane.Window.Visible = False If Scope = vbScopeAllProc Then For i = 1 To .CountOfLines - 1 strLine = .Lines(i, 1) procName = .ProcOfLine(i, vbext_pk_Proc) ' Type d'argument ByRef incompatible ~~> Requires VBIDE library as a Reference for the VBA Project If procName <> vbNullString Then startOfProcedure = .ProcStartLine(procName, vbext_pk_Proc) bodyOfProcedure = .ProcBodyLine(procName, vbext_pk_Proc) countOfProcedure = .ProcCountLines(procName, vbext_pk_Proc) prelinesOfProcedure = bodyOfProcedure - startOfProcedure 'postlineOfProcedure = ??? not directly available since endOfProcedure is itself not directly available. lengthOfProcedure = countOfProcedure - prelinesOfProcedure ' includes postlinesOfProcedure ! 'endOfProcedure = ??? not directly available, each line of the proc must be tested until the End statement is reached. See below. If endOfProcedure <> 0 And startOfProcedure < endOfProcedure And i > endOfProcedure Then GoTo NextLine End If If i = bodyOfProcedure Then inprocbodylines = True If bodyOfProcedure < i And i < startOfProcedure + countOfProcedure Then If Not (.Lines(i - 1, 1) Like "* _") Then inprocbodylines = False PreviousIndentAdded = 0 If Trim(strLine) = "" And Not AddLineNumbersToEmptyLines Then GoTo NextLine If IsProcEndLine(wbName, vbCompName, i) Then endOfProcedure = i If AddLineNumbersToEndOfProc Then Call IndentProcBodyLinesAsProcEndLine(wbName, vbCompName, LabelType, endOfProcedure) Else GoTo NextLine End If End If If LabelType = vbLabelColon Then If HasLabel(strLine, vbLabelColon) Then strLine = RemoveOneLineNumber(.Lines(i, 1), vbLabelColon) If Not HasLabel(strLine, vbLabelColon) Then temp_strLine = strLine .ReplaceLine i, CStr(i) & ":" & strLine new_strLine = .Lines(i, 1) If Len(new_strLine) = Len(CStr(i) & ":" & temp_strLine) Then PreviousIndentAdded = Len(CStr(i) & ":") Else PreviousIndentAdded = Len(CStr(i) & ": ") End If End If ElseIf LabelType = vbLabelTab Then If Not HasLabel(strLine, vbLabelTab) Then strLine = RemoveOneLineNumber(.Lines(i, 1), vbLabelTab) If Not HasLabel(strLine, vbLabelColon) Then temp_strLine = strLine .ReplaceLine i, CStr(i) & vbTab & strLine PreviousIndentAdded = Len(strLine) - Len(temp_strLine) End If End If Else If Not inprocbodylines Then If LabelType = vbLabelColon Then .ReplaceLine i, Space(PreviousIndentAdded) & strLine ElseIf LabelType = vbLabelTab Then .ReplaceLine i, Space(4) & strLine End If Else End If End If End If End If NextLine: Next i ElseIf AddLineNumbersToEmptyLines And Scope = vbScopeThisProc Then End If .CodePane.Window.Visible = True End With End Sub Function IsProcEndLine(ByVal wbName As String, _ ByVal vbCompName As String, _ ByVal Line As Long) As Boolean With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule If Trim(.Lines(Line, 1)) Like "End Sub*" _ Or Trim(.Lines(Line, 1)) Like "End Function*" _ Or Trim(.Lines(Line, 1)) Like "End Property*" _ Then IsProcEndLine = True End With End Function Sub IndentProcBodyLinesAsProcEndLine(ByVal wbName As String, ByVal vbCompName As String, ByVal LabelType As vbLineNumbers_LabelTypes, ByVal ProcEndLine As Long) Dim procName As String Dim startOfProcedure As Long Dim endOfProcedure As Long With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule procName = .ProcOfLine(ProcEndLine, vbext_pk_Proc) bodyOfProcedure = .ProcBodyLine(procName, vbext_pk_Proc) endOfProcedure = ProcEndLine strEnd = .Lines(endOfProcedure, 1) j = bodyOfProcedure Do Until Not .Lines(j - 1, 1) Like "* _" And j <> bodyOfProcedure strLine = .Lines(j, 1) If LabelType = vbLabelColon Then If Mid(strEnd, Len(CStr(endOfProcedure)) + 1 + 1 + 1, 1) = " " Then .ReplaceLine j, Space(Len(CStr(endOfProcedure)) + 1) & strLine Else .ReplaceLine j, Space(Len(CStr(endOfProcedure)) + 2) & strLine End If ElseIf LabelType = vbLabelTab Then If endOfProcedure < 1000 Then .ReplaceLine j, Space(4) & strLine Else Debug.Print "This tool is limited to 999 lines of code to work properly." End If End If j = j + 1 Loop End With End Sub Sub RemoveLineNumbers(ByVal wbName As String, ByVal vbCompName As String, ByVal LabelType As vbLineNumbers_LabelTypes) Dim i As Long With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule 'MsgBox ("nr of lines = " & .CountOfLines & vbNewLine & "Procname = " & procName) 'MsgBox ("nr of lines REMEMBER MUST BE LARGER THAN 7! = " & .CountOfLines) For i = 1 To .CountOfLines procName = .ProcOfLine(i, vbext_pk_Proc) If procName <> vbNullString Then If i > 1 Then 'MsgBox ("Line " & i & " is a body line " & .ProcBodyLine(procName, vbext_pk_Proc)) If i = .ProcBodyLine(procName, vbext_pk_Proc) Then inprocbodylines = True If .Lines(i - 1, 1) <> "" Then 'MsgBox (.Lines(i - 1, 1)) End If If Not .Lines(i - 1, 1) Like "* _" Then 'MsgBox (inprocbodylines) inprocbodylines = False 'MsgBox ("recoginized a line that should be substituted: " & i) 'MsgBox ("about to replace " & .Lines(i, 1) & vbNewLine & " with: " & RemoveOneLineNumber(.Lines(i, 1), LabelType) & vbNewLine & " with label type: " & LabelType) .ReplaceLine i, RemoveOneLineNumber(.Lines(i, 1), LabelType) Else If IsInProcBodyLines Then ' do nothing 'MsgBox (i) Else .ReplaceLine i, Mid(.Lines(i, 1), RemovedChars_previous_i + 1) End If End If End If Else ' GoTo NextLine End If NextLine: Next i End With End Sub Function RemoveOneLineNumber(ByVal aString As String, ByVal LabelType As vbLineNumbers_LabelTypes) RemoveOneLineNumber = aString If LabelType = vbLabelColon Then If aString Like "#:*" Or aString Like "##:*" Or aString Like "###:*" Or aString Like "####:*" Then RemoveOneLineNumber = Mid(aString, 1 + InStr(1, aString, ":", vbTextCompare)) If Left(RemoveOneLineNumber, 2) Like " [! ]*" Then RemoveOneLineNumber = Mid(RemoveOneLineNumber, 2) End If ElseIf LabelType = vbLabelTab Then If aString Like "# *" Or aString Like "## *" Or aString Like "### *" Or aString Like "#### *" Then RemoveOneLineNumber = Mid(aString, 5) If aString Like "#" Or aString Like "##" Or aString Like "###" Or aString Like "####" Then RemoveOneLineNumber = "" End If End Function Function HasLabel(ByVal aString As String, ByVal LabelType As vbLineNumbers_LabelTypes) As Boolean If LabelType = vbLabelColon Then HasLabel = InStr(1, aString & ":", ":") < InStr(1, aString & " ", " ") If LabelType = vbLabelTab Then HasLabel = Mid(aString, 1, 4) Like "# " Or Mid(aString, 1, 4) Like "## " Or Mid(aString, 1, 4) Like "### " Or Mid(aString, 1, 5) Like "#### " End If End Function Function RemoveLeadingSpaces(ByVal aString As String) As String Do Until Left(aString, 1) <> " " aString = Mid(aString, 2) Loop RemoveLeadingSpaces = aString End Function Function WhatIsLineIndent(ByVal aString As String) As String i = 1 Do Until Mid(aString, i, 1) <> " " i = i + 1 Loop WhatIsLineIndent = i End Function Function HowManyLeadingSpaces(ByVal aString As String) As String HowManyLeadingSpaces = WhatIsLineIndent(aString) - 1 End Function
With calling the replacement on sub learn()with the code below, pasted in temporarymodule3:
使用sub learn()下面的代码调用替换,粘贴到临时module3:
Sub AddLineNumbers_vbLabelColon()
AddLineNumbers wbName:="Book1.xlsm", vbCompName:="Module1", LabelType:=vbLabelColon, AddLineNumbersToEmptyLines:=True, AddLineNumbersToEndOfProc:=True, Scope:=vbscopeallproc
End Sub
Sub AddLineNumbers_vbLabelTab()
AddLineNumbers wbName:="Book1.xlsm", vbCompName:="Module1", LabelType:=vbLabelTab, AddLineNumbersToEmptyLines:=True, AddLineNumbersToEndOfProc:=True, Scope:=vbscopeallproc
End Sub
Sub RemoveLineNumbers_vbLabelColon()
RemoveLineNumbers wbName:="Book1.xlsm", vbCompName:="Module1", LabelType:=vbLabelColon
End Sub
Sub RemoveLineNumbers_vbLabelTab()
RemoveLineNumbers wbName:="Book1.xlsm", vbCompName:="Module1", LabelType:=vbLabelTab
End Sub
Now it worked (both adding and removing line numbers, with all 4 methods of calling the adding/removal of line numbers pasted in temporarymodule2for a single sub in a module (module1in the example case). So I tried to put 2 subs behind eachother in the same module. In that case, the code did not change the add line numbers to the 2nd sub.
现在它起作用了(添加和删除行号,所有 4 种调用添加/删除行号的方法都为模块中的单个子临时粘贴了行号module2(module1在示例情况下)。所以我尝试将 2 个子放在彼此后面在同一个模块中。在那种情况下,代码没有将添加行号更改为第二个子项。
So I added the following line above
Module1:Global allow_for_line_addition As String
所以我在上面添加了以下行
Module1:Global allow_for_line_addition As String
Making Module1look like:
制作Module1看起来像:
Global allow_for_line_addition As String
Sub learn()
ThisWorkbook.Worksheets("Sheet1").Activate
Range("A1").Activate
Range("A1").Select
Range("A1").Value = Range("A1").Value + 1
End Sub
Sub learn2()
ThisWorkbook.Worksheets("Sheet1").Activate
Range("A1").Activate
Range("A1").Select
Range("A1").Value = Range("A1").Value + 1
End Sub
Now it added the line numbers to the entire module, but it did not remove the line numbers from the entire module, so I edited the removal code of hymceds answer as well and already put it in the long code of **final**Module2`.
现在它给整个模块添加了行号,但是并没有从整个模块中删除行号,所以我编辑了hymced s answer as well and already put it in the long code of **final**Module2`的删除代码。
Note: If you have empty white lines after the end of a sub or function, it will keep on adding white lines every time you run the script to add the line numbers (which after the first run, simply updates the line numbers). These empty line numbers cause an error when executing the code, so you should remove them once. If there are no empty lines at the end of a sub, this code will also not add new ones.
注意:如果在 sub 或 function 结束后有空的白线,则每次运行脚本以添加行号时,它都会继续添加白线(在第一次运行后,只需更新行号)。这些空行号在执行代码时会导致错误,因此您应该将它们删除一次。如果 sub 末尾没有空行,此代码也不会添加新行。
To add line numbers to all of your modules in your workbook, keep the long code in final
Module2as I modified it and replace the code of temporaryModule3with finalModule3:Global allow_for_line_addition As String 'this is just so that you can automatically add linenumbers Sub remove_line_numbering_all_modules() 'source: https://stackoverflow.com/questions/36791473/vba-getting-the-modules-in-workbook 'This code numbers all the modules in your .xlsm Dim vbcomp As VBComponent Dim modules As Collection Set modules = New Collection For Each vbcomp In ThisWorkbook.VBProject.VBComponents 'if normal or class module If ((vbcomp.Type = vbext_ct_StdModule) Or (vbcomp.Type = vbext_ct_ClassModule)) Then 'V0: RemoveLineNumbers wbName:=ThisWorkbook.name, vbCompName:=vbcomp.name, LabelType:=vbLabelColon 'V1: 'Call RemoveLineNumbers(ThisWorkbook.name, vbcomp.name) End If Next vbcomp End SubAnd add the following code to final
Module4:Global allow_for_line_addition As String 'this is just so that you can automatically add linenumbers 'This sub adds line numbers to all the modules after you have added the following line to every module 'add tools references microsoft visual basic for applications (5.3) as checked 'Source httpsstackoverflow.comquestions40731182excel-vba-how-to-turn-on-line-numbers-in-code-editor50368332#50368332 Sub add_line_numbering_all_modules() 'source: https://www.stackoverflow.com/questions/36791473/vba-getting-the-modules-in-workbook 'This code numbers all the modules in your .xlsm Dim vbcomp As VBComponent Dim modules As Collection Set modules = New Collection For Each vbcomp In ThisWorkbook.VBProject.VBComponents 'if normal or class module If ((vbcomp.Type = vbext_ct_StdModule) Or (vbcomp.Type = vbext_ct_ClassModule)) Then 'V0: Call AddLineNumbers(ThisWorkbook.name, vbcomp.name, vbLabelColon, True, True, vbScopeAllProc) 'v1 'Call AddLineNumbers(ThisWorkbook.name, vbcomp.name) End If Next vbcomp End Sub
要添加行号到所有模块的工作簿,保持长码在最后
Module2,我修改了它和替换的代码临时Module3与最后Module3:Global allow_for_line_addition As String 'this is just so that you can automatically add linenumbers Sub remove_line_numbering_all_modules() 'source: https://stackoverflow.com/questions/36791473/vba-getting-the-modules-in-workbook 'This code numbers all the modules in your .xlsm Dim vbcomp As VBComponent Dim modules As Collection Set modules = New Collection For Each vbcomp In ThisWorkbook.VBProject.VBComponents 'if normal or class module If ((vbcomp.Type = vbext_ct_StdModule) Or (vbcomp.Type = vbext_ct_ClassModule)) Then 'V0: RemoveLineNumbers wbName:=ThisWorkbook.name, vbCompName:=vbcomp.name, LabelType:=vbLabelColon 'V1: 'Call RemoveLineNumbers(ThisWorkbook.name, vbcomp.name) End If Next vbcomp End Sub并将以下代码添加到final
Module4:Global allow_for_line_addition As String 'this is just so that you can automatically add linenumbers 'This sub adds line numbers to all the modules after you have added the following line to every module 'add tools references microsoft visual basic for applications (5.3) as checked 'Source httpsstackoverflow.comquestions40731182excel-vba-how-to-turn-on-line-numbers-in-code-editor50368332#50368332 Sub add_line_numbering_all_modules() 'source: https://www.stackoverflow.com/questions/36791473/vba-getting-the-modules-in-workbook 'This code numbers all the modules in your .xlsm Dim vbcomp As VBComponent Dim modules As Collection Set modules = New Collection For Each vbcomp In ThisWorkbook.VBProject.VBComponents 'if normal or class module If ((vbcomp.Type = vbext_ct_StdModule) Or (vbcomp.Type = vbext_ct_ClassModule)) Then 'V0: Call AddLineNumbers(ThisWorkbook.name, vbcomp.name, vbLabelColon, True, True, vbScopeAllProc) 'v1 'Call AddLineNumbers(ThisWorkbook.name, vbcomp.name) End If Next vbcomp End Sub
where you can either substitute "Book1.xlsm"with the name of your own workbook, or with thisworkbook(notice no ""), or vice versa.
您可以"Book1.xlsm"用您自己的工作簿的名称替换,或者用thisworkbook(注意没有“”)替换,反之亦然。

