numeros - Problema de formato de número COBOL COMP-3
funcion format vba excel (5)
Estoy llegando a esto un poco tarde, pero tengo un par de sugerencias que pueden hacer su vida más fácil ...
Primero, vea si puede hacer que las partes de su mainframe conviertan todos los datos no característicos (es decir, numéricos binarios y decimales empaquetados) al formato de visualización (por ejemplo, PIC X) antes de descargarlo. Entonces solo necesita tratar con el rango "imprimible" de caracteres numéricos que representan de 0 a 9. Las conversiones de página de códigos solo imprimibles son bastante estándar y tienden a no estropearse tanto. Reformatear los datos proporcionados en un cuaderno no es una perspectiva difícil para alguien competente en un entorno de mainframe. Desafortunadamente, a veces se obtiene el "rodeo" y se hace un reclamo que es extremadamente costoso o requiere un software especial o cualquiera de las cien excusas falsas.
Si obtienes el "rodeo", entonces lo mejor es descargar el archivo en formato binario y hacer tu propia conversión de página de códigos para los datos del personaje (bastante sencillo). Luego, trate los datos binarios en base a las definiciones de su cuaderno. Con unos pocos Googles, deberías poder encontrar suficiente información para pasar los datos PACKED-DECIMAL (COMP-3) a lo que necesites.
Aquí hay un par de enlaces para que comiences:
No recomiendo intentar realizar una ingeniería inversa de las conversiones de página de códigos aplicadas por el paquete de transferencia de archivos para decodificar el decimal empaquetado y otros datos binarios.
Tengo un volcado de "formato de cinta" de cobol que tiene una combinación de campos de texto y números. Estoy leyendo el archivo en C # como una matriz binaria (matriz de bytes). Tengo el libro de copia y los formatos se alinean bien en los campos de texto. Hay una serie de campos COMP-3 también. Los datos en esos campos no parecen coincidir con ningún formato BCD. Sé cuáles deberían ser los datos y tengo los bytes sin formato del COMP-3. Intenté convertir a EBCDIC primero, lo que no arrojó mejores resultados. ¿Alguna idea de cómo se puede almacenar internamente un número COMP-3? A continuación hay tres ejemplos del PIC, los datos brutos y el número esperado. Sé que tengo las posiciones de campo correctas porque hay datos alfa en cada lado de los números y todos se alinean correctamente.
Primer ejemplo: el PIC del campo es 9 (9) COMP-3 Hay 5 bytes para los datos, los valores hexadecimales son 02 01 20 91 22 Los datos resultantes deben ser una fecha (00CCYYMMDD). Esta fecha particular debe ser 3-17-14.
Segundo ejemplo: El PIC del campo es S9 (3) COMP-3 Hay 2 bytes para los datos, los valores hexadecimales son 0A 14 El valor resultante debe estar entre 900 y 999 Mi entendimiento es que la "S" significa que el El último mordisco debe ser 0xC o 0xD para indicar + o -
Tercer ejemplo: El PIC del campo es S9 (15) V99 COMP-3 Hay 9 bytes para los datos, los valores hexadecimales son 00 00 00 00 00 01 80 0C El valor resultante debe ser 12.00
Muy bien, gracias a las personas que respondieron cuando me indicaron en la dirección correcta. Este es de hecho un problema de representación ASCII / EBCDIC. El BCD se almacena en EBCDIC. El uso de una tabla de conversión de ASCII a EBCDIC produce dígitos BCD correctamente formateados:
Utilicé este enlace para mapear los datos: http://shop.alterlinks.com/ascii-table/ascii-ebcdic-us.php
Mis datos: 0A 14 Convertido: 25 3C (resulta que 253 es un valor válido, la especificación era incorrecta) C = +, todo bien
Mis datos: 01 80 0C (sin incluir los ceros a la izquierda) Convertido: 01 20 0C 12.00 C = +, implica 2 dígitos en el formato, todo bien
Mis datos: 02 01 20 91 22 Convertido: 02 01 40 31 7F 2014/03/17 (F es un mordisco no utilizado), todo bien
Muy bien, gracias a las dos personas que respondieron cuando me indicaron en la dirección correcta. Este es de hecho un problema de representación ASCII / EBCDIC. El BCD se almacena en EBCDIC. El uso de una tabla de conversión de ASCII a EBCDIC produce dígitos BCD correctamente formateados:
Utilicé este enlace para mapear los datos: http://shop.alterlinks.com/ascii-table/ascii-ebcdic-us.php
My data: 0A 14
Converted: 25 3C (turns out that 253 is a valid value, spec was wrong) C = +, all good
My data: 01 80 0C (excluding leading zeros)
Converted: 01 20 0C 12.00 C = +, implied 2 digits in format, all good
My data: 02 01 20 91 22
Converted: 02 01 40 31 7F 2014/03/17 (F is unused nibble), all good
Gracias de nuevo por las dos respuestas anteriores que me condujeron en la dirección correcta.
Bien, echemos un vistazo a su primer ejemplo. Dado el formato y el valor, el contenido BCD original debería haber sido algo así como
02 01 40 31 7F
Al transformar eso de EBCDIC a ASCII, tenemos problemas con el primer, segundo y cuarto byte porque son caracteres de control, así que aquí necesitaríamos más detalles sobre cómo funcionaba el convertidor ASCII-> EBCDIC. Mirando los dos bytes restantes esos serían cambiados
EBCDIC ASCII CHARACTER
40 -> 20 (blank)
7F -> 22 "
Asumiendo que los dos primeros bytes permanecen sin cambios y el tercero se convierte como 31->91
, terminamos con
02 01 20 91 22
que es lo que tienes Entonces parece que se produjo algún tipo de conversión EBCDIC-> ASCII. Si ese es el caso, es posible que no pueda reparar los datos, ya que la transformación puede no ser uno a uno y, por lo tanto, no reversible.
Mirando el segundo ejemplo y usando
EBCDIC ASCII CHARACTER
25 -> 0A (LF)
3C -> 14 (DC4)
habrías comenzado con 25 3C
que se ajustaría al formato pero no al rango que diste.
En el tercer ejemplo, el 01 20 0C
original podría convertirse a 01 80 0C
ya que 20
también es un carácter de control EBCDIC sin equivalente ASCII directo.
Pero dado el resto de ejemplos, supongo que hay algún problema de conversión de página de códigos. Si utilizó algún tipo de transferencia de archivos para mover los datos desde el mainframe (supuesto), asegúrese de que esté configurado en modo binario y no realice ninguna conversión de caracteres antes de dividir el archivo en campos y saber qué se supone que es un personaje Y qué no.
EDITAR: Puede encontrar una lista de varias páginas de códigos EBCDIC y ASCII aquí o buscar aquí lo mismo que un pdf.
Puede evitar los problemas anteriores haciendo que los datos se conviertan en un método moderno para transferir datos: XML.
No existe el COBOL "tape format"
aunque la frase puede significar algo para la persona que le proporcionó los datos.
La clave de tu problema es que puedes leer el texto. Conéctelo a la etiqueta EBCDIC y su referencia a C #.
Por lo tanto, está leyendo datos que originalmente provienen de un Mainframe, muy probablemente un IBM Mainframe, que usa EBCDIC en lugar de ASCII.
COBOL no tiene soporte nativo para BCD.
Lo que un alma amable ha hecho por ti es "convertir" los datos de EBCDIC a ASCII. De lo contrario, ni siquiera reconocerías el "texto".
Desafortunadamente, lo que eso significa para cualquier campo binario o decimal empaquetado o coma flotante (no verá mucho de lo último, pero son COMP-1 / COMP-2) es que "convertir" significa "potencialmente codificado", porque la cobertura está asumiendo bytes individuales, con valores de bytes simples, mientras que todos esos campos tienen codificación convencional, ya sea a través de bytes múltiples o valores no EBCDIC o ambos.
Entonces: COMP-3 PIC 9 (9). Como dices, cinco bytes. No está firmado, por lo que el nybble más a la derecha será F (todos los bits activados). Estás ligeramente fuera con tus posiciones debido a que la posición del signo está ocupada, incluso para un campo sin firmar.
En Mainframe, contiene un valor X''020140317F''
. Solo ese campo en su totalidad puede tener algún sentido en cuanto a su valor. Sin embargo, la conversión EBCDIC a ASCII lo ha convertido en X''0201209122 ''.
¿Cómo?
Busque el valor EBCDIC de X''02''
y X''01''
. Ellos no cambian Busque el valor de X''40''
, whoops, eso es un espacio, cámbielo a ASCII X''20''
. Busque el valor de X''31''
. Realmente no hay nada especial allí, y se ha convertido en algo más alto que X''7F''
, pero si miras la tabla de traducción utilizada, supongo que verás por qué sucede. El X''7F''
es una comilla doble, por lo que se cambia a X''22''
.
Los otros valores que muestra sufren el mismo problema.
Solo debe tomar datos de un Mainframe en formato de solo caracteres. Hay muchas respuestas aquí sobre esto, debe mirar lo related
a la derecha.
Eche un vistazo a esta pregunta reciente: convierta el COMP y el Com-3 Packed Decimal en un valor legible con C