Итерирование Systems.Collections.List в Fujitsu COBOL

Как мне просмотреть коллекцию?

Я использую пробную версию компилятора Fujitsu/Alchemy и получаю медленную и слабую поддержку от поставщика.

Я в основном хочу передать List из C# в COBOL, а затем позволить COBOL использовать его и, возможно, обновить.

В C# обычным способом перебора коллекции является использование конструкции "foreach".

Однако конструкция C# "foreach" является сокращением для следующего:

private static void test1()
{
    List<IDMSMapField> list1 = new List<IDMSMapField>();
    int listSize = list1.Count;
    // was just checking exact variablename and case here to copy into COBOL code.
    int itemNumber = 0;

    System.Collections.Generic.List<IDMSMapField>.Enumerator enumerator1 = list1.GetEnumerator();

    while (enumerator1.MoveNext())
    {
        Console.Write("Okay" + enumerator1.Current);
    }
}

Я могу написать это на языке COBOL, если вы поможете мне определить этот класс:

System.Collections.Generic.List<IDMSMapField>.Enumerator

Структура "Перечислитель" описана на сайте MSDN Microsoft.

Это говорит о том, что "перечислитель" - это структура, а не класс!

Из того, что я могу сказать в руководстве "Создание COBOLfromDotnetFrameworkDox.pdf", структуры определены как классы в репозитории COBOL.

Пример из руководства:

Define specifiers for structure in REPOSITORY, and any struct members:
CLASS STRUCT-name AS "struct-namespace"
PROPERTY PROP-struct-member AS "external-property-name"
Handle structures like classes. E.g. object to store a struct instance:
01 struct-object OBJECT REFERENCE STRUCT-name.

Ниже я повторяю некоторые варианты, которые я пробовал, которые не удалось скомпилировать из-за ошибки "невозможно решить". Если вы можете показать мне, как это правильно заявить, я думаю, мы можем двигаться вперед.

1.

    REPOSITORY.
           CLASS  CLASS-LIST         AS "System.Collections.Generic.List<>"
           CLASS  STRUCT-Enumerator  AS "System.Collections.Generic.List<>.Enumerator"
           .

Ошибка во второй строке:

ошибка JMN1795I-S: именованная ссылка 'System.Collections.Generic.List<>.Enumerator' не может быть разрешена.

  1. Точно такая же ошибка для этого:

        REPOSITORY.
               CLASS  CLASS-LIST         AS "System.Collections.Generic.List<>"
               CLASS  STRUCT-Enumerator  AS "System.Collections.Generic.List<T>.Enumerator"
               .
    

ошибка JMN1795I-S: именованная ссылка System.Collections.Generic.List.Enumerator не может быть разрешена.

  1. Та же ошибка для этого:

    СКЛАД. CLASS CLASS-LIST AS "System.Collections.Generic.List<>" Класс CLUC STRUCT-Enumerator как "System.Collections.Generic.List.Enumerator" .

ошибка JMN1795I-S: именованная ссылка System.Collections.Generic.List.Enumerator не может быть разрешена.

Другая альтернатива состоит в том, чтобы рассматривать это как массив, но я застрял на этом также.

REPOSITORY.
    CLASS LIST-IDMSMapField    AS "System.Collections.Generic.List<>[]"
    CLASS CLASS-IDMSMapField   AS "Lightyear.ERCB.IDMSDC.IDMSMapField"
    CLASS CLASS-LIST-IDMSMapField EXPANDS LIST-IDMSMapField USING CLASS-IDMSMapField.

METHOD-ID. TW1DR4000-PF06 AS "TW1DR4000_PF06".
DATA DIVISION.
WORKING-STORAGE SECTION.

01 MapFieldItem USAGE OBJECT REFERENCE CLASS-IDMSMapField.

LINKAGE SECTION.

01 MapFieldList USAGE OBJECT REFERENCE CLASS-LIST-IDMSMapField.

PROCEDURE DIVISION...
...
SET MapFieldItem TO MapFieldList(1).

ошибка JMN2671I-S: ':' должно быть указано в модификаторе ссылки. ':' предполагается.

Я думаю, что компилятор видит (1) как операцию подстроки, возможно.

2 ответа

Решение

Это заняло некоторое время, но вот полный рабочий образец. Было несколько других приемов, чтобы добраться до свойств и переместить значения свойств, такие как Count, в переменную COBOL с соответствующим предложением USAGE. Ключевое слово "EXPANDS" (в хранилище) является еще одной ключевой частью решения.

