2010-10-21 12 views
14

Perdón por molestarlos a todos, pero estoy atascado en mi tarea para COBOL. Hice dos intentos, ninguno de los cuales funciona como se esperaba.Necesito ayuda con mi tarea de COBOL

A continuación se muestran los dos intentos y su resultado, seguidos de los resultados finales que necesita. Les agradezco a todos por su ayuda.

Primer intento:

IDENTIFICATION DIVISION. 
PROGRAM-ID. MAIL-LABEL. 
* 
****************************************************************** 
* This program prints duplicate side by side mailing labels. 
****************************************************************** 
ENVIRONMENT DIVISION. 
INPUT-OUTPUT SECTION. 
FILE-CONTROL. 

SELECT LABEL-FILE-IN 
ASSIGN TO 'MAIL-LABEL.SEQ' 
ORGANIZATION IS LINE SEQUENTIAL. 

SELECT LABEL-FILE-OUT 
ASSIGN TO 'MAIL-LABEL.RPT' 
ORGANIZATION IS LINE SEQUENTIAL. 

DATA DIVISION. 
FILE SECTION. 

FD LABEL-FILE-IN. 
01 LABEL-RECORD-IN. 
05 NAME-IN PIC X(20). 
05 ADDRESS-IN PIC X(20). 
05 CITY-STATE-ZIP-IN PIC X(20). 

FD LABEL-FILE-OUT. 
01 LABEL-RECORD-OUT. 
05 LEFT-LABEL-OUT PIC X(20). 
05 BLANK-OUT PIC X(15). 
05 RIGHT-LABEL-OUT PIC X(20). 
05 BLANK-A-OUT PIC X(5). 

WORKING-STORAGE SECTION. 
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'. 

PROCEDURE DIVISION. 
100-MAIN. 
OPEN INPUT LABEL-FILE-IN 
OPEN OUTPUT LABEL-FILE-OUT 

PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO' 
READ LABEL-FILE-IN 
AT END 
MOVE 'NO' TO ARE-THERE-MORE-RECORDS 
NOT AT END 
PERFORM 200-PROCESS-ONE-RECORD 
END-READ 
END-PERFORM 

CLOSE LABEL-FILE-IN 
CLOSE LABEL-FILE-OUT 
STOP RUN. 

200-PROCESS-ONE-RECORD. 
MOVE NAME-IN TO LEFT-LABEL-OUT 
MOVE ADDRESS-IN TO BLANK-OUT 
MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT 
MOVE SPACES TO BLANK-A-OUT 
WRITE LABEL-RECORD-OUT. 

Esto produce:

*IAN HENDERSON  1309 SPRINGBANKDETROIT  MI 48024 
*JANET LEASA   12700 GRATIOT SWARREN  MI 48077 
*COREY HAYES   400 BRUSH ST. DETROIT  MI 48024 
*SCOTT TOKLEY  2003 INDIAN RD.TAYLOR  MI 48075 
*JUDY FISHER   2200 WOODWARD ADETROIT  MI 48025 
*SHAWN MITCHELL  510 HOLLYWOOD PDETROIT  MI 48025 
*MARCUS PILLON  1450 JOY RD DEARBORN MI 48077 
*BRIAN GUENETTE  456 TRUMBULL STDETROIT  MI 48024 
*KIM MIKA   456 LAFAYETTE SDETROIT  MI 48024 
*KYLE THOMPSON  1617 MAPLE RD. WARREN  MI 48056 
*SUE DONALDSON  11 CASS AVE. DETROIT  MI 48024 

Mi segundo intento:

IDENTIFICATION DIVISION. 
PROGRAM-ID. MAIL-LABEL. 
* 
****************************************************************** 
* This program prints duplicate side by side mailing labels. 
****************************************************************** 
ENVIRONMENT DIVISION. 
INPUT-OUTPUT SECTION. 
FILE-CONTROL. 

SELECT LABEL-FILE-IN 
ASSIGN TO 'MAIL-LABEL.SEQ' 
ORGANIZATION IS LINE SEQUENTIAL. 

SELECT LABEL-FILE-OUT 
ASSIGN TO 'MAIL-LABEL.RPT' 
ORGANIZATION IS LINE SEQUENTIAL. 

