I have a program that displays 4 subfiles similarly to this:
COL1 COL2 COL3
SFLAA----------------------------|
1 9999 9999 9999
2 9999 9999 9999
3 9999 9999 9999
*More...
SFLBB----------------------------|
1 9999 9999 9999
2 9999 9999 9999
3 9999 9999 9999
*More...
SFLCC----------------------------|
1 9999 9999 9999
2 9999 9999 9999
3 9999 9999 9999
*More...
SFLDD----------------------------|
1 9999 9999 9999
2 9999 9999 9999
3 9999 9999 9999
*More...
These subfiles show various types of summary information and users want to be able to click on any of these summary numbers and "drill down" to the underlying details. In order to do that I have to know which record in which subfile they clicked on.
I'm retrieving the cursor location from the INFDS
so when a user clicks on the screen I know which subfile they are clicking in (because I know what row they clicked on).
The SFLCSRRRN
keyword works wonderfully for the SFLAA
subfile because it's the "active" subfile (the program does an EXFMT CTLAA
, all other control formats are displayed via WRITE
). So far I have not been able to figure out how to determine which record of a subfile has been clicked on if it's SFLBB
, SFLCC
or SFLDD
.
Each subfile holds up to ~100 records (all loaded at once) so it's possible (and likely) the user has scrolled the subfiles before clicking on them.
How do I determine which subfile record the user clicked on if they click on one of the "non-active" subfiles?
---- BEGIN EDIT ----
I can get the Row/Col of where the user clicked on the screen just fine, my problem is when the user scrolls SFLBB, SFLCC or SFLDD down to say the 75th subfile record and then they click on that subfile. I can tell they clicked on row 8 on the screen (this would be the first line of SFLBB) - but I can't tell that's record 75 in SFLBB.
---- END EDIT ----
I've tried SFLCSRRRN
, SFLRCDNBR
, and SFLSCROLL
in various combinations and just cannot get anything to work for the non-active subfiles.
Here's relevant code from the DSPF
:
A DSPSIZ(24 80 *DS3)
A MOUBTN(*ULP CF06)
A R SFLAA SFL
A RRN1 4Y 0O 4 11EDTCDE(Z)
A R CTLAA SFLCTL(SFLAA)
A SFLSIZ(9999)
A SFLPAG(0003)
A CF03
A OVERLAY
A SFLCSRRRN(&ARRN)
A 10 SFLDSP
A SFLDSPCTL
A N10 SFLCLR
A 11 SFLEND(*MORE)
A ARRN 5S 0H
A 3 2'SFLAA'
A R SFLBB SFL
A RRN2 4Y 0O 9 11EDTCDE(Z)
A R CTLBB SFLCTL(SFLBB)
A SFLSIZ(9999)
A SFLPAG(0003)
A OVERLAY
A* Doesn't work SFLCSRRRN(&BRRN)
A 15 SFLDSP
A SFLDSPCTL
A N15 SFLCLR
A 16 SFLEND(*MORE)
A* Doesn't work BRRN 5S 0H
A* Doesn't work BRRN2 5S 0H SFLSCROLL
A 8 2'SFLBB'
Subfiles and control records SFLCC/CTLCC
and SFLDD/CTLDD
are logically identical to SFLBB/CTLBB
so I have omitted them.
Relevant RPGLE code:
ftestd cf e workstn sfile(sflaa: rrn1)
f sfile(sflbb: rrn2)
f sfile(sflcc: rrn3)
f sfile(sfldd: rrn4)
f infds(cusloc)
...
dcusloc ds
d rowcol 370 371b 0
...
drrn1 s 4 0 inz(0)
drrn2 s 4 0 inz(0)
drrn3 s 4 0 inz(0)
drrn4 s 4 0 inz(0)
...
c/free
...
begsr mouse_sr;
row# = rowcol / 256;
col# = %rem(rowcol: 256);
select;
when row# >= 4 and row# <= 6;
chain arrn sflaa;
if %found();
exsr detail1_sr;
endif;
when row# >= 9 and row# <= 11;
chain brrn sflbb;
if %found();
exsr detail2_sr;
endif;
when row# >= 14 and row# <= 16;
chain crrn sflcc;
if %found();
exsr detail3_sr;
endif;
when row# >= 19 and row# <= 21;
chain drrn sfldd;
if %found();
exsr detail4_sr;
endif;
endsl;
endsr;
...
c/end-free
The code as posted had a typo (SFLBB overlaid SFLAA). I added the little bit of glue to make it compile and ran it on IBM i 7.1. My machine is current with PTFs. Runs as expected. Here is the complete code:
DDS:
A DSPSIZ(24 80 *DS3)
A MOUBTN(*ULP CF06)
A R SFLAA SFL
A RRN1 4Y 0O 4 11EDTCDE(Z)
A R CTLAA SFLCTL(SFLAA)
A SFLSIZ(9999)
A SFLPAG(0003)
A CF03(03)
A OVERLAY
A SFLCSRRRN(&ARRN)
A 10 SFLDSP
A SFLDSPCTL
A N10 SFLCLR
A 11 SFLEND(*MORE)
A ARRN 5S 0H
A 3 2'SFLAA'
A R SFLBB SFL
A RRN2 4Y 0O 9 11EDTCDE(Z)
A R CTLBB SFLCTL(SFLBB)
A SFLSIZ(9999)
A SFLPAG(0003)
A OVERLAY
A* Doesn't work
A SFLCSRRRN(&BRRN)
A 15 SFLDSP
A SFLDSPCTL
A N15 SFLCLR
A 16 SFLEND(*MORE)
A BRRN 5S 0H
A* Doesn't work BRRN2 5S 0H SFLSCROLL
A 8 2'SFLBB'
And RPG:
fsotest cf e workstn sfile(sflaa: rrn1)
f sfile(sflbb: rrn2)
f infds(cusloc)
dcusloc ds
d rowcol 370 371b 0
drow# s 10i 0 inz(0)
dcol# s 10i 0 inz(0)
c/free
*in10 = *off; // SFLDSP AA
*in15 = *off; // SFLDSP BB
write ctlbb;
write ctlaa;
*in10 = *on; // SFLDSP AA
*in15 = *on; // SFLDSP BB
for rrn1 = 1 to 5;
rrn2 = rrn1;
write sflaa;
write sflbb;
endfor;
dow 1=1;
write ctlbb;
exfmt ctlaa;
if *in03;
*inlr = *on;
leave;
endif;
exsr mouse_sr;
enddo;
begsr mouse_sr;
row# = rowcol / 256;
col# = %rem(rowcol: 256);
select;
when row# >= 4 and row# <= 6;
chain arrn sflaa;
if %found();
// exsr detail1_sr;
endif;
when row# >= 9 and row# <= 11;
ADD THE FOLLOWING LINE
read ctlbb; // to get SFLRRN
chain brrn sflbb;
if %found();
// exsr detail2_sr;
endif;
endsl;
endsr;
/end-free
I run it in debug and look at row# and col# at the SELECT and they always look OK. See if you have the same results with this test code (both named SOTEST). If this test code runs as expected, the problem in the production code probably isn't row/column. If this test code exhibits incorrect row/column numbers, check your PTF levels. If current, call it in as a bug.
EDIT: I misunderstood the problem. RPG will fill in the I/O fields (like SFLCSRRRN) from the control record only when the control record is READ. The EXFMT handles this for CTLAA. In order to handle it for the other control records, insert a READ inside the calculations where you've determined which subfile the user is in.