Tipps zum Golfen in VBA

16

Ähnlich wie diese , diese und diese Frage ...

Welche allgemeinen Tipps haben Sie zum Golfen VBA? Ich bin auf der Suche nach Ideen, die sich auf Code-Golf-Probleme im Allgemeinen anwenden lassen, die zumindest etwas spezifischer sind VBA(z. B. "Kommentare entfernen" ist keine Antwort). Bitte posten Sie einen Tipp pro Antwort.

Während ich mit anderen Sprachen gearbeitet habe, bin ich am stärksten in VBAund ich sehe nicht viele Golfer VBAauf dieser Seite.

Gaffi
quelle
Gemäß Richtlinie in Community-Wiki konvertiert.
dmckee
Entschuldigung, das war nicht automatisch von meiner Seite!
Gaffi
Kein Problem. Tatsächlich haben sie den Benutzern die Macht genommen, Fragen CW zu entziehen (ich denke, Sie können immer noch Antworten geben). Sie könnten die Aufmerksamkeit des Moderators auf sich ziehen, aber so wenig Aktivität wie CodeGolf benötigt dies kaum.
dmckee
2
VBA ist eine relativ ausführliche Sprache mit wenigen Syntaxverknüpfungen. Wenn Sie das beste Ergebnis erzielen möchten, ist VBA möglicherweise keine gute Wahl. Wenn Sie Ihre Fähigkeiten verbessern möchten, haben Sie mehr Kraft.
Mr. Llama
2
@GigaWatt Honing meine Fähigkeiten ist es. Seit ich mit verschiedenen Herausforderungen herumgespielt habe, habe ich mir bereits ein paar neue Tricks für die Arbeit mit VBA angeeignet! Ich erwarte nicht, mit VBA echte Code-Golf- Herausforderungen zu gewinnen, aber es ist eine gute Übung. :-)
Gaffi

Antworten:

8

Nutzen Sie die ByRefStandardeinstellung, wenn Sie Subs anrufen

Es ist manchmal möglich, einen SubAnruf anstelle von Functionzu verwenden, um ein paar zusätzliche Zeichen zu speichern ...

Dies ( 87 Zeichen)

Sub a()
b = 0
Do Until b = 5
b = c(b)
Loop
End Sub
Function c(d)
c = d + 1
End Function

kann überarbeitet werden auf ( 73 Zeichen):

Sub a()
b = 0
Do Until b = 5
c b
Loop
End Sub
Sub c(d)
d = d + 1
End Sub

Beachten Sie, dass dies NICHT für immer wiederholt wird, obwohl der bWert anscheinend nie neu zugewiesen wird.

Das oben Genannte verwendet keinen FunctionAufruf, sondern nutzt stattdessen die ByRef("Nach Referenz") - Funktionalität des SubAufrufs. Dies bedeutet, dass das übergebene Argument dieselbe Variable wie in der aufrufenden Funktion ist (im Gegensatz zu der ByValÜbergabe "Nach Wert", bei der es sich um eine Kopie handelt). Alle Änderungen an der übergebenen Variablen werden zurück in die aufrufende Funktion übersetzt.

Standardmäßig nimmt alle Argumente als an ByRef, sodass keine Zeichen für die Definition erforderlich sind.

Das obige Beispiel wird möglicherweise nicht perfekt für Sie übersetzt, abhängig vom Rückgabewert Ihrer Funktion. (dh es wird ein anderer Datentyp als der übergebene zurückgegeben), dies ermöglicht jedoch auch die Möglichkeit, einen Rückgabewert abzurufen, während die ursprüngliche Variable weiterhin geändert wird.

Beispielsweise:

Sub a()
b = 0
Debug.Print c(b) ' This will print 0, and b will equal 1.'
End Sub
Function c(d)
c = d
d = d + 1
End Function
Gaffi
quelle
7

Schreiben Sie den VBA-Code und führen Sie ihn im Direktfenster aus

Das Direktfenster wertet alle gültigen ausführbaren VBA-Anweisungen aus. Geben Sie einfach eine Anweisung in das Direktfenster ein, wie Sie es im Code-Editor tun würden. Es führt schnell VBA-Code aus und kann viele zusätzliche Zeichen speichern, weil:

  1. Das Fragezeichen (?) Am Anfang der Anweisung weist das Direktfenster an, das Ergebnis Ihres Codes anzuzeigen.

Bildbeschreibung hier eingeben

  1. Sie müssen in Ihrem Code kein Sub und kein End Sub verwenden.

Bildbeschreibung hier eingeben


Hier ist das Beispiel für VBA-Code im Direktfenster, um den Beitrag von PPCG mit dem Tag zu beantworten : Der Buchstabe A ohne A

?Chr(88-23);

von Joffan beantwortet .


Kreditbilder: Excel Campus

Anastasiya-Romanova 秀
quelle
1
Verwendet das eine REPL-Umgebung? Das heißt, es ist nur ein Ausschnitt, kein Programm oder eine Funktion
Caird Coinheringaahing
Ich denke, ein weiteres Beispiel könnte sein, dass Sie auch Variablen inline erstellen können. zB a="value":?asetzt zuerst den Wert von aund druckt ihn dann aus.
Greedo
6

Bedingte Prüfungen vor dem Schleifen

Einige bedingte Prüfungen sind in Verbindung mit Schleifen überflüssig. Beispielsweise wird eine ForSchleife nicht verarbeitet, wenn die Startbedingung außerhalb des Bereichs der laufenden Bedingung liegt.

Mit anderen Worten, dies ( 49 Zeichen):

If B > 0 Then
For C = A To A + B
'...
Next
End If

Kann in diese umgewandelt werden ( 24 Zeichen):

For C = A To A + B ' if B is 0 or less, then the code continues past Next, unabated.
'...
Next
Gaffi
quelle
Der Kommentar unten ist falsch. Wenn B = 0 ist, wird die Schleife eingegeben. pastebin.com/97MBB7hq
QHarr
5

Variable Aussage

In den meisten Fällen können Sie in VBA viele Ihrer Variablen Option Explicitüberspringen Dim.

Dabei ( 96 Zeichen):

Option Explicit

Sub Test()
Dim S As String
Dim S2 As String
S = "Test"
S2 = S
MsgBox S2
End Sub

Wird dies ( 46 Zeichen):

Sub Test()
S = "Test"
S2 = S
MsgBox S2
End Sub

Wenn Sie bestimmte Objekte (z. B. Arrays) verwenden müssen, müssen Sie Dimdiese Variable möglicherweise weiterhin verwenden .