DATA DIVISION. 
FILE SECTION. 

FD LABEL-FILE-IN. 
01 LABEL-RECORD-IN. 
05 NAME-IN PIC X(20). 
05 ADDRESS-IN PIC X(20). 
05 CITY-STATE-ZIP-IN PIC X(20). 

FD LABEL-FILE-OUT. 
01 LABEL-RECORD-OUT. 
05 LEFT-LABEL-OUT PIC X(20). 
05 BLANK-OUT PIC X(15). 
05 RIGHT-LABEL-OUT PIC X(20). 
05 BLANK-A-OUT PIC X(5). 

WORKING-STORAGE SECTION. 
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'. 

PROCEDURE DIVISION. 
100-MAIN. 
OPEN INPUT LABEL-FILE-IN 
OPEN OUTPUT LABEL-FILE-OUT 

PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO' 
READ LABEL-FILE-IN 
AT END 
MOVE 'NO' TO ARE-THERE-MORE-RECORDS 
NOT AT END 
PERFORM 200-PROCESS-ONE-RECORD 
END-READ 
END-PERFORM 

CLOSE LABEL-FILE-IN 
CLOSE LABEL-FILE-OUT 
STOP RUN. 

200-PROCESS-ONE-RECORD. 
MOVE NAME-IN TO LEFT-LABEL-OUT 
MOVE ADDRESS-IN TO LEFT-LABEL-OUT 
MOVE CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT 
MOVE SPACES TO BLANK-OUT 
MOVE NAME-IN TO RIGHT-LABEL-OUT 
MOVE ADDRESS-IN TO RIGHT-LABEL-OUT 
MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT 
MOVE SPACES TO BLANK-A-OUT 
WRITE LABEL-RECORD-OUT 

producido:

*DETROIT  MI 48024    DETROIT  MI 48024 
*WARREN  MI 48077    WARREN  MI 48077 
*DETROIT  MI 48024    DETROIT  MI 48024 
*TAYLOR  MI 48075    TAYLOR  MI 48075 
*DETROIT  MI 48025    DETROIT  MI 48025 
*DETROIT  MI 48025    DETROIT  MI 48025 
*DEARBORN MI 48077    DEARBORN MI 48077 
*DETROIT  MI 48024    DETROIT  MI 48024 
*DETROIT  MI 48024    DETROIT  MI 48024 
*WARREN  MI 48056    WARREN  MI 48056 
*DETROIT  MI 48024    DETROIT  MI 48024 

Lo que necesito a terminar con algo como:

*IAN HENDERSON      IAN HENDERSON 
*1309 SPRINGBANK ST.    1309 SPRINGBANK ST. 
*DETROIT  MI 48024    DETROIT  MI 48024 

*JANET LEASA      JANET LEASA 
*12700 GRATIOT ST.     12700 GRATIOT ST. 
*WARREN  MI 48077    WARREN  MI 48077 

*COREY HAYES      COREY HAYES 
*400 BRUSH ST.      400 BRUSH ST. 
*DETROIT  MI 48024    DETROIT  MI 48024 

*SCOTT TOKLEY      SCOTT TOKLEY 
*2003 INDIAN RD.     2003 INDIAN RD. 
*TAYLOR  MI 48075    TAYLOR  MI 48075 

¿Qué hay de malo en mi código?

Respuesta

3

Creo que su segundo intento fue casi correcta. Como Paxdiablo señaló en su respuesta, el problema que tiene es sobrescribir datos.

Si entiendo su problema correctamente, debe leer en un solo registro que contiene una dirección completa (Nombre, Dirección, Ciudad-Estado-Código postal) y tener a imprimir dos copias una al lado de la otra.

Observe que para cada línea que lea, debe imprimir 3. Observe también que solo tiene un búfer de registros de salida. Esto significa que solo puede procesar una línea de salida en un tiempo . La solución es mover cada componente de dirección a la izquierda y a la derecha de la línea de salida, dar salida a la línea y luego pasar al siguiente componente de dirección. Dado que hay 3 componentes de dirección, terminas imprimiendo 3 líneas para cada lectura.

