Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 15-02-2012
Avatar de richy08
richy08 richy08 is offline
Miembro
 
Registrado: may 2007
Ubicación: Bucerias, Nayarit Mexico
Posts: 529
Poder: 17
richy08 Va por buen camino
Access Violation con dato tipo record

buenos dias compañeros tengo una duda que no he podido resolver y no encuentro informacion sobre esto, estoy revisando un codigo donde se crea un tipo record de esta forma

Código Delphi [-]
type
  TRegClienteProveedor = Record
    cCodigoCliente                      : Array[0..kLongCodigo] of Char;
    cRazonSocial                        : Array[0..kLongNombre] of Char;
    cFechaAlta                          : Array[0..kLongFecha] of Char;
    cRFC                                : Array[0..kLongRFC] of Char;
    cCURP                               : Array[0..kLongCURP] of Char;
    cDenComercial                       : Array[0..kLongDenComercial] of Char;
    cRepLegal                           : Array[0..kLongRepLegal] of Char;
    cNombreMoneda                       : Array[0..kLongNombre] of Char;
    cListaPreciosCliente                : LongInt;
    cDescuentoMovto                     : Double;
    cBanVentaCredito                    : LongInt; // 0 = No se permite venta a crédito, 1 = Se permite venta a crédito
    cCodigoValorClasificacionCliente1   : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionCliente2   : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionCliente3   : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionCliente4   : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionCliente5   : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionCliente6   : Array[0..kLongCodValorClasif] of Char;
    cTipoCliente                        : LongInt; // 1 - Cliente, 2 - Cliente/Proveedor, 3 - Proveedor
    cEstatus                            : LongInt; // 0. Inactivo, 1. Activo
    cFechaBaja                          : Array[0..kLongFecha] of Char;
    cFechaUltimaRevision                : Array[0..kLongFecha] of Char;
    cLimiteCreditoCliente               : Double;
    cDiasCreditoCliente                 : LongInt;
    cBanExcederCredito                  : LongInt; // 0 = No se permite exceder crédito, 1 = Se permite exceder el crédito
    cDescuentoProntoPago                : Double;
    cDiasProntoPago                     : LongInt;
    cInteresMoratorio                   : Double;
    cDiaPago                            : LongInt;
    cDiasRevision                       : LongInt;
    cMensajeria                         : Array[0..kLongDesCorta] of Char;
    cCuentaMensajeria                   : Array[0..kLongDescripcion] of Char;
    cDiasEmbarqueCliente                : LongInt;
    cCodigoAlmacen                      : Array[0..kLongCodigo] of Char;
    cCodigoAgenteVenta                  : Array[0..kLongCodigo] of Char;
    cCodigoAgenteCobro                  : Array[0..kLongCodigo] of Char;
    cRestriccionAgente                  : LongInt;
    cImpuesto1                          : Double;
    cImpuesto2                          : Double;
    cImpuesto3                          : Double;
    cRetencionCliente1                  : Double;
    cRetencionCliente2                  : Double;
    cCodigoValorClasificacionProveedor1 : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionProveedor2 : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionProveedor3 : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionProveedor4 : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionProveedor5 : Array[0..kLongCodValorClasif] of Char;
    cCodigoValorClasificacionProveedor6 : Array[0..kLongCodValorClasif] of Char;
    cLimiteCreditoProveedor             : Double;
    cDiasCreditoProveedor               : LongInt;
    cTiempoEntrega                      : LongInt;
    cDiasEmbarqueProveedor              : LongInt;
    cImpuestoProveedor1                 : Double;
    cImpuestoProveedor2                 : Double;
    cImpuestoProveedor3                 : Double;
    cRetencionProveedor1                : Double;
    cRetencionProveedor2                : Double;
    cBanInteresMoratorio                : LongInt; // 0 = No se le calculan intereses moratorios al cliente, 1 = Si se le calculan intereses moratorios al cliente.
    cTextoExtra1                        : Array[0..kLongTextoExtra] of Char;
    cTextoExtra2                        : Array[0..kLongTextoExtra] of Char;
    cTextoExtra3                        : Array[0..kLongTextoExtra] of Char;
    cFechaExtra                         : Array[0..kLongFecha]  of Char;
    cImporteExtra1                      : Double;
    cImporteExtra2                      : Double;
    cImporteExtra3                      : Double;
    cImporteExtra4                      : Double;
  end {RegClienteProveedor};

