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 .

39voto

Vityata Punkte 41203

Vermeidung von Select y Activate ist der Schritt, der Sie zu einem etwas besseren VBA-Entwickler macht. Ganz allgemein, Select y Activate werden bei der Aufzeichnung eines Makros verwendet, so dass die Parent Arbeitsblatt oder Bereich wird immer als das aktive Arbeitsblatt betrachtet.

So können Sie vermeiden Select y Activate in den folgenden Fällen:


Hinzufügen eines neuen Arbeitsblatts und Kopieren einer Zelle darin:

Von (mit dem Makro-Recorder erzeugter Code):

Sub Makro2()
    Range("B2").Select
    Sheets.Add After:=ActiveSheet
    Sheets("Tabelle1").Select
    Sheets("Tabelle1").Name = "NewName"
    ActiveCell.FormulaR1C1 = "12"
    Range("B2").Select
    Selection.Copy
    Range("B3").Select
    ActiveSheet.Paste
    Application.CutCopyMode = False
End Sub

An:

Sub TestMe()
    Dim ws As Worksheet
    Set ws = Worksheets.Add
    With ws
        .Name = "NewName"
        .Range("B2") = 12
        .Range("B2").Copy Destination:=.Range("B3")
    End With
End Sub

Wenn Sie einen Bereich zwischen Arbeitsblättern kopieren möchten:

Von:

Sheets("Source").Select
Columns("A:D").Select
Selection.Copy
Sheets("Target").Select
Columns("A:D").Select
ActiveSheet.Paste

An:

Worksheets("Source").Columns("A:D").Copy Destination:=Worksheets("Target").Range("a1")

Phantasievoll benannte Bereiche verwenden

Sie können auf sie zugreifen mit [] Das ist wirklich schön, verglichen mit dem anderen Weg. Überprüfen Sie sich selbst:

Dim Months As Range
Dim MonthlySales As Range

Set Months = Range("Months")    
Set MonthlySales = Range("MonthlySales")

Set Months =[Months]
Set MonthlySales = [MonthlySales]

Das obige Beispiel würde wie folgt aussehen:

Worksheets("Source").Columns("A:D").Copy Destination:=Worksheets("Target").[A1]

Werte nicht kopieren, sondern übernehmen

Normalerweise, wenn Sie bereit sind select Wenn Sie etwas nicht verstehen, kopieren Sie wahrscheinlich etwas. Wenn Sie nur an den Werten interessiert sind, ist dies eine gute Möglichkeit, die Auswahl zu vermeiden:

Range("B1:B6").Value = Range("A1:A6").Value


Versuchen Sie immer, auch auf das Arbeitsblatt zu verweisen

Dies ist wahrscheinlich der häufigste Fehler bei vba . Wenn Sie Bereiche kopieren, wird das Arbeitsblatt manchmal nicht referenziert, so dass VBA das falsche Blatt als aktives Arbeitsblatt betrachtet.

'This will work only if the 2. Worksheet is selected!
Public Sub TestMe()
    Dim rng As Range
    Set rng = Worksheets(2).Range(Cells(1, 1), Cells(2, 2)).Copy
End Sub

'This works always!
Public Sub TestMe2()
    Dim rng As Range
    With Worksheets(2)
        .Range(.Cells(1, 1), .Cells(2, 2)).Copy
    End With
End Sub

Kann ich wirklich niemals .Select o .Activate für irgendetwas?

  • Ein gutes Beispiel dafür, wann es gerechtfertigt ist, die .Activate y .Select ist, wenn Sie sicherstellen wollen, dass ein bestimmtes Arbeitsblatt aus optischen Gründen ausgewählt ist. Z.B., dass Ihr Excel immer mit dem zuerst ausgewählten Deckblatt geöffnet wird, unabhängig davon, welches Blatt beim Schließen der Datei das aktive Blatt war.

So etwas wie der folgende Code ist also absolut in Ordnung:

Private Sub Workbook_Open()
    Worksheets("Cover").Activate
End Sub

36voto

Bitte beachten Sie, dass ich im Folgenden den Select-Ansatz (den der OP vermeiden möchte) mit dem Range-Ansatz (und das ist die Antwort auf die Frage) vergleiche. Hören Sie also nicht auf zu lesen, wenn Sie das erste Select sehen.

