Microsoft Excel

Herbers Excel/VBA-Archiv

Informationen und Beispiele zum Thema MsgBox
BildScreenshot zu MsgBox MsgBox-Seite mit Beispielarbeitsmappe aufrufen

Verständnisproblem "ByVal" bei Objektvariablen

Betrifft: Verständnisproblem "ByVal" bei Objektvariablen von: Sabrina
Geschrieben am: 20.08.2014 09:44:15

Hallo zusammen,

ich bin gerade dabei, mich in VBA einzuarbeiten und da bin ich nun auf ein arges Verständnisproblem gestossen, welches mir keine Ruhe lässt. Vielleicht könnte jemand von euch da etwas Licht drauf werfen...

Und zwar geht um folgenden Beispielcode:

Private Sub Worksheet_Change(ByVal Target As Range)

   If Target.Column = 1 Then

      Target.Value = UCase(Target.Value)

   End If

End Sub

Warum funktioniert das?

Target wird doch by value übergeben, sollte also eigentlich als Kopie an die Prozedur übergeben werden, aber trotzdem bewirkt Target.Value = UCase(Target.Value) die gewünschte Veränderung in der geänderten Zelle.

Viele Grüße,
Sabrina

  

Betrifft: AW: Verständnisproblem "ByVal" bei Objektvariablen von: Rudi Maintaire
Geschrieben am: 20.08.2014 10:03:59

Hallo,,
das hat Auswirkungen, wenn die Var von einer Prozedur an eine andere übergeben wird.

Sub a()
  Dim x As Range
  Set x = Range("A1")
  MsgBox x.Address
  b x
  MsgBox x.Address
  c x
  MsgBox x.Address
End Sub

Sub b(ByRef x As Range)
 Set x = Range("A2")
End Sub

Sub c(ByVal x As Range)
  Set x = Range("A1")
End Sub

Gruß
Rudi


  

Betrifft: AW: Verständnisproblem "ByVal" bei Objektvariablen von: Sabrina
Geschrieben am: 20.08.2014 10:14:46

Hallo Rudi,

ja, das ist mir schon klar.

Was ich nur seltsam finde, ist, dass, wenn ich eine Eigenschaft des by value übergebenen Objektes ändere (z.B. Target.Value), dann ändert sich diese Eigenschaft auch in dem originalen Objekt.


Gruß,
Sabrina


  

Betrifft: AW: Verständnisproblem "ByVal" bei Objektvariablen von: Luschi
Geschrieben am: 20.08.2014 11:06:47

Hallo Sabrina,

hier noch ein Link dazu:

http://www.activevb.de/rubriken/faq/faq0131.html

Achte besonders auf den Hinweis:
Steuerelemente werden immer als ByRef übergeben, da die Variable nur einen Zeiger auf das Objekt bereithält. Hier ist es unnütz, zwischen Kopie und Original zu unterscheiden, da beide auf das gleiche Objekt verweisen.
Anmerkung: Dazu zählen auch die Excel-Objekte Workbook, Worksheet, Range, Cells, und und und...

Gruß von Luschi
aus klein-Paris


  

Betrifft: AW: Verständnisproblem "ByVal" bei Objektvariablen von: Sabrina
Geschrieben am: 20.08.2014 12:46:15

Ah, Danke für den Link. Der Hinweis erklärt es dann.

Jedoch verstehe ich dann nicht, warum Excel dann diesen Code generiert:

Private Sub Worksheet_Change(ByVal Target As Range)

und nicht nicht

Private Sub Worksheet_Change(ByRef Target As Range)


Auch wenn es in diesem Fall egal ist, jedoch wäre Letzteres dann doch stimmiger.


Viele Grüße,
Sabrina


  

Betrifft: AW: Verständnisproblem "ByVal" bei Objektvariablen von: Daniel
Geschrieben am: 20.08.2014 13:03:02

Hi
Eine Variablenübergabe "byRef" funktioniert in Eventmarkos nicht, weil es bei den Event-Makros kein Aufrufendes Makro gibt, in welchem die Variable hinterlegt ist und auf welche sich TARGET im Change-Event beziehen kann.
Daher muss der Zellbezug byVal übergeben werden, damit im Eventmakro eine eigene Variable angelegt wird.

Beachte: eine Ojektvariable ist immer nur eine Referenz auf das Objekt
das hat nichts, aber auch gar nichts damit zu tun, ob die Variable zwischen zwei Makros als Wert oder als Referenz übergeben wird (bei Objektvariablen ist im Prinzip die Referenz auf das Objekt der Wert).

Gruß Daniel


  