Gaffi
quelle
Warten Sie eine Sekunde, Sie haben Ihre eigene Antwort auf Ihre Frage akzeptiert. Nicht cool, Alter.
Taylor Scott
1
@TaylorScott Es ist ein Wiki-Beitrag - keine Punkte, und in diesem Fall gibt es keine einzige beste Antwort. :) Ich akzeptiere die Antwort vor ~ 5 Jahren, um zu vermeiden, dass eine Flagge in meiner Fragenliste steht.
Gaffi
1
@ TaylorScott auch wenn Sie Ihre eigene Antwort akzeptieren, erhalten Sie nicht +15 oder +2 (für die Annahme)
Caird Coinheringaahing
5

Evaluate() Und []

Wie bereits erwähnt, können hartcodierte Reichweitenanrufe mithilfe der [A1]Notation in eckigen Klammern reduziert werden . Es hat jedoch viel mehr Verwendungen als nur das.

Gemäß der MSDN-Dokumentation verwendet die Application.Evaluate()Methode ein einzelnes Argument, das Namedurch die Namenskonvention von Microsoft Excel definiert ist.

NB [string]ist eine Abkürzung für Evaluate("string")(beachten Sie die ""Sprachmarkierungen für den Datentyp der Zeichenfolge), obwohl am Ende einige wichtige Unterschiede behandelt werden.

Was bedeutet das alles in Bezug auf die Nutzung?

Stellt im Wesentlichen [some cell formula here]eine Zelle in einem Excel-Arbeitsblatt dar, und Sie können so ziemlich alles hineinstecken und alles herausholen, was Sie mit einer normalen Zelle könnten

Was geht in

Zusammenfassend mit Beispielen

  • A1-artige Referenzen. Alle Referenzen gelten als absolute Referenzen.
    • [B7] gibt einen Verweis auf diese Zelle zurück
    • Da Referenzen absolut sind, wird ?[B7].Addresszurückgegeben"B$7$"
  • Bereiche Sie können die Operatoren range, intersect und union (Doppelpunkt, Leerzeichen bzw. Komma) mit Referenzen verwenden.
    • [A1:B5]gibt eine Bereichsreferenz auf A1:B5(Range) zurück
    • [A1:B5 A3:D7]gibt einen Bereichsverweis auf A3:B5(Intersect) zurück
    • [A1:B5,C1:D5]gibt einen Bereichsverweis auf A1:D5(technisch A1:B5,C1:D5) (Union) zurück
  • Definierte Namen
    • Benutzerdefiniert wie unter [myRange]Bezugnahme auf A1: G5
    • Automatisch, wie Tabellennamen [Table1](möglicherweise weniger nützlich für Codegolf)
    • Alles andere finden Sie im Menü [Formulas]>[Name Manager]
  • Formeln
    • Sehr nützlich ; Jede Formel, die in eine Zelle gehen kann, kann in Evaluate()oder gehen[]
    • [SUM(1,A1:B5,myRange)]Gibt eine arithmetische Summe von Werten in den Bereichen zurück. myRange bezieht sich hier auf einen Arbeitsmappennamen und nicht auf eine VBA-Variable
    • [IF(A1=1,"true","false")](1 Byte kürzer als VBA-Äquivalent Iif([A1]=1,"true","false"))
    • Matrixformeln [CONCAT(IF(LEN(A1:B7)>2,A1:B7&" ",""))]- Verbindet alle Zeichenfolgen im Bereich, deren Länge größer als 2 ist, mit einem Leerzeichen
  • Externe Referenzen
    • Mit dem !Operator können Sie auf eine Zelle oder auf einen Namen verweisen, der in einer anderen Arbeitsmappe definiert ist
    • [[BOOK1]Sheet1!A1]Gibt einen Bereichsverweis auf A1 in BOOK1 oder ['[MY WORKBOOK.XLSM]Sheet1!'A1]für denselben in zurückMY WORKBOOK
    • Beachten Sie die 'für Arbeitsmappen mit Leerzeichen im Namen und das Fehlen der Erweiterung für standardmäßig benannte Arbeitsmappen ( BOOK+n)
  • Diagrammobjekte (siehe MSDN-Artikel)

NB Ich habe eine Frage zu SO für diese Info gestellt, also schau dort nach einer besseren Erklärung

Was kommt raus?

Ähnlich dem, was hereinkommt, enthält das, was herauskommt, alles, was eine Arbeitsblattzelle zurückgeben kann. Dies sind die Standard-Excel-Datentypen (und ihre VBA-Entsprechungen):

  • Logisch ( Boolean)
  • Text ( String)
  • Numerisch ( Double)
  • Error ( Variant/Error) (Dies sind nicht unterbrechende Fehler, dh sie stoppen die Codeausführung nicht, werden ?[1/0]einwandfrei ausgeführt.)

Es können jedoch einige Dinge zurückgegeben werden, die Zellen nicht zurückgeben können:

  • Bereichsreferenz ( Range) (siehe oben)
  • Arrays ( Variant())

Arrays

Wie gezeigt wurde, []können damit Matrixformeln ausgewertet werden, die einen der Standard-Excel-Datentypen zurückgeben. zB [CONCAT(IF(LEN(A1:B7)>2,A1:B7&" ",""))]was zurückkommt Text. Jedoch Evaluatekönnen auch Anordnungen von VariantRücktyp. Das kann sein

Hardcoded:

[{1,2;3,4}]- gibt ein 2D-Array aus: ,Ist das Spaltentrennzeichen, ;trennt Zeilen. Kann ein 1D-Array ausgeben

Matrixformeln:

[ROW(A1:A5)]- gibt ein 2D- Array aus {1,2,3,4,5}, dh (2,1) ist das zweite Element (dennoch geben einige Funktionen 1D-Arrays aus)

  • Aus irgendeinem Grund geben einige Funktionen standardmäßig keine Arrays zurück

[LEN(A1:A5)] Gibt nur die Länge des Texts in der 1. Zelle eines Bereichs aus

  • Diese können jedoch zu Arrays gezwungen werden

Split([CONCAT(" "&LEN(A1:A5))]) gibt ein 1D-Array von 0 bis 5 an, wobei das erste Element leer ist

[INDEX(LEN(A1:A5),)]Dies ist eine weitere Problemumgehung. Im Wesentlichen müssen Sie eine Arrayhandhabungsfunktion verwenden, um das gewünschte Arrayrückgabeverhalten zu erhalten, ähnlich dem Hinzufügen einer sinnlosen Funktion RAND(), um Ihre Arbeitsblattformeln flüchtig zu machen.

  • Ich habe eine Frage zu SO gestellt , um zu versuchen, bessere Informationen zu erhalten. Bitte bearbeite / kommentiere mit besseren Optionen, wenn du sie findest

Evaluate() vs []