Try modificando el párrafo 200-PROCESO-ONE-RECORD como sigue

200-PROCESS-ONE-RECORD. 
MOVE NAME-IN TO LEFT-LABEL-OUT 
MOVE SPACES TO BLANK-OUT 
MOVE NAME-IN TO RIGHT-LABEL-OUT 
MOVE SPACES TO BLANK-A-OUT 
WRITE LABEL-RECORD-OUT 

MOVE ADDRESS-IN TO LEFT-LABEL-OUT 
MOVE SPACES TO BLANK-OUT 
MOVE ADDRESS-IN TO RIGHT-LABEL-OUT 
MOVE SPACES TO BLANK-A-OUT 
WRITE LABEL-RECORD-OUT 

MOVE CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT 
MOVE SPACES TO BLANK-OUT 
MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT 
MOVE SPACES TO BLANK-A-OUT 
WRITE LABEL-RECORD-OUT 

Esto se lleva a una línea de entrada, produce 3 líneas de salida. Es posible que desee dar salida a una cuarta línea en blanco para separar las direcciones (como se ilustra en la salida de muestra - Voy a que le permite averiguar cómo hacerlo).

Creo que la solución de Paxdiablo resolvió un problema ligeramente diferente en el que se imprimirá una copia de cada dirección, pero las direcciones de impresión serán 2.

BTW ... A pesar de la cantidad de comentarios despectivos "drive by" que obtuvo su pregunta, COBOL todavía se utiliza activamente en algunos segmentos de esta industria.

+0

@After probar la versión de paxdiablo y dormir en él desperté con una idea simplemente como este recordando que estaba escribiendo hacia adelante y hacia atrás cada vez que se ingresaban nuevos datos.Lo tuyo fue por todos los motivos, excepto que tuve que espaciar entre etiquetas, pero para eso todo lo que hice fue hacer otro párrafo de código y enviar espacios a cada campo. Gracias por todo tu ayuda. – Kimmy1235

+0

Aarrgghh, solo pasé diez minutos averiguando qué significaba tu comentario sobre mi respuesta y arreglando el código solo para ver que ya respondiste con casi el mismo código (Scène à faire, supongo, COBOL en el otro extremo del espectro de la forma de pensar de Perl "hay miles de millones de formas de hacerlo"). De todos modos, +1 para una mejor respuesta. – paxdiablo

+0

Puede mover espacios en el nivel 01 al registro de salida, pero si recuerdo bien, eso solo se necesita una vez cuando el programa comienza y no es necesario dentro del ciclo. –

9

Normalmente, no le daría tanta ayuda para los deberes, pero, ya que has puesto un poco de esfuerzo en ello y es poco probable que encuentres muchos de nosotros dinosaurios aquí, te ayudaré. .

Su problema está aquí (ignorar las cosas en paréntesis de la derecha, son sólo comentarios para ayudarle a salir):

200-PROCESS-ONE-RECORD. 
    MOVE NAME-IN TO LEFT-LABEL-OUT 
    MOVE ADDRESS-IN TO LEFT-LABEL-OUT    (overwrite) 
    MOVE CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT   (overwrite) 
    MOVE SPACES TO BLANK-OUT 
    MOVE NAME-IN TO RIGHT-LABEL-OUT 
    MOVE ADDRESS-IN TO RIGHT-LABEL-OUT    (overwrite) 
    MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT  (overwrite) 
    MOVE SPACES TO BLANK-A-OUT 
    WRITE LABEL-RECORD-OUT       (only wrote one line) 

Este es el párrafo que procesa una registro. Lo que está haciendo aquí es poner tres cosas en las secciones de salida izquierda y derecha (de modo que las dos primeras se sobrescriban).

Lo que necesita es una variable de alternar para seleccionar si está procesando un valor a la izquierda o uno correcto, y la capacidad de almacenar los datos a la izquierda para poder generarlos ambos cuando procesa los datos correctos, algo como:

WORKING-STORAGE SECTION. 
    01 ARE-THERE-MORE-RECORDS  PIC X(3) VALUE 'YES'. 
    01 DOING-LEFT     PIC X(3) VALUE 'YES'. 
    01 LEFT-NAME-IN    PIC X(20). 
    01 LEFT-ADDRESS-IN   PIC X(20). 
    01 LEFT-CITY-STATE-ZIP-IN  PIC X(20). 

a continuación, modifique el código de procesamiento de registro de este modo (comprobar la sintaxis IF, ha sido un tiempo desde que corté cualquier código COBOL):

200-PROCESS-ONE-RECORD. 
    IF DOING-LEFT = 'YES' THEN 
     PERFORM 201-PROCESS-LEFT-RECORD 
    ELSE 
     PERFORM 202-PROCESS-RIGHT-RECORD. 

201-PROCESS-LEFT-RECORD. 
    MOVE NAME-IN TO LEFT-NAME-IN.      (just store it) 
    MOVE ADDRESS-IN TO LEFT-ADDRESS-IN. 
    MOVE CITY-STATE-ZIP-IN TO LEFT-CITY-STATE-ZIP. 
    MOVE 'NO' TO DOING-LEFT.       (and toggle to right) 

202-PROCESS-RIGHT-RECORD. 
    MOVE LEFT-NAME-IN TO LEFT-LABEL-OUT.    (first line, both sides) 
    MOVE SPACES TO BLANK-OUT. 
    MOVE NAME-IN TO RIGHT-LABEL-OUT. 
    MOVE SPACES TO BLANK-A-OUT. 
    WRITE LABEL-RECORD-OUT. 

    MOVE LEFT-ADDRESS-IN TO LEFT-LABEL-OUT.   (second line, both sides) 
    MOVE SPACES TO BLANK-OUT. 
    MOVE ADDRESS-IN TO RIGHT-LABEL-OUT. 
    MOVE SPACES TO BLANK-A-OUT. 
    WRITE LABEL-RECORD-OUT. 

    MOVE LEFT-CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT.  (third line, both sides) 
    MOVE SPACES TO BLANK-OUT. 
    MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT. 
    MOVE SPACES TO BLANK-A-OUT. 
    WRITE LABEL-RECORD-OUT. 

    MOVE 'YES' TO DOING-LEFT.       (toggle back to left) 

Entonces, al final, después de que el archivo tiene leído por completo, debe detectar si ha rellenado los datos de la izquierda (es decir, había un número impar de líneas de entrada). Este será el caso si DOING-LEFT se establece en 'NO'.

lo dejo a usted, pero se trata de mover los datos de izquierda y llenar los datos correctos con espacios, de una manera muy similar a 202-PROCESS-RIGHT-RECORD anterior (empujar, empujar, guiño, guiño).


Y, ahora que he tenido una buena miradaen la salida deseada, parece que realmente necesita dos copias de cada dirección en tanto la izquierda y la derecha.¿Estás seguro de que es la forma en que quieres hacerlo, ya que es un requisito bastante inusual para un programa de etiqueta de correo?

En cualquier caso, dejaré todo el código anterior ya que es una buena manera de hacer el método de cada una de las etiquetas postales, pero el código que parece necesitar es mucho más simple, una variación muy leve del 202-PROCESS-RIGHT-RECORD párrafo.

olvidar todo el almacenamiento de trabajo adicional que he mencionado, y sólo cambiar a 200-PROCESS-ONE-RECORD:

200-PROCESS-ONE-RECORD. 
    MOVE NAME-IN TO LEFT-LABEL-OUT. 
    MOVE SPACES TO BLANK-OUT. 
    MOVE NAME-IN TO RIGHT-LABEL-OUT. 
    MOVE SPACES TO BLANK-A-OUT. 
    WRITE LABEL-RECORD-OUT. 

    MOVE ADDRESS-IN TO LEFT-LABEL-OUT. 
    MOVE SPACES TO BLANK-OUT. 
    MOVE ADDRESS-IN TO RIGHT-LABEL-OUT. 
    MOVE SPACES TO BLANK-A-OUT. 
    WRITE LABEL-RECORD-OUT. 

    MOVE CITY-STATE-ZIP-IN TO LEFT-LABEL-OUT. 
    MOVE SPACES TO BLANK-OUT. 
    MOVE CITY-STATE-ZIP-IN TO RIGHT-LABEL-OUT. 
    MOVE SPACES TO BLANK-A-OUT. 
    WRITE LABEL-RECORD-OUT. 
