640 Stimmen

Wie man die Verwendung von Select in Excel VBA vermeidet

Ich habe viel über die verständliche Abneigung gegen die Verwendung von .Select in Excel VBA, aber ich bin mir nicht sicher, wie ich das vermeiden kann. Ich bin der Meinung, dass mein Code besser wiederverwendbar wäre, wenn ich Variablen anstelle von Select Funktionen. Ich bin mir jedoch nicht sicher, wie ich auf Dinge verweisen soll (wie die ActiveCell usw.), wenn nicht mit Select .

Ich habe gefunden dieser Artikel über Reichweiten y dieses Beispiel über die Vorteile der Nichtverwendung von select aber ich kann nichts finden über wie .

11voto

Eleshar Punkte 483

IMHO ist die Verwendung von .select kommt von Leuten, die wie ich angefangen haben, VBA aus der Not heraus zu lernen, indem sie Makros aufgezeichnet und dann den Code geändert haben, ohne zu merken, dass .select und anschließende selection ist nur ein unnötiger Mittelsmann.

.select lässt sich, wie bereits mehrfach gepostet, vermeiden, indem man direkt mit den bereits vorhandenen Objekten arbeitet, was verschiedene indirekte Verweise ermöglicht, wie z. B. die Berechnung von i und j auf komplexe Weise und die anschließende Bearbeitung von cell(i,j), usw.

Ansonsten gibt es nichts, was implizit gegen die .select Ich habe z. B. ein Arbeitsblatt, das ich mit Daten fülle, ein Makro aktiviere, das damit irgendetwas anstellt und es in einem akzeptablen Format auf ein separates Blatt exportiert, was jedoch einige abschließende manuelle (unvorhersehbare) Eingaben in eine benachbarte Zelle erfordert. Hier kommt also der Moment für .select Das erspart mir zusätzliche Mausbewegungen und Klicks.

10voto

Dominique Punkte 13206

Wie kann man Copy-Paste vermeiden?

Seien wir ehrlich: Bei der Aufzeichnung von Makros kommt dieser Punkt häufig vor:

Range("X1").Select
Selection.Copy
Range("Y9").Select
Selection.Paste

Das einzige, was die Person will, ist:

Range("Y9").Value = Range("X1").Value

Daher würde ich statt der Verwendung von Copy-Paste in VBA-Makros die folgende einfache Vorgehensweise empfehlen:

Destination_Range.Value = Source_Range.Value

6voto

pgSystemTester Punkte 6433

Mir ist aufgefallen, dass in keiner dieser Antworten die .offset-Eigenschaft . Dies kann auch verwendet werden, um die Verwendung des Select Aktion, wenn bestimmte Zellen manipuliert werden, insbesondere in Bezug auf eine ausgewählte Zelle (wie im OP erwähnt mit ActiveCell ).

Hier sind einige Beispiele:

Ich werde auch davon ausgehen, dass die ActiveCell es J4 .

ActiveCell.Offset(2, 0).Value = 12

  • Dies ändert den Wert der Zelle zwei Zeilen unterhalb von activecell (das ist J6 ) auf einen Wert von 12
  • Ein Minus von -2 hätte den Wert 12 zwei Zeilen weiter oben in J2

ActiveCell.Offset(0,1).Copy ActiveCell.Offset(,2)

  • Dadurch wird die Zelle eine Spalte nach rechts kopiert ( k4 ) in die Zelle, die zwei Spalten von der activecell ( L4 ).
  • なお 0 kann im Offset-Parameter weggelassen werden
    • Also: ActiveCell.Offset(,2) ist dasselbe wie ActiveCell.Offset(0,2)
  • Ähnlich wie im vorigen Beispiel würde eine -1 eine Spalte weiter links stehen ( i4 )

Das soll nicht heißen, dass es sich um besser als die oben genannten Optionen, aber es ist definitiv besser als die Verwendung von select . Beachten Sie, dass die Verwendung des EXCEL FUNCTION Versatz sollte in einem Arbeitsblatt vermieden werden, da es sich um eine flüchtige Funktion handelt.

6voto

Geoff Griswald Punkte 690

