Start new project.

Add 2 buttons to your form. Double click on the first button to go to the coding area.

Outside the button1 sub declare this variable: 
Dim bb As Integer = 20

Below the "bb" declaration write this:
Function aa(ByVal cc As Integer)
cc = cc * 3
Return cc
End Function

- this will create the "aa" function which will be expecting one integer variable when called. The "cc" variable is declared with the ByVal modifier, which stands for: by value.
ByVal allows us to insert and use variables into the function without changing the value that they hold.

Inside the button1 sub write:
MsgBox(aa(bb))

- we insert the "bb" variable into our "aa" function. The message box will display the returned value of the function. However, this doesn't mean "bb" was changed - it was only used.

Go to the design page, double click the second button, inside the sub add this:
MsgBox(bb)

Code:


    Public Class Form1

    Dim bb As Integer = 20

    Function aa(ByVal cc As Integer)
    cc = cc * 3
    Return cc
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    MsgBox(aa(bb))
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    MsgBox(bb)
    End Sub
    End Class


Try button2, then button1, then again button2. "bb" should stay the same.

We will now take the ByVal declaration of "cc":
Function aa(ByVal cc As Integer)
and change it into ByRef:
Function aa(ByRef cc As Integer)

Other changes are not necessary. Try button2, button1 and button2 again. "bb" will be modified after using the "aa" function.
That's because ByRef changes the value of the variable that is used in the function.
I trust the difference is now noticeable.

The same goes when declaring variables for subs.
The main difference between functions and subs is that subs don't return values.

Let's change the previous code line to:
Sub aa(ByVal cc As Integer)

- "End Function" will directly change to "End Sub". The problem that appears in the Error List:
'Return' statement in a Sub or a Set cannot return a value.

Erase the "Return cc" code line inside the "aa" sub.
Also erase "MsgBox(aa(bb))" from the button1 sub, and write only this instead:
aa(bb)

- button1 will start the sub, but it won't be displaying anything.

Start the program, and just like before try button2, button1 and then button2 again.
Change the ByVal modifier inisde the "aa" sub into ByRef again.

Final code:

    Public Class Form1

    Dim bb As Integer = 20

    Sub aa(ByRef cc As Integer)
    cc = cc * 3
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    aa(bb)
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    MsgBox(bb)
    End Sub
    End Class


ByVal
Specifies that an argument is passed in such a way that the called procedure or property cannot change the value of a variable underlying the argument in the calling code. Resource

ByRef
Specifies that an argument is passed in such a way that the called procedure can change the value of a variable underlying the argument in the calling code. Resource