e inmediatamente crean una variable de ese tipo record asi
Código Delphi [-]
LPFREGCTEPROV =  ^TRegClienteProveedor;
mi pregunta es que significa este simbolo ^, por que al tratar de mandar este record a una funcion que se encuantra en el sdk de contpaq i para el cfdi me marca violacion de memoria



Código Delphi [-]
var
lError, entero : Integer;
.
.
.

datos1.cCodigoCliente[0]:='3';
datos1.cRazonSocial[0]:='3';
datos1.cFechaAlta:='3';
.
.
.
.
.
.
 entero:=3;
    

    lError :=fAltaCteProv(entero, datos1);


    if lError <> kSIN_ERRORES  then
    begin
      rMensajeError( lError );
      Exit;
    end;

gracias por cualquier comentario
Responder Con Cita
  #2  
Antiguo 15-02-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por richy08 Ver Mensaje
e inmediatamente crean una variable de ese tipo record asi
Código Delphi [-]
LPFREGCTEPROV =  ^TRegClienteProveedor;
Aquí no estás creando ninguna variable, sino declarando un tipo de datos. Las variables de tipo LPFREGCTEPROV serían apuntadores a variables del tipo record. El caret, ^, significa apunta a.

Tendrías que declarar una variabe de ese tipo:

Código Delphi [-]
var
  P: LPFREGCTEPROV;

Y, una de dos, asignar a dicha variable la direccción de un registro ya existente o bien asignarle memoria con New o GetMem.

// Saludos
Responder Con Cita
  #3  
Antiguo 15-02-2012
Avatar de richy08
richy08 richy08 is offline
Miembro
 
Registrado: may 2007
Ubicación: Bucerias, Nayarit Mexico
Posts: 529
Poder: 17
richy08 Va por buen camino
Gracias roman por la aclaracion creo que andaba muy perdido, hice el codigo asi y ya inserta el sdk pero a parte del valor que le doy para el campo me pone otros caracteres que me hacen pensar que pasa algo con la memoria el codigo que uso es este

Código Delphi [-]
var
lError, entero : Integer;
datos1 :LPFREGCTEPROV;
.
.
.
.

     GetMem(datos1, SizeOf(TRegProducto));
     datos1.cCodigoCliente[0]:='3';
     datos1.cRazonSocial[0]:='3';
     datos1.cFechaAlta:='02132012';


    datos1.cRFC:='3';
    datos1.cCURP:='3' ;
    datos1.cDenComercial :='3' ;
    datos1.cRepLegal:='3' ;
    datos1.cNombreMoneda:='3' ;

lError :=fAltaCteProv(entero, datos1);


    if lError <> kSIN_ERRORES  then
    begin
      rMensajeError( lError );
      Exit;
    end;

    showmessage(inttostr(entero));
    FreeMem(datos1);

existe algo en este codigo que pueda ocasionarme este comportamiento

mil gracias
Responder Con Cita
  #4  
Antiguo 15-02-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
¿Cuál campo? ¿En dónde es que te muestra caracteres extraños?

// Saludos
Responder Con Cita
  #5  
Antiguo 15-02-2012
Avatar de richy08
richy08 richy08 is offline
Miembro
 
Registrado: may 2007
Ubicación: Bucerias, Nayarit Mexico
Posts: 529
Poder: 17
richy08 Va por buen camino
Cita:
Empezado por roman Ver Mensaje
¿Cuál campo? ¿En dónde es que te muestra caracteres extraños?

// Saludos
perdon se me olvido especificar el campo, con esta instruccion mando los datos a una funcion del sdk del contpaq

Código Delphi [-]
lError :=fAltaCteProv(entero, datos1);


donde datos1.cCodigoCliente[0]:='3'; escribe sobre el campo llamado CIDCLIEN01 de la tabla MGW10002.dbf que es un campo caracter de longitud 30
y si abro el contpaqi factura electronica si esta el registro guardaro pero en el campo su valor me muestra esto 3$otrocarcterextraño
Responder Con Cita
  #6  
Antiguo 15-02-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por richy08 Ver Mensaje
donde datos1.cCodigoCliente[0]:='3';
¿Por qué haces así la asignación? Aunque sea sólo un caracter, debería ser

Código Delphi [-]
datos1.cCodigoCliente:='3';