Betrifft: AW: Verständnisproblem "ByVal" bei Objektvariablen von: Sabrina
Geschrieben am: 20.08.2014 13:46:10

Ah, OK, danke.


  

Betrifft: AW: Verständnisproblem "ByVal" bei Objektvariablen von: Daniel
Geschrieben am: 20.08.2014 11:14:39

Hi

eine Objektvariable ist immer eine Referenz auf ein Objekt.
das hat jetzt nichts mit byVal oder byRef zu tun, denn da gehts darum ob im aufgerufenen Makro eine neue Variable angelegt wird, oder ob stattdessen nur eine Referenz auf die alte Variable erstellt wird.

aber auch wenn du wegen byVal eine neue Objektvariable anlegst und den Inhalt kopierst, das referenzierte Objekt ist das selbe.

Relevant wird das nur, wenn du der Variablen mit SET ein neues Objekt bzw eine andere Zelle zuweist.
Gruß Daniel


  

Betrifft: AW: Verständnisproblem "ByVal" bei Objektvariablen von: Dieter Klemke
Geschrieben am: 20.08.2014 13:03:28

Hallo Sabrina,

ein interessantes Problem was du da angerissen hast. Wenn man schon lange im Geschäft ist, stellt man ja solche Fragen nicht mehr.
Ich habe mir das jetzt mal angeschaut und dabei festgestellt, dass man eine Objektvariable ByVal übergeben kann, wenn im Unterprogramm keine Veränderung in Excel vorgenommen wird.
Das siehst du an dem Beispiel Test_1. Dort wird einer Objektvariablen im Unterprogramm nur ein anderer Zellbereich zugewiesen, d.h. es wird keine Änderung im Tabellenblatt vorgenommen (ich habe das kurz "keine Veränderung in Excel" genannt). Hier funktioniert der Unterschied von ByVal und ByRef.
Dagegen wird im Beispiel Test_2 im Unterprogramm der Inhalt einer Zelle geändert. Jetzt gibt es keinen Unterschied zwischen ByVal und ByRef mehr.

Sub Test_1()
   Dim rng1 As Range
   Dim rng2 As Range
   Dim ws As Worksheet
   
   Set ws = ThisWorkbook.Worksheets(1)
   Set rng1 = ws.Range("A1:B5")
   Set rng2 = rng1
   Keine_Veränderung_in_Excel_ByVal Bereich:=rng1
   MsgBox Prompt:="Vorher: " & rng2.Address & _
                  vbNewLine & "Nachher: " & rng1.Address, _
          Title:="ByVal"
   Keine_Veränderung_in_Excel_ByRef Bereich:=rng1
   MsgBox Prompt:="Vorher: " & rng2.Address & _
                  vbNewLine & "Nachher: " & rng1.Address, _
          Title:="ByRef"
End Sub
 
Sub Keine_Veränderung_in_Excel_ByVal(ByVal Bereich As Range)
   Dim ws As Worksheet
   
   Set ws = ThisWorkbook.Worksheets(1)
   Set Bereich = ws.Range("X3:Y7")
End Sub
 
Sub Keine_Veränderung_in_Excel_ByRef(ByRef Bereich As Range)
   Dim ws As Worksheet
   
   Set ws = ThisWorkbook.Worksheets(1)
   Set Bereich = ws.Range("X3:Y7")
End Sub

Sub Test_2()
  Dim rng As Range
  Dim wert As Variant
  Dim ws As Worksheet
  
  Set ws = ThisWorkbook.Worksheets(1)
  Set rng = ws.Range("A1")
  rng = 4711
  wert = rng.Value
  Veränderung_in_Excel_ByVal Zelle:=rng
  MsgBox Prompt:="Vorher: " & wert & _
                 vbNewLine & "Nachher: " & rng.Value, _
         Title:="ByVal"
  rng = 4711
  wert = rng.Value
  Veränderung_in_Excel_ByRef Zelle:=rng
  MsgBox Prompt:="Vorher: " & wert & _
                 vbNewLine & "Nachher: " & rng.Value, _
         Title:="ByRef"
End Sub

Sub Veränderung_in_Excel_ByVal(ByVal Zelle As Range)
  Zelle = 5812
End Sub

Sub Veränderung_in_Excel_ByRef(ByRef Zelle As Range)
  Zelle = 5812
End Sub
Viel Spaß bei der weiteren Forschungsarbeit und viele Grüße
Dieter


  

Betrifft: AW: Verständnisproblem "ByVal" bei Objektvariablen von: Sabrina
Geschrieben am: 20.08.2014 13:44:09

Danke Dir, Dieter.