出于调试原因,我希望在我的VBA代码中包含行号。这将使我知道发生特定错误的位置。
是否有自动功能(例如设置中的选项)?或者我需要编写自己的宏吗?
如果我需要编写自己的宏来完成这项任务,我该如何做这样的事情呢?
答案 0 :(得分:14)
不是"调试原因",不是为了什么。行号被弃用是因为:在程序存在之前,它们是古代的遗物,而GOTO
是获得任何地方的唯一途径。
Erl
仅在引发错误之前返回上次遇到的行号。如果您记录错误,这可能意味着误导性错误日志:
Sub DoSomething()
10 On Error GoTo 50
Debug.Print 42 / 0
30 Exit Sub
50 Debug.Print "Error raised on line " & Erl 'returns 10
End Sub
此外,行号只有Integer
分辨率(VBA模块最多可以有65,535行,这是分辨率的两倍),如果你不这样做,它会默默地失败并愉快地报告错误的行号牢记这一点:
Sub DoSomething()
99997 On Error GoTo 99999
99998 Debug.Print 42 / 0
99999
Debug.Print Erl 'Prints 34462 - and which line is that?
End Sub
任何严肃的VBA应用程序都将使用结构化错误处理。
编写小型的专业程序(即遵循现代最佳实践的编写代码),行号变得毫无意义。
行号是颈部疼痛的维持;它们使代码混乱并使其整体难以阅读(因此也需要调试)。
也就是说,IIRC MZ-Tools 3具有这样的功能。
请记住,当行号是一个东西时BASIC看起来像这样:
10 GOSUB 100
20 GOSUB 1000
99 END
100 REM CLEAR SCREEN
110 PRINT CHR$(147)
120 RETURN
200 REM MODULO
210 LET MOD% = V%-INT(V%/FB%)*FB%
220 RETURN
1000 REM INIT VARIABLES
1010 LET FIZZ$ = "FIZZ"
1011 LET BUZZ$ = "BUZZ"
1020 LET FIZZ% = 3
1021 LET BUZZ% = 5
1030 LET MIN% = 1
1031 LET MAX% = 15
1100 PRINT FIZZ$ + ":" + STR$(FIZZ%)
1101 PRINT BUZZ$ + ":" + STR(BUZZ%)
1102 PRINT FIZZ$ + BUZZ$ + ":" + STR$(FIZZ%*BUZZ%)
1105 PRINT
2000 REM ACTUAL FIZZBUZZ LOOP
2010 FOR X = MIN% TO MAX%
2015 LET RESULT$ = STR$(X)
2020 LET FB% = FIZZ%*BUZZ%
2021 LET V% = X
2024 GOSUB 200
2025 IF MOD%=0 THEN LET RESULT$=FIZZ$+BUZZ$ : GOTO 2050
2030 LET FB% = FIZZ%
2031 GOSUB 200
2035 IF MOD%=0 THEN LET RESULT$=FIZZ$ : GOTO 2050
2040 LET FB% = BUZZ%
2041 GOSUB 200
2045 IF MOD%=0 THEN LET RESULT$=BUZZ$ : GOTO 2050
2050 PRINT RESULT$
2090 NEXT X
2099 RETURN
以上是一个有效的Commodore 64 BASIC 2.0 fizzbuzz程序。 VBA具有出色的向后兼容性。只需稍加修改,它就可以在VBA中运行:
Sub Main()
10 GoSub 100
20 GoSub 1000
99 End
100 Rem CLEAR SCREEN
110 'Debug.Print Chr$(147) 'Chr$(147) was a special character on C64
120 Return
200 Rem MODULO
210 Let Modulo% = V% - Int(V% / FB%) * FB%
220 Return
1000 Rem INIT VARIABLES
1010 Let FIZZ$ = "FIZZ"
1011 Let BUZZ$ = "BUZZ"
1020 Let FZZ% = 3
1021 Let BZZ% = 5
1030 Let Min% = 1
1031 Let Max% = 15
1100 Debug.Print FIZZ$ + ":" + Str$(FZZ%)
1101 Debug.Print BUZZ$ + ":" + Str(BZZ%)
1102 Debug.Print FIZZ$ + BUZZ$ + ":" + Str$(FZZ% * BZZ%)
1105 Debug.Print
2000 Rem ACTUAL FIZZBUZZ LOOP
2010 For X = Min% To Max%
2015 Let RESULT$ = Str$(X)
2020 Let FB% = FZZ% * BZZ%
2021 Let V% = X
2024 GoSub 200
2025 If Modulo% = 0 Then Let RESULT$ = FIZZ$ + BUZZ$: GoTo 2050
2030 Let FB% = FZZ%
2031 GoSub 200
2035 If Modulo% = 0 Then Let RESULT$ = FIZZ$: GoTo 2050
2040 Let FB% = BZZ%
2041 GoSub 200
2045 If Modulo% = 0 Then Let RESULT$ = BUZZ$: GoTo 2050
2050 Debug.Print RESULT$
2090 Next X
2099 Return
End Sub
不要写出1980年的代码,我们已经30年了。
答案 1 :(得分:2)
我使用此代码为我的Excel项目添加行号。我在网上发现了一段时间,我不记得我从哪里得到它,所以归功于最初写这篇文章的人:
Sub AddLineNumbers(wbName As String, vbCompName As String)
'See MakeUF
Dim i As Long, j As Long, lineN As Long
Dim procName As String
Dim startOfProceedure As Long
Dim lengthOfProceedure As Long
Dim newLine As String
With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule
.CodePane.Window.Visible = False
For i = 1 To .CountOfLines
procName = .ProcOfLine(i, vbext_pk_Proc)
If procName <> vbNullString Then
startOfProceedure = .ProcStartLine(procName, vbext_pk_Proc)
lengthOfProceedure = .ProcCountLines(procName, vbext_pk_Proc)
If startOfProceedure + 1 < i And i < startOfProceedure + lengthOfProceedure - 1 Then
newLine = RemoveOneLineNumber(.Lines(i, 1))
If Not HasLabel(newLine) And Not (.Lines(i - 1, 1) Like "* _") Then
.ReplaceLine i, CStr(i) & ":" & newLine
End If
End If
End If
Next i
.CodePane.Window.Visible = True
End With
End Sub
Sub RemoveLineNumbers(wbName As String, vbCompName As String)
'See MakeUF
Dim i As Long
With Workbooks(wbName).VBProject.VBComponents(vbCompName).CodeModule
For i = 1 To .CountOfLines
.ReplaceLine i, RemoveOneLineNumber(.Lines(i, 1))
Next i
End With
End Sub
Function RemoveOneLineNumber(aString)
RemoveOneLineNumber = aString
If aString Like "#:*" Or aString Like "##:*" Or aString Like "###:*" Then
RemoveOneLineNumber = Mid(aString, 1 + InStr(1, aString, ":", vbTextCompare))
End If
End Function
Function HasLabel(ByVal aString As String) As Boolean
HasLabel = InStr(1, aString & ":", ":") < InStr(1, aString & " ", " ")
End Function
你必须修改它以满足你的需求,因为你在Access工作,但我确信它的主要部分仍然适用。在Excel中,有一个userform用于启动您指定的模块的代码,但您应该只能传入模块名称(vbCompName
)来指定模块。我不熟悉Access VBA,因此我不确定您在代码中替换Workbooks(wbName)
的内容。
答案 2 :(得分:2)
答案 3 :(得分:1)
MZ-Tools for VBA具有向单个函数,模块或整个项目添加和删除行号的功能。
请参阅http://www.mztools.com/v8/onlinehelp/index.html?add_remove_line_numbers.htm
注意1:我发现将行号增量配置为1而不是10更好。您永远不会在中间手动添加行号 - 每当您编辑代码时,首先删除行号,然后在您添加时将它们添加回来已经完成了。
注意2:直到几年前,MZ-Tools还有3.0版的免费版本,但很难找到副本。但这是一项很好的投资 - 还有许多其他有用的功能(例如自动添加错误处理程序)。
答案 4 :(得分:1)
这适用于我......将其添加到自己的模块中。调用代码将打开或关闭行号。在引号中添加模块标题和/或过程标题将仅更新名为的模块或过程。
Option Compare Database
Option Explicit
Sub AddLineNumbers(Optional vbCompName As String, Optional vbCompSubName As String)
On Error Resume Next
DoCmd.Hourglass True
Application.VBE.ActiveVBProject.References.AddFromGuid "{0002E157-0000-0000-C000-000000000046}", 5, 0
Call ExecuteAddLineNumbers(vbCompName, vbCompSubName)
DoCmd.Hourglass False
End Sub
Sub ExecuteAddLineNumbers(Optional vbCompName As String, Optional vbCompSubName As String)
On Error GoTo Err_Handler
'create a reference to the Microsoft Visual Basic for Applications Extensibility library
Dim i As Long, j As Long, lineN As Long
Dim procName As String
Dim startOfProceedure As Long
Dim lengthOfProceedure As Long
Dim newLine As String
Dim objComponent As Object
Dim lineNumber As Long
Dim HasLineNumbers As Boolean
For Each objComponent In Application.VBE.ActiveVBProject.VBComponents
If (vbCompName = vbNullString Or objComponent.Name = vbCompName) And objComponent.Name <> _
Application.VBE.ActiveCodePane.CodeModule.Name) Then
Debug.Print objComponent.Name
With objComponent.CodeModule
.CodePane.Window.Visible = False
For i = 1 To .CountOfLines
'Debug.Print .ProcOfLine(i, vbext_pk_Proc)
If procName = "" And .ProcOfLine(i, vbext_pk_Proc) <> "" Then
procName = .ProcOfLine(i, vbext_pk_Proc)
'vbext_pk_Get Specifies a procedure that returns the value of a property.
'vbext_pk_Let Specifies a procedure that assigns a value to a property.
'vbext_pk_Set Specifies a procedure that sets a reference to an object.
'vbext_pk_Proc Specifies all procedures other than property procedures.
'type=vbext_ct_ClassModule
'type=vbext_ct_StdModule
'type=vbext_ct_Document
If objComponent.Type = vbext_ct_ClassModule Then
If InStr(.Lines(i + 1, 1), " Let ") > 0 Then
startOfProceedure = .ProcStartLine(procName, vbext_pk_Let)
lengthOfProceedure = .ProcCountLines(procName, vbext_pk_Let)
ElseIf InStr(.Lines(i + 1, 1), " Get ") > 0 Then
startOfProceedure = .ProcStartLine(procName, vbext_pk_Get)
lengthOfProceedure = .ProcCountLines(procName, vbext_pk_Get)
ElseIf InStr(.Lines(i + 1, 1), " Set ") > 0 Then
startOfProceedure = .ProcStartLine(procName, vbext_pk_Set)
lengthOfProceedure = .ProcCountLines(procName, vbext_pk_Set)
Else
startOfProceedure = .ProcStartLine(procName, vbext_pk_Proc)
lengthOfProceedure = .ProcCountLines(procName, vbext_pk_Proc)
End If
Else
startOfProceedure = .ProcStartLine(procName, vbext_pk_Proc)
lengthOfProceedure = .ProcCountLines(procName, vbext_pk_Proc)
End If
lineNumber = 10
HasLineNumbers = .Find("## ", startOfProceedure + 1, 1, startOfProceedure + lengthOfProceedure - 1, 1, _
False, False, True)
End If
If (vbCompSubName = vbNullString And procName <> vbNullString) Or _
(vbCompSubName <> vbNullString And procName = vbCompSubName) Then
If startOfProceedure + 1 < i And i < startOfProceedure + lengthOfProceedure - 1 Then
newLine = RemoveOneLineNumber(.Lines(i, 1), HasLineNumbers)
If Trim(newLine) <> vbNullString Then
If Not HasLabel(newLine) And Not (.Lines(i - 1, 1) Like "* _") Then
If HasLineNumbers = False Then newLine = CStr(lineNumber) & vbTab & newLine
.ReplaceLine i, newLine
lineNumber = lineNumber + 10
ElseIf Not HasLineNumbers Then
.ReplaceLine i, vbTab & newLine
Else
.ReplaceLine i, newLine
End If
End If
ElseIf i = startOfProceedure + lengthOfProceedure - 1 Then
procName = ""
End If
Else
procName = ""
End If
Next i
.CodePane.Window.Visible = True
End With
End If
Next objComponent
Exit Sub
Err_Handler:
MsgBox (Err.Number & ": " & Err.Description)
End Sub
Function RemoveOneLineNumber(aString As String, HasLineNumbers As Boolean)
Dim i As Double
RemoveOneLineNumber = aString
i = ((Len(Trim(Str(Val(aString)))) / 4) - Int(Len(Trim(Str(Val(aString)))) / 4)) * 4
If aString Like "#*" Then
RemoveOneLineNumber = Space(i) & Mid(aString, InStr(1, aString, " ", vbTextCompare))
RemoveOneLineNumber = Right(aString, Len(aString) - 4)
ElseIf HasLineNumbers And aString Like " *" Then
RemoveOneLineNumber = Right(aString, Len(aString) - 4)
End If
End Function
Function HasLabel(ByVal aString As String) As Boolean
HasLabel = False
If Right(Trim(aString), 1) = ":" Or _
Left(Trim(aString), 3) = "Dim" Or _
Left(Trim(aString), 3) = "ReDim" Or _
Left(Trim(aString), 1) = "'" Or _
Left(Trim(aString), 6) = "Option" Or _
Left(Trim(aString), 5) = "Debug" Or _
Left(Trim(aString), 3) = "Sub" Or _
Left(Trim(aString), 11) = "Private Sub" Or _
Left(Trim(aString), 10) = "Public Sub" Or _
Left(Trim(aString), 8) = "Function" Or _
Left(Trim(aString), 12) = "End Function" Or _
Left(Trim(aString), 8) = "Property" Or _
Left(Trim(aString), 12) = "End Property" Or _
Left(Trim(aString), 7) = "End Sub" Then HasLabel = True
End Function
答案 5 :(得分:1)
任何体面的错误处理程序将报告的不仅仅是行号。它将报告错误代码、描述和发生错误的模块。不管 ERL 是否在整个应用程序中重复行号,如果您找不到报告的其他线索的问题,也许您需要休假。或者,地狱,添加一个变量来增加模块级 alpha 代码作为行号的附属物,例如“newERL = strProcLevel & ERL”,为您提供“A12345”作为行号。
答案 6 :(得分:0)
这不是100%测试,但使用VBA可扩展性,您可以执行以下操作
Sub line_number(strModuleName As String)
Dim vbProj As VBProject
Dim vbComp As VBComponent
Dim cmCode As CodeModule
Dim intLine As Integer
Set vbProj = Application.VBE.ActiveVBProject
Set vbComp = vbProj.VBComponents(strModuleName)
Set cmCode = vbComp.CodeModule
For intLine = 2 To cmCode.CountOfLines - 1
cmCode.InsertLines intLine, intLine - 1 & cmCode.Lines(intLine, 1)
cmCode.DeleteLines intLine + 1, 1
Next intLine
End Sub
这给出了之前和之后的结果,但不推荐以这种方式改变。
答案 7 :(得分:0)
Arich的答案就像个人模块的魅力一样。如果要为整个工作簿提供(更新的)行号,请应用以下步骤* ^:
做一次:
Module2
中的大代码粘贴到工作簿中。Module3
的代码粘贴到工作簿中。Module4
的代码粘贴到工作簿中。Global allow_for_line_addition As String
行,这样您就可以自动添加每个第一行上方/的内容
模块。end sub
,end function
或End Property
之后不会输入任何内容。每次修改代码时都会这样做:
Module3
的代码,删除工作簿中所有模块的行号。Module4
的代码,为工作簿中的所有模块添加行号。 <强> 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
<强> 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
<强> 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
您可以将"Book1.xlsm"
替换为您自己的工作簿的名称,或者使用thisworkbook
(注意不是“”),反之亦然。
line 2440:
放在line 2303:
之上)。通过删除和重新添加它们,行号将再次自动更正。