Die Frage ist nicht so sehr "Warum macht Enterprise COBOL das?", Weil es dokumentiert ist, wie "warum generieren diese anderen zwei Compiler Programme, die tun, was ich will?", Was wahrscheinlich auch dokumentiert ist.
Hier ist ein Zitat aus dem Entwurf des späteren 2014 COBOL Standard (die tatsächliche Standard-Geld kostet):
C.3.4.1 Subskribierung indexNamen
Um diese zu erleichtern Operationen wie Tabellensuche und Manipulation bestimmter Elemente, ist eine Technik namens Indizierung verfügbar. Um diese Technik zu verwenden, weist der Programmierer einem Element, dessen Datenbeschreibungseintrag eine OCCURS-Klausel enthält, einen oder mehrere Indexnamen zu. Ein Index, der einem Indexnamen zugeordnet ist, fungiert als Index, und sein Wert entspricht einer Häufigkeitsnummer für das Element, dem der Indexname zugeordnet ist.
Die INDEXED BY-Angabe, mit der der Indexname identifiziert wird, und , die seiner Tabelle zugeordnet ist, ist ein optionaler Teil der OCCURS-Klausel. Es gibt keinen separaten Eintrag zur Beschreibung des Indexes, der index-name zugeordnet ist, da seine Definition vollständig hardwareorientiert ist.Bei Laufzeit entspricht der Inhalt des Index einer Vorkommenummer für die spezifische Dimension der Tabelle, mit der der Index zugeordnet ist; die Art der Übereinstimmung wird jedoch durch den Implementierer bestimmt. Der Anfangswert eines Index zur Laufzeit ist nicht definiert, und der Index soll vor der Verwendung initialisiert werden. Der Anfangswert eines -Index wird mit der PERFORM-Anweisung mit der VARYING-Angabe, der SEARCH-Anweisung mit der ALL-Anweisung oder der SET-Anweisung zugewiesen.
[...]
Ein Index-Name kann nur die Tabelle, auf die sie über die indizierte BY Phrase zugeordnet ist Referenz verwendet werden.
Aus dem zweiten Absatz wird klar, dass die Implementierung eines Indexes auf den Implementierer des Compilers zurückzuführen ist. Was bedeutet, dass das, was ein Index tatsächlich enthält und wie er intern manipuliert wird, von Compiler zu Compiler variieren kann, solange die Ergebnisse gleich sind.
Der letzte zitierte Absatz gibt an, dass ein bestimmter Index vom Standard nur für die Tabelle verwendet werden kann, die diesen spezifischen Index definiert.
Sie haben einen entsprechenden Code in 310-CALC-TOTALS
: Nehmen Sie ein Quelldatenelement mit dem Index aus seiner Tabelle, und verwenden Sie diesen Index aus der "falschen" Tabelle, um einen abgeleiteten Wert in einer anderen Tabelle zu speichern.
Dies unterbricht die "Ein Index-Name kann verwendet werden, um nur die Tabelle zu referenzieren, mit der er über den INDEXED BY-Ausdruck verknüpft ist."
Sie haben also Ihren Code in 310-CALC-TOTALS geändert in: nehmen Sie ein Quelldatenelement mit dem Index aus seiner Tabelle und verwenden Sie einen in der Zieltabelle definierten Datennamen oder Index, um einen davon abgeleiteten Wert zu speichern in einer anderen Tabelle.
So funktioniert nun Ihr Code, und Sie erhalten das gleiche Ergebnis mit jedem Compiler.
Warum kompiliert der Enterprise COBOL-Code, wenn der Standard (und dies war der gleiche für frühere Standards) verbietet diese Verwendung?
IBM hat eine Spracherweiterung. In der Tat zwei Erweiterungen, die zu Ihrem Fall anwendbar sind (aus der Unternehmen COBOL-Sprachreferenz zitiert in Anhang A):
Indexing und Subskribierung ... eine Tabelle mit einem Index-Namen referenzieren definiert nicht für einen anderen Tisch
und
OCCURS ... Verweis auf eine Tabelle, durch Indizieren, wenn indizierte BY Phrase
angegeben
So haben Sie keine Kompilierung-Fehler erhalten, als einen Index aus einer anderen Tabelle und unter Verwendung eines Index, wenn kein Index für die Tabelle sind beide OK definiert ist.
Also, was macht es, wenn Sie einen anderen Index verwenden?Wieder von der Sprachreferenz, Subskribierung diesmal auf Indexnamen (Indexierung)
Ein Index-Name jeder Tabelle verweisen verwendet werden kann. Jedoch sollte das Element Länge der Tabelle, auf die verwiesen wird, und der Tabelle, die der Indexname zugeordnet ist, übereinstimmen. Andernfalls wird der Verweis nicht auf das gleiche Tabellenelement in jeder Tabelle verweisen, und Sie erhalten möglicherweise Laufzeitfehler.
Welches ist genau das, was dir passiert ist. Der Unterschied in den Längen der Elemente in den OCCURS liegt an den "Einfüge-Bearbeitungs" -Symbolen in Ihrem PICture für die Tabelle, von der Sie ANZEIGEN. Wenn die Elemente in den beiden Tabellen die gleiche Länge hätten, hätten Sie kein Problem bemerkt.
Sie gaben eine VALUE-Klausel für Ihre Tabellenelemente (unnötig, da Sie immer etwas in sie vor der Ausgabe geben würden) und dies verließ Ihre "sechste" Spalte, die fünf vorherigen Spalten wurden als kürzere Elemente geschrieben. Beachten Sie die Verwirrung, die entsteht, wenn die Bearbeitung auf eine Länge erfolgt und das Speichern mit einer anderen impliziten Länge erfolgt, Sie überschreiben sogar die zweite Dezimalstelle.
IBMs Implementierung von INDEXED BY bedeutet, dass die Länge der indizierten Elemente intrinsisch ist. Daher die unerwarteten Ergebnisse, wenn die referenzierten Felder tatsächlich unterschiedliche Längen haben.
Was ist mit den anderen beiden Compilern? Sie müssen ihre Dokumentation treffen, um sicher zu sein, was passiert ist (etwas so Einfaches wie der Index durch eine Eintragsnummer dargestellt wird (also Ebene 1, 2, 3, usw.) und das Erlauben eines Index, sich auf einen anderen zu beziehen Tisch wäre genug). Es sollte zwei Erweiterungen geben: um zu ermöglichen, dass ein Index für eine Tabelle verwendet wird, die diesen Index nicht definiert hat; um zu ermöglichen, dass ein Index für eine Tabelle verwendet wird, für die kein Index definiert ist. Die beiden kommen logisch als ein Paar, und beide müssen nur spezifisch sein (das erste würde anders tun), weil sie spezifisch gegen den Standard sind.
Micro Focus verfügt über eine Sprachenerweiterung, wobei ein Index aus einer Tabelle verwendet werden kann, um Daten aus einer anderen Tabelle zu referenzieren. Es ist nicht explizit, dass dies eine Referenzierung einer Tabelle ohne definierte Indizes beinhaltet, aber dies ist offensichtlich so.
Tutorialsoft verwendet OpenCOBOL 1.1. OpenCOBOL ist jetzt GnuCOBOL. GnuCOBOL 1.1 ist die aktuelle Version, die anders und aktueller als OpenCOBOL 1.1 ist. GnuCOBOL 2.0 kommt bald. Ich trage den Diskussionsbereich für GnuCOBOL bei SourceForge.Net bei und habe das Thema dort angesprochen. Simon Sobisch vom GnuCOBOL-Projekt hat sich bereits an Ideaone und Tuturialspoint über die Verwendung des veralteten OpenCOBOL 1.1 gewandt. Ideaone hat positives Feedback gegeben, Tutorialpoint, mit dem Simon sich heute noch nicht in Verbindung gesetzt hat, noch nichts.
Als Nebenproblem sieht es so aus, als ob Sie SEARCH ALL
verwenden, um eine Binärsuche Ihrer Tabelle durchzuführen. Für "kleine" Tabellen ist es wahrscheinlich, dass der Overhead der Mechanismen der verallgemeinerten Binärsuche, die von SUCHEN ALL bereitgestellt wird, die erwarteten Einsparungen bei den Maschinenressourcen überwiegt. Wenn Sie große Datenmengen verarbeiten, ist eine einfache SUCHE wahrscheinlich effizienter als die SUCHE ALL.
Wie klein "klein" ist, hängt von Ihren Daten ab. Fünf ist wahrscheinlich zu fast 100% klein.
Bessere Leistung als die Funktionen SEARCH und SEARCH ALL können durch Kodieren erreicht werden, aber denken Sie daran, dass SEARCH und SUCHE ALLE keine Fehler machen.
Aber vor allem mit SEARCH ALL sind Fehler durch den Programmierer einfach.Wenn die Daten nicht in der richtigen Reihenfolge sind, funktioniert SEARCH ALL nicht korrekt. Das Definieren von mehr Daten als das Auffüllen von Daten führt dazu, dass eine Tabelle schnell aus der Reihenfolge kommt. Wenn Sie SEARCH ALL mit einer variablen Anzahl von Elementen verwenden, sollten Sie die Verwendung von OCCURS DEPENDING ON für die Tabelle oder "Auffüllen" von nicht verwendeten nachgestellten Einträgen mit einem Wert über dem maximal möglichen Schlüsselwert in Betracht ziehen.
Notwendigkeit zu sehen: W02-O-IDX; W02-B-IDX; W12-BÜRO-COUNT. Da einige Leute das Suffix "IDX" und eine Pseudozufallsart verwenden, müssen wir die Definitionen sehen. Nimm die VALUE-Klausel auf W-B-TOTAL ab und die Nullen werden auf magische Weise weggehen (sie werden etwas anderes sein). –
Jetzt, da der Fix in ist, richtet sich die gesamte Ausgabe gleich aus? Schau dir deine Screenshots an. Warum befindet sich die Spalte TOTAL, die vom Problem OCCURS unbeeinflusst ist, an einer anderen Stelle als die Überschriften der beiden Beispiele? –