Versteckte functionen von VBA

Welche functionen der VBA-Sprache sind entweder schlecht dokumentiert oder werden einfach nicht oft verwendet?

   

Dieser Trick funktioniert nur in Access VBA, Excel und anderen wird es nicht zulassen. Sie können jedoch ein Standardmodul im Objektbrowser ausblenden, indem Sie dem Modulnamen einen Unterstrich voranstellen. Das Modul ist dann nur sichtbar, wenn Sie den Objektbrowser so ändern, dass versteckte Objekte angezeigt werden.

Dieser Trick funktioniert mit Enums in allen vb6-basierten Version von VBA. Sie können ein verborgenes Mitglied einer Enum erstellen, indem Sie den Namen in Klammern einschließen und dann mit einem Unterstrich voranstellen. Beispiel:

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 

In Excel-VBA können Sie auf Zellen verweisen, indem Sie sie in eckige Klammern einschließen. Die eckigen Klammern dienen auch als auswerten-Befehl , mit dem Sie die Formel-Syntax auswerten können:

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

Sie können auch Rohdaten ohne MemCopy (RtlMoveMemory) weitergeben, indem Sie LSet mit benutzerdefinierten Typen derselben Größe kombinieren:

 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 

Oktal- und Hex-Literale sind eigentlich vorzeichenlose Typen, diese geben beide -32768 aus:

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

Wie bereits erwähnt, führt die Übergabe einer Variablen in Klammern dazu, dass ByVal übergeben wird:

 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 

Sie können einen String direkt einem Byte-Array zuweisen und umgekehrt:

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

"Mid" ist auch ein Operator. Wenn Sie es verwenden, überschreiben Sie bestimmte Teile von Strings ohne die langwierige String-Verkettung von 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 

Es gibt eine wichtige, aber fast immer vermisste Eigenschaft der Mid () -statement. Das ist, wo Mid () auf der linken Seite einer Zuweisung im Gegensatz zu der Mid () -function angezeigt wird, die auf der rechten Seite oder in einem Ausdruck angezeigt wird.

Wenn die Zielzeichenfolge kein Zeichenfolgenliteral ist und dies der einzige Verweis auf die Zielzeichenfolge ist und die Länge des einzufügenden Segments der Länge des zu ersetzenden Segments entspricht, wird die Zeichenfolge wie behandelt veränderbar für die Operation.

Was bedeutet das? Es bedeutet, dass wenn Sie einen großen Bericht oder eine große Liste von Strings zu einem einzelnen String-Wert zusammenfassen, die Auswertung dieser Zeichenfolge die Verarbeitung Ihrer Strings viel schneller machen wird.

Hier ist eine einfache class, die davon profitiert. Es gibt Ihrem VBA die gleiche StringBuilder-Fähigkeit wie .NET.

 ' 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 

Und hier ist ein Beispiel, wie man es benutzt:

  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 

VBA selbst scheint eine versteckte Eigenschaft zu sein. Leute, die jahrelang Office-Produkte verwendet haben, haben keine Ahnung, dass es sogar ein Teil der Suite ist.

Ich habe dies hier auf mehreren Fragen gepostet, aber der Objektbrowser ist meine Geheimwaffe. Wenn ich schnell etwas mit Ninja Code schreiben muss, aber die DLLs nicht kenne, rettet der Objektbrowser mein Leben. Es macht es viel einfacher, die classnstrukturen als MSDN zu lernen.

Das Locals-Fenster eignet sich auch hervorragend zum Debuggen. Machen Sie eine Pause in Ihrem Code und es zeigt Ihnen alle Variablen, ihre Namen und ihre aktuellen Werte und Typen im aktuellen Namespace.

Und wer könnte unseren guten Freund Immediate Window vergessen? Es ist nicht nur ideal für Debug.Print Standard-Ausgabe, aber Sie können auch in Befehle eingeben. Wissen Sie, was VariableX ist?

 ?VariableX 

Müssen Sie wissen, welche Farbe diese Zelle hat?

 ?Application.ActiveCell.Interior.Color 

Tatsächlich sind all diese Fenster großartige Werkzeuge, um mit VBA produktiv zu sein.

Es ist kein Feature, aber eine Sache, die ich so oft in VBA (und VB6) gesehen habe: Klammern hinzugefügt bei Methodenaufrufen, wo es die Semantik ändern wird:

 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 

Versteckte functionen

  1. Obwohl es “Basic” ist, können Sie OOP – classn und Objekte verwenden
  2. Sie können API-Aufrufe durchführen

Möglicherweise sind die am wenigsten dokumentierten functionen in VBA diejenigen, die Sie nur verfügbar machen können, indem Sie im VBA-Objektbrowser “Verborgene Elemente anzeigen” auswählen. Versteckte Elemente sind die functionen in VBA, die jedoch nicht unterstützt werden. Sie können sie verwenden, aber Microsoft kann sie jederzeit beseitigen. Keiner von ihnen hat eine Dokumentation zur Verfügung gestellt, aber Sie können einige im Internet finden. Möglicherweise am meisten gesprochen von diesen versteckten functionen bietet Zugriff auf pointers in VBA. Für eine anständige Write-up, Check-out; Nicht so leicht – Shlwapi.dll

