Apology accpeted.

I think that you will find that is only the case if you are passing a reference type.
For most practical purposes, I'd say we are talking about reference types; it can be evidenced in this thread, that many users really do think that the object data on the heap, of a reference type, is copied when the reference is passed ByVal.
Given that most of the time, in OO programming, we are using reference types, it makes sense to treat them as the normal case and take steps to ensure that anyone such as the OP is NOT left with the notion that a 100,000 row datatable is cloned in its entirety when it is passed ByVal.
pass a value type a copy of the argument would be created and passed to the parameter in the sub or function called.
Yes, because value types (as i mentioned) are small enough to live entirely on the stack. They are copied by ByVal because all stack entries are copied by ByVal. When a stack entry is a reference to an object on the heap, it is the stack entry that is copied. This has been a consistent message through
all our posts, but in your initial post it was hard to see.
I think one of the separations here occurred as a result of you prioritising value (stack) types as being the major area of interest to the OP, and me prioritising the reference (heap) types. I personally feel in an OO language that there are more heaped objects in my programs than stacked ones.. so its important for me to know that BR and BV mean in terms of a heap object.
--
I'll summarise an answer for the OP, because we havent exactly answered his question:
The difference between ByRef and ByVal is well hammered out here. As for when you should use them: Always use ByVal, until you understand the entirety of the explanation here of the difference between the two. When you understand the explanation, you will be equipped to judge when to use ByRef. Until that time, use ByVal.
If you find yourself doing something and it's not working, and you guess at it, swap ByRef/ByVal around and it works.. it would be best to return here and ask why one works and the other does not.
Additionally, when you understand about ByRef and ByVal, you'll see that vis, jmc and I are discussing the same concept, using various words to communicate the concept. Out on the net, reading articles you'll meet people who call things variables, references, stack pointers, pointers, object pointers, reference types; they are all related to this notion that we have a large amount of data in a heap and we have a reference for where we keep that data, in another place called a stack.
If youre familiar with databases then a suitable analog would be a table holding a lot of data somewhere on disk, and an index that lets us find that data quickly by saying "person id 1234 is stored in row number 100456 on disk at sector 67890"