Oor*_*ang 32
此技巧仅适用于Access VBA,Excel和其他人不允许这样做.但是,您可以通过在模块名称前加下划线来使对象浏览器隐藏标准模块.只有在您更改对象浏览器以显示隐藏对象时,才会显示该模块.
这个技巧适用于所有基于vb6的VBA版本中的Enums.您可以通过在括号中包含它的名称来创建Enum的隐藏成员,然后在其前面添加下划线.例:
Public Enum MyEnum
meDefault = 0
meThing1 = 1
meThing2 = 2
meThing3 = 3
[_Min] = meDefault
[_Max] = meThing3
End Enum
Public Function IsValidOption(ByVal myOption As MyEnum) As Boolean
If myOption >= MyEnum.[_Min] Then IsValidOption myOption <= MyEnum.[_Max]
End Function
Run Code Online (Sandbox Code Playgroud)
在Excel-VBA中,您可以通过将单元格括在括号中来引用单元格,括号也可以用作评估命令,允许您评估公式语法:
Public Sub Example()
[A1] = "Foo"
MsgBox [VLOOKUP(A1,A1,1,0)]
End Sub
Run Code Online (Sandbox Code Playgroud)
通过将LSet与相同大小的用户定义类型组合,您可以在不使用MemCopy(RtlMoveMemory)的情况下传递原始数据:
Public Sub Example()
Dim b() As Byte
b = LongToByteArray(8675309)
MsgBox b(1)
End Sub
Private Function LongToByteArray(ByVal value As Long) As Byte()
Dim tl As TypedLong
Dim bl As ByteLong
tl.value = value
LSet bl = tl
LongToByteArray = bl.value
End Function
Run Code Online (Sandbox Code Playgroud)
Octal和Hex Literals实际上是无符号类型,它们都输出-32768:
Public Sub Example()
Debug.Print &H8000
Debug.Print &O100000
End Sub
Run Code Online (Sandbox Code Playgroud)
如上所述,在括号内传递变量会导致它传递ByVal:
Sub PredictTheOutput()
Dim i&, j&, k&
i = 10: j = i: k = i
MySub (i)
MySub j
MySub k + 20
MsgBox Join(Array(i, j, k), vbNewLine), vbQuestion, "Did You Get It Right?"
End Sub
Public Sub MySub(ByRef foo As Long)
foo = 5
End Sub
Run Code Online (Sandbox Code Playgroud)
您可以将字符串直接分配给字节数组,反之亦然:
Public Sub Example()
Dim myString As String
Dim myBytArr() As Byte
myBytArr = "I am a string."
myString = myBytArr
MsgBox myString
End Sub
Run Code Online (Sandbox Code Playgroud)
"Mid"也是一名运营商.使用它可以覆盖字符串的特定部分而无需VBA众所周知的慢字符串连接:
Public Sub Example1()
''// This takes about 47% of time Example2 does:
Dim myString As String
myString = "I liek pie."
Mid(myString, 5, 2) = "ke"
Mid(myString, 11, 1) = "!"
MsgBox myString
End Sub
Public Sub Example2()
Dim myString As String
myString = "I liek pie."
myString = "I li" & "ke" & " pie" & "!"
MsgBox myString
End Sub
Run Code Online (Sandbox Code Playgroud)
Swa*_*nny 18
Mid()语句有一个重要但几乎总是错过的功能.这就是Mid()出现在赋值的左侧而不是出现在右侧或表达式中的Mid()函数的位置.
规则是如果目标字符串不是字符串文字,并且这是对目标字符串的唯一引用,并且插入的段的长度与要替换的段的长度匹配,则该字符串将被视为操作可变.
那是什么意思?这意味着如果您将一个大型报表或一个庞大的字符串列表构建到单个字符串值中,那么利用它将使您的字符串处理更快.
这是一个受益于此的简单类.它为您的VBA提供了与.Net相同的StringBuilder功能.
' Class: StringBuilder
Option Explicit
Private Const initialLength As Long = 32
Private totalLength As Long ' Length of the buffer
Private curLength As Long ' Length of the string value within the buffer
Private buffer As String ' The buffer
Private Sub Class_Initialize()
' We set the buffer up to it's initial size and the string value ""
totalLength = initialLength
buffer = Space(totalLength)
curLength = 0
End Sub
Public Sub Append(Text As String)
Dim incLen As Long ' The length that the value will be increased by
Dim newLen As Long ' The length of the value after being appended
incLen = Len(Text)
newLen = curLength + incLen
' Will the new value fit in the remaining free space within the current buffer
If newLen <= totalLength Then
' Buffer has room so just insert the new value
Mid(buffer, curLength + 1, incLen) = Text
Else
' Buffer does not have enough room so
' first calculate the new buffer size by doubling until its big enough
' then build the new buffer
While totalLength < newLen
totalLength = totalLength + totalLength
Wend
buffer = Left(buffer, curLength) & Text & Space(totalLength - newLen)
End If
curLength = newLen
End Sub
Public Property Get Length() As Integer
Length = curLength
End Property
Public Property Get Text() As String
Text = Left(buffer, curLength)
End Property
Public Sub Clear()
totalLength = initialLength
buffer = Space(totalLength)
curLength = 0
End Sub
Run Code Online (Sandbox Code Playgroud)
以下是如何使用它的示例:
Dim i As Long
Dim sb As StringBuilder
Dim result As String
Set sb = New StringBuilder
For i = 1 to 100000
sb.Append CStr( i)
Next i
result = sb.Text
Run Code Online (Sandbox Code Playgroud)
man*_*oid 15
VBA本身似乎是一个隐藏的功能.我知道多年来一直使用Office产品的人不知道它甚至是套件的一部分.
我在这里发布了多个问题,但对象浏览器是我的秘密武器.如果我需要忍者快速编写代码,但我不熟悉dll,对象浏览器可以挽救我的生命.它使得学习类结构比MSDN更容易.
Locals Window也非常适合调试.在代码中暂停,它将显示当前命名空间中的所有变量,名称以及它们的当前值和类型.
谁能忘记我们的好朋友立即窗口?它不仅适用于Debug.Print标准输出,而且您也可以输入命令.需要知道VariableX是什么?
?VariableX
Run Code Online (Sandbox Code Playgroud)
需要知道那个细胞是什么颜色的?
?Application.ActiveCell.Interior.Color
Run Code Online (Sandbox Code Playgroud)
事实上,所有这些窗口都是使用VBA提高工作效率的绝佳工具.
Dir*_*mar 13
这不是一个功能,但是我在VBA(和VB6)中已经多次看到错误:在方法调用中添加了括号,它将改变语义:
Sub Foo()
Dim str As String
str = "Hello"
Bar (str)
Debug.Print str 'prints "Hello" because str is evaluated and a copy is passed
Bar str 'or Call Bar(str)
Debug.Print str 'prints "Hello World"
End Sub
Sub Bar(ByRef param As String)
param = param + " World"
End Sub
Run Code Online (Sandbox Code Playgroud)
隐藏的功能
可能在VBA中记录最少的功能是您只能通过在VBA对象浏览器上选择"显示隐藏的成员"来公开的功能.隐藏成员是VBA中的那些功能,但不受支持.您可以使用它们,但Microsoft可能会随时消除它们.他们都没有提供任何文件,但你可以在网上找到一些.可能最受关注的这些隐藏功能可以访问VBA中的指针.对于体面的写作,请查看; 不那么轻量级 - Shlwapi.dll
记录,但可能更加模糊(无论如何都是excel)使用ExecuteExcel4Macro来访问属于整个Excel应用程序实例而不是特定工作簿的隐藏全局命名空间.
字典.没有它们,VBA几乎毫无价值!
参考Microsoft Scripting Runtime,Scripting.Dictionary
用于任何足够复杂的任务,并且从此过上幸福的生活.
Scripting Runtime还为您提供了FileSystemObject,强烈建议使用它.
从这里开始,然后挖掘一下......
http://msdn.microsoft.com/en-us/library/aa164509%28office.10%29.aspx