如何使用行号自动填充VBA编辑器?

问题描述 投票:0回答:7

出于调试原因,我希望在我的VBA代码中包含行号。这将使我知道发生特定错误的位置。

是否有自动功能(例如设置中的选项)?或者我需要编写自己的宏?

如果我需要编写自己的宏来完成这项任务,我该如何做这样的事情呢?

vba basic
7个回答
15
投票

你不想要行号。

不是为了“调试原因”,不是为了任何事情。行号被弃用是因为:在程序存在之前它们是古代遗物,而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 程序。 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年代码,我们40年后。


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
投票

VBA编辑器具有内置方式,可在“标准”工具栏下查看行号:

enter image description here

当您选择一行代码时,行号将在“Ln”旁边显示。


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,但是很难找到副本。但这是一项很好的投资 - 还有许多其他有用的功能(例如自动添加错误处理程序)。


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

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

这给出了之前和之后的结果,但不推荐以这种方式改变。


0
投票

Arich的答案就像个人模块的魅力一样。如果要为整个工作簿提供(更新的)行号,请应用以下步骤* ^:

做一次:

  1. Module2中的大代码粘贴到工作簿中。
  2. Module3的代码粘贴到工作簿中。
  3. Module4的代码粘贴到工作簿中。
  4. 然后粘贴行Global allow_for_line_addition As Stringthis就是这样你就可以自动在每个模块的第一行上面/中添加linenumbers。
  5. 删除每个模块末尾的所有空行(因此在模块的最后一个end subend functionEnd Property之后不会输入)。
  6. 在VBA编辑器中,虽然没有运行代码,但没有处于“中断”模式:单击工具>引用>标记:`Microsoft Visual Basic for Applications Extensibility 5.3“

每次修改代码时都这样做:

  1. °运行Module3的代码,删除工作簿中所有模块的行号。
  2. °运行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(注意没有“”),反之亦然。

  • *请注意这在excel 2016中有效,我还没有在2013年尝试过。
  • ^它是Hemced的答案here.的修改版本,反过来看起来很像Arich的答案。
  • °因为有时你会出现错误,如果你切出线或移动它们(例如把line 2440:放在line 2303:上方)。通过删除和重新添加它们,行号再次自动更正。
© www.soinside.com 2019 - 2024. All rights reserved.