如何在 Excel 的 VBA 编辑器中禁用自动格式设置?
How can one disable autoformatting in Excel's VBA editor?
Excel 的内置 VBA 编辑器中最烦人的一个功能是——我的意见——代码的激进自动格式化,它坚持在光标离开该行时立即重写我输入的内容。尤其令人沮丧的是,编辑器折叠了所有空格,从而阻止了任何有意义的代码对齐。例如,如果我尝试用等号对齐一系列赋值,并用小数点分隔符对齐值:
price = 10.01
quantity = 3.2
vat = 0.11
编辑器不可避免地通过折叠所有空格来打乱它:
price = 10.01
quantity = 3.2
vat = 0.11
有什么办法可以避免这种不受欢迎的自动格式化?
分配化妆品:-)
There's neither a special VBE property to change the VBE (autoformatting) options directly nor a way to do it programatically. - So afaik VBE irrevocably forces autoformatting upon the user by partial workarounds.
a) Class 方法
为了艺术和乐趣,实际上(非常)基本的class方法给你一个开始的想法;赋值参数作为 strings 传递,允许任何光学格式 - 如果那是你真正想要的:
当前模块中的示例调用
Sub ExampleCall()
Dim x As New cVars
x.Add "price = 11.11" ' wrong assignment
'...
x.Add "price = 10.01" ' later correction
x.Add "quantity = 1241.01"
x.Add "vat = 0.11"
Debug.Print "The price is $ " & x.Value("price")
End Sub
Class模块cVars
Option Explicit
Private dict As Object
Sub Add(ByVal NewValue As Variant)
'split string tokens via equal sign
Dim tmp
tmp = Split(Replace(Replace(NewValue, vbTab, ""), " ", "") & "=", "=")
'Identify key and value item
Dim myKey As String, myVal
myKey = tmp(0)
myVal = tmp(1): If IsNumeric(myVal) Then myVal = Val(myVal)
'Add to dictionary
If dict.exists(myKey) Then
dict(myKey) = myVal
Else
dict.Add myKey, myVal
End If
'Debug.Print "dict(" & myKey & ") =" & dict(myKey)
End Sub
Public Property Get Value(ByVal myVarName As String) As Variant
'get variable value
Value = dict(myVarName)
End Property
Private Sub Class_Initialize()
'set (late bound) dict to memory
If dict Is Nothing Then Set dict = CreateObject("Scripting.Dictionary")
End Sub
Private Sub Class_Terminate()
Set dict = Nothing
End Sub
编辑#1截至 2021 年 3 月 3 日
b)Rem
评价方法
再一次只是为了艺术的缘故,一种阅读作业的方法进入了注释掉的代码行通过,是的通过Rem
(起伏对这种起源于前 Basic 时代 ) 的古老用法深感叹息,因为它允许使用任何想要的空格或制表符来格式化数据,并且不会通过撇号 '
.[希望与当前的 outcommentings 混淆。 =33=]
这个 Test
过程只需要通常的声明加上一些赋值调用以及提到的 Rem
部分。两个简单的帮助程序获取代码行,通过字典分析它们 class cVars
并最终分配它们。
注意下面的例子
- 需要对
Microsoft Visual Basic Extensibility 5.3
和 的库引用
- 使用 a) 部分未更改的 class
cVars
只是为了避免重写它。
Option Explicit
Private Const THISMODULE As String = "Module1" ' << change to current code module name
Sub Test() ' procedure name of example call
'Declare vars
Dim price As Double: Assign "price", price
Dim quantity As Double: Assign "quantity", quantity
Dim vat As Double: Assign "vat", vat
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Enter assignments via Rem(ark)
'(allowing any user defined formatting therein)
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rem price = 10.01
Rem quantity = 1241.01
Rem vat = 0.11
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Debug.Print quantity & " à $" & price & " = " & Format(quantity * price, "$#,##0.00")
End Sub
帮助程序 Assign
评估程序 Rem
代码行 Test
Sub Assign(ByVal myVarName As String, ByRef myvar)
Const MyProc As String = "Test"
Dim codelines
getCodelines codelines, THISMODULE, ProcedureName:=MyProc
'Debug.Print Join(codelines, vbNewLine)
Dim x As New cVars ' set class instance to memory
Dim line As Variant, curAssignment
For Each line In codelines
curAssignment = Split(line, "Rem ")(1) ' remove Rem prefix from codelines
If curAssignment Like myVarName & "*" Then
x.Add curAssignment
myvar = x.Value(myVarName)
End If
Next
End Sub
帮助程序getCodelines
由上述过程调用Assign
。 Returns 来自调用过程 Test
的相关 Rem
代码行。 - 当然可以只过滤一个代码行。
Sub getCodelines(ByRef arr, ByVal ModuleName As String, ByVal ProcedureName As String)
Const SEARCH As String = "Rem "
'a) set project
Dim VBProj As Object
Set VBProj = ThisWorkbook.VBProject
If VBProj.Protection = vbext_pp_locked Then Exit Sub ' escape locked projects
'b) set component
Dim VBComp As Object
Set VBComp = VBProj.VBComponents(ModuleName)
Dim pk As vbext_ProcKind
'd) get relevant code lines
With VBComp.CodeModule
'count procedure header lines
Dim HeaderCount As Long: HeaderCount = .ProcBodyLine(ProcedureName, pk) - .ProcStartLine(ProcedureName, pk)
'get procedure code
Dim codelines
codelines = Split(.lines(.ProcBodyLine(ProcedureName, pk), .ProcCountLines(ProcedureName, pk) - HeaderCount), vbNewLine)
'filter code lines containing "Rem" entries
codelines = Filter(codelines, SEARCH, True)
End With
'return elements
arr = codelines
End Sub
不要忘记集成 a) 部分中的 class 模块 CVars
!
Excel 的内置 VBA 编辑器中最烦人的一个功能是——我的意见——代码的激进自动格式化,它坚持在光标离开该行时立即重写我输入的内容。尤其令人沮丧的是,编辑器折叠了所有空格,从而阻止了任何有意义的代码对齐。例如,如果我尝试用等号对齐一系列赋值,并用小数点分隔符对齐值:
price = 10.01
quantity = 3.2
vat = 0.11
编辑器不可避免地通过折叠所有空格来打乱它:
price = 10.01
quantity = 3.2
vat = 0.11
有什么办法可以避免这种不受欢迎的自动格式化?
分配化妆品:-)
There's neither a special VBE property to change the VBE (autoformatting) options directly nor a way to do it programatically. - So afaik VBE irrevocably forces autoformatting upon the user by partial workarounds.
a) Class 方法
为了艺术和乐趣,实际上(非常)基本的class方法给你一个开始的想法;赋值参数作为 strings 传递,允许任何光学格式 - 如果那是你真正想要的:
当前模块中的示例调用
Sub ExampleCall()
Dim x As New cVars
x.Add "price = 11.11" ' wrong assignment
'...
x.Add "price = 10.01" ' later correction
x.Add "quantity = 1241.01"
x.Add "vat = 0.11"
Debug.Print "The price is $ " & x.Value("price")
End Sub
Class模块cVars
Option Explicit
Private dict As Object
Sub Add(ByVal NewValue As Variant)
'split string tokens via equal sign
Dim tmp
tmp = Split(Replace(Replace(NewValue, vbTab, ""), " ", "") & "=", "=")
'Identify key and value item
Dim myKey As String, myVal
myKey = tmp(0)
myVal = tmp(1): If IsNumeric(myVal) Then myVal = Val(myVal)
'Add to dictionary
If dict.exists(myKey) Then
dict(myKey) = myVal
Else
dict.Add myKey, myVal
End If
'Debug.Print "dict(" & myKey & ") =" & dict(myKey)
End Sub
Public Property Get Value(ByVal myVarName As String) As Variant
'get variable value
Value = dict(myVarName)
End Property
Private Sub Class_Initialize()
'set (late bound) dict to memory
If dict Is Nothing Then Set dict = CreateObject("Scripting.Dictionary")
End Sub
Private Sub Class_Terminate()
Set dict = Nothing
End Sub
编辑#1截至 2021 年 3 月 3 日
b)Rem
评价方法
再一次只是为了艺术的缘故,一种阅读作业的方法进入了注释掉的代码行通过,是的通过Rem
(起伏对这种起源于前 Basic 时代 ) 的古老用法深感叹息,因为它允许使用任何想要的空格或制表符来格式化数据,并且不会通过撇号 '
.[希望与当前的 outcommentings 混淆。 =33=]
这个 Test
过程只需要通常的声明加上一些赋值调用以及提到的 Rem
部分。两个简单的帮助程序获取代码行,通过字典分析它们 class cVars
并最终分配它们。
注意下面的例子
- 需要对
Microsoft Visual Basic Extensibility 5.3
和 的库引用
- 使用 a) 部分未更改的 class
cVars
只是为了避免重写它。
Option Explicit
Private Const THISMODULE As String = "Module1" ' << change to current code module name
Sub Test() ' procedure name of example call
'Declare vars
Dim price As Double: Assign "price", price
Dim quantity As Double: Assign "quantity", quantity
Dim vat As Double: Assign "vat", vat
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Enter assignments via Rem(ark)
'(allowing any user defined formatting therein)
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rem price = 10.01
Rem quantity = 1241.01
Rem vat = 0.11
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Debug.Print quantity & " à $" & price & " = " & Format(quantity * price, "$#,##0.00")
End Sub
帮助程序 Assign
评估程序 Rem
代码行 Test
Sub Assign(ByVal myVarName As String, ByRef myvar)
Const MyProc As String = "Test"
Dim codelines
getCodelines codelines, THISMODULE, ProcedureName:=MyProc
'Debug.Print Join(codelines, vbNewLine)
Dim x As New cVars ' set class instance to memory
Dim line As Variant, curAssignment
For Each line In codelines
curAssignment = Split(line, "Rem ")(1) ' remove Rem prefix from codelines
If curAssignment Like myVarName & "*" Then
x.Add curAssignment
myvar = x.Value(myVarName)
End If
Next
End Sub
帮助程序getCodelines
由上述过程调用Assign
。 Returns 来自调用过程 Test
的相关 Rem
代码行。 - 当然可以只过滤一个代码行。
Sub getCodelines(ByRef arr, ByVal ModuleName As String, ByVal ProcedureName As String)
Const SEARCH As String = "Rem "
'a) set project
Dim VBProj As Object
Set VBProj = ThisWorkbook.VBProject
If VBProj.Protection = vbext_pp_locked Then Exit Sub ' escape locked projects
'b) set component
Dim VBComp As Object
Set VBComp = VBProj.VBComponents(ModuleName)
Dim pk As vbext_ProcKind
'd) get relevant code lines
With VBComp.CodeModule
'count procedure header lines
Dim HeaderCount As Long: HeaderCount = .ProcBodyLine(ProcedureName, pk) - .ProcStartLine(ProcedureName, pk)
'get procedure code
Dim codelines
codelines = Split(.lines(.ProcBodyLine(ProcedureName, pk), .ProcCountLines(ProcedureName, pk) - HeaderCount), vbNewLine)
'filter code lines containing "Rem" entries
codelines = Filter(codelines, SEARCH, True)
End With
'return elements
arr = codelines
End Sub
不要忘记集成 a) 部分中的 class 模块 CVars
!