the popular use of is INTERACTIVE.

But there is a BATCH option:   

SAMPLES>zn "%SYS"
 
%SYS>d BATCH^GBLOCKCOPY
 
1) Manage Batches
2) Run a Batch
3) Restart a Batch
4) Add Processes to a running Batch
5) Stop a Running batch
6) Monitor Running Batch
7) Batch Report
8) Exit
 
Option? 1
 
1) Create a Batch
2) Edit a Batch
3) List Batches
4) Delete a Batch
5) Exit
 
Option?

I never used it myself.

it seems to me you should find it in  ^%SYS("GBLOCKCOPY")

But the source code is open in %SYS and easy to read:

BATCH
 !
 !,"1) Manage Batches"
 !,"2) Run a Batch"
 !,"3) Restart a Batch"
 !,"4) Add Processes to a running Batch"
 !,"5) Stop a Running batch"
 !,"6) Monitor Running Batch"
 !,"7) Batch Report"
 !,"8) Exit"
 !
 Option=$$OPTION("Option? ",8,8)
 Option=1 BATCHMANAGE BATCH
 Option=2 BATCHRUN BATCH
 Option=3 BATCHRESTART BATCH
 Option=4 BATCHADDPROCESSES BATCH
 Option=5 BATCHSTOP BATCH
 Option=6 BATCHMONITOR BATCH
 Option=7 BATCHREPORT BATCH
 q
BATCHMANAGE
 !
 !,"1) Create a Batch"
 !,"2) Edit a Batch"
 !,"3) List Batches"
 !,"4) Delete a Batch"
 !,"5) Exit"
 !
 Option=$$OPTION("Option? ",5,5)
 Option=1 BATCHCREATE BATCHMANAGE
 Option=2 BATCHEDIT BATCHMANAGE
 Option=3 BATCHLIST BATCHMANAGE
 Option=4 BATCHDELETE BATCHMANAGE
 q
BATCHCREATE $zt="BATCHE"
 Name=$$GETNAME("Batch name to create? ",0,0) q:POP
 f  !!,"Adding to batch: "_Name BATCHSETUP q:POP
 BATCHCREATE
BATCHEDIT   $zt="BATCHE"
 Name=$$GETNAME("Batch name to edit? ",1,0) q:POP
 Status=$$GETSTATUS(Name,1)
 $p(Status,"~",4)'="Queue" !,"Batch "_Name_" has been run, please re-enter" BATCHEDIT
 $$YN("Do you want to add to the batch","Y")="Y" f  !!,"Adding to batch: "_Name BATCHSETUP q:POP
 $$YN("Do you want to delete entries from batch "_Name,"N")="N" BATCHEDIT
BATCHEDIT1
 SUMMARYREPORT(Name,0)
 Option=$$OPTION("Delete which entry? ",0,+$o(^|"^^"_$zu(12)|%SYS("GBLOCKCOPY",Name,""),-1))
 Option=0 BATCHEDIT
. . . . . . . .

HTH,

to count the number of changes you may use this approach

 Set ^Data("Cambridge") = "1" if  $increment(change("Cambridge"))
 Set ^Data("New York") = "2" if  $increment(change("New York"))
 Set ^Data("Boston") = "3" if  $increment(change("Boston"))
 Set ^Data("London") = "4" if  $increment(change("London"))
 Set ^Data("Athens") = "5" if  $increment(change("Athens"))
 Set ^Data("Athens") = "6" if  $increment(change("Athens"))
 Set ^Data("Athens") = "7" if  $increment(change("Athens"))

zw change

change("Athens")=3
change("Boston")=1
change("Cambridge")=1 
change("London")=1 
change("New York")=1

This is a rather common misunderstanding.
The naming GLOBAL was created in the 60ties.
Long before any other programming language even had anything named Global or similar.

GLOBAL in Caché is a persistent storage component that builds the backbone of (SQL) Tables and Persistent Objects.

see this documentation: Using Caché Globals

the data property is a standard HTML page.
I'm not aware of some function in Caché that converts HTML to JSON.

But asking Google "convert HTML to JSON"  shows that this a standard feature in JavaScript. 
so I see 2 options:

- write your own parser (or someone in the community has done this before ???

- call an external tool (eg. node.js) to it for you

see:   https://stackoverflow.com/questions/34504050/how-to-convert-selected-html-to-json

or  https://stackoverflow.com/questions/12980648/map-html-to-json

or https://stackoverflow.com/questions/43469412/convert-html-source-code-to-json-object

I prefer this solution as it is in full accordance with the documentation and
with no need also for beginners to fiddle into internals .
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_flist

<snip>

  • $LIST(list,position,end) returns a “sublist” (an encoded list string) containing the elements of the list from the specified start position through the specified end position (inclusive). If position and end specify the same element, $LIST returns this element as an encoded list.

</snip> 

(XMLPROJECTION="wrapped");

should separate your items.

from docs:  https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GXMLPROJ_basics#GXMLPROJ_basics_collections

Effect of XMLPROJECTION on Collection Properties

Value of XMLPROJECTIONEffect on Collection Properties
"WRAPPED"The property is projected as an element with subelements; each subelement corresponds to an item of the collection. This is the default for collection properties.
"ELEMENT"Each item in the collection is projected as an element, without being wrapped in the parent property.
 

my personal rule:

  • In the development stage, programmers should have full access but data are anonymized.
  • In the test stage - only some qualified developers get limited access
  • in the production stage, neither users nor developers should have access to the studio or terminal.
    Access is given only temporary, to top experts for error analysis.
    That's like the doctors that take care of places of your body you won't' show to anybody else.