VBA的隐藏功能VBA的隐藏功能(Hidden features of VBA)

2019-05-14 10:01发布

VBA语言的哪些功能要么记录不完整,或者干脆不经常用的?

Answer 1:

这招只适用于访问VBA,Excel和别人也不会允许它。 但是你可以用下划线前缀的模块名称进行标准模块从对象浏览器中隐藏。 如果你改变了对象浏览器显示隐藏的对象模块然后才可以看到。

这个技巧在VBA中的所有VB6基于版本枚举。 您可以通过在括号包围它的名字,然后用下划线前缀它创建一个枚举的隐藏的成员。 例:

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

在Excel-VBA可以通过在括号括起来的参考电池中,括号也充当评估命令允许您评估公式语法:

Public Sub Example()
    [A1] = "Foo"
    MsgBox [VLOOKUP(A1,A1,1,0)]
End Sub

您也可以通过各地的原始数据,而无需使用MEMCOPY(RtlMoveMemory)通过LSET与同样大小的用户定义类型组合:

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

八和十六进制字面实际上是无符号的类型,它们都将输出-32768:

Public Sub Example()
    Debug.Print &H8000
    Debug.Print &O100000
End Sub

如所提到的,通过一变量在括号内导致它被传递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

您可以直接指定字符串转换成字节数组,反之亦然:

Public Sub Example()
    Dim myString As String
    Dim myBytArr() As Byte
    myBytArr = "I am a string."
    myString = myBytArr
    MsgBox myString
End Sub

“中”也是一个运营商。 使用它,你没有覆盖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


Answer 2:

还有就是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

这里是如何使用它的一个例子:

  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


Answer 3:

VBA本身似乎是一个隐藏的功能。 伙计们,我知道谁已经使用Office产品多年不知道它甚至套件的一部分。

我在这里张贴了这个在多个问题,但对象浏览器是我的秘密武器。 如果我需要忍者码点真快,但我不熟悉的DLL,对象浏览器节省了我的生活。 这使得它更容易学习类结构比MSDN。

本地窗口是伟大的调试,以及。 将暂停在你的代码,它会告诉你当前的命名空间内的所有变量,他们的名字,他们的当前值和类型。

谁又能忘记我们的好朋友立即窗口? 它不仅是伟大的Debug.Print标准输出,但你可以在命令进入它。 要知道VariableX是什么?

?VariableX

需要知道什么颜色的细胞是什么?

?Application.ActiveCell.Interior.Color

事实上所有的窗户都很好的工具是生产力与VBA。



Answer 4:

这不是一个功能,但一件事我已经在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


Answer 5:

隐藏功能

  1. 虽然这是“基本”,你可以使用OOP - 类和对象
  2. 您可以进行API调用


Answer 6:

可能在VBA中至少记录功能是那些你只能选择“显示隐藏成员”对VBA对象浏览器暴露。 隐藏的成员是那些在VBA功能,但不支持。 您可以使用它们,但微软可能随时消除它们。 他们没有一个具有提供的任何文件,但你可以找到一些在网络上。 可能是最受关注的,这些隐藏的功能提供了访问在VBA指针。 一个体面的书面记录,检查; 不那么轻量级- Shlwapi.dll中

记载,但也许更模糊的(在Excel反正)使用ExecuteExcel4Macro访问属于整个Excel应用程序实例,而不是一个具体的工作簿中的隐藏的全局命名空间。



Answer 7:

可以实现与接口Implements关键字。



Answer 8:

字典。 VBA是没有他们几乎一文不值!

引用Microsoft脚本运行时,使用Scripting.Dictionary任何足够复杂的任务,并从此过上幸福生活。

该脚本运行时也为您提供了一个FileSystemObject,这也值得大力推荐。

从这里开始,然后周围挖了一下...

http://msdn.microsoft.com/en-us/library/aa164509%28office.10%29.aspx



Answer 9:

键入VBA. 将打开的所有内置函数和常量的智能感知上市。



Answer 10:

随着一点点的工作,你可以遍历像这样的自定义类别:

' Write some text in Word first.'
Sub test()
    Dim c As New clsMyCollection
        c.AddItems ActiveDocument.Characters(1), _
            ActiveDocument.Characters(2), _
            ActiveDocument.Characters(3), _
            ActiveDocument.Characters(4)

    Dim el As Range
    For Each el In c
        Debug.Print el.Text
    Next
    Set c = Nothing
End Sub

您的自定义集合代码(在一个类中调用clsMyCollection ):

Option Explicit

Dim m_myCollection As Collection

Public Property Get NewEnum() As IUnknown
    ' This property allows you to enumerate
    ' this collection with the For...Each syntax
    ' Put the following line in the exported module
    ' file (.cls)!'
    'Attribute NewEnum.VB_UserMemId = -4
    Set NewEnum = m_myCollection.[_NewEnum]
End Property

Public Sub AddItems(ParamArray items() As Variant)

    Dim i As Variant

    On Error Resume Next
    For Each i In items
        m_myCollection.Add i
    Next
    On Error GoTo 0
End Sub

Private Sub Class_Initialize()
    Set m_myCollection = New Collection
End Sub


Answer 11:

  • 通过键入保存4个全按键debug.? xxx debug.? xxx代替debug.print xxx
  • 通过添加崩溃它: enum foo: me=0: end enum到含有任何其他代码的模块的顶部。


Answer 12:

支持本地化版本,这(至少在上个世纪)支持使用本地化值表达式。 像真理报为真和Fałszywy(不太清楚,但它确实有有趣的大号至少)在波兰的假...其实英文版本将能够在任何语言来读取宏和转换的飞行。 其他本地化版本不会处理,虽然。

失败。



Answer 13:

所述VBE(Visual Basic中扩展性)的对象模型是在较小的已知的和/或利用不足的功能。 它可以让你编写VBA代码来处理VBA代码,模块和项目。 我曾经写过一个Excel项目将装配其他Excel项目从一组模块文件。

对象模型也适用从VBScript和卫生技术评估。 我写了一个HTA一次帮我保留大量的Word,Excel和Access项目的轨道。 许多项目将使用通用代码模块,它是容易模块在一个系统中“成长”,然后需要被迁移到其他系统。 我的HTA,让我向所有模块导出一个项目,比较它们版本的共同文件夹和合并更新程序(使用BeyondCompare),然后重新导入更新的模块。

VBE对象模型的工作方式稍有不同的Word,Excel和Access之间,而遗憾的是不与Outlook在所有的工作,但还是提供了一个管理代码能力极强。



Answer 14:

IsDate("13.50")返回True ,但IsDate("12.25.2010")返回False

这是因为, IsDate可以更精确地命名IsDateTime 。 而且由于时间( . )被视为一个时间分隔符,而不是一个日期分隔符。 见这里更全面的解释 。



Answer 15:

VBA支持位运算符用于比较两个值的二进制数字(比特)。 例如,表述4和7的计算结果的图4(0100)和7(0111)的比特值,并返回图4(也就是在这两个数字的位。)同样,表达式4或8的计算结果在4位值(0100 )和8(1000),并返回图12(1100),即,其中任一个为真位。

不幸的是,位运算符必须在逻辑比较运营商相同的名字:而且,EQV,小鬼,不,OR和XOR。 这可能会导致歧义,甚至是相互矛盾的结果。

作为一个例子,打开立即窗口(Ctrl + G)和输入:? (2和4)它返回零,因为有在没有比特共同2(0010)之间和4(0100)。



Answer 16:

DEFTYPE声明

此功能用于向后兼容性可能存在。 或者写绝望混淆意大利面条代码。 你挑。



文章来源: Hidden features of VBA