Es gibt ein paar Unterschiede zwischen Evaluate()und []zu beachten

  1. Strings vs hardcoded
    • Der vielleicht wichtigste Unterschied ist, dass Evaluate eine Zeichenfolge eingibt, für die [] eine fest codierte Eingabe erforderlich ist
    • Dies bedeutet , dass Ihr Code kann die Zeichenfolge mit Variablen aufbauen zB Evaluate("SUM(B1,1,"&v &",2)")würde summieren [B1], 1, 2und variablev
  2. Arrays

    Bei der Rückgabe eines Arrays kann nur Evaluate mit einem Array-Index verwendet werden

    v=Evaluate("ROW(A1:A5)")(1,1) ''#29 bytes

    ist äquivalent zu

    i=[ROW(A1:A5)]:v=i(1,1) ''#23 bytes
Greedo
quelle
Entschuldigen Sie den Mammut-Beitrag. Wenn jemand der Meinung ist, dass er Bereiche präziser gestalten kann, oder wenn Sie Tipps zum Hinzufügen haben, dann fühlen Sie sich frei. Auch wenn ich einiges davon recherchiert habe, wurde durch Experimentieren in VBA ein angemessener Teil gefunden. Wenn Sie also Fehler bemerken, die das Gefühl haben, dass etwas fehlt, zögern Sie nicht, dies zu kommentieren / zu bearbeiten!
Greedo
1
Tatsächlich ist der letzte Abschnitt auf Arrays etwas abweichend - er kann im unmittelbaren Fenster verwendet werdeni=[ROW(A1:A5)]:v=i(2,1):?v
Taylor Scott
@TaylorScott Sie können also, ich wusste überhaupt nicht, dass Sie Werte in Variablen setzen / halten können, die noch nicht definiert wurden, aber ich nehme an, das liegt daran, dass ich immer noch mit den Immediate-Window-1-Linern zurechtkomme. Haben entsprechend aktualisiert
Greedo
Funktioniert das mit Match? Ich habe es versucht, aber es gibt immer Fehler zurück. Ich habe jedoch ein Array anstelle eines Bereichs übergeben.
Seadoggie01
5

kombinieren Sie NextStatements

Next:Next:Next

Darf bis auf kondensiert werden

Next k,j,i

wo die Iteratoren für die ForSchleifen sind i, jund k- in dieser Reihenfolge.

Zum Beispiel die unten (69 Bytes)

For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next
Next
Next

Kann auf 65 Bytes reduziert werden

For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next k,j,i

Und was die Auswirkungen auf Formatierung und Einrückung angeht, ist es meiner Meinung nach am besten, die nächste Anweisung an der äußersten for-Anweisung auszurichten. Z.B.

For i=0To[A1]
    For j=0To[B1]
        For k=0To[C1]
            Debug.?i;j;k
Next k,j,i
Taylor Scott
quelle
4

IfAnweisungen reduzieren

Wenn Sie eine Variable mit einem bedingten If ... Then ... ElseHäkchen zuweisen , können Sie den Code reduzieren, indem Sie das End Ifentfernen, indem Sie das gesamte Häkchen in eine Zeile setzen.

Zum Beispiel ist dies ( 37 Zeichen):

If a < b Then
c = b
Else
c = a
End If

Kann darauf reduziert werden ( 30 Zeichen)

If a < b Then c = b Else c = a

Wenn Sie mehr als eine verschachtelte Bedingung haben, können Sie diese auch auf diese Weise minimieren:

If a Then If b Then If c Then Z:If d Then Y:If e Then X Else W Else V:If f Then U 'Look ma! No "End If"!

Beachten :Sie, dass Sie innerhalb eines IfBlocks mehr als eine Zeile / einen Befehl hinzufügen können .

In einfachen Fällen wie diesem können Sie das normalerweise auch entfernen, Elseindem Sie die Variable vor dem IfCheck setzen ( 25 Zeichen):

c = a
If a < b Then c = b

Noch besser ist, dass das oben Genannte mit der IIf()Funktion ( 20 Zeichen) weiter darauf reduziert werden kann :

c = IIf(a < b, b, a)
Gaffi
quelle
3

Range("A1")Anrufe reduzieren und liken

Range("A1").Value(17 Bytes) und die einfacheren Range("A1")(11 Bytes) können auf [A1](4 Bytes) reduziert werden

Taylor Scott
quelle
2
Oder im Allgemeinen ist die Verwendung von []zum Ersetzen Evaluate()in VBA viel vielseitiger als nur Bereichsaufrufe. ZB können Sie es WorksheetFunction.FuncName(args)mit nur ersetzen [FuncName(args)], wie ?[SUMPRODUCT({1,3,5},{2,7,-1})]oder die sehr nützliche [MIN(1,2,3)]/[MAX(1,2,3)]
Greedo
Greedo, das ist eine unglaublich wichtige Funktion, von der ich nicht wusste, dass du sie als eigene Antwort hinzufügen solltest.
Taylor Scott
1
Klar, ich schreibe gleich was auf. Ja, Evaluate("str")oder Kurzschrift [str]ist in VBA sehr mächtig, das habe ich erst kürzlich herausgefunden, und ich vermute, es wird auch zum Golfen nützlich sein!
Greedo
Sehr nützlich, genug, damit ich meine Antworten noch einmal durchgehen kann, um zu sehen, ob ich mein bytecount deswegen auf irgendetwas ablegen kann
Taylor Scott
3

Leerzeichen entfernen

VBA wird automatisch formatiert, um viel Abstand hinzuzufügen, den es eigentlich nicht benötigt. Es gibt eine Antwort auf Meta , die für mich sehr sinnvoll ist, warum wir durch automatische Formatierung hinzugefügte Bytes rabattieren können. Es ist jedoch wichtig, immer zu überprüfen, ob Sie nicht zu viel entfernt haben. Als Beispiel hier eine Antwort von mir , die durch das Entfernen von Leerzeichen um fast 22% reduziert wurde:

Originalversion: (188 Byte)

Sub g(n)
For i = 0 To 1
For x = -3 To 3 Step 0.05
y = n ^ x * Cos(Atn(1) * 4 * x)
If y < m Then m = y
If i = 1 Then Cells(500 * (1 - y / m) + 1, (x + 3) * 100 + 1) = "#"
Next
Next
End Sub

Reduzierte Version: (146 Bytes)

Sub g(n)
For i=0To 1
For x=-3To 3Step 0.05
y=n^x*Cos(Atn(1)*4*x)
If y<m Then m=y
If i=1Then Cells(500*(1-y/m)+1,(x+3)*100+1)="#"
Next
Next
End Sub