y lo mismo en todos los demás campos similares.

// Saludos
Responder Con Cita
  #7  
Antiguo 15-02-2012
Avatar de richy08
richy08 richy08 is offline
Miembro
 
Registrado: may 2007
Ubicación: Bucerias, Nayarit Mexico
Posts: 529
Poder: 17
richy08 Va por buen camino
Cita:
Empezado por roman Ver Mensaje
¿Por qué haces así la asignación? Aunque sea sólo un caracter, debería ser

Código Delphi [-]datos1.cCodigoCliente:='3';


y lo mismo en todos los demás campos similares.

// Saludos

en la definicion del record esta asi

Código Delphi [-]
type   TRegClienteProveedor = Record     cCodigoCliente                      : Array[0..kLongCodigo] of Char;

al parecer esta guardando un arreglo de caracteres donde kloncodigo es una constante con el valor de 30, es por eso que lo asigno de esta manera

Código Delphi [-]
datos1.cCodigoCliente[0]:='4';

no se si esta correcto??, me supongo que la funcion es capaz de insertar multiples clientes en una sola llamada

tienes razon al cambiar la asignacion de esta forma

Código Delphi [-]
datos1.cCodigoCliente:='4';

ya no inserta caracteres extraños, lo cual me surge una duda el codigo en el que me estoy basando fue programado por una persona de contpaq, lo mas extraño es que no tiene ejemplos de insercciones por lo cual no se que tan correcto sea dejar el record con ese estructura

mil gracias roman por tu tiempo

Última edición por richy08 fecha: 15-02-2012 a las 21:25:47.
Responder Con Cita
  #8  
Antiguo 15-02-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Con seguridad, la empresa tendrá más de 10 clientes, así que es de esperar que el campo datos1.cCodigoCliente admita más de un caracter. Estrictamente hablando, no tengo manera de saber qué es lo que hace el programador original con el valor de ese registro. Pero como aparece basura (caracteres extra no identificados) en el campo final, es de sospecharse que dichos valores los está mandando como cadenas de caracteres.

En Delphi, un arreglo de Char, que comience con índice 0, es compatible con un string, y de ahí que puedas hacer la asignación:

Código Delphi [-]
datos1.cCodigoCliente:='4';

o bien

Código Delphi [-]
datos1.cCodigoCliente:='4084';

Si en la declaración del tipo de datos TRegClienteProveedor cambias el campo

Código Delphi [-]
cCodigoCliente                      : Array[0..kLongCodigo] of Char;

por

Código Delphi [-]
cCodigoCliente                      : Array[1..kLongCodigo] of Char;

verás que ni siquiera te permite compilar cuando haces una asignación como la de arriba.

Ahora bien, cuando usas cadenas de caracteres en un registro asignado dinámicamente (como es tu caso, al asignar memoria), no conviene usar el tipo de datos string ya que éste es, en el fondo, un apuntador, y, como tal, mide 4 bytes, por lo que la llamada a

Código Delphi [-]
GetMem(datos1, SizeOf(TRegProducto));

te daría un tamaño incorrecto. Por ello, en estos casos conviene usar tipos de datos de longitud fija, y quizá por ello el programador original escogió usar esos arreglos de caracteres.

Sin embargo, no es la única manera y quizá podrías sustituir esos arreglos por cadenas de longitud fija:

Código Delphi [-]
cCodigoCliente                      : string[kLongCodigo];

// Saludos
Responder Con Cita
  #9  
Antiguo 15-02-2012
Avatar de richy08
richy08 richy08 is offline
Miembro
 
Registrado: may 2007
Ubicación: Bucerias, Nayarit Mexico
Posts: 529
Poder: 17
richy08 Va por buen camino
gracias roman por la explicacion
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Leer un fichero de tipo record Isuri Varios 3 31-03-2009 15:29:12
Tipo de dato MaMu OOP 1 15-12-2008 08:12:58
tipo de dato arnedokpo Conexión con bases de datos 1 14-07-2008 17:37:06
pasar un tipo de datos (array of record) entre aplicaciones mauqu Varios 4 26-10-2007 21:04:31
Pregunta teórica sobre el tipo Record en DLLs en Delphi 7 nlsgarcia Varios 2 02-03-2007 04:05:41


La franja horaria es GMT +2. Ahora son las 13:21:37.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi