Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

problemas con TBlobField

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: problemas con TBlobField Responder citando

Hola

presento la situación: Utilizo Firebird 2.01, con dbx en Builder 6. Tengo dos tablas con una relación maestro-detalle.

El siguiente código está dentro de un TDataModule. Se utiliza para recuperar los datos del maestro (que no lo muestro) y el detalle _dDetAP. Este _DetAP luego lo tomo desde el form y lo muestro en una grilla (TStringGrid)

Código:

Cargar(..., stcArchivos *&_dDetAP, int &_regAP)
...
   qryBuscar->SQL->Clear();
   qryBuscar->SQL->Add("select * from Archivos");
   qryBuscar->SQL->Add("where IdProyecto = " + AnsiString(_Id) + ";");

   try{
      qryBuscar->Close();
      qryBuscar->Open();
      cdsBuscar->Close();
      cdsBuscar->Open();
      if(!cdsBuscar->Eof){
         cdsBuscar->Last();
         cdsBuscar->First();
         _regAP = cdsBuscar->RecordCount;
         _dDetAP = new stcArchivos[_regAP];
         contador = 0;
         while(!cdsBuscar->Eof){
            _dDetAP[contador].Id = cdsBuscar->FieldByName("Id")->AsInteger;
            _dDetAP[contador].IdProyecto = cdsBuscar->FieldByName("IdProyecto")->AsInteger;
            _dDetAP[contador].Nombre = cdsBuscar->FieldByName("Nombre")->AsString;
            _dDetAP[contador].Descripcion = cdsBuscar->FieldByName("Descripcion")->AsString;
            //_dDetAP[contador].Ruta = cdsBuscar->FieldByName("Ruta")->AsString;
            _dDetAP[contador].Archivo = (TBlobField *)cdsBuscar->FieldByName("Archivo");
            contador += 1;
            cdsBuscar->Next();
         }
      }
      else{
         _regAP = 0;
         _dDetAP = NULL;
      }
   }
   catch(...){
      throw;
   }


Este código pasa el puntero a la grilla:

Código:

   ...
   /*Detalle_AP*/
   stgArchivos->RowCount = 2;
   for(int i = 0; i <stgArchivos>ColCount; i++){
      stgArchivos->Cells[i][1] = "";
   }
   for(int i = 0; i <regDetalleAP>Cells[0][i+1] = AnsiString(fcDetAP[i].Id);
      stgArchivos->Cells[1][i+1] = fcDetAP[i].Descripcion;
      stgArchivos->Cells[4][i+1] = fcDetAP[i].Nombre;
      stgArchivos->Cells[5][i+1] = fcDetAP[i].Ruta;
      stgArchivos->Cells[6][i+1] = "0";
      stgArchivos->RowCount += 1;
   }
   if(stgArchivos->RowCount > 2){
      stgArchivos->RowCount -= 1;
   }
   ...



En la grilla se muestran correctamente los valores correspondientes a Nombre y Descripcion para cada registro, pero en todos los casos cuando quiero recuperar el archivo almacenado en el BLOB (valor de Archivo), obtengo el correspondiente al último registro del detalle.

el codigo es éste:

Código:

...
Archivo = dlgGuardar->FileName;
fcDetAP[stgArchivos->Row-1].Archivo->SaveToFile(Archivo);
...


fcDetAP es el puntero a la estructura, corresponde a _dDetAP
stgArchivos es la grilla TStringGrid

No se si se entendió

Saludos
TJose
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Controlando un poco veo que el error (que no sé cual es) está del lado del TDataModule.
Si pongo la siguiente línea:

_dDetAP[contador].Archivo->SaveToFile("E:\\arch\\" + _dDetAP[contador].Nombre);
en el while

