2

我想知道我想做的事情是否可以在 COBOL 中完成。我正在尝试从一个无序的文件中读取医院和患者数据。我将使用数组以某种方式对传入的数据进行排序,而不是使用排序(就像每个人在现实生活中一样)。最后,我应该将报告打印到按医院编号分组的另一个文件中。

所以,

Hospital #
patient 018
patient 020

total for hospital #

Hospital #
patient 011
patient 009

total for hospital #

所有这些医院的人数都在 1 到 30 之间,患者人数在 1 到 20 之间。我很清楚该怎么做以及如何总结患者余额,但你觉得这样去做怎么样:

将数据读入数组(这显然不止一维)。此时数据在数组中未排序。我认为它是否在数组中排序并不重要,只要它出现在排序的报告中即可。这听起来对吗?是的,这是一个任务。任何提示或建议,可以在不给出答案的情况下提供的反馈?

编辑:好的,所以我尝试创建一个二维类型数组,其中包含完成工作所需的字段(hos num、pat name、pat num、pat amnt)。当然,我想将每个患者的数量添加到医院小计的运行总计中。

这是我的数组:

01  HospArray value spaces.
       05  hosnum   occurs 30 times indexed by subsa.
         07  patnum   occurs 20 times indexed by subsb.
           10  patname  PIC X(20).
           10  patamt   PIC 9(7)v99.
         07  hossubtotal  PIC 9(7)v99.

在读取文件并将其移动到我的工作存储字段时,我尝试执行两个执行不同的循环,如下所示:

 perform varying subsa from 1 by 1 until subsa > 30
             move hos-num-ws to hosnum (subsa)
          perform varying subsb from 1 by 1 until subsb > 20

               move pat-name-ws to patname(subsa, subsb)
               move pat-amnt-od-ws to patamt(subsa, subsb)
               add  patamt(subsa, subsb) to hossubtotal (suba)

          end-perform
       end-perform

由于某种原因,这将无法编译,并给出以下错误:意外添加,我不确定为什么。我正在使用 openCobol。我没有很多经验,所以我不确定为什么不编译。我仍然不确定我是否朝着正确的方向前进。我知道我想说,为什么计数是在给定的医院号码上将患者数据移动到变量中,然后我应该知道当前医院号码何时完成。输出医院小计,然后再次重复该过程。

4

2 回答 2

2

“所有这些医院的人数都在 1 到 30 之间,患者人数在 1 到 20 之间”

因此,将这些值用作表中的“下标”。第一级的医院编号(1 到 30),第二级的患者编号(1 到 20)。一切都预先设置为空间。

当你列出来的时候,列出不是空格的医院(当时下标的值可以告诉你哪个,或者存储医院)和他们所有的不是空格的病人。

但是,您的样本输出中的患者“有点超出”1-20 :-)

编辑:

您的代码有几处问题。

加载表格时,您一次只会添加一个医院/患者组合。

从表中提取数据时,您将“循环”通过它。

您将医院编号移至表中,但将其移至组级别,因此将删除该条目下的任何内容。

我已经在评论中提到了错字。当您收到这样的编译消息时,您必须使用“好吧,这条线或这条线上方有问题”。

您在没有将起始值设置为零的情况下进行运行总计。

您不需要在进行过程中进行汇总,您可以在列出数据时进行。

其他几件事。您将索引称为“subsa”和“subsb”。这既没有“意义”又令人困惑(它们是索引,下标略有不同)。

你应该与缩写保持一致。您应该努力获得有意义的数据名称。

