可扩展子文件问题
Expandable subfile issue
我编写了下面的可扩展子文件程序,其中似乎存在一个问题,一旦定位到功能用于定位到特定记录,它就会无法正常工作。一旦显示定位到特定记录,程序似乎不再检测到 Pagedown/Page 向上按键。不知道为什么。如果未使用要显示的位置,则分页会按预期工作。我认为显示文件 DDS 没有问题,因此没有发布它。
HOPTION(*NODEBUGIO)
FSFLTBL IF E K DISK Rename(SFLTBL:SFLTBLR)
FSFLDSPF CF E WorkStn SFILE(SFLRCD:RRN1)
F INFDS(INFO)
DInfo DS
DCfKey 369 369
DExit C Const(X'33')
DCancel C Const(X'3C')
DEnter C Const(X'F1')
DRollUp C Const(X'F5')
DSflPag C Const(15)
DLstRrn S 4 0 Inz(0)
DI S 4 0 Inz(0)
/Free
Exsr Clear_Subfile;
Exsr Build_Subfile;
Dou (*Inkc or *InKl);
Write Footer;
Exfmt SFLCTLRCD;
Select;
When (CfKey = Enter and Ptname <> *Blanks);
Setll (PtName) Sfltbl;
Exsr Clear_Subfile;
Exsr Build_Subfile;
Clear PtName;
When (CfKey = Rollup and Not *In32);
Exsr Build_Subfile;
EndSl;
EndDo;
*Inlr = *On;
BegSr Clear_Subfile;
Rrn1 = *Zero;
LstRrn = *Zero;
*In31 = *On;
Write SFLCTLRCD;
*In32 = *Off;
*In31 = *Off;
*In90 = *Off;
EndSr;
BegSr Build_Subfile;
Rrn1 = LstRrn;
For i = 1 to SflPag;
Read Sfltblr;
If %Eof();
*In90 = *On;
Leave;
Else;
Rrn1 += 1;
Write SFLRCD;
EndIf;
EndFor;
If (Rrn1 > 0);
*In32 = *Off;
EndIf;
LstRrn = Rrn1;
EndSr;
/End-Free
以下 DSPF DDS:
A*%%TS SD 20170914 151431 THEJU112 REL-V5R3M0 5722-WDS
A*%%EC
A DSPSIZ(24 80 *DS3)
A PRINT
A ERRSFL
A CA03
A CA12
A R SFLRCD SFL
A FNAME R O 5 2REFFLD(SFLTBL/FNAME *LIBL/SFLTBL)
A MNAME R O 5 24REFFLD(SFLTBL/FNAME *LIBL/SFLTBL)
A LNAME R O 5 46REFFLD(SFLTBL/FNAME *LIBL/SFLTBL)
A R SFLCTLRCD SFLCTL(SFLRCD)
A*%%TS SD 20170914 151431 THEJU112 REL-V5R3M0 5722-WDS
A SFLSIZ(0016)
A SFLPAG(0015)
A OVERLAY
A N32 SFLDSP
A N31 SFLDSPCTL
A 31 SFLCLR
A 90 SFLEND(*SCRBAR *SCRBAR)
A ALARM
A ROLLUP
A RRN1 4S 0H SFLRCDNBR
A 1 2USER
A 1 69DATE
A EDTCDE(Y)
A 2 69TIME
A 4 5'FIRST NAME'
A COLOR(BLU)
A DSPATR(UL)
A DSPATR(RI)
A 4 28'MIDDLE NAME'
A COLOR(BLU)
A DSPATR(UL)
A DSPATR(RI)
A 4 49'LAST NAME'
A COLOR(BLU)
A DSPATR(UL)
A DSPATR(RI)
A 1 24'EXPANDABLE SUBFILE'
A COLOR(RED)
A 3 6'Position To...'
A PTNAME 20 I 3 21
A R FOOTER
A 23 2'F3 = Exit'
A 23 16'F12 = Previous'
我认为您的部分问题是 SFLRCDNBR
设置为用于子文件 IO 操作的相对记录号的同一字段 RRN1
。因此,无论您做什么,当按下 Enter
或 Page Down
时,子文件将始终重新定位到写入 SFLRCD
.
的最后一条记录
好的,这是一个问题,但这是另一个问题:
When (CfKey = Enter and Ptname <> *Blanks);
Setll (PtName) Sfltbl;
Exsr Clear_Subfile;
Exsr Build_Subfile;
Clear PtName;
当您将子文件定位到 Ptname
时,您正在清除子文件,因此没有任何内容可以回滚。不要清除子文件,您应该通读子文件直到找到正确的记录,然后将 SFLRCDNBR
字段设置为该值。您可能还想在 DDS 中指定 SFLRCDNBR(*TOP)
,并确保您在该记录之后的子文件中有整页。
注意:SFLRCDNBR
有时会有点难以处理,因为它不能使用条件指标,并且可能不是无效值(即它必须具有 1 和记录数之间的值在子文件中)。因此,在每次写入子文件控制格式时,您都需要确切地知道哪条记录需要成为显示屏上的第一条子文件记录(如果您使用的是 *TOP
),或者至少是显示屏上的一条记录。
您可以使用子过程在加载的子文件中定位记录。可以使用 CHAIN rrn
读取子文件记录,其中 rrn 是相对记录号。因此,只要我知道我向子文件写入了多少条记录,我就可以使用 for
循环遍历它们。找到要搜索的记录后,我从过程 return 传回我刚刚读取的记录号。那将是我在子文件中找到的记录的相对记录号。
dcl-proc FindNameInSubfile;
dcl-pi *n Int(5)
PtName Char(20) const;
end-pi;
dcl-ds sflds LikeRec(sflrcd: *input) Inz;
dcl-s ix Int(5) Inz(0);
for ix = 1 to maxrrn;
chain ix sflrcd sflds;
if sflds.lastname = PtName;
return ix;
endif;
endfor;
return -1;
end-proc;
如果未找到子文件记录,则此子程序returns -1。要使用它来设置 sflrcdnbr
你会想做这样的事情:
When (CfKey = Enter and Ptname <> *Blanks);
sflrrn = FindNameInSubfile(Ptname);
if sflrrn > 0;
sflrcdnbr = sflrrn;
endif;
Ptname = '';
注意,sflrrn
是定义为 Int(5)
的新工作字段,sflrcdnbr
是附加到 SFLRCDNBR
DDS 的新字段(不是 RRN1)关键字。
我编写了下面的可扩展子文件程序,其中似乎存在一个问题,一旦定位到功能用于定位到特定记录,它就会无法正常工作。一旦显示定位到特定记录,程序似乎不再检测到 Pagedown/Page 向上按键。不知道为什么。如果未使用要显示的位置,则分页会按预期工作。我认为显示文件 DDS 没有问题,因此没有发布它。
HOPTION(*NODEBUGIO)
FSFLTBL IF E K DISK Rename(SFLTBL:SFLTBLR)
FSFLDSPF CF E WorkStn SFILE(SFLRCD:RRN1)
F INFDS(INFO)
DInfo DS
DCfKey 369 369
DExit C Const(X'33')
DCancel C Const(X'3C')
DEnter C Const(X'F1')
DRollUp C Const(X'F5')
DSflPag C Const(15)
DLstRrn S 4 0 Inz(0)
DI S 4 0 Inz(0)
/Free
Exsr Clear_Subfile;
Exsr Build_Subfile;
Dou (*Inkc or *InKl);
Write Footer;
Exfmt SFLCTLRCD;
Select;
When (CfKey = Enter and Ptname <> *Blanks);
Setll (PtName) Sfltbl;
Exsr Clear_Subfile;
Exsr Build_Subfile;
Clear PtName;
When (CfKey = Rollup and Not *In32);
Exsr Build_Subfile;
EndSl;
EndDo;
*Inlr = *On;
BegSr Clear_Subfile;
Rrn1 = *Zero;
LstRrn = *Zero;
*In31 = *On;
Write SFLCTLRCD;
*In32 = *Off;
*In31 = *Off;
*In90 = *Off;
EndSr;
BegSr Build_Subfile;
Rrn1 = LstRrn;
For i = 1 to SflPag;
Read Sfltblr;
If %Eof();
*In90 = *On;
Leave;
Else;
Rrn1 += 1;
Write SFLRCD;
EndIf;
EndFor;
If (Rrn1 > 0);
*In32 = *Off;
EndIf;
LstRrn = Rrn1;
EndSr;
/End-Free
以下 DSPF DDS:
A*%%TS SD 20170914 151431 THEJU112 REL-V5R3M0 5722-WDS
A*%%EC
A DSPSIZ(24 80 *DS3)
A PRINT
A ERRSFL
A CA03
A CA12
A R SFLRCD SFL
A FNAME R O 5 2REFFLD(SFLTBL/FNAME *LIBL/SFLTBL)
A MNAME R O 5 24REFFLD(SFLTBL/FNAME *LIBL/SFLTBL)
A LNAME R O 5 46REFFLD(SFLTBL/FNAME *LIBL/SFLTBL)
A R SFLCTLRCD SFLCTL(SFLRCD)
A*%%TS SD 20170914 151431 THEJU112 REL-V5R3M0 5722-WDS
A SFLSIZ(0016)
A SFLPAG(0015)
A OVERLAY
A N32 SFLDSP
A N31 SFLDSPCTL
A 31 SFLCLR
A 90 SFLEND(*SCRBAR *SCRBAR)
A ALARM
A ROLLUP
A RRN1 4S 0H SFLRCDNBR
A 1 2USER
A 1 69DATE
A EDTCDE(Y)
A 2 69TIME
A 4 5'FIRST NAME'
A COLOR(BLU)
A DSPATR(UL)
A DSPATR(RI)
A 4 28'MIDDLE NAME'
A COLOR(BLU)
A DSPATR(UL)
A DSPATR(RI)
A 4 49'LAST NAME'
A COLOR(BLU)
A DSPATR(UL)
A DSPATR(RI)
A 1 24'EXPANDABLE SUBFILE'
A COLOR(RED)
A 3 6'Position To...'
A PTNAME 20 I 3 21
A R FOOTER
A 23 2'F3 = Exit'
A 23 16'F12 = Previous'
我认为您的部分问题是 SFLRCDNBR
设置为用于子文件 IO 操作的相对记录号的同一字段 RRN1
。因此,无论您做什么,当按下 Enter
或 Page Down
时,子文件将始终重新定位到写入 SFLRCD
.
好的,这是一个问题,但这是另一个问题:
When (CfKey = Enter and Ptname <> *Blanks);
Setll (PtName) Sfltbl;
Exsr Clear_Subfile;
Exsr Build_Subfile;
Clear PtName;
当您将子文件定位到 Ptname
时,您正在清除子文件,因此没有任何内容可以回滚。不要清除子文件,您应该通读子文件直到找到正确的记录,然后将 SFLRCDNBR
字段设置为该值。您可能还想在 DDS 中指定 SFLRCDNBR(*TOP)
,并确保您在该记录之后的子文件中有整页。
注意:SFLRCDNBR
有时会有点难以处理,因为它不能使用条件指标,并且可能不是无效值(即它必须具有 1 和记录数之间的值在子文件中)。因此,在每次写入子文件控制格式时,您都需要确切地知道哪条记录需要成为显示屏上的第一条子文件记录(如果您使用的是 *TOP
),或者至少是显示屏上的一条记录。
您可以使用子过程在加载的子文件中定位记录。可以使用 CHAIN rrn
读取子文件记录,其中 rrn 是相对记录号。因此,只要我知道我向子文件写入了多少条记录,我就可以使用 for
循环遍历它们。找到要搜索的记录后,我从过程 return 传回我刚刚读取的记录号。那将是我在子文件中找到的记录的相对记录号。
dcl-proc FindNameInSubfile;
dcl-pi *n Int(5)
PtName Char(20) const;
end-pi;
dcl-ds sflds LikeRec(sflrcd: *input) Inz;
dcl-s ix Int(5) Inz(0);
for ix = 1 to maxrrn;
chain ix sflrcd sflds;
if sflds.lastname = PtName;
return ix;
endif;
endfor;
return -1;
end-proc;
如果未找到子文件记录,则此子程序returns -1。要使用它来设置 sflrcdnbr
你会想做这样的事情:
When (CfKey = Enter and Ptname <> *Blanks);
sflrrn = FindNameInSubfile(Ptname);
if sflrrn > 0;
sflrcdnbr = sflrrn;
endif;
Ptname = '';
注意,sflrrn
是定义为 Int(5)
的新工作字段,sflrcdnbr
是附加到 SFLRCDNBR
DDS 的新字段(不是 RRN1)关键字。