Dokumentiert, aber vielleicht obskurer (in Excel sowieso) verwendet ExecuteExcel4Macro, um auf einen versteckten globalen Namespace zuzugreifen, der zu der gesamten Excel-Anwendungsinstanz im Gegensatz zu einer bestimmten Arbeitsmappe gehört.

Sie können Schnittstellen mit dem Schlüsselwort Implements .

Wörterbücher. VBA ist praktisch ohne sie wertlos!

Verweisen Sie auf die Microsoft Scripting Runtime, verwenden Sie Scripting.Dictionary für jede ausreichend komplizierte Aufgabe und leben Sie glücklich danach.

Die Scripting Runtime bietet Ihnen auch das FileSystemObject, das ebenfalls sehr empfehlenswert ist.

Fang hier an und grabe etwas herum …

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

Eingabe von VBA. Es wird eine Intellisense-Liste aller integrierten functionen und Konstanten angezeigt.

Mit ein wenig Arbeit können Sie über benutzerdefinierte Sammlungen wie folgt iterieren:

 ' 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 

Ihr benutzerdefinierter Sammlungscode (in einer class namens 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 
  • Speichern Sie 4 ganze Tastenanschläge, indem Sie debug.? xxx debug.? xxx statt debug.print xxx .
  • Absturz durch Hinzufügen von: enum foo: me=0: end enum die enum foo: me=0: end enum an die Spitze eines Moduls, das irgendeinen anderen Code enthält.

Unterstützung für lokalisierte Versionen, die (mindestens im vorherigen Jahrhundert) Ausdrücke mit lokalisierten Werten unterstützten. Wie Pravda für True und Fałszywy (nicht sicher, aber zumindest hatte es das witzige L) für False auf Polnisch … Eigentlich könnte die englische Version Makros in jeder Sprache lesen und im Handumdrehen konvertieren. Andere lokalisierte Versionen würden das jedoch nicht behandeln.

SCHEITERN.

Das VBE-Objektmodell (Visual Basic Extensibility) ist eine weniger bekannte und / oder zu wenig genutzte function. Sie können VBA-Code schreiben, um VBA-Code, Module und Projekte zu bearbeiten. Ich schrieb einmal ein Excel-Projekt, das andere Excel-Projekte aus einer Gruppe von Moduldateien zusammenstellen würde.

Das Objektmodell funktioniert auch mit VBScript und HTAs. Ich habe einmal eine HTA geschrieben, um mir dabei zu helfen, eine große Anzahl von Word-, Excel- und Access-Projekten zu verfolgen. Viele der Projekte würden gemeinsame Codemodule verwenden, und es war einfach für Module, in einem System zu “wachsen” und dann zu anderen Systemen migriert zu werden. Meine HTA würde es mir ermöglichen, alle Module in einem Projekt zu exportieren, sie mit Versionen in einem gemeinsamen Ordner zu vergleichen und aktualisierte Routinen zusammenzuführen (mit BeyondCompare) und dann die aktualisierten Module erneut zu importieren.

Das VBE-Objektmodell funktioniert in Word, Excel und Access leicht unterschiedlich und funktioniert leider nicht mit Outlook, bietet aber dennoch eine großartige Möglichkeit zur Codeverwaltung.

IsDate("13.50") gibt True aber IsDate("12.25.2010") gibt False

Dies liegt daran, dass IsDate genauer IsDateTime genannt werden IsDateTime . Und weil der Punkt ( . ) Als Zeittrennzeichen und nicht als Datumstrennzeichen behandelt wird. Sehen Sie hier für eine vollständige Erklärung .

VBA unterstützt bitweise Operatoren zum Vergleichen der Binärziffern (Bits) zweier Werte. Zum Beispiel wertet der Ausdruck 4 und 7 die Bitwerte von 4 (0100) und 7 (0111) aus und gibt 4 zurück (das Bit, das in beiden Zahlen leuchtet.) In ähnlicher Weise wertet der Ausdruck 4 oder 8 die Bitwerte in 4 (0100 ) und 8 (1000) und gibt 12 (1100) zurück, dh die Bits, bei denen beide wahr sind.

Leider haben die bitweisen Operatoren dieselben Namen bei den logischen Vergleichsoperatoren: Und, Eqv, Imp, Not, Or und Xor. Dies kann zu Mehrdeutigkeiten und sogar widersprüchlichen Ergebnissen führen.

Öffnen Sie als Beispiel das Direktfenster (Strg + G) und geben Sie ein:? (2 und 4) Dies gibt Null zurück, da zwischen 2 (0010) und 4 (0100) keine Bits gemeinsam sind.

DefType-statementen

Diese function existiert vermutlich aus Gründen der Abwärtskompatibilität. Oder um hoffnungslos verschleierten Spaghetti Code zu schreiben. Deine Wahl.