Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Impresión (https://www.clubdelphi.com/foros/forumdisplay.php?f=4)
-   -   Migración QReport 3 a QReport 6 (https://www.clubdelphi.com/foros/showthread.php?t=93059)

QuiqueSalamanca 04-05-2018 10:17:02

Migración QReport 3 a QReport 6
 
Buenos días a todos, hacía mucho que no pasaba por aquí.

Estoy migrando una aplicación desde Delphi 7 a Delphi 10.2.3 Tokyo.

Os pongo primero en antecendentes, conseguí migrar dicha aplicación a Delphi XE7, compilada perfectamente (con el QuickReport 5.05). Ahora la empresa para la que trabajo ha comprado la versión 10.2.3 y ando en la migración (que no debería dar ningún problema, excepto algunos componentes nuevos...).

Todos los componentes de terceros están instalados y migrados (los gratuitos y antiguos que vienen desde D7) correctamente (de hecho los he probado en aplicaciones independientes). El problema me surge a la hora de compilar, me lleva a la unit qrpcontrols y me da un error de incompatibilidad de tipos.

Lo raro es que la incompatibilidad de tipos que me da es "TField" y "TBlobField", aquí me descuadra todo porque un "TBlobField" hereda de "TField".

Este código me compila y entra en el IF correspondiente sin problemas:

Código Delphi [-]
var
   oField     : TField;
   oBlobField : TBlobField;
begin  
  oField     := TField.Create( Self );
  oBlobField := TBlobField.Create( Self );

  if oBlobField is TField then
     ShowMessage( 'Entra en TField' );

  if oField is TBlobField then
    ShowMessage( 'No debe entrar nunca.' );

  oField.Free;
  oBlobField.Free;
end;

Pues en la unit de qrpcontrols me da el error en esta parte:

Código Delphi [-]
procedure TQRPDBImage.LoadPicture;
var
  S: String;
begin
  if (DataField<>'') and (Dataset<>NIL) then
    begin
      try
        If Not (DataSet.FindField(DataField) is TBlobField) Then // --> En esta linea me da el error
          begin
            S:=ExpandFileName(Dataset.FindField(DataField).AsString);
            If ExtractFileExt(S)='' Then S:=ChangeFileExt(S,'.BMP');
            If FileExists(S) Then Picture.LoadFromFile(S);
          end
        Else
          Picture.Assign(Dataset.FindField(DataField));
      except
      end;
    end;
end;

Os pongo la clase TQRPDBImage:

Código Delphi [-]
TQRPDBImage = class(TQRDBImage)
  private
    FFixBottomPosition       : Boolean;
    FStretchHeightWithBand   : Boolean;
  protected
    procedure Print(OfsX, OfsY : integer); override;
  public
    procedure LoadPicture;
  published
    property FixBottomPosition: Boolean Read FFixBottomPosition
                                        Write FFixBottomPosition;
    property StretchHeightWithBand: Boolean Read FStretchHeightWithBand
                                            write FStretchHeightWithBand;
  end;

Hereda de esta que está en la unit QRCtrls:

Código Delphi [-]
  TQRDBImage = class(TQRPrintable)
  private
    FField : TField;
    FDataSet : TDataSet;
    FDataField : string;
    FPicture: TPicture;
    FStretch: boolean;
    FCenter: boolean;
    FPictureLoaded: boolean;
    procedure PictureChanged(Sender: TObject);
    procedure SetCenter(Value: Boolean);
    procedure SetDataField(const Value: string);
    procedure SetDataSet(Value: TDataSet);
    procedure SetPicture(Value: TPicture);
    procedure SetStretch(Value: Boolean);
  protected
    function GetPalette: HPALETTE; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure Paint; override;
    procedure Prepare; override;
    procedure Print(OfsX, OfsY : integer); override;
    procedure UnPrepare; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure GetExpandedHeight(var newheight : extended ); override;
    procedure GetFieldString( var DataStr : string); override;
    procedure LoadPicture;
    property Field: TField read FField;
    property Picture: TPicture read FPicture write SetPicture;
  published
    property Center: boolean read FCenter write SetCenter default True;
    property DataField: string read FDataField write SetDataField;
    property DataSet: TDataSet read FDataSet write SetDataSet;
    property Stretch: boolean read FStretch write SetStretch default False;
    property ActiveInPreview;
  end;

Estas funciones son idénticas y no han cambiado nada en QuickReport 5.05 y en XE7 funciona.

Me estoy volviendo un poco loco :confused:

Gracias de antemano.

Casimiro Notevi 04-05-2018 10:26:22

Hola, ¿puedes copiar y pegar el mensaje del error?
¿Has mirado en la web de qreport por si tienen alguna información al respecto?
Saludos.

QuiqueSalamanca 04-05-2018 10:31:22

Buenas Casimiro,

Por supuesto!

Código:

[dcc32 Error] qrpctrls.pas(555): E2010 Incompatible types: 'TField' and 'TBlobField'
Llevo días buscando en san google y en QuickReport y no encuentro nada.

Al final desinstalaré el IDE y volveré a instalar todo como siga así jeje.

Gracias!

Casimiro Notevi 04-05-2018 11:02:20

¿Será porque no encuentra datafield?
Al ser un string, lo mismo, al cambiar la versión de delphi, deberías usar ansistring, por el tema de unicode.

QuiqueSalamanca 04-05-2018 11:10:54

Cita:

Empezado por Casimiro Notevi (Mensaje 526033)
¿Será porque no encuentra datafield?
Al ser un string, lo mismo, al cambiar la versión de delphi, deberías usar ansistring, por el tema de unicode.

Me debería dar el mismo problema en Delphi XE7 y con el QuickReport 5.05 (las funciones son idénticas) que fue donde migre la aplicación por primera vez y ahí funciona perfectamente.

Por eso decía que me está volviendo un poco loco.

Casimiro Notevi 04-05-2018 11:15:04

No recuerdo si el cambio de unicode fue en xe7, por eso lo comento.

QuiqueSalamanca 04-05-2018 11:32:29

Cita:

Empezado por Casimiro Notevi (Mensaje 526035)
No recuerdo si el cambio de unicode fue en xe7, por eso lo comento.

Vino antes sí. Menudo jaleo jeje

Casimiro Notevi 04-05-2018 12:23:22

¿Has probado a poner un cast( ... ) as blobfield, por si acaso?

QuiqueSalamanca 04-05-2018 12:38:35

Cita:

Empezado por Casimiro Notevi (Mensaje 526037)
¿Has probado a poner un cast( ... ) as blobfield, por si acaso?

No tiene mucho sentido puesto que lo que busca la sentencia es que si el campo que se le pasa y que devuelve el método "FindField" del objeto TDataset no es de tipo TBlobField, vendrá una ruta y si existe el archivo que lo cargue en el componente, sino que cargue la imagen directamente de la BB.DD.

A parte de que, supongo, debería dar algún error en ejecución.

Código Delphi [-]
 If Not (DataSet.FindField(DataField) is TBlobField) Then ...

Eso me funciona en código aparte en una unit de prueba mía.

Casimiro Notevi 04-05-2018 13:09:55

Por probar, inserta tu código de ejemplo dentro de esa parte de TQRPDBImage.LoadPicture, a ver si se "lo traga", o da el mismo error.

QuiqueSalamanca 08-05-2018 13:12:21

Cita:

Empezado por Casimiro Notevi (Mensaje 526040)
Por probar, inserta tu código de ejemplo dentro de esa parte de TQRPDBImage.LoadPicture, a ver si se "lo traga", o da el mismo error.

Siento la tardanza.

He probado lo que me has dicho, y sí me lo traga. Ahora ya si que me vuelvo más loco :eek: !!

También he probado a desinstalar todo el IDE y los componentes y reinstalarlos de cero, pero nada...

Casimiro Notevi 08-05-2018 14:09:01

Cita:

Empezado por QuiqueSalamanca (Mensaje 526093)
He probado lo que me has dicho, y sí me lo traga. Ahora ya si que me vuelvo más loco :eek: !!

Exactamente, ¿qué codigo has usado?

Cita:

Empezado por QuiqueSalamanca (Mensaje 526093)
También he probado a desinstalar todo el IDE y los componentes y reinstalarlos de cero, pero nada...

Te lo podías haber ahorrado :p

QuiqueSalamanca 08-05-2018 16:12:25

Cita:

Empezado por Casimiro Notevi (Mensaje 526095)
Exactamente, ¿qué codigo has usado?


Te lo podías haber ahorrado :p


¡Y tanto que me lo podía haber ahorrado!

Este es el código sin modificar:
Código Delphi [-]
procedure TQRPDBImage.LoadPicture;
var
  S: String;
begin
  if (DataField<>'') and (Dataset<>NIL) then
    begin
      try
        If Not (DataSet.FindField(DataField) is TBlobField) Then // --> En esta linea me da el error
          begin
            S:=ExpandFileName(Dataset.FindField(DataField).AsString);
            If ExtractFileExt(S)='' Then S:=ChangeFileExt(S,'.BMP');
            If FileExists(S) Then Picture.LoadFromFile(S);
          end
        Else
          Picture.Assign(Dataset.FindField(DataField));
      except
      end;
    end;
end;
Y este es el código modificado:
Código Delphi [-]
procedure TQRPDBImage.LoadPicture;
var
  S: String;
  oDS : TDataSet;
begin
  if (DataField<>'') and (Dataset<>NIL) then
    begin
      try
        oDS := TDataSet.Create( nil );
        if not ( oDS.FindField( 'Prueba' ) is TBlobField ) then
          oDS := nil;

        If Not (DataSet.FindField(DataField) is TBlobField) Then
          begin
            S:=ExpandFileName(Dataset.FindField(DataField).AsString);
            If ExtractFileExt(S)='' Then S:=ChangeFileExt(S,'.BMP');
            If FileExists(S) Then Picture.LoadFromFile(S);
          end
        Else
          Picture.Assign(Dataset.FindField(DataField));
      except
      end;
    end;
end;

Solo me da error en el segundo IF NOT, vamos donde me daba antes siendo la condición idéntica.

Lo único que se me ocurre es que DataSet es una propiedad del objeto TQRPDBImage de tipo TDataSet (vamos lo mismo) y que se esté haciendo la picha un lío...

Casimiro Notevi 08-05-2018 17:12:38

Cita:

Empezado por QuiqueSalamanca (Mensaje 526102)
Lo único que se me ocurre es que DataSet es una propiedad del objeto TQRPDBImage de tipo TDataSet (vamos lo mismo) y que se esté haciendo la picha un lío...

¿No tienes acceso al fuente para ver de qué hereda ese dataset?

QuiqueSalamanca 08-05-2018 17:15:24

Cita:

Empezado por Casimiro Notevi (Mensaje 526106)
¿No tienes acceso al fuente para ver de qué hereda ese dataset?

Sí, sí, es un TDataSet de la unit DB...

Casimiro Notevi 08-05-2018 18:22:58

Bueno, ¿y el blobfield de dónde viene, lo has mirado?

QuiqueSalamanca 08-05-2018 18:23:45

Cita:

Empezado por Casimiro Notevi (Mensaje 526108)
Bueno, ¿y el blobfield de dónde viene, lo has mirado?

Exactamente igual, DB...

Casimiro Notevi 08-05-2018 18:37:29

¿Pero del mismo db y tipo?

Es que algo tiene que haber diferente, no puede ser que uno vaya bien y el otro no, así que la diferencia es del tipo que heredan.

QuiqueSalamanca 08-05-2018 18:53:43

Cita:

Empezado por Casimiro Notevi (Mensaje 526111)
¿Pero del mismo db y tipo?

Es que algo tiene que haber diferente, no puede ser que uno vaya bien y el otro no, así que la diferencia es del tipo que heredan.

Exactamente igual, más abajo sale el segundo error que es este:

Código Delphi [-]
 [dcc32 Error] qrpctrls.pas(736): E2010 Incompatible types: 'Data.DB.TDataSet' and 'Data.DB.TDataSet'

Esto es una locura, al final quitaré los más de cincuenta informes de la aplicación y los reharé más adelante, sino queda otra...

EDITO: el anterior error sobre TField y TBlobField también heredan de la misma unit. En algún lado se está quedando gilip*****

Casimiro Notevi 08-05-2018 19:22:53

Un momento, es que db no es lo mismo que data.db


La franja horaria es GMT +2. Ahora son las 12:54:58.

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