1

Su pregunta ya está bien respondida sobre las sobrescrituras, pero agregaría dos cosas que mejorarán en gran medida su código Cobol en legibilidad y facilidad de mantenimiento.

Está utilizando un meme Cobol '74 aquí con la variable ARE-THERE-MORE-RECORDS y moviendo los literales 'YES' y 'NO' a él. Esto es muy frágil y propenso a la rotura. Un enfoque mucho más agradable, menos frágil, más legible es el uso de los condicionales que Cobol proporciona, también conocido como 88 de:

05 Filler   Pic x(1) Value 'Y'. 
    88 More-Records   Value 'Y'. 
    88 No-More-Records  Value 'N'. 

Puede probar con:

Perform until No-More-Records 

y el gatillo con:

Set No-More-Records to true 

Esto hace varias cosas por usted.

  • Nadie va a querer mantener una de sus literales a 'no' en lugar de 'NO' o de otra manera munge su código fuente. Esto puede ser un problema real en sistemas antiguos que hacen suposiciones sobre mayúsculas/minúsculas para sus usuarios y sus terminales conectados.

  • Nadie puede mover 'BOB' a su bandera porque no le dio un nombre, lo hizo relleno. Tienen que salir de su camino para asignar a esa variable en lugar de usar los nombres de las condiciones. Y si son lo suficientemente capaces de ir tan lejos, son lo suficientemente capaces de saber por qué NO DEBEN hacerlo.

  • Le da control de bucle y el control de archivos comprueba nombres significativos. Por supuesto, ARE-THERE-MORE-RECORDS 'SÍ'/'NO' es bastante significativo, pero en el verdadero código de producción encontrará muchas condiciones diferentes, a menudo con nombres inusuales y lógica retorcida detrás de ellos, a veces 'SÍ'/'NO' no es tan claro como podría ser. Proporcionar un buen nombre de condición de 30 caracteres es mucho más fácil para los programadores que lo seguirán para realizar el mantenimiento.

La otra cosa que debes hacer es utilizar el sistema de numeración de párrafos. Fue una idea poco pensada cuando los diagramas de flujo de papel cuadriculado eran toda la documentación que tenías y el control de la fuente no era aún un centelleo en el ojo de nadie.

100-MAIN. 
200-PROCESS-ONE-RECORD. 

Realmente no le compra nada, y viene con varias desventajas.

Con control de fuente moderno, los cambios a todos los demás números de párrafo que no están relacionados con el cambio específico que está realizando se destacarán como un pulgar dolorido. (Suponiendo que alguien vuelva a numerar sus párrafos cuando su lógica cambie, cosa que nunca hacen)

Fomenta los nombres de los párrafos realmente repugnantes. Considere esto, perfectamente válida bajo el sistema de numeración de los párrafos:

100-Read-File 
    200-Read-File 
    300-Read-File 
    110-Write-File 
    210-Write-File 
    310-Write-File 

Obviamente tenemos tres archivos diferentes, o por lo menos tres combinaciones de archivos y leer los tipos, pero no hay ninguna indicación de lo que es diferente con el nombre párrafo. También es propenso al error & de pegar donde alguien copia un párrafo, lo renumera, y no cambia por completo el contenido para golpear el nuevo archivo o establece los nuevos indicadores condicionales para el archivo separado, creando así sutiles y difíciles de encontrar loco.

Un enfoque mucho mejor es:

Read-Master-File 
    Read-Transaction-File 
    Write-Master-File 
    Write-Transaction-File 
    Write-Log-File 

Eso es más fácil hacer lo correcto y más difícil de hacer mal.

Recuerda que escribes el código fuente para que otros humanos lo lean, el compilador tomará cualquier tipo de basura, pero tu mantenimiento es el 90% del ciclo de vida de un programa y eso significa que otras personas * pasarán diez veces más tiempo tratando de entender lo que escribiste mientras lo escribiste. Hágalo fácil para ellos.

  • Muy a menudo, esto va a ser usted, pero usted no reconocerá el código que escribió hace seis meses ...
Cuestiones relacionadas