可扩展子文件问题

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。因此,无论您做什么,当按下 EnterPage 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)关键字。