这是一些示例片段。我花了一些时间来命名和格式化。您可能认为这似乎需要付出很多努力,但这就是您的编辑器的能力所在。我没有多次输入任何长名称,但我敢打赌,您输入了每个短名称。

   01  HospArray value spaces.
       05  FILLER occurs 30 times 
                      indexed by I-Hospital-Entry.
           10  HA-Hospital-Entry.
               15  HA-Hospital-Number      pic xx. 
                   88  HA-hospital-not-present
                                           VALUE SPACE.
               15  FILLER occurs 20 times
                          indexed by I-Patient-Entry.
                   20  HA-Patient-Entry.
                       25  HA-Patient-Number         pic xx.
                           88  HA-Patient-not-present
                                           VALUE SPACE.
                       25  HA-Patient-Name           PIC X(20).
                       25  HA-Patient-Payment-Amount PIC 9(7)v99.
   01  Hospital-Sub-Total                            PIC 9(7)v99.
   01  W-Patient-Name                                pic x(20).
   01  Patient-Payment-Amount                        pic 9(7)v99.
   01  Hospital-Number.
       05  Hospital-Number-N                         pic 99.
   01  Patient-Number.
       ...
       SET I-Hospital-Entry         TO Hospital-Number-N
       SET I-Patient-Entry          TO Patient-Number-N 
       MOVE Hospital-Number         TO HA-Hospital-Number 
                                        ( I-Hospital-Entry )
       MOVE Patient-Number          TO HA-Patient-Number 
                                        ( I-Hospital-Entry 
                                           I-Patient-Entry )
       MOVE W-Patient-Name          TO HA-Patient-Name
                                        ( I-Hospital-Entry 
                                           I-Patient-Entry )
       MOVE Patient-Payment-Amount  TO HA-Patient-Payment-Amount
                                        ( I-Hospital-Entry 
                                           I-Patient-Entry )
       ...
       to output the results
       PERFORM                      LIST-PATIENTS-BY-HOSPITAL

       GOBACK
       .
   LIST-PATIENTS-BY-HOSPITAL.

       perform 
         varying I-Hospital-Entry 
           from 1 by 1 
           until I-Hospital-Entry > 30
           IF HA-hospital-not-present ( I-Hospital-Entry ) 
               CONTINUE
           ELSE
               PERFORM              LIST-PATIENTS
               DISPLAY Hospital-Sub-Total
           END-IF
           move HA-Hospital-Number 
                 ( I-Hospital-Entry ) 
                                    TO Hospital-Number
       end-perform
       .
   LIST-PATIENTS.
       perform 
         varying I-Patient-Entry 
           from 1 by 1 
           until I-Patient-Entry > 20
           IF HA-hospital-not-present ( I-Hospital-Entry ) 
               CONTINUE
           ELSE
               PERFORM              PATIENT-DETAILS
           END-IF
           DISPLAY Hospital-Sub-Total
       end-perform
       .
   PATIENT-DETAILS.
       move HA-Patient-Name 
             ( I-Hospital-Entry 
                I-Patient-Entry )   TO W-Patient-Name 
       move HA-Patient-Payment-Amount
             ( I-Hospital-Entry 
                I-Patient-Entry )   TO Patient-Payment-Amount 
       add Patient-Payment-Amount   TO Hospital-Sub-Total
       the "target" fields here can be in a formatted line for printing/DISPLAYing.
       .
于 2013-04-02T16:01:17.347 回答
1

您提供的示例患者编号超出了 1 到 20 的范围。我猜你的意思是说每家医院有 1 到 20 名患者,而不是说患者人数在 1 到 20 之间。

我还认为您的陈述:“以某种方式对进来的数据进行排序”是这里的真正目标。

输入文件中的数据未排序,但您需要对其进行排序。有几种方法可以做到这一点:

  • 将所有数据读入表中,然后使用外部 SORT 程序或您自己编写的内部排序(例如冒泡排序或类似的东西)对表进行排序。走这条路线将涉及进行两种排序,一种用于表格的每个维度(例如,按医院排序,然后按医院内的患者)

  • 读取一条记录并将其添加到表中,以便始终对表进行排序。这意味着能够在表的顶部、表中的两个现有项目之间或表的末尾插入一个新项目。同样,这将是一个二维过程:添加医院,在医院内添加患者

  • 比尔伍德格建议的方法只有在医院和患者人数在非常小的范围内时才会有效(正如您所建议的那样)。

无论如何,你现在有三个建议要跟进。由于这是一项家庭作业,我会根据围绕该作业教授的课程材料来选择。如果强调内部/外部排序,则走排序路线。如果多维表声明和操作是最近的主题,那么构建并保持表排序。如果出现散列,请考虑比尔的建议。

于 2013-04-02T18:38:18.257 回答