HERBERS Excel-Forum - VBA-Basics

Thema: ByRef und ByVal

Inhaltsverzeichnis
  • 1 Zu ByRef und ByVal
  • 2 Die Beispiele
  • Zu ByRef und ByVal

    Variablen können an Funktionen oder Unterprogramme übergeben, dort zu Berechnungen verwendet und mit geänderten Werten zurückgegeben werden. Entscheidend hierfür ist das Schlüsselwort der Parameter-Definition des aufnehmenden Unterprogramms.

    VBA kennt die Parameterübergaben ByRef und ByVal. Im ersten Fall - das ist die Standardeinstellung, d.h. wenn keine Vorgabe erfolgt, wird der Parameter als ByRef behandelt - wird der Wert des Parameters weiterverarbeitet; Änderungen sind auch für das aufrufende Programm wirksam. Im zweiten Fall wird eine Kopie des Parameters übergeben; die Wirksamkeit beschränkt sich auf das aufgerufene Unterprogramm und der Parameter im aufrufenden Programm behält seinen ursprünglichen Wert.

    Dies gilt nicht für Objekt-Variablen. Diese behalten auch bei der Verwendung des Schlüsselwortes ByRef in der aufrufenden Prozedur ihren ursprünglichen Wert.

    Die Beispiele

    • Aufruf einer benutzerdefinierten Funktion ohne ByRef/ByVal-Festlegung



      Die Funktion errechnet anhand der übergebenen Parameter den Wert und gibt diesen an das aufrufende Programm zurück, wobei die übergebenen Parameter nicht geändert werden.

      
      Sub CallFunction()
         Dim dQM As Double
         dQM = fncQM( _
            Range("A2").Value, _
            Range("B2").Value, _
            Range("C2").Value)
         MsgBox "Quadratmeter Außenfläche: " & _
            Format(dQM, "0.000")
      End Sub
      
      Private Function fncQM( _
         dLong As Double, dWidth As Double, dHeight As Double)
         fncQM = 2 * (dLong * dWidth + _
            dLong * dHeight + _
            dWidth * dHeight)
      End Function
      
    • Aufruf eines Unterprogramms ohne ByRef/ByVal-Festlegung



      Das Unterprogramm wird mit den für die Berechnung notwendigen Parametern und zusätzlich mit einer 0-Wert-Double-Variablen, die als Container für das Berechnungsergebnis dient, aufgerufen. Alle Parameter gelten als ByRef, da kein Schlüsselwort verwendet wurde.

      
      Sub CallMacro()
         Dim dQM As Double
         Call GetQm( _
            dQM, _
            Range("A2").Value, _
            Range("B2").Value, _
            Range("C2").Value)
         MsgBox "Quadratmeter Außenfläche: " & _
            Format(dQM, "0.000")
      End Sub
      
      Private Sub GetQm( _
         dValue As Double, dLong As Double, _
         dWidth As Double, dHeight As Double)
         dValue = 2 * (dLong * dWidth + _
            dLong * dHeight + _
            dWidth * dHeight)
      End Sub
      
    • Aufruf mit einer Integer-Variablen bei Anwendung von ByVal



      Das Unterprogramm wird mit einer Variablen aufgerufen. Der Wert dieser Variablen verändert sich während des Ablauf des Unterprogramms, ohne dass sich im aufrufenden Programm der Variablenwert ändert.

      
      Sub AufrufA()
         Dim iRow As Integer, iStart As Integer
         iRow = 2
         iStart = iRow
         Call GetRowA(iRow)
         MsgBox "Ausgangszeile: " & iStart & _
            vbLf & "Endzeile: " & iRow
      End Sub
      
      Private Sub GetRowA(ByVal iZeile As Integer)
         Do Until IsEmpty(Cells(iZeile, 1))
            iZeile = iZeile + 1
         Loop
      End Sub
      
    • Aufruf mit einer Integer-Variablen bei Anwendung von ByRef



      Das Unterprogramm wird mit einer Variablen aufgerufen. Der Wert dieser Variablen verändert sich während des Ablauf des Unterprogramms, damit auch der Wert der Variablen im aufrufenden Programm.

      
      Sub AufrufB()
         Dim iRow As Integer, iStart As Integer
         iRow = 2
         iStart = iRow
         Call GetRowB(iRow)
         MsgBox "Ausgangszeile: " & iStart & _
            vbLf & "Endzeile: " & iRow
      End Sub
      
      Private Sub GetRowB(ByRef iZeile As Integer)
         Do Until IsEmpty(Cells(iZeile, 1))
            iZeile = iZeile + 1
         Loop
      End Sub
      
      
    • Aufruf mit einer String-Variablen bei Anwendung von ByVal



      Das Unterprogramm wird mit einer Variablen aufgerufen. Der Wert dieser Variablen verändert sich während des Ablauf des Unterprogramms, ohne dass sich im aufrufenden Programm der Variablenwert ändert.

      
      Sub CallByVal()
         Dim sPath As String, sStart As String
         sPath = ThisWorkbook.Path
         sStart = sPath
         Call GetByVal(sPath)
         MsgBox "Vorher: " & sStart & _
            vbLf & "Nachher: " & sPath
      End Sub
      
      Private Sub GetByVal(ByVal sDir As String)
         If Right(sDir, 1) <> "\" Then
            sDir = sDir & "\"
         End If
      End Sub
      
      
    • Aufruf mit einer String-Variablen bei Anwendung von ByRef



      Das Unterprogramm wird mit einer Variablen aufgerufen. Der Wert dieser Variablen verändert sich während des Ablauf des Unterprogramms, damit auch der Wert der Variablen im aufrufenden Programm.

      
      Sub CallByRef()
         Dim sPath As String, sStart As String
         sPath = ThisWorkbook.Path
         sStart = sPath
         Call GetByRef(sPath)
         MsgBox "Vorher: " & sStart & _
            vbLf & "Nachher: " & sPath
      End Sub
      
      Private Sub GetByRef(ByRef sDir As String)
         If Right(sDir, 1) <> "\" Then
            sDir = sDir & "\"
         End If
      End Sub
      
      
    • Aufruf mit einer Objekt-Variablen bei Anwendung von ByVal



      Das Unterprogramm wird mit einer Variablen aufgerufen. Der Wert dieser Variablen verändert sich während des Ablauf des Unterprogramms, ohne dass sich im aufrufenden Programm der Variablenwert ändert.

      
      Sub CallObjectA()
         Dim rngA As Range, rngB As Range
         Set rngA = Range("A1:A10")
         Set rngB = rngA
         Call GetObjectA(rngA)
         MsgBox "Vorher: " & rngB.Address(False, False) & _
            vbLf & "Nachher: " & rngA.Address(False, False)
      End Sub
      
      Private Sub GetObjectA(ByVal rng As Range)
         Set rng = Range("F1:F10")
      End Sub
      
      
    • Aufruf mit einer Objekt-Variablen bei Anwendung von ByRef



      Das Unterprogramm wird mit einer Variablen aufgerufen. Der Wert dieser Variablen verändert sich während des Ablauf des Unterprogramms, ohne dass sich im aufrufenden Programm der Variablenwert ändert.

      
      Sub CallObjectB()
         Dim rngA As Range, rngB As Range
         Set rngA = Range("A1:A10")
         Set rngB = rngA
         Call GetObjectA(rngA)
         MsgBox "Vorher: " & rngB.Address(False, False) & _
            vbLf & "Nachher: " & rngA.Address(False, False)
      End Sub
      
      Private Sub GetObjectB(ByRef rng As Range)
         Set rng = Range("F1:F10")
      End Sub