Es hängt wirklich davon ab, was Sie erreichen wollen. Wie auch immer, ein einfaches Beispiel könnte nützlich sein. Nehmen wir an, dass Sie den Wert der aktiven Zelle auf "foo" setzen wollen. Mit ActiveCell würden Sie etwas wie dieses schreiben:

Sub Macro1()
    ActiveCell.Value = "foo"
End Sub

Wenn Sie die Funktion für eine Zelle verwenden möchten, die nicht die aktive Zelle ist, z. B. für "B2", müssen Sie diese zuerst auswählen, etwa so:

Sub Macro2()
    Range("B2").Select
    Macro1
End Sub

Mit Hilfe von Ranges können Sie ein allgemeineres Makro schreiben, mit dem Sie den Wert einer beliebigen Zelle auf den gewünschten Wert setzen können:

Sub SetValue(cellAddress As String, aVal As Variant)
    Range(cellAddress).Value = aVal
End Sub

Dann können Sie Makro2 wie folgt umschreiben:

Sub Macro2()
    SetCellValue "B2", "foo"
End Sub

Und Makro1 als:

Sub Macro1()
    SetValue ActiveCell.Address, "foo"
End Sub

20voto

user1644564 Punkte 255

Geben Sie immer die Arbeitsmappe, das Arbeitsblatt und die Zelle/den Bereich an.

Zum Beispiel:

Thisworkbook.Worksheets("fred").cells(1,1)
Workbooks("bob").Worksheets("fred").cells(1,1)

Denn Endbenutzer werden immer nur auf Schaltflächen klicken, und sobald sich der Fokus von der Arbeitsmappe wegbewegt, mit der der Code arbeiten soll, geht alles schief.

Und verwenden Sie niemals den Index einer Arbeitsmappe.

Workbooks(1).Worksheets("fred").cells(1,1)

Sie wissen nicht, welche anderen Arbeitsmappen geöffnet sein werden, wenn der Benutzer Ihren Code ausführt.

18voto

LFB Punkte 666

Diese Methoden sind eher stigmatisiert, daher sollte man die Führung übernehmen von Vityata und Jeeped, um einen Strich durch die Rechnung zu machen:

Rufen Sie an. .Activate , .Select , Selection , ActiveSomething methoden/eigenschaften

Vor allem, weil sie in erster Linie aufgerufen werden, um Benutzereingaben über die Benutzeroberfläche der Anwendung zu verarbeiten. Da sie die Methoden sind, die aufgerufen werden, wenn der Benutzer Objekte über die Benutzeroberfläche handhabt, sind sie diejenigen, die vom Makro-Recorder aufgezeichnet werden, und deshalb ist der Aufruf dieser Methoden in den meisten Situationen entweder spröde oder überflüssig: Sie müssen kein Objekt auswählen, um eine Aktion mit Selection gleich danach.

Diese Definition regelt jedoch die Situationen, in denen sie benötigt werden:

Wann Sie anrufen sollten .Activate , .Select , .Selection , .ActiveSomething methoden/eigenschaften

Im Grunde genommen, wenn Sie erwarten, dass die Endverbraucher bei der Ausführung eine Rolle zu spielen.

Wenn Sie entwickeln und erwarten, dass der Benutzer die Objektinstanzen auswählt, die Ihr Code behandeln soll, dann .Selection o .ActiveObject sind angemessen.

Andererseits, .Select y .Activate sind von Nutzen, wenn Sie die nächste Aktion des Benutzers ableiten können und Sie möchten, dass Ihr Code den Benutzer anleitet und ihm möglicherweise einige Zeit und Mausklicks erspart. Wenn Ihr Code zum Beispiel gerade eine neue Instanz eines Diagramms erstellt oder ein Diagramm aktualisiert hat, könnte der Benutzer es überprüfen wollen, und Sie könnten .Activate Wenn Sie wissen, dass der Benutzer einige Bereichswerte aktualisieren muss, können Sie diesen Bereich programmatisch auswählen.

11voto

FinPro.Online Punkte 141

Um die Verwendung des .Select Methode können Sie eine Variable gleich der gewünschten Eigenschaft setzen.

Wenn Sie zum Beispiel den Wert in Cell A1 können Sie eine Variable setzen, die der Werteigenschaft dieser Zelle entspricht.

  • valOne = Range("A1").Value

Wenn Sie z.B. den Codenamen 'Sheet3' haben wollen, können Sie eine Variable setzen, die der Codename Eigenschaft dieses Arbeitsblatts.

  • valTwo = Sheets("Sheet3").Codename

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