В моей реальной программе я получу список в разделе LINKAGE, и у меня будет список более сложных объектов... но пример кода представляет собой более простой сценарий, который стоит отдельно и выполняется "как есть".

   IDENTIFICATION DIVISION.
   PROGRAM-ID. MAIN AS "COBOLEnumerationSample.Main".
   ENVIRONMENT DIVISION.
   CONFIGURATION SECTION.
   SPECIAL-NAMES.
   REPOSITORY.
       CLASS List        AS "System.Collections.Generic.List<>"
       CLASS SysString   AS "System.String"
       CLASS SysBoolean  AS "System.Boolean" 
       CLASS ListString EXPANDS List USING SysString
       CLASS Enumerator  AS "System.Collections.Generic.List<>+Enumerator"
       CLASS StringEnumerator EXPANDS Enumerator USING SysString
       PROPERTY PROP-Count   AS "Count"      
       PROPERTY PROP-Current AS "Current"
       .       
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01 myList              OBJECT REFERENCE ListString.
   01 myEnum              OBJECT REFERENCE StringEnumerator.   
   01 myBooleanEnumResult OBJECT REFERENCE SysBoolean. 
   01 myDotNetString      OBJECT REFERENCE SysString.  
   01 myLoopCounter       PIC 9(4)  value zero. 
   01 myCobolCount        PIC S9(9) COMP-5 VALUE ZERO.
   01 myCobolString       PIC X(30) value spaces. 
   01 YN-END-LOOP         PIC X     value "N". 
   01 WS-ACCEPT-INPUT     PIC X(80) value spaces. 

   PROCEDURE DIVISION.
   1000-START.
       INVOKE ListString "NEW" returning myList.
       INVOKE myList "Add" using "Apples"
       INVOKE myList "Add" using "Bananas"
       INVOKE myList "Add" using "Orange"


       SET myCobolCount to PROP-Count of myList 
       DISPLAY "Size of MyList = " myCobolCount

       INVOKE myList "GetEnumerator" returning myEnum.


       PERFORM UNTIL YN-END-LOOP = "Y" 
             INVOKE myEnum "MoveNext" returning myBooleanEnumResult  
  * How to test for Boolean, True = B'1' and False = B'0' 
             IF myBooleanEnumResult = B'0' 
                MOVE "Y" TO YN-END-LOOP 
             ELSE       
                SET myDotNetString TO PROP-Current of myEnum 
                ADD 1 TO myLoopCounter
                SET myCobolString to myDotNetString 
                DISPLAY myLoopCounter " " myCobolString 
             END-IF    

       END-PERFORM 

       DISPLAY "END OF PROGRAM - PRESS ENTER TO END" 
       ACCEPT WS-ACCEPT-INPUT
       .

   END PROGRAM MAIN.

Используя.NET-реализацию Micro Focus, код может использовать расширение "выполнять перемены" для просмотра списка.

Итак, измененная версия:

   IDENTIFICATION DIVISION.
   PROGRAM-ID. MAIN AS "COBOLEnumerationSample.Main".
   ENVIRONMENT DIVISION.
   CONFIGURATION SECTION.
   SPECIAL-NAMES.
   REPOSITORY.
       CLASS List        AS "System.Collections.Generic.List"
       CLASS SysString   AS "System.String"
       CLASS SysBoolean  AS "System.Boolean"
       CLASS ListString EXPANDS List USING SysString
       PROPERTY PROP-Count   AS "Count"
       PROPERTY PROP-Current AS "Current"
       .
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01 myList              OBJECT REFERENCE ListString.
   01 myLoopCounter       PIC 9(4)  value zero.
   01 myCobolCount        PIC S9(9) COMP-5 VALUE ZERO.
   01 myCobolString       PIC X(30) value spaces.
   01 WS-ACCEPT-INPUT     PIC X(80) value spaces.

   PROCEDURE DIVISION.
   1000-START.
       INVOKE ListString "NEW" returning myList.
       INVOKE myList "Add" using "Apples"
       INVOKE myList "Add" using "Bananas"
       INVOKE myList "Add" using "Orange"

       SET myCobolCount to PROP-Count of myList
       DISPLAY "Size of MyList = " myCobolCount

       move 0 to myLoopCounter
       PERFORM varying myCobolString through myList
           DISPLAY myLoopCounter " " myCobolString
           ADD 1 to myLoopCounter
       END-PERFORM

       DISPLAY "END OF PROGRAM - PRESS ENTER TO END"
       ACCEPT WS-ACCEPT-INPUT
       .

   END PROGRAM MAIN.

Далее, вместо использования синтаксиса репозитория и расширений, вы можете использовать встроенное объявление, например:

   IDENTIFICATION DIVISION.
   PROGRAM-ID. MAIN AS "COBOLEnumerationSample.Main".
   WORKING-STORAGE SECTION.
   01 myList         type "System.Collections.Generic.List"[string].
   01 myLoopCounter   PIC 9(4)  value zero.
   01 myCobolCount    PIC S9(9) COMP-5 VALUE ZERO.
   01 myCobolString   PIC X(30) value spaces.
   01 WS-ACCEPT-INPUT PIC X(80) value spaces.

   PROCEDURE DIVISION.
   1000-START.
       INVOKE type "System.Collections.Generic.List"[string]::"NEW"
             returning myList
       INVOKE myList "Add" using "Apples"
       INVOKE myList "Add" using "Bananas"
       INVOKE myList "Add" using "Orange"


       SET myCobolCount TO myList::"Count"
       DISPLAY "Size of MyList = " myCobolCount

       MOVE 0 TO myLoopCounter
       PERFORM varying myCobolString through myList
           DISPLAY myLoopCounter " " myCobolString
           ADD 1 TO myLoopCounter
       END-PERFORM

       DISPLAY "END OF PROGRAM - PRESS ENTER TO END"
       ACCEPT WS-ACCEPT-INPUT
       .

   END PROGRAM MAIN.

В любом случае, мне просто нравится, что мы можем сделать это в COBOL, независимо от того, какой продукт используется.. Наслаждайтесь...

Другие вопросы по тегам