Código:

 while(!cdsBuscar->Eof){
            _dDetAP[contador].Id = cdsBuscar->FieldByName("Id")->AsInteger;
            _dDetAP[contador].IdProyecto = cdsBuscar->FieldByName("IdProyecto")->AsInteger;
            _dDetAP[contador].Nombre = cdsBuscar->FieldByName("Nombre")->AsString;
            _dDetAP[contador].Descripcion = cdsBuscar->FieldByName("Descripcion")->AsString;
            //_dDetAP[contador].Ruta = cdsBuscar->FieldByName("Ruta")->AsString;
            _dDetAP[contador].Archivo = (TBlobField *)cdsBuscar->FieldByName("Archivo");
            _dDetAP[contador].Archivo->SaveToFile("E:\\arch\\" + _dDetAP[contador].Nombre);
            contador += 1;
            cdsBuscar->Next();
         }


los archivos son recuperados correctamente, ahora si la pongo fuera de while de esta forma

Código:

while(!cdsBuscar->Eof){
            _dDetAP[contador].Id = cdsBuscar->FieldByName("Id")->AsInteger;
            _dDetAP[contador].IdProyecto = cdsBuscar->FieldByName("IdProyecto")->AsInteger;
            _dDetAP[contador].Nombre = cdsBuscar->FieldByName("Nombre")->AsString;
            _dDetAP[contador].Descripcion = cdsBuscar->FieldByName("Descripcion")->AsString;
            //_dDetAP[contador].Ruta = cdsBuscar->FieldByName("Ruta")->AsString;
            _dDetAP[contador].Archivo = (TBlobField *)cdsBuscar->FieldByName("Archivo");
            contador += 1;
            cdsBuscar->Next();
         }
         for(int i = 0; i <contador>SaveToFile("E:\\arch\\" + _dDetAP[i].Nombre);
         }


siempre guarda el mismo archivo.

la estructura que utilizo es esta:

Código:

struct stcArchivos{
   int Id;
   int IdProyecto;
   AnsiString Nombre;
   AnsiString Descripcion;
   TBlobField *Archivo;
   AnsiString Ruta;
   bool Modificado;
   AnsiString Accion;
};
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Si tengo la siguiente estructura, análoga a la del caso real:

Código:

struct stcPrueba{
   int Id;
   TEdit *edt;
   AnsiString Texto;
};


y en un form pongo dos TEdit y un TButton y hago en el onClick del TButton:

Código:

   stcPrueba *pp = new stcPrueba[2];

   pp[0].Id = 1;
   pp[0].edt = (TEdit *)Edit1;
   pp[0].Texto = "Primer texto";

   pp[1].Id = 2;
   pp[1].edt = (TEdit *)Edit2;
   pp[1].Texto = "Segundo texto";

   for(int i = 0; i <2>Text);
   }
   pp[0].edt->Color = clGreen;
   pp[1].edt->Color = clRed;


   delete[] pp;


funciona bien.

Ahora bien, en el programa de la situación planteada, que es, conceptualmente igual, mantiene el valor del ultimo blob cargado, en este caso sería como si ambos TEdit (Edit1 y Edit2) se pusieran color rojo, pero repito con este código hace lo que se espera deba hacer.

Saludos
TJose
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola

He cambiado alguna cosa para probar, pero sigue sin funcionar:

agregué esta línea antes de while

Código:
TBlobField *pp[3];

(lo pruebo con una opción conocida que tiene tres registros el detalle)

Código:

while(!cdsBuscar->Eof){
            ...
            pp[contador] = (TBlobField *)cdsBuscar->FieldByName("Archivo");
            pp[contador]->SaveToFile("E:\\arch\\x_" + _dDetAP[contador].Nombre); //Aqui se recuperan correctamente los archivos
            contador += 1;
            cdsBuscar->Next();
         }
         for(int i = 0; i <contador>SaveToFile("E:\\arch\\" + _dDetAP[i].Nombre); //Aquí se recupera siempre el archivo correspondiente al último regisro
         }


Ya no sé que hacer; o me estoy perdiendo de algo, conceptualmente hablando, o hay algo muy simple que no lo estoy viendo.

Saludos
TJose
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.