Visio Guy

Visio Discussions => Programming & Code => Topic started by: dmbalzer on April 27, 2021, 07:09:33 PM

Title: Passing Shape to sub by reference or by value
Post by: dmbalzer on April 27, 2021, 07:09:33 PM
I have an event monitor that tracks if a shape is dropped and if the shape meets a certain criteria (has certain cells with values) I do some manipulation to its shape data on its drop.

My subroutine(s) that does the manipulation has the dropped shape as its argument.

My question is if there any benefits to passing a shape as an argument to a subroutine (or a class) by value or by reference?  Is there a performance gain doing it by reference vs value?
Title: Re: Passing Shape to sub by reference or by value
Post by: Nikolay on April 27, 2021, 11:28:00 PM
Here is an example to clarify "ByRef" vs "ByVal" semantics, it basically has nothing to do with performance, when we are talking about shapes:

ByVal:

Sub Foo(ByVal shape)
  Set shape = F
End Sub

Set s = S
Call Foo(s)  // s = S after call (still)

ByRef:

Sub Foo(ByRef shape)
  Set shape = F
End Sub

Set s = S
Call Foo(s) // s = F after call (modified)


In your scenario, there is no difference because all you have is the "Foo" handler and you basically don't care what happens after your handler (Foo) is executed.
Please also notice that modifying input parameters is not a good practice anyway (behavior of the second example with "ByRef" may be "unexpected" and "unexpected" things are bad)
Title: Re: Passing Shape to sub by reference or by value
Post by: dmbalzer on April 28, 2021, 12:46:32 AM
Thank you for the response Nikolay, that makes sense.  I definitely would prefer to go by best practices, and at least with my limited C programming knowledge working with local variables is strongly encouraged with functions to prevent some hard to trace bugs.  Thanks!
Title: Re: Passing Shape to sub by reference or by value
Post by: Visisthebest on April 29, 2021, 11:38:31 AM
Is it possible to truly pass a shape (that is on a page) by value in VBA? What happens in this instance, hopefully one of the Visio development experts can explain. Shape objects I always pass by reference.

I agree it is best to program with the concept of immutability in the back of your mind, but it is not a good fit overall for programming VBA and Microsoft Office object models.

If a shape is truly passed by value, then a complete copy would have to be created. However, if this is a shape on a page that means there are suddenly 2 shape objects, one currently in the context of the sub to which it is passed.

Because a shape refers to so many other objects (that are in effect still passed by reference in the by-value-copied shape) all these objects are still mutable you only protect the shape object from changes but not the objects in its context that the sub can change.

From the goal of your code:

"I have an event monitor that tracks if a shape is dropped and if the shape meets a certain criteria (has certain cells with values) I do some manipulation to its shape data on its drop.

My subroutine(s) that does the manipulation has the dropped shape as its argument.

My question is if there any benefits to passing a shape as an argument to a subroutine (or a class) by value or by reference?  Is there a performance gain doing it by reference vs value?"

By reference is faster, but seldom noticeably so. Passing a 1 Gigabyte size array by value probably is slower though. You want to mutate (change) the original shape, pass the shape by reference and like Nikolay (he is a top Visio programmer, I am a true amateur) make sure that you understand the effects the changes may have (are you triggering other event handlers, what kind of code flows are possible).

Immutability/functional programming can make complex code much simpler to debug, but OOP has other advantages.

I am personally not a big OOP code writing fan (meaning developing new classes and objects beyond what is already there), but I like using the objects Microsoft/the Visio dev team has created for us, I like using UDTs when passing multiple values to subs/functions:
https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/type-statement

It allows me to just pass one argument with a set of values to a sub/function, and add values if needed at some point.

I pass the UDT by value but even if I forget to set ByVal, the code calling the sub/function loads the values in to the UDT and NEVER uses the UDT again after calling the sub/function. It is used only once, to provide information to the sub/function to do its processing.

When you add values to a UDT to pass additional information to a sub/function, you don't have to rewrite calls to a sub/function because more arguments have been added.

There are no doubt trade-offs and disadvantages to this approach, but it has worked well for me with subs/functions that allow a lot of input values, and it supports immutability thinking. The sub/function can never change something that will impact my code elsewhere, because the UDT is never used again.

Title: Re: Passing Shape to sub by reference or by value
Post by: dmbalzer on April 29, 2021, 12:32:30 PM
Very good points Visisthebest, I had not considered making custom types for grouping related parameters such as a shape itself, and maybe some strings for the shape data you want to work with.

I am guessing that is similar to using structs in C, where you don't have class creating but can get close with structs.

Thank you both for the great insight. Has definitely given me a better understanding.
Title: Re: Passing Shape to sub by reference or by value
Post by: Visisthebest on April 29, 2021, 12:46:14 PM
Yes it is like structs/structures, in VB.NET they also call it structs.

Of course objects have a lot more functionality, but with UDTs I can simplify my code with very little effort.

Objects have the disadvantage that the wrong choices up front will make for a lot of wasted effort (and refactoring), and I often do not know where I'll end up exactly as I build a solution. For a mature project where I understand the ins and outs, refactoring parts by creating new classes and objects makes sense of course.

There are some real OOP haters out there:
https://thenewstack.io/why-are-so-many-developers-hating-on-object-oriented-programming/

I for one am very grateful for the Visio, Excel and Word object model. Microsoft put in a HUGE effort to develop these, and as an 'object consumer' this works very well for me!
Title: Re: Passing Shape to sub by reference or by value
Post by: Paul Herber on April 29, 2021, 04:20:38 PM
Quote from: Visisthebest on April 29, 2021, 12:46:14 PM
Microsoft put in a HUGE effort to develop these

Ooo, no. It was developed by Shapeware, then MS bought them in the year 2000. MS have done some additions to the model, so far without messing anything up (well, I think there have been a few messups but nothing too egregious).


Title: Re: Passing Shape to sub by reference or by value
Post by: dmbalzer on April 29, 2021, 04:30:34 PM
I believe he was referring to Visual Basic for Applications, which may have been included with Visio 5.0 before it was bought by Microsoft?
Title: Re: Passing Shape to sub by reference or by value
Post by: Paul Herber on April 29, 2021, 04:33:08 PM
I think VBA has been in Visio almost right from the start. It was something companies could license from MS.

Title: Re: Passing Shape to sub by reference or by value
Post by: Visisthebest on April 29, 2021, 04:58:27 PM
Yes of course Paul but those Visio employees have all become Microsofties I just assumed :).

I remember, hopefully correctly, that some Visio versions became a lot less expensive after Microsoft acquired Visio.

And yes a big part of it is the appeal of Visio within a suite of VBA applications, I use Excel with Visio often and Access when the data needs more structure, if it was just Visio that would leave a big gap.

Now if only Microsoft started investing more in developing the Visio desktop application than it has in the past years... ;)
Title: Re: Passing Shape to sub by reference or by value
Post by: wapperdude on April 29, 2021, 07:19:43 PM
M$ = less expensive.  😵  Not in this universe.  Maybe older, u unsupported version s.
Title: Re: Passing Shape to sub by reference or by value
Post by: Surrogate on April 29, 2021, 09:26:01 PM
Quote from: Visisthebest on April 29, 2021, 04:58:27 PM
Yes of course Paul but those Visio employees have all become Microsofties I just assumed :).
Not all Visio Corp employees become Microsoft employees  :(
Quote from: Visisthebest on April 29, 2021, 04:58:27 PMNow if only Microsoft started investing more in developing the Visio desktop application than it has in the past years... ;)
Really ? In last years we can see giant new opportunities like:
(http://osiprodwusodcspstoa01.blob.core.windows.net/en-us/media/99e8c4cf-ccb2-40d1-9775-5df4033186b9.png)
Quote from: Mukul Kumar in article Six Visio releases that enhance the Microsoft 365 better together and touch experiences (https://techcommunity.microsoft.com/t5/visio-blog/six-visio-releases-that-enhance-the-microsoft-365-better/ba-p/825261)6) Crime Scene Investigation template: Back by popular request, our template for crime scene investigations has been re-introduced to Visio desktop.
(https://support.content.office.net/en-us/media/018ce80b-44e4-42b7-b003-ec412d137ed2.png)

Quote from: See what's new in the August 2018 feature update, Version 1808 (Build 10730.20088). (https://support.microsoft.com/en-us/office/what-s-new-in-visio-798f4f39-2833-486b-9ae9-55162672102e?ui=en-US&rs=en-AU&ad=AU#Audience=Previous_Releases)Enjoy an iconic moment in your next diagram Pick from 26 new stencils with icons for analytics, arts, celebration, faces, sports, and more.
(https://support.content.office.net/en-us/media/f2056571-f25a-4026-820c-2d34a7ad20f2.png)

Title: Re: Passing Shape to sub by reference or by value
Post by: Visisthebest on May 04, 2021, 09:55:44 AM
dmbalzer I want to add a caveat for vb.net add-ins, there I think simple classes are preferable to structures, in particular because the whole boxing/unboxing thing can be a nightmare with structures:

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/boxing-and-unboxing

It gets worse if you create a list of structures:

https://stackoverflow.com/questions/7126318/how-do-you-assign-values-to-structure-elements-in-a-list-in-vb-net

So here classes and objects are easier even if OOP isn't quite the strongest defense against mutation, as even an object passed byval can be mutated by the receiving sub/function.

In VBA big fan of UDTs though!
Title: Re: Passing Shape to sub by reference or by value
Post by: dmbalzer on May 04, 2021, 03:26:09 PM
Thanks for the additional info!