FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Ayuda con Objeto Stream de ADO (Solucionado)
Posts: 229
Joined: Sat Mar 18, 2006 03:42 PM
Re: Ayuda con Objeto Stream de ADO
Posted: Thu Jul 09, 2015 11:09 PM
Armando

Con las versiones que tu usas, si funciona. El problema es con versiones superiores por ejemplo con la que prob茅: FWH10.3 + Harbour 3.2 + BCC582 ya no me ha funcionado.

Para ver los datos puedes usar NAVICAT 8 para mysql. Al abrir la tabla puedes dar click en el bot贸n "Image" de la barra de herramientas y podr谩s ver en la parte inferior el contenido del campo BLOB

Pero si en verdad quieres el c贸digo para leer, el proceso m谩s o menos es el siguiente:
1. Se lee el contenido de la Tabla en un objeto stream
2. Con el contenido binario lo podemos pasar a una variable o un objeto TIMAGE
3. Yo lo que hago es lo contrario a la subida. Con el contenido ya puesto en el objeto Stream lo guardo en el disco y luego lo leo para colocarlo en un control IMAGE.

Te adjunto el c贸digo que lee la imagen, no he borrado nada. Hay c贸digo que ya ni me acuerdo para qu茅 sirve. As铆 que si lo puedes minimizar que mejor.

La idea con este c贸digo es que cada imagen que se recupera de la base de datos lo guardo en una carpeta temporal en disco, son fotos de un veh铆culo. Por cada veh铆culo se crea una carpeta en funci贸n de su id y se graban las fotos all铆, luego estas fotos de disco son mostradas en un objeto IMAGE.
Code (fw): Select all Collapse
//--------------------------------------------------------------
//cnombre : Nombre de la foto
METHOD LeerFoto(cnombre,oImg) CLASS TVehic
local nBookMark:=0
local sumatot:=0,cnom,ncod:="0"
local oRsFoto,Stream , ofoto,cFold,cfoto

//oRsV es el recordset que ya esta abierto y guarda toda la tabla
if !::oRsV:EOF .and. !::oRsV:BOF
聽 聽 cFold:="V"+alltrim(str(::oRsV:Fields('cod_veh'):Value)) 
else
聽 聽 return nil
endif

//Recuperamos del nombre pasado el codigo de la foto
cnom:=cfileNoExt(cnombre)
ncod:=substr(cnom,at("f",cnom)+1)

//Recordset para la foto grande
TRY
聽 聽 oRsFoto := TOleAuto():New("adodb.recordset") 
CATCH oError
聽 聽 MsgStop( "No se pudo crear el recordset para la Foto !", CAR_VERSION)
聽 聽 RETURN .f.
END

//Configuramos el recordset que me dovolvera una foto
oRsFoto:CursorLocation := adUseClient
oRsFoto:LockType := adLockOptimistic
oRsFoto:CursorType := adOpenKeyset//adOpenDynamic
oRsFoto:Source := "SELECT cod,foto,tipo FROM fotos_veh where cod ="+ nCod 
****oRsFoto:ActiveConnection(oCon)

TRY
聽 聽 oRsFoto:Open(oRsFoto:Source,oCon)
CATCH oError
聽 聽 MsgStop( "No se pudo abrir la Tabla de la Foto!", car_version)
聽 聽 ShowError(oError,oCon)
聽 聽 RETURN .f.
END

TRY
聽 聽 ::oStream := TOleAuto():New("adodb.Stream") 
CATCH oError
聽 聽 MsgStop( "No se pudo crear el Stream para leer la Foto !", CAR_VERSION)
END

// Especifica el tipo de datos ( binario ) 聽 
::oStream:Type := adTypeBinary 

TRY
聽 聽 ::oStream:Open()
CATCH oError
聽 聽 MsgStop( "No se pudo establecer la conexion stream!", car_version)
聽 聽 ShowError(oError,oCon)
聽 聽 return .f.
END