Wenn Sie die reduzierte Version in VBA kopieren / einfügen, wird sie automatisch im Original erweitert. Sie können damit herumspielen, wo es gültig ist, Leerzeichen zu entfernen. Diejenigen, die ich bisher gefunden habe, scheinen alle dem Muster zu folgen, bei dem von VBA erwartet wird, dass ein bestimmter Befehl angezeigt wird, da es ohne ihn keinen gültigen Code gibt. Hier sind einige, die ich bisher gefunden habe:

  • Vor und nach jeder mathematischen Operation: +-=/*^usw.
  • Vor Tound Stepin einer ForAussage:For x=-3To 3Step 0.05
  • Eigentlich vor jedem reservierten Wort ( To, &, Then, etc.) , wenn es von einer wörtlichen wie beispielsweise eine Zahl vorangestellt ist, ), ?, %usw.
  • Nach dem &beim Kombinieren von Strings:Cells(1,1)=Int(t)&Format(t,":hh:mm:ss")
  • Nach Funktionsaufrufen: If s=StrReverse(s)Then
  • Innerhalb von Funktionsaufrufen: Replace(Space(28)," ",0)
Ingenieur Toast
quelle
Wie lautet die Regel für das Hinzufügen von Nicht-Leerzeichen durch automatische Formatierung? So etwas wie ?vs Printsehe ich akzeptabel, aber setzen bei Typdeklaration wie &unmittelbar nach einer Variablen zB Debug.?a&"z"gibt Debug.Print a&; "z". Das ;hinzugefügte Zeichen ist für die Ausführung des Codes unerlässlich. Ist dies noch zulässig?
Greedo
2
@Greedo Ich sehe es so, wie es in der Meta-Antwort beschrieben wurde: Wenn Sie es kopieren / in den Editor einfügen können und der Code ausgeführt wird, ist es OK. IE, wenn VBA das Zeichen automatisch wieder hinzufügt, wenn Sie den Code einfügen, dann ist es OK.
Ingenieur Toast
1
@EngineerToast Sie tatsächlich ein Byte mehr aus Ihrem Beispiel fallen können: If i=1 Then werden kann , If i=1Then weil in der Regel ein reserviertes Wort , das wörtlich folgt, sein , dass eine Reihe, ), ?, %, .. etc, muss nicht durch eine getrennt werden Weltraum
Taylor Scott
1
@EngineerToast, Sie können auch ein Byte von Ihrem dritten Aufzählungspunkt entfernen, da Sie die Leerzeichen zwischen einem )(oder einem anderen Nicht-Zahlen-Literal) und&
Taylor Scott
3

Vorbereitung für Pixel Art

Pixelkunst ist bei weitem einer der stärksten Bereiche von Excel, da keine Leinwand erstellt werden muss, da sie bereits für Sie vorhanden ist. Sie müssen lediglich einige kleine Anpassungen vornehmen

1) Stellen Sie die Zellen quadratisch

Cells.RowHeight=48

oder alternativ für 1 Byte mehr, aber weitaus einfacher zu bearbeiten

Cells.ColumnWidth=2

2) Färben Sie den gewünschten Bereich ein

Jedes RangeObjekt kann durch Aufrufen eingefärbt werden

`MyRangeObj`.Interior.Color=`ColorValue`

Hinweis: Dies kann und sollte mit anderen Tricks kombiniert werden, die in diesem Wiki aufgeführt sind, z. B. das Referenzieren von Bereichen mithilfe der []Notation (z. B. [A1:R5,D6]) über die Verwendung eines Cells(r,c)oder eines Range(cellAddress)Anrufs. Wie in diesem Wiki erwähnt, kann dies mit einem negativen Farbwert kombiniert werden, um die Größe der Farbreferenzen zu verringern

Schnellreferenzen

Bereichsreferenz

Auf die Zelle A1kann auf eine der folgenden Arten verwiesen werden

Range("A1")
Cells(1,1)
[A1]

und der Bereich A1:D4kann auf eine der folgenden Arten referenziert werden

Range("A1:D4")
Range("A1").Resize(4,4)
Cells(1,1).Resize(4,4)
[A1].Resize(4,4,)
[A1:D4]

Farbreferenz

Black  0
White  -1
Red    255
Aqua   -256
Taylor Scott
quelle
3

Integrierte Funktionen vereinfachen

Wenn Sie bestimmte Funktionen häufig verwenden, weisen Sie sie einer benutzerdefinierten Funktion zu.

Der folgende Code ( 127 Zeichen) kann reduziert werden von:

Sub q()
w = 0
x = 1
y = 2
z = 3
a = Format(w, "0.0%")
b = Format(x, "0.0%")
c = Format(y, "0.0%")
d = Format(z, "0.0%")
End Sub

bis ( 124 Zeichen):

Sub q()
w = 0
x = 1
y = 2
z = 3
a = f(w)
b = f(x)
c = f(y)
d = f(z)
End Sub
Function f(g)
f = Format(g, "0.0%")
End Function

In Kombination mit dem ByRef-Trick können Sie noch mehr Zeichen speichern (bis zu 114 ):

Sub q()
w = 0
x = 1
y = 2
z = 3
a = f(w)
b = f(x)
c = f(y)
d = f(z)
End Sub
Sub f(g)
g = Format(g, "0.0%")
End Sub

Gehen Sie dabei mit Bedacht vor, da VBA zum Definieren von a viele Zeichen benötigt Function. Der zweite Codeblock wäre tatsächlich größer als der erste mit einer beliebigen Anzahl von weniger Format()Aufrufen.

Gaffi
quelle
2
im letzten a = f(w)Fall benötigen Sie keinen Zuweisungsaufruf, was bedeutet, dass er auff w
Taylor Scott
3

STDIN und STDOUT

Eingabe in SubRoutinen und Functions über Eingabevariablen

Public Sub A(ByRef B as String)

Darf reduziert werden auf

Sub a(b$) 

Die Aufrufe Publicund ByRefsind die Standardeinstellung für VBA und daher implizit und können (fast) immer verworfen werden.

Das Typliteral $erzwingt bden Typ String.

Andere Typliterale

  • ! Single
  • @ Währung
  • # Doppelt
  • % Ganze Zahl
  • $ String
  • & Lange
  • ^ LongLong (nur 64 Bit)

Darüber hinaus wird allgemein akzeptiert, dass Sie die Eingabevariable als Standardtyp Variantbelassen und typbasierte Fehler unbehandelt lassen können. Z.B. Sub E(F)in dem Ferwartet wird, dass er vom Typ ist Boolean[](der wie folgt an die Routine übergeben wird E Array(True, False, False))

Eingabe in SubRoutinen und Direktfensterfunktionen überCells

VBA hat keine voll funktionsfähige Konsole und daher keine offizielle STDIN und ermöglicht daher ein gewisses Spiel mit der Weitergabe von Eingaben.

In Excel ist es allgemein akzeptiert, Eingaben von einer Zelle oder einem Zellbereich zu übernehmen, wie dies auch geschehen kann

s=[A1]

die implizit die .valueaus der Zelle [A1](die auch als cells(1,1)oder verwiesen werden kannrange("A1")

Beispiel Problem: Zeigen Sie die Eingabe in einer Messagebox an

Über Unterprogramm Sub A:msgbox[A1]:End Sub

Über die Sofortfensterfunktion msgbox[A1]

Eingabe über bedingte Kompilierungsargumente

VBA-Projekte unterstützen die Übernahme von Argumenten über die Befehlszeile oder über die VBAProject-Eigenschaften (Ansicht über den Projektexplorer -> [Ihr VBA-Projekt] - (Rechtsklick) -> VBAProject-Eigenschaften -> Bedingte Kompilierungsargumente).

Dies ist vor allem bei Fehlercode-Herausforderungen hilfreich

Mit dem Argument n=für bedingte Kompilierung [some_value] kann Code ausgeführt werden, der einen Fehlercode erzeugt, der auf dem Wert von basiert n. Beachten Sie, dass dies ein Hinzufügen von 2 Byte zu Ihrem Code für den n=Abschnitt mit den bedingten Kompilierungsargumenten des VBAProject-Eigenschaftsfensters erfordert.

Beispielcode

...
#If n=3 then
return ''  Produces error code '3', Return without GoSub
#ElseIf n=20 then
resume ''  Produces error code '20', Resume without Error
#EndIf
...

Ausgabe über Funktionswert

Es ist hier nicht viel zu sagen, dass die im Folgenden zitierte allgemeine Form so kompakt ist, wie sie hergestellt werden kann.

Public Function A(b)
    ...
    A=C
End Function

HINWEIS: In den allermeisten Fällen ist es mehr Byte, die Methode in eine Unterroutine umzuwandeln und an das VBE-Direktfenster auszugeben (siehe unten).

Ausgabe von SubRoutinen und Functions über das VBE- Direktfenster

Die Ausgabe in das VBE-Direktfenster (AKA, das VBE-Debug-Fenster) ist eine übliche Ausgabemethode für VBA für textbasierte Herausforderungen. Es ist jedoch wichtig zu bedenken, dass der Debug.Print "Text"Anruf möglicherweise im Wesentlichen ausgenutzt wird.

Debug.Print "Text"

ist funktional identisch mit

Debug.?"Text"

als ?autoformate zu Print.

Ausgabe von SubRoutinen und VBE- Direktfensterfunktionen über andere Methoden

In seltenen Fällen, in denen die Situation genau richtig ist, können Sie Eingaben von einigen der trivialeren Eingaben für VBA abrufen, z. B. von der Einstellung der Schriftgröße, der Schriftauswahl und dem Zoom. ( Z. B. Emulieren der Wort-Schriftgrößenauswahl )

Taylor Scott
quelle
2

Kurzer Hinweis zur Formatierung

Da StackExchange Markdown und Prettify.js verwendet, können Sie Ihren Codierungsantworten ein Sprachkennzeichen hinzufügen, wodurch sie im Allgemeinen professioneller aussehen. Ich kann zwar nicht garantieren, dass Sie dadurch beim Golfen in VBA besser werden, aber ich kann garantieren, dass Sie so aussehen, wie Sie sind.

Wenn Sie eines der folgenden Flags hinzufügen, wird es umgewandelt

Public Sub a(ByRef b As Integer) ' this is a comment

zu

Public Sub a(ByRef b As Integer) ' this is a comment

VBA-Sprach-Tags

<!-- language: lang-vb -->

<!-- language-all: lang-vb -->

Hinweis: Letzteres transformiert alle Codesegmente in Ihrer Antwort, während das Vorherige nur die unmittelbar folgenden Codesegmente transformiert

Taylor Scott
quelle
lang-vbwie? - Seltsamerweise formatiert sich das besser als lang-vbabei vba-antworten.
Greedo
1
@Greedo, das heißt, während lang-vbaHervorhebungen bereitgestellt werden, ist dies eigentlich nur die Standardhervorhebung. Anscheinend wurde VBA nicht in Prettify.js implementiert, daher müssen wir uns an die VB-Hervorhebung halten
Taylor Scott
2

mehrere If .. ThenKontrollen

Wie in anderen Sprachen können Mehrfachprüfungen Ifnormalerweise in einer einzigen Zeile kombiniert werden, wodurch die Verwendung von And/ Or(dh &&/ ||in C und anderen) ermöglicht wird, das in VBA sowohl a Thenals auch an ersetzt End If.

Zum Beispiel mit einer verschachtelten Bedingung ( 93 Zeichen):

'There are MUCH easier ways to do this check (i.e. a = d).
'This is just for the sake of example.
If a = b Then
    If b = c Then
        If c = d Then
            MsgBox "a is equal to d"
        End If
    End If
End If

kann werden ( 69 Zeichen):

If a = b And b = c And c = d Then
    MsgBox "a is equal to d"
End If

Dies funktioniert auch mit nicht verschachtelten Bedingungen.

Betrachten Sie ( 84 Zeichen):

If a = b Then            
    d = 0
End If

If c = b Then            
    d = 0
End If

Dies kann ( 51 Zeichen) werden:

If a = b Or c = b Then            
    d = 0
End If
Gaffi
quelle
1
In If - then - Anweisungen ist der Teil "End - If" optional, sofern Sie den Code in eine einzelne Zeile schreiben.
Rohan
@ newguy Richtig. Siehe auch diese andere Antwort: codegolf.stackexchange.com/a/5788/3862
Gaffi
Die Aussage oben kann weiter zud=iif(a=b or c=b,0,d)
Taylor Scott
2

Ending ForLoops

Bei der Verwendung von ForSchleifen benötigt eine NextZeile keinen Variablennamen (obwohl es wahrscheinlich besser ist, sie in der normalen Codierung zu verwenden).

Deshalb,

For Variable = 1 to 100
    'Do stuff
Next Variable

kann gekürzt werden auf:

For Variable = 1 to 100
    'Do stuff
Next

(Die Einsparungen hängen von Ihrem Variablennamen ab. Wenn Sie jedoch Golf spielen, ist dies wahrscheinlich nur 1 Zeichen + 1 Leerzeichen.)

Gaffi
quelle
1
2 Zeichen, vergiss nicht das Leerzeichen zu zählen!
11684
Ich identifiziere die Variable fast nie, auch nicht im normalen Code!
Dienstag,
2

Teilen Sie eine Zeichenfolge in ein Zeichenfeld auf

Manchmal kann es nützlich sein, eine Zeichenfolge in einzelne Zeichen aufzuteilen. In VBA kann dies jedoch etwas Code erfordern.

ReDim a(1 To Len(s))
' ReDim because Dim can't accept non-Const values (Len(s))
For i = 1 To Len(s)
    a(i) = Mid(s, i, 1)
Next

Stattdessen können Sie eine einzeilige, relativ minimale Funktionskette verwenden, um die Aufgabe zu erledigen:

a = Split(StrConv(s, 64), Chr(0))

Dadurch wird die Zeichenfolge sdem VariantArray zugewiesen a. Seien Sie jedoch vorsichtig, da das letzte Element im Array eine leere Zeichenfolge ( "") ist, die entsprechend behandelt werden muss.

So funktioniert es: Die StrConvFunktion konvertiert a Stringin ein anderes von Ihnen angegebenes Format. In diesem Fall 64 = vbUnicode, wird also in ein Unicode-Format konvertiert. Bei einfachen ASCII-Zeichenfolgen ist das Ergebnis ein Nullzeichen (keine leere Zeichenfolge ""), das nach jedem Zeichen eingefügt wird.

Im Folgenden Splitwird das Ergebnis Stringin ein Array konvertiert , wobei das Nullzeichen Chr(0)als Begrenzer verwendet wird.

Es ist wichtig zu beachten , dass Chr(0)nicht das gleiche wie die leere Zeichenkette ist "", und die Verwendung Splitauf ""nicht das Array zurückgeben Sie vielleicht erwarten. Gleiches gilt auch für vbNullString(aber wenn Sie Golf spielen, warum sollten Sie dann überhaupt eine solche wortreiche Konstante verwenden?).

Gaffi
quelle
Sie sollten erwähnen, dass das resultierende Array am Ende eine zusätzliche leere Zeichenfolge enthält.
Howard
@ Howard Ja, ich sollte. Es war in meinem Kopf, als ich das abtippte, muss mein Verstand verloren haben.
Gaffi
2

Verwenden With(Manchmal! Siehe Fußnote)

Die Verwendung der WithAnweisung kann Ihre Codegröße erheblich reduzieren, wenn Sie einige Objekte wiederholt verwenden.

dh dies ( 80 Zeichen):

x = foo.bar.object.a.value
y = foo.bar.object.b.value
z = foo.bar.object.c.value

kann codiert werden als ( folgt 79 Zeichen):

With foo.bar.object
    x = .a.value
    y = .b.value
    z = .c.value
End With

Das oben Genannte ist nicht einmal das beste Szenario. Wenn Sie etwas mit verwenden Application, z. B. Excel.Applicationaus Access heraus, ist die Verbesserung viel bedeutender.


* Je nach Situation Withkann oder kann nicht effizienter sein als dies ( 64 Zeichen):

Set i = foo.bar.object
x = i.a.value
y = i.b.value
z = i.c.value
Gaffi
quelle
2

Endlosschleifen

Sollten Sie sie ersetzen

Do While a<b
'...
Loop

oder

Do Until a=b
'...
Loop

mit der veralteten aber niedrigeren Byteanzahl

While a<b
'...
Wend

Wenn Sie a Suboder Functionvorzeitig beenden müssen, verwenden Sie stattExit ...

For i=1To 1000
    If i=50 Then Exit Sub
Next

Erwägen End

For i=1To 1E3
    If i=50 Then End
Next

Beachten Sie, dass die Endgesamte Codeausführung angehalten und alle globalen Variablen gelöscht werden. Gehen Sie also mit Bedacht vor

Greedo
quelle
Sie sollten erwägen, den letzten Abschnitt ( Forund End) neu zu schreiben, um zu berücksichtigen, dass der Fall 100niemals erfüllt wird, und ein unnötiges Byte hinzuzufügen
Taylor Scott
Auch wenn dies sehr gut lesbar ist, können Sie das Leerzeichen entfernen, um die möglichen Vorteile dieser Methoden besser zu verdeutlichen (es ist immer gut, die automatische Formatierung in VBA für das Codegolfing zu missbrauchen)
Taylor Scott
2

Verwenden Sie Spc(n)über Space(n),[Rept(" ",n)] oderString(n," ")

Wenn Sie versuchen, mehrere Leerzeichen einzufügen n, verwenden Sie

Spc(n)              ''  6  bytes

Über

B1=n:[Rept(" ",B1)] ''  19 bytes
String(n," ")       ''  13 bytes
Space(n)            ''  8  bytes

Hinweis: Ich bin mir nicht sicher, warum, aber es scheint, dass Sie die Ausgabe Spc(n)einer Variablen nicht zuweisen können und dass sie lieber direkt gedruckt werden muss - in bestimmten Fällen Space(n)ist dies immer noch der beste Weg.

Taylor Scott
quelle
2

Reduzieren Debug.Printund Printtelefonieren

Debug.Print [some value] 

(12 Bytes; beachten Sie das nachfolgende Leerzeichen) kann auf reduziert werden

Debug.?[some value]

(7 Bytes; beachte den fehlenden Trailing Space).

Ähnlich,

Print 

(6 Bytes) dürfen auf reduziert werden

?

(1 Byte).

Wenn Sie im Kontext einer anonymen VBE-Direktfensterfunktion arbeiten, wird die DebugAnweisung möglicherweise vollständig gelöscht und stattdessen über in das VBE-Direktfenster gedruckt? Direktfensterfunktion gearbeitet wird, verworfen werden kann angenommen werden, dass das Direktfenster über STDIN / STDOUT erfolgt

Spezielle Charaktere

Beim Drucken von Zeichenfolgen können Sie anstelle von auch Sonderzeichen verwenden & . Diese ermöglichen alternative Formate beim Drucken oder beim Entfernen von Leerzeichen

Zum Verbinden von variablen Zeichenfolgen anstelle von

Debug.Print s1 &s2

Sie können ein Semikolon verwenden ;

Debug.?s1;s2

Dieses Semikolon ist das Standardverhalten für aufeinanderfolgende Zeichenfolgen, sofern keine Mehrdeutigkeit vorliegt. Diese sind also gültig:

Debug.?s1"a"
Debug.?"a"s1

Aber nicht

Debug.?s1s2 'as this could be interpreted as a variable named "s1s2", not 2 variables
            'use Debug.?s1 s2 instead (or s1;s2)
Debug.?"a""b" 'this prints a"b, so insert a space or ; for ab

Beachten Sie, dass ein; am Ende einer Zeile unterdrückt eine neue Zeile, da diese standardmäßig nach jedem Druck hinzugefügt wird. Das Zählen der vom VBA-Code zurückgegebenen Bytes ist umstritten

Um mit einem Tabulator zu verbinden, verwenden Sie ein Komma ,(tatsächlich 14 Leerzeichen, aber entsprechend)

Debug.?s1,s2 'returns "s1              s2"

Schließlich können Sie auch Typdeklarationen verwenden, um Zeichenfolgen anstelle von; zu verbinden. Jede dieser Deklarationen wirkt sich geringfügig auf die Formatierung aus. Für alle unten a = 3.14159steht die erste Zeile

Debug.?a&"is pi" -> " 3 is pi" 'dims a as long, adds leading and trailing space to a
Debug.?a!"is pi" -> " 3.14159 is pi" 'dims a as single, adds leading and trailing space
Debug.?a$"is pi" -> "3.14159is pi" 'dims a as string, no spaces added
Taylor Scott
quelle
2

Verwenden Sie einen Helfer SubzuPrint

Wenn der Code die Verwendung von mehr als sechs Debug.? Anweisungen erfordert, können Sie Bytes reduzieren, indem Sie alle Debug-Anweisungen ersetzen. Leitungen mit einem Anruf zu einem Sub wie der folgenden. Um eine leere Zeile zu drucken, müssen Sie aufrufen, p ""da ein Parameter erforderlich ist.

Sub p(m)
Debug.?m
End Sub
Ben
quelle
1
So drucken Sie eine neue Zeile mit , dass Sie würde nur benötigen p""oder wenn es nicht abgeschlossen sein kann, p". In den allermeisten Fällen ist es jedoch sinnvoller, eine Zeichenfolgenvariable zu verwenden und die Zeichenfolgenvariable nur am Ende zu drucken.
Taylor Scott
1

Verwenden Sie Array() Choose()anstelle von SelectoderIf...Then

Wenn Sie eine Variable basierend auf dem Wert einer anderen Variablen zuweisen, ist es sinnvoll, die Schritte If...Thenwie folgt mit einem Häkchen zu versehen:

If a = 1 Then
b = "a"
ElseIf a = 2 Then
b = "c"
'...
End If

Dies kann jedoch viel Codeplatz in Anspruch nehmen, wenn mehr als eine oder zwei Variablen zu überprüfen sind (es gibt im Allgemeinen immer noch bessere Möglichkeiten, dies zu tun).

Stattdessen Select Casehilft die Anweisung, die Größe der Überprüfungen zu verringern, indem alles in einem Block eingeschlossen wird, wie folgt:

Select Case a
Case 1:
b = "a"
Case 2:
b = "c"
'...
End Select

Dies kann zu viel kleinerem Code führen, aber für sehr einfache Fälle wie diesen gibt es eine noch effizientere Methode: Choose()Diese Funktion wählt einen Wert aus einer Liste basierend auf dem an sie übergebenen Wert aus.

b = Choose(a,"a","c",...)

Die Auswahlmöglichkeit ( ain diesem Fall) ist ein ganzzahliger Wert, der als erstes Argument übergeben wird. Bei allen nachfolgenden Argumenten handelt es sich um die Werte, aus denen Sie auswählen können (1-indiziert, wie bei den meisten VBA). Die Werte können beliebige Datentypen sein, solange sie mit der gesetzten Variablen übereinstimmen (dh Objekte funktionieren ohne das SetSchlüsselwort nicht) und können sogar Ausdrücke oder Funktionen sein.

b = Choose(a, 5 + 4, String(7,"?"))

Eine zusätzliche Option ist die Verwendung der ArrayFunktion, um den gleichen Effekt beim Speichern eines anderen Zeichens zu erzielen:

b = Array(5 + 4, String(7,"?"))(a)
Gaffi
quelle
Eine interessante und möglicherweise sehr nützliche Verwendung für das Golfen ist die Verwendung in Verbindung mit dem einen IIf()oder anderen Choose():A1=IIf(a=Choose(b,c,d,e),Choose(Choose(f,g,h,i),j,k,l),Choose(IIf(m=n,Choose(p,q,r,s),IIf(t=u,v,w)),x,y,z))
Gaffi
1

Bitverschobene RGB-Werte

Aufgrund der Art und Weise, wie Excel mit Farben umgeht (vorzeichenlose 6-stellige hexadezimale Ganzzahl), können Sie negativ vorzeichenbehaftete Ganzzahlen verwenden, von denen Excel nur die richtigen 6 Bytes verwendet, um einen Farbwert zuzuweisen

Dies ist etwas verwirrend, so dass nachfolgend einige Beispiele aufgeführt sind

Nehmen wir an, Sie möchten die Farbe Weiß verwenden, die als gespeichert ist

rgbWhite

und ist äquivalent zu

&HFFFFFF ''#value: 16777215

Um dies abzuspielen, müssen wir nur einen negativen Hexadezimalwert finden, der auf endet, FFFFFFund da negative Hexadezimalwerte in dem Format FFFFXXXXXX(also Xeinem gültigen Hexadezimalwert) vorliegen müssen, das von FFFFFFFFFF( -1) bis FFFF000001( -16777215) herunterzählt.

Wenn wir das wissen, können wir die Formel verallgemeinern

Let Negative_Color_Value = -rgbWhite + Positive_Color_Value - 1
                         = -16777215 + Positive_Color_Value - 1
                         = -16777216 + Positive_Color_Value

Hiermit sind einige nützliche Konvertierungen verbunden

rgbWhite = &HFFFFFF = -1 
rgbAqua  = &HFFFF00 = -256
16747627 = &HFF8C6B = -29589
Taylor Scott
quelle
Gut zu wissen, was dort vor sich ging, ich habe es gerade zufällig in dieser Frage entdeckt - aber diese klare Erklärung zeigt genau, wie es funktioniert. Beachten Sie auch, dass bestimmte Schlüsselfarben mit mathematischen Operatoren reduziert werden können. rgbWhite= 2^24-1obwohl möglicherweise weiter reduziert werden könnte, wenn Sie das -1 verpassen, um ungefähr dorthin zu gelangen
Greedo
1
Tatsächlich ist hier eine Liste von Farben mit ihren mathematischen Darstellungen, die kürzer sind als die positive oder negative Dezimalversion: &000080: 2^7, &000100: 2^8, &000200: 2^9, &000400: 2^10, &000800: 2^11, &001000: 2^12, &002000: 2^13, &004000: 2^14, &008000: 2^15, &010000: 2^16, &01FFFF: 2^17-1, &020000: 2^17, &03FFFF: 2^18-1, &040000: 2^18, &07FFFF: 2^19-1, &080000: 2^19, &0FFFFF: 2^20-1, &100000: 2^20, &1FFFFF: 2^21-1, &3FFFFF: 2^22-1, &400000: 2^22, &7FFFFF: 2^23-1 nb nicht unbedingt vollständig, aber ich denke, ich habe ziemlich gründliche Arbeit geleistet
Greedo
1

Terminal auslassen, "wenn in Sofortfenster gedruckt wird

Dazu die unten stehende Funktion, die im Debug-Fenster verwendet werden soll

h="Hello":?h", World!"

Das Terminal "kann für -1 Byte gelöscht werden, wobei der String nicht geschlossen bleibt und das Programm das gleiche ohne Fehler ausführen soll

h="Hello":?h", World!

Noch überraschender ist, dass dies innerhalb vollständig definierter Subroutinen erfolgen kann.

Sub a
h="Hello":Debug.?h", World!
End Sub

Die obige Unterroutine wird wie erwartet ausgeführt und formatiert sich automatisch nach

Sub a()
h = "Hello": Debug.Print h; ", World!"
End Sub
Taylor Scott
quelle
1

Verwenden Sie in Bedingungen die Variablen Truthy und Falsey

Manchmal implizite Typumwandlung genannt - direkt einen Nummerntyp in einer Verwendung If, [IF(...)]oder IIf(...)Anweisung, durch die truthy und Falsey Natur dieser Zahl mit absolut sparen Sie einige Bytes.

In VBA wird jede Variable vom Typ Zahl, die nicht Null ist, als wahr angesehen (und daher ist Null 0der einzige falsche Wert)

If B <> 0 Then 
    Let C = B
Else 
    Let C = D
End If 

kann zu kondensiert sein

If B Then C=B Else C=D

und weiter zu

C=IIf(B,B,D)
Taylor Scott
quelle
1

Adressblätter nach Namen

Anstatt ein WorkSheetObjekt durch Aufrufen zu adressieren

Application.ActiveSheet
''  Or 
ActiveSheet   

Man darf verwenden

Sheets(n)  ''  Where `n` is an integer
''  Or 
[Sheet1]

Oder bevorzugter kann man direkt auf das Objekt zugreifen und es verwenden

Sheet1
Taylor Scott
quelle
1

Exponentiation und LongLongs in 64-Bit-VBA

Die allgemeine Form der Potenzierung,

A to the power of B

Kann wie in VBA als dargestellt werden

A^B 

Aber nur bei 32-Bit-Installationen von Office , bei 64 -Bit-Installationen von Office , ist dies der kürzeste Weg, den Sie möglicherweise fehlerfrei darstellen

A ^B

Dies liegt daran, dass in 64-Bit-Versionen von VBA ^sowohl das Exponentiationsliteral als auch das LongLongTypdeklarationszeichen verwendet werden . Dies bedeutet, dass einige seltsam aussehende, aber gültige Syntax auftreten können, wie z

a^=2^^63^-1^

die Variable zuweist a, um den Maximalwert von a zu haltenLonglong

Taylor Scott
quelle
1

Byte-Arrays als String komprimieren

Für Herausforderungen, bei denen die Lösung konstante Daten speichern muss, kann es nützlich sein, diese Daten als einzelne Zeichenfolge zu komprimieren und anschließend die Zeichenfolge zu durchlaufen, um die Daten abzurufen.

In VBA kann jeder Bytewert mit direkt in ein Zeichen konvertiert werden

Chr(byteVal)

Und ein longoder integerWert kann mit in zwei Zeichen umgewandelt werden

Chr(longVal / 256) & Chr(longVal Mod 256)

Für ein byteArray würde ein Komprimierungsalgorithmus ungefähr so ​​aussehen

For Each Var In bytes
    Select Case Var
        Case Is = Asc(vbNullChar)
            outstr$ = outstr$ & """+chr(0)+"""
        Case Is = Asc(vbTab)
            outstr$ = outstr$ & """+vbTab+"""
        Case Is = Asc("""")
            outstr$ = outstr$ & """"""
        Case Is = Asc(vbLf)
            outstr$ = outstr$ & """+vbLf+"""
        Case Is = Asc(vbCr)
            outstr$ = outstr$ & """+vbCr+"""
        Case Else
            outstr$ = outstr$ & Chr$(Var)
    End Select
Next
Debug.Print "t="""; outstr$

Beachten Sie, dass der Select CaseAbschnitt aufgrund der Zeichen implementiert wird, die möglicherweise nicht als Literale in der Zeichenfolge gespeichert sind.

Aus der resultierenden Zeichenfolge, die ungefähr so ​​aussieht

t="5¼-™):ó™ˆ"+vbTab+"»‘v¶<®Xn³"+Chr(0)+"~ίšÐ‘š;$ÔÝ•óŽ¡¡EˆõW'«¡*{ú{Óx.OÒ/R)°@¯ˆ”'®ïQ*<¹çu¶àªp~ÅP>‹:<­«a°;!¾y­›/,”Ì#¥œ5*B)·7    

Die Daten können dann unter Verwendung der Funktionen Ascund extrahiert werden Mid, z

i=Asc(Mid(t,n+1))
Taylor Scott
quelle
1

Verwenden Sie falsche Konstanten

VBA ermöglicht in einigen Fällen die Verwendung von nicht aufgelisteten oder falschen Konstanten in Ausdrücken, die konstante Werte erfordern. Hierbei handelt es sich häufig um Legacy-Werte, die kürzer sind als die richtigen Werte.

Zum Beispiel können die folgenden Werte verwendet werden, wenn ein Wert von der rng.HorizantalAlignmentEigenschaft gehalten werden soll.

UnsachgemäßRichtigAllgemeine KonstantexlHAlign  Konstante11xlAllgemeinxlHAlignGeneral2-4131xlLeftxlHAlignLeft3-4108xlCenterxlHAlignCenter4-4152xlRightxlHAlignRight55xlFillxlHAlignFill6-4130xlJustifyxlHAlignJustify77xlCenterAcrossSelectionxlHAlignCenterAcrossSelection8-4117xlVerteiltxlHAlignDistributed

Dies bedeutet zum Beispiel, dass eine Zelle so eingestellt wird, dass der Text zentriert ist

rng.HorizantalAlignment=-4108

kann gekürzt werden auf

rng.HorizantalAlignment=3

durch Ersetzen des falschen konstanten Werts 3durch den richtigen Wert -4108. Beachten Sie, dass beim Abrufen des rng.HorizantalAlignmentEigenschaftswerts der richtige Wert zurückgegeben wird. In diesem Fall wäre das -4108.

Taylor Scott
quelle
1

Erstellen Sie in Excel numerische Arrays, indem Sie Bereiche zusammenfassen

S[{...}]Split(String)

ΔByteanzahl=-5 BytesS

Beispiel

Zum Beispiel,

x=Split("1 2 34 567 8910")

kann geschrieben werden als

x=[{1,2,34,567,8910}]

Es ist ferner anzumerken, dass diese Methode zwar keine direkte Indizierung ermöglicht, jedoch eine direkte Iteration über die for-Schleife, d. H

For Each s In[{1,3,5,7,9,2,4,6,8}]
Taylor Scott
quelle