Der Hauptgrund, niemals Select oder Activesheet zu verwenden, liegt darin, dass die meisten Leute mindestens ein paar andere Arbeitsmappen geöffnet haben (manchmal auch Dutzende), wenn sie Ihr Makro ausführen, und wenn sie während der Ausführung Ihres Makros von Ihrem Blatt wegklicken und auf ein anderes geöffnetes Buch klicken, ändert sich das "Activesheet", und die Zielarbeitsmappe für einen unqualifizierten "Select"-Befehl ändert sich ebenfalls.

Im besten Fall stürzt Ihr Makro ab, im schlimmsten Fall schreiben Sie Werte oder ändern Zellen in der falschen Arbeitsmappe und haben keine Möglichkeit, diese Änderungen rückgängig zu machen.

Ich habe eine einfache goldene Regel, die ich befolge: Ich füge Variablen mit den Namen "wb" und "ws" für ein Workbook-Objekt und ein Worksheet-Objekt hinzu und verwende diese immer, um auf mein Makrobuch zu verweisen. Wenn ich auf mehr als ein Buch oder mehr als ein Blatt verweisen muss, füge ich weitere Variablen hinzu.

Zum Beispiel,

Dim wb as Workbook
Dim ws as Worksheet
Set wb = ThisWorkBook
Set ws = wb.sheets("Output")

Der Befehl "Set wb = ThisWorkbook" ist absolut entscheidend. "DieseArbeitsmappe" ist ein spezieller Wert in Excel, der die Arbeitsmappe bezeichnet, in der sich Ihr VBA-Code befindet. läuft derzeit von . Eine sehr hilfreiche Abkürzung, um Ihre Workbook-Variable mit zu setzen.

Nachdem Sie das am Anfang Ihres Unterverzeichnisses getan haben, könnte die Verwendung nicht einfacher sein: Verwenden Sie sie einfach überall dort, wo Sie "Auswahl" verwenden würden:

Um also den Wert der Zelle "A1" in "Ausgabe" in "Hallo" zu ändern, anstatt:

Sheets("Output").Activate
ActiveSheet.Range("A1").Select
Selection.Value = "Hello"

Das können wir jetzt tun:

ws.Range("A1").Value = "Hello"

Das ist nicht nur viel zuverlässiger und weniger absturzgefährdet, wenn der Benutzer mit mehreren Tabellenkalkulationen arbeitet; es ist auch viel kürzer, schneller und einfacher zu schreiben.

Ein zusätzlicher Bonus: Wenn Sie immer Wenn Sie Ihre Variablen "wb" und "ws" nennen, können Sie den Code von einem Buch in ein anderes kopieren und einfügen, und er funktioniert in der Regel mit minimalen Änderungen, wenn überhaupt.

5voto

barneyos Punkte 576

Arbeiten mit dem .Elternteil Funktion zeigt dieses Beispiel, wie das Setzen von nur einer myRng-Referenz den dynamischen Zugriff auf die gesamte Umgebung ohne .Select, .Activate, .Activecell, .ActiveWorkbook, .ActiveSheet usw. ermöglicht. (Es gibt keine generische .Kind Funktion).

Sub ShowParents()
    Dim myRng As Range
    Set myRng = ActiveCell
    Debug.Print myRng.Address                    ' An address of the selected cell
    Debug.Print myRng.Parent.name                ' The name of sheet, where MyRng is in
    Debug.Print myRng.Parent.Parent.name         ' The name of workbook, where MyRng is in
    Debug.Print myRng.Parent.Parent.Parent.name  ' The name of application, where MyRng is in

    ' You may use this feature to set reference to these objects
    Dim mySh  As Worksheet
    Dim myWbk As Workbook
    Dim myApp As Application

    Set mySh = myRng.Parent
    Set myWbk = myRng.Parent.Parent
    Set myApp = myRng.Parent.Parent.Parent
    Debug.Print mySh.name, mySh.Cells(10, 1).Value
    Debug.Print myWbk.name, myWbk.Sheets.Count
    Debug.Print myApp.name, myApp.Workbooks.Count

    ' You may use dynamically addressing
    With myRng
        .Copy

        ' Pastes in D1 on sheet 2 in the same workbook, where the copied cell is
        .Parent.Parent.Sheets(2).Range("D1").PasteSpecial xlValues

        ' Or myWbk.Sheets(2).Range("D1").PasteSpecial xlValues

        ' We may dynamically call active application too
        .Parent.Parent.Parent.CutCopyMode = False

        ' Or myApp.CutCopyMode = False
    End With
End Sub

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X