Discussion (11)2
Log in or sign up to continue

Yes, ^SPOOL is the simplest way to achieve this. If you need a string rather than a global, you can just get all lines from ^SPOOL, for example :

ClassMethod ZWriteToString() As %String
{
 #Dim result as %String
 #Dim i,lineCount as %Integer
 
 kill ^SPOOL($j)
 open 2:$j
 use 2
 zwrite
 s result=""
 s lineCount=$select($data(var):$za-1,1:$za-2)
 close 2
 for i=1:1:lineCount s result=result_^SPOOL($j,i)	
 return result
}

Yeah, but it should be used with precautions. Let's see what happens when two processes access spooling device concurrently: 

USER>f {q:'($zh\1#20)} k a o 2 f i=1:1:10 {s a(i)=i*100} u 2 zw a c 2 ; process #1
USER>s i="" f  {s i=$o(^SPOOL(1,i),1,line) q:i=""  w line} ; look inside ^SPOOL(1)...
a(1)=100
a(2)=200
a(3)=300
a(4)=400
a(5)=500
a(6)=600
a(7)=700
a(8)=800
a(9)=900
a(10)=1000
{66892,65205{11
USER>f {q:'($zh\1#20)} k a o 2 f i=1:1:10 {s a(i)=i} u 2 zw a c 2 ; process #2
USER>s i="" f  {s i=$o(^SPOOL(1,i),1,line) q:i=""  w line} ; look inside ^SPOOL(1)...
a(1)=100
a(2)=200
a(3)=300
a(4)=400
a(5)=500
a(6)=600
a(7)=700
a(8)=800
a(9)=900
a(10)=1000
{66892,65205{11

As you can notice, one process's output suppressed the other's one. To avoid it, firstly RTFM: OPEN and USE Commands for Spooling Device, and implement some synchronization pattern, e.g. 

USER>f {q:'($zh\1#20)} s docIdx=$i(^SPOOL) k a o 2:(docIdx) f i=1:1:10 {s a(i)=i*100} u 2 zw a c 2 ; process #1
USER>s i="" f  {s i=$o(^SPOOL(docIdx,i),1,line) q:i=""  w line}
a(1)=100
a(2)=200
a(3)=300
a(4)=400
a(5)=500
a(6)=600
a(7)=700
a(8)=800
a(9)=900
a(10)=1000
{66892,66645{11{
USER>f {q:'($zh\1#20)} s docIdx=$i(^SPOOL) k a o 2:(docIdx) f i=1:1:10 {s a(i)=i} u 2 zw a c 2 ; process #2
USER>s i="" f  {s i=$o(^SPOOL(docIdx,i),1,line) q:i=""  w line}
a(1)=1
a(2)=2
a(3)=3
a(4)=4
a(5)=5
a(6)=6
a(7)=7
a(8)=8
a(9)=9
a(10)=10
{66892,66645{11{

Each process has got it's own output in ^SPOOL(docIdx) now. This approach works if every consumer of spooling facility follows the same pattern; incrementing ^SPOOL is just an easiest approach, while it would be better avoid touching system globals and increment something else according to your taste.

^SPOOL(docIdx) approach allows spooling sharing across ECP network, while ^SPOOL($j) does not :)

%IS is an utility which allows to choose devices by CHUI routines users and %SPOOL utility can manipulate with spool files opened using the %IS utility only.

It seems that initial purpose of spooling facility has gone with such a users and such a printers (strictly character based, w/o ability of font selection, etc), while its usage still can be actual in rather exotic cases like this one.

Hi,

After many years of development and support I've become wary of one-line requests. 🤔 I wonder why you need this (Five whys - Wikipedia). For example, if you are trying to debug a mysterious state in a background job then maybe you just need "D LOG^%ETN" to store the variables in the error log. Or, at least you could look in there for ways to use $ORDER and $QUERY  to scan local variables without involving ^SPOOL (or, as we once did, opening a file to ZW to, closing, and then reading it back).