if !lisDir("imgtmp")
聽 聽 lMkDir("imgtmp")
endif
if !lisDir("imgtmp\" + cFold )
聽 聽 聽lMkDir("imgtmp\" + cFold )
endif

if !oRsFoto:EOF .and. !oRsFoto:BOF
聽 聽 //Graba los datos en el objeto stream 聽 
聽 聽 IF oRsFoto:Fields('foto'):Value !=nil
聽 聽 聽 聽 ::Write(oRsFoto:Fields('foto'):Value) 
聽 聽 聽 聽 cfoto:="imgtmp\" + cFold+"fg"+alltrim(str(oRsFoto:Fields('cod'):Value)) + "." + alltrim(oRsFoto:Fields('tipo'):Value)
聽 聽 聽 聽 if file(cfoto)
聽 聽 聽 聽 聽 聽 ferase(cfoto)
聽 聽 聽 聽 endif
聽 聽 聽 聽 //Se graba un 聽archivo temporal 聽en disco
聽 聽 聽 聽 ::SaveToFile(cfoto, adSaveCreateOverWrite) 聽 
聽 聽 聽 聽 if fsize(cfoto)>0 聽//aqui se debe cargar una imagen si no hay la precisa
聽 聽 聽 聽 聽 聽 oImg:LoadBmp(cfoto)
聽 聽 聽 聽 else
聽 聽 聽 聽 聽 聽 oImg:LoadImage( "shade" )
聽 聽 聽 聽 endif
聽 聽 聽 聽 oimg:Refresh()
聽 聽 endif
endif

::Close()
oRsfoto:Close()

return .t.


Saludos
Marcelo Jingo
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Ayuda con Objeto Stream de ADO
Posted: Fri Jul 10, 2015 11:18 AM

Marcelo,

Ya te he enviado el EXE construido a tu email

aguardo tus noticias

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 229
Joined: Sat Mar 18, 2006 03:42 PM
Re: Ayuda con Objeto Stream de ADO
Posted: Fri Jul 10, 2015 02:01 PM

Antonio

Lamentablemente, sigue igual, se obtiene el mismo error : "La operaci贸n en varios pasos gener贸 errores. Compruebe los valores de estado (0x80040E21)".
Por si sirve de algo la versi贸n de ado obtenido en oCon:Version es 6.3.

Decid铆 regresar a la versi贸n anterior, y ya ver茅 como arregl谩rmelas con actualizaciones que hab铆a con la versi贸n mas nueva que ten铆a.

Antonio gracias por tu tiempo. Cuando tenga m谩s tiempo seguir茅 investigando este tema, ojal谩 alguien encuentre la soluci贸n y de seguro es una tonter铆a.

Saludos

Marcelo Jingo
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Ayuda con Objeto Stream de ADO
Posted: Fri Jul 10, 2015 02:21 PM

Marcelo,

Yo creo que el problema viene de cambios realizados en Harbour, porque ahi no hay c贸digo de FWH
salvo que me equivoque.

Algo se ha modificado en el soporte de OLE que ha afectado a tu c贸digo.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 229
Joined: Sat Mar 18, 2006 03:42 PM
Re: Ayuda con Objeto Stream de ADO(Solucionado)
Posted: Sun Jul 12, 2015 12:09 AM
...UF!!!

Despu茅s de buscar y buscar en internet, donde se comenta mucho sobre el mensaje "La operaci贸n en varios pasos gener贸 errores. Compruebe los valores de estado (0x80040E21"), que en resumen se trata de un error que ocurre cuando se intenta asignar datos de tipos diferentes o cuando la longitud del campo de la tabla es m谩s peque帽o que lo que se quiere asignar, entre otros. Por lo tanto comenc茅 a indagar por 茅l lado de tipos de datos; y las respuestas las obtuve en este mismo foro, encontr茅 este post que me ayudo mucho viewtopic.php?f=6&t=30559&hilit=base64 donde Carlos Vargas da una opci贸n. No me funcion贸 de la forma exacta c贸mo all铆 se explica pero fue el camino a la soluci贸n.

Para subir las im谩genes a mi tabla Mysql en un campo MEDIUMBLOB bast贸 con cambiar

Code (fw): Select all Collapse
oRsfoto:fields('foto'):Value := oStream:Read()

Por
Code (fw): Select all Collapse
oRsfoto:fields('foto'):Value := HB_STRTOHEX(oStream:Read())


Con esto se grab贸 correctamente en la Tabla MySQL. Ahora para leer la imagen cre铆 que funcionar铆a igual haciendo lo opuesto con HB_HEXTOSTR(), por nop. Creo que son cosas de ADO, o de ODBC, o de Mysql ... no s茅. Pero mirando en el visor en hexadecimal para campos blob que tiene NAVICAT, pude darme cuenta que los datos grabados estaban en el mismo formato de imagen y se lo pod铆a visualizar en el visor de imagen de NAVICAT. Con esto pienso que Mysql antes de grabar transforma los datos que yo le envio con strtohex() a su forma original que es binario.

Para la lectura fue otro largo trajinar, porque no funcion贸 ni hb_strtohex(), ni hb_hextostr(), por lo que tuve que improvisar y se modific贸 la forma c贸mo lo hac铆a antes. Ahora ya no uso ADO Stream para grabar las fotos peque帽as a disco ni para ver la foto grande, s贸lo lo hago utilizando los datos del recordset directamente (Hoy me pregunto...por qu茅 no lo hice as铆 antes???).

Antes hac铆a esto:
Code (fw): Select all Collapse
聽 聽 聽 聽 聽 聽 聽 聽 //Se carga en el objeto stream el valor del campo blob
聽 聽 聽 聽 oStrp:Write(::oRsFoto:Fields('foto_p'):Value)
聽 聽 聽 聽 //Se graba en un archivo temporal a disco mediante el m茅todo del objeto stream
聽 聽 聽 聽 ::oStream:SaveToFile(cfile, adSaveCreateOverWrite)

Pero ahora al hacer oStrp:Write se obtiene el mensaje: "argumentos incorrectos, fuera del intervalo permitido o en conflicto con otros "

Po lo que ya no busqu茅 m谩s y opt茅 por no usar el objeto stream, la soluci贸n fue:
Code (fw): Select all Collapse
聽 聽 聽 聽 聽 聽 聽 聽 //Con esto grabo el contenido del campo blob a un archivo en disco
聽 聽 聽 聽 聽 聽 聽 聽 //cfile es el nombre de un archivo
聽 聽 聽 聽 聽 聽 fichero:= fCreate( cfile )
聽 聽 聽 聽 fWrite( fichero, ::oRsFoto:Fields('foto_p'):Value) 
聽 聽 聽 聽 fClose( fichero )


Por otro lado para mostrar la imagen, hacemos la consulta SQL para obtener un recordset y luego con la clase TIMAGE podemos visualizarla as铆:
Code (fw): Select all Collapse
oImg:LoadFromMemory(oRsFoto:Fields('foto'):Value)
oImg:Refresh()


Me dir谩n..."s贸lo para esto te demoraste tanto??", pues as铆 pasa cuando sucede. Uno nunca sabe lo que nos depara las actualizaciones, y no s茅 si es cosa de FWH, de Harbour, de BCC582, de ADO, de MySQL o m铆a. Como decimos por aqu铆: "Dios averig眉e y perdone" , je je je.

Gracias Antonio, Gracias Foro por contribuir a esta soluci贸n.
Marcelo Jingo
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: Ayuda con Objeto Stream de ADO (Solucionado)
Posted: Sun Jul 12, 2015 02:12 AM

Marcelo:

Excelente que hayas solucionado el problema, como decimos en algunas partes
de mi pa铆s "El que porfia mata venado, aunque a veces lo matan por porfiado" :D

Por cierto, parece que la clase TImage no funciona con im谩genes PDF, conoces
alguna otra clase que me permita mostrar im谩genes PDF?

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 229
Joined: Sat Mar 18, 2006 03:42 PM
Re: Ayuda con Objeto Stream de ADO (Solucionado)
Posted: Sun Jul 12, 2015 04:49 PM

Armando

Lamentablemente no tengo experiencia con Visores PDF, para generar un documento PDF lo que hago simplemente es usar cualquier driver estilo impresora como CUTEPDF, y enviar la impresi贸n.

Saludos

Marcelo Jingo
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: Ayuda con Objeto Stream de ADO (Solucionado)
Posted: Sun Jul 12, 2015 06:01 PM

Marcelo:

Gracias por la respuesta, para crear el PDF no tengo problema, mi problema es
mostrarlo en un dialogo o window, tal vez alguien m谩s en el foro nos pueda apoyar

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 229
Joined: Sat Mar 18, 2006 03:42 PM
Re: Ayuda con Objeto Stream de ADO (Solucionado)
Posted: Sun Jul 12, 2015 10:58 PM
Armando

Si lo que quieres es s贸lo visualizar y nada m谩s, podemos hacer uso de los recursos que casi todos los pcs tienen ya instalado: Explorer y Acrobat Reader, para ello podemos aprovechar ActiveX.

Aqu铆 un ejemplo que lo arm茅 al vuelo:
Code (fw): Select all Collapse
function VerPDF(cfile) 聽
聽 聽 local ownd, oactivex,oFold
聽 聽 default cfile:="C:\camisetas\SOFTWARE.pdf"
聽 聽 
聽 聽DEFINE WINDOW oWnd TITLE "Archivo: "+alltrim(cfile)
聽 聽 @5,25 FOLDER oFold size 100,500;
聽 聽 PROMPT "Folder" ;
聽 聽 PIXEL of oWnd
聽 聽 
聽 聽 oActiveX = TActiveX():New( oWnd, "Shell.Explorer.2" )
聽 聽//oWnd:oClient = oActiveX //ocupa toda la ventana
聽 聽oActiveX : Do("Navigate2",cfile)
聽 聽ACTIVATE WINDOW oWnd 聽maximized on init (oWnd:acontrols[2]:nHeight:=500,oWnd:acontrols[2]:nWidth:=600,oWnd:acontrols[2]:nTop:=25,oWnd:acontrols[2]:nLeft:=150) 

RETUR NIL

Es s贸lo una idea inicial.

Saludos
Marcelo Jingo
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: Ayuda con Objeto Stream de ADO (Solucionado)
Posted: Mon Jul 13, 2015 03:27 PM

Marcelo:

Muchas gracias por el c贸digo, voy a tirar por ah铆.

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero

Continue the discussion