By: Paul S. Cilwa | Viewed: 12/7/2023 Posted: 6/28/2021 |
Page Views: 802 | |

Topics: #object-orientedprogramming #Organica #Percentageclass #Shell #VB.NET |
|||

A general purpose class for easily calculating percentages and values without bothering with all that math stuff. |

I have dyslexia, and as a partial consequence I can never get the equation
for calculating percentages right on the first try. *Which side does the 100 go on,
and is it divide or multiply?* And so, for me at least, it makes sense to get it right
*once*…in a reusable function (or, better yet, object) that I can reference by
name when needed? And thus is born the *Percentage* class.

The premise of the class is that objects of this type could be used as properties for other objects that might need to store a value that can be expressed as either a percentage or a hard value (given a maximum value). In my current need there will never be negative or superfluous (+100%) percentages, so this class doesn't allow values below zero or higher than the provided maximum.

To create a file for the class to live in, use the *Project..Add Class* menu command
and change the default name ("Class1") to "Percentage".

Clicking the **Add** button will open a code window for you with the class
skeleton pre-typed.

```
Public Class Percentage
End Class
```

Since, among the three entities *Value*, *MaxValue*, and *Percent*, any one can be derived from
the other two, we only require the storage of two of them.

```
Public Class Percentage
```** Private MyValue As Single
Private MyMaxValue As Single
Public Sub New(aValue As Single, aMaxValue As Single)
MyMaxValue = aMaxValue
MyValue = Math.Min(Math.Max(0, aValue), MyMax)
End Sub
**
End Class

The code to implement **Value** and **MaxValue** as properties is textbook basic.

```
…
```** Property Value As Single
Set(aValue As Single)
MyValue = Math.Min(Math.Max(0, aValue), MaxValue)
End Set
Get
Return MyValue
End Get
End Property
Property MaxValue As Single
Set(aMax As Single)
MyMaxValue = Math.Min(0, aMax)
If MyMaxValue < MyValue Then MyValue = MyMaxValue
End Set
Get
Return MyMaxValue
End Get
End Property**

The fun is in the *Percent* property, since it must be calculated on demand, or
used to change the *Value* property if written to.

```
…
```**Property Percent As Single
Set(NewPercent As Single)
NewPercent = Math.Min(Math.Max(0, NewPercent), 100)
Value = MaxValue * NewPercent / 100
End Set
Get
Return Value / MaxValue * 100
End Get
End Property**

### Stand-alone Functions

While the above code describes a useful class for when these values must be retained,
it's also true that many times a percentage is needed to be calculated using pre-existing
values, and instantiating an entire object is rather overkill. For these occasions, we
can add **Shared** functions to the class. A **Shared** function is one that is
called through the class name itself (as well as through an instantiated object),
with all data provided via arguments.

```
…
```**Public Shared Function CalcPercentage(aValue As Single, aMaxValue As Single) As Single
Return aValue / aMaxValue * 100.0
End Function
Public Shared Function CalcValue(aPercentage As Single, aMaxValue As Single) As Single
aPercentage = Math.Min(Math.Max(0, aPercentage), 100)
Return aMaxValue * aPercentage / 100.0
End Function**