Is my assumption correct, you use for the property "PrijsAkCatVm" an own data type (Asci.Getal) instead of %Numeric, in order to be able to use some extra parameters like HINT, VIEW, VISIBLE etc.
Is that correct? If yes, then there is a much simpler solution where neither  MS nor SQL won't stumble over it. The catchword is PropertyClass.

/// Create a new Cache class.
/// Define here all the extra parameter you need.
///
Class Extra.Props
{
    Parameter HINT;
    Parameter VIEW = 1;
    Parameter VISIBLE = 1;
    Parameter VOLGORDE;
    // etc.
}

/// then take your Cache Table, add the above defined class
/// to your Cache Table, complete the property definitions with
/// the appropriate parameters - Done.
///
Class Your.CacheTable Extends %Persistent [ PropertyClass = Extra.Props ]
{
   Property PrijsAkCatVm As %Numeric (CAPTION="...", "HINT=...", etc.); 
}

Now you can use the above defined (extra) parameters in each and every property  in this class.

There are two aspects of the question,
a) how to get the old property value of a modified property and
b) what happens, if one still opens the same object in the SAME PROCESS once again.

For a) the answer is already given by either using the GetStored() method or cloning the object. In cases, where an old propvalue is needed, I prefer the object cloning, especially if the base object contains embedded objects.
Of course, if the application uses the %Reload() method, then the %OnReload() callback method should do the same as %OnOpen() does.

Class DC.Data Extends %Persistent
{
Property Name As %String;
Property Addr As DataAddr;
Property oldObj As Data [ ReadOnly, Transient ];
Method %OnOpen() As %Status [ Private, ServerOnly = 1 ]
{
    set r%oldObj=..%ConstructClone(1)  // do a deep clone
    do ..%SetModified(0)               // clear modified state
    Quit $$$OK
}
}

Class DC.DataAddr Extends %SerialObject
{
Property Street As %String;
Property City As %String;
}

kill
set obj=##class(DC.Data).%New(),obj.Name="Joe"
set obj.Addr.Street="Abbey Rd. 123", obj.Addr.City="London"
write obj.%Save() --> 1

kill
set obj=##class(DC.Data).%OpenId(1)

set obj.Name="Paul"
write obj.Name --> Paul
write obj.oldObj.Name --> Joe

set obj.Addr.City="London East"
write obj.Addr.City --> London East
write obj.oldObj.Addr.City --> London

For b), it was said, that a second open (of the same object) returns the same OID. This is true. But there is one more thing. That second open doesn't even trys to get that object from the database but just keeps a lookout in the memory. This means two things (assuming no locks are used)
1) if the object was modified by another process, you "open the old version" already in the memory of your process, and
2) nevertheless that an other process deletes that object, your proces will open a nonexisting object...

Seq  Process-A                                  Process-B
-------------------------------------------------------------------------
 1   set obj1=##class(DC.Data).%OpenId(1)
 2                                              do ##class(DC.Data).%DeleteId(1)
 3   write ##class(DC.Data).%ExistsId(1) --> 0
 4   set obj2=##class(DC.Data).%OpenId(1)
 5   write obj1=obj2 --> 1
 

As a consequence of the above, I have learned not to use a simple open:

set obj=##class(Some.Class).%OpenId(oid)

but a more secure open, by invalidating a possible old instance:

set obj="", obj=##class(Some.Class).%OpenId(oid)

Nice, the first part of the problem (or project, if you wish) is solved. What about a "side project", not pinging all but the active VPNs only? Use the netstat command to get all the established connections

/// Execute an arbitrary OS command and return the command output
ClassMethod OSCmd(cmd, ByRef ans)
{
    kill ans
    open cmd:"QR":10
    set old=$system.Process.SetZEOF(1), ans=0
    if $test {
        use cmd
        for {read line quit:$zeof  set ans($increment(ans))=line}
        close cmd
    }
    quit ans
}

Of course, you have to take into account OS specific differences and access rights

do ##class(your.classname).OSCmd("ping google.com", .ans) zw ans
ans=11
ans(1)=""
ans(2)="Pinging google.com [142.250.185.174] with 32 bytes of data:"
ans(3)="Reply from 142.250.185.174: bytes=32 time=21ms TTL=114"
ans(4)="Reply from 142.250.185.174: bytes=32 time=27ms TTL=114"
ans(5)="Reply from 142.250.185.174: bytes=32 time=19ms TTL=114"
ans(6)="Reply from 142.250.185.174: bytes=32 time=18ms TTL=114"
ans(7)=""
ans(8)="Ping statistics for 142.250.185.174:"
ans(9)="    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),"
ans(10)="Approximate round trip times in milli-seconds:"
ans(11)=""

do ##class(your.classname).OSCmd("netstat -ano | findstr ""ESTABLISHED""", .ans) zw ans
ans=6
ans(1)="  TCP    127.0.0.1:23           127.0.0.1:50814        ESTABLISHED     8272"
ans(2)="  TCP    127.0.0.1:23           127.0.0.1:60874        ESTABLISHED     2872"
ans(3)="  TCP    127.0.0.1:23           127.0.0.1:63199        ESTABLISHED     8272"
ans(4)="  TCP    127.0.0.1:1972         127.0.0.1:49436        ESTABLISHED     2404"
ans(5)="  TCP    127.0.0.1:1972         127.0.0.1:51840        ESTABLISHED     2404"
ans(6)="  TCP    127.0.0.1:1972         127.0.0.1:54330        ESTABLISHED     2404"

Now you can analyse and process the command output...

Also, see this post too.

Four short lines of Objectscript code


ClassMethod Ping(host)
{
	set cmd="ping "_host
	open cmd:"QR":10
	for {use cmd read ans quit:$zeof  use 0 write ans,!}
	close cmd
}

// some test
do ##class(your.class).Ping("google.com")

Pinging google.com [142.250.185.110] with 32 bytes of data:
Reply from 142.250.185.110: bytes=32 time=25ms TTL=114
Reply from 142.250.185.110: bytes=32 time=26ms TTL=114
Reply from 142.250.185.110: bytes=32 time=19ms TTL=114
Reply from 142.250.185.110: bytes=32 time=19ms TTL=114

Ping statistics for 142.250.185.110:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 19ms, Maximum = 26ms, Average = 22ms

Merely you have to "open" the article to get those tags into top position. If you just browse (see the screenshot) over the articles: (a) you have to scroll down and (b) a tag name could have but must not have the same meaning as an acronym. In my opinion, an acronym should always be explained after the first usage - either you write it out or you insert a link or whatever...  

By the way, you can also "shorten" a given node and start over...

// from the above example,
// name = ^A("TEST1","TEST2", ... "TEST10")
// now we take that global with the first two subscripts
set name = $name(@name,2)
// and add new subscripts
set name = $name(@name@(3333,4444))
set @name = "new data"

Try it and then ZWRITE ^A  to see the effect

I assume, we are talking about ObjectScript? Then you got in the main method a <SYNTAX> error because "calling" is not a command keyword. So what are you really doing? We don't need the whole main method, the line with the call would be enough. By the way, a method name like "this_method" is not a valid name except if you place it in (double)quotes.  Something, which is formal correct, looks like this:

Method "this_MainMethod"()
{
    do ..SecondMethod()
}

Method SecondMethod()
{
    // ...
}