/* * Proyecto: MySQLDATASET * Fichero: TMySQLquery.prg * Descripción: * Autor: * Fecha: 10/09/2006 */ #include "Xailer.ch" *#include "cmbtl6.ch" CLASS TMySQLquery PUBLIC: DATA xEtiquetasImprimir //AS NUMERIC INIT {|oMem,aDef| 1 } // Un Número, Carácter, Codebloc con oMem DATA aDef AS ARRAY INIT {} // Objeto, métodos y parámetros para ejecutar cada vez que cambia la clave DATA objExterno, cMetodo, aParametros DATA cClaveRuptura AS CHARACTER INIT "" // Clave ruptura serparadas por + DATA nSeg DATA oMySQLdatasource DATA cSelect AS CHARACTER INIT "" DATA oQuery DATA oMem DATA lDatos AS LOGICAL INIT .F. DATA aFields DATA oBrw DATA aTablesView // Array de Tablas a aplicar las vistas actuales, antes del query() DATA oMemPublics, oMemPublics2, oMemPublics3,oMemPublics4, oMemPublics5, bPreImprimir DATA oRS, lRS METHOD New( oConnect ) CONSTRUCTOR METHOD RunQuery() METHOD RunQueryInc(oBrowse) METHOD RunQueryRS() METHOD SetBrowse(oBrowse) METHOD SetBrowseAll(oBrowse) // 1=Design, 2=Preview, 3=Print METHOD Imprimir( cLst, cTitle , ntipoImp , lEtiqueta) METHOD AddFieldToMem( oMem, cNameNewFieldMem, cNameFieldMemToRelation,; oDataSet, cNameFieldDataRelation , cFieldValorToAdd , bAction ) ENDCLASS METHOD New( oConnect ) CLASS TMySQLquery ::oMySQLdatasource := oConnect if oConnect<>NIL ::oQuery := TQuery():New(::oMySQLdatasource) endif ::aFields := {} ::aTablesView := {} if oConnect<>NIL ::oRs := TResultset():new(::oMySQLdatasource) endif ::lRS := .F. Return Self METHOD RunQueryRS() CLASS TMySQLquery ::lRS := .T. ::oRs:Query( ::cSelect ) *msginfo( len(::oRS:aRes) ) *msginfo(::cselect) if !::oRS:lError .and. ::oRS:next() ::oMem := ::oRs:registro() endif return nil METHOD RunQuery(oBrowse,oLabelResultado,lCargo,lTitulosField) CLASS TMySQLquery Local x DEFAULT lCargo TO .F. DEFAULT lTitulosField TO .F. //::cSelect := upper(::cSelect) *::cSelect := lower(::cSelect) // Existen vistas definidas if !empty(::oMySQLdatasource:cFilterAllQuerys) FOR EACH x IN ::aTablesView // Sustituir nombre de las vistas en la consulta ::cSelect := StrTran( ::cSelect, lower(x) , ::oMySQLdatasource:AddView(x) ) ::cSelect := StrTran( ::cSelect, upper(x) , ::oMySQLdatasource:AddView(x) ) NEXT endif ::nSeg := Seconds() ::oQuery:Query( ::cSelect ) if ::oQuery:lError // Informe al programador error en la consulta msginfo( ::oQuery:cError ) msginfo( ::cSelect ) endif ::nSeg := Seconds() - ::nSeg if oLabelResultado<>Nil oLabelResultado:cText := "Tiempo: "+alltrim(str(::nSeg))+"seg. Registros: "+alltrim(str(::oQuery:nRows)) endif if( ::lDatos := len(::oQuery:aRes)>0) if len(::aFields)=0 FOR EACH x IN ::oQuery:aStruct aadd( ::aFields, x[1] ) NEXT endif ::oMem := oMemArraycreate( "oMemQuery", ::oQuery:aRes , ::aFields, .F. ) /* WITH OBJECT ::oMem := TMemDataSet():Create() :cName := "oMemQuery" :Open( ::oQuery:aRes , ::aFields ) END */ else * msginfo("No existen datos en la consulta","¡Atención!") endif if oBrowse<>Nil .and. ::lDatos if lCargo oBrowse:SetArray( fDatas( oBrowse, ::oMem ) , HeadersBrw(oBrowse) ) else if lTitulosField oBrowse:reset() oBrowse:SetArray( ::oMem:aData, ::aFields , .T. ) oBrowse:lAutoOrder := .T. else ::SetBrowse(oBrowse) endif endif else if !::lDatos .and. oBrowse<>Nil oBrowse:Zap() endif endif /* if oBrowse<>Nil .and. ::lDatos if lTitulosField oBrowse:reset() oBrowse:SetArray( ::oMem:aData, ::aFields , .T. ) oBrowse:lAutoOrder := .T. else ::SetBrowse(oBrowse) endif else if !::lDatos .and. oBrowse<>Nil oBrowse:Zap() endif endif */ Return Self METHOD RunQueryInc(oBrowse,oLabelResultado,lCargo,lTitulosField) CLASS TMySQLquery Local x DEFAULT lCargo TO .F. DEFAULT lTitulosField TO .F. *::cSelect := lower(::cSelect) // Existen vistas definidas if !empty(::oMySQLdatasource:cFilterAllQuerys) FOR EACH x IN ::aTablesView // Sustituir nombre de las vistas en la consulta ::cSelect := StrTran( ::cSelect, lower(x) , ::oMySQLdatasource:AddView(x) ) NEXT endif ::nSeg := Seconds() * ::oQuery:Query( ::cSelect , oBrowse , oLabelResultado ) /* Incremental sería aRes := {} WITH OBJECT ::oRS := TResultset():new(::oMySQLdatasource) :query(::cSelect) Do While :next() aadd( aRes, :aRes ) Enddo :close() END if oBrowse<>Nil .and. len(aRes)>0 WITH OBJECT ::oMem := TMemDataSet():Create() :cName := "oMemQuery" :Open( aRes , :aFields ) END if lCargo oBrowse:SetArray( fDatas( oBrowse, ::oMem ) , HeadersBrw(oBrowse) ) else if lTitulosField oBrowse:reset() oBrowse:SetArray( ::oMem:aData, ::oRS:aFields , .T. ) oBrowse:lAutoOrder := .T. else ::SetBrowse(oBrowse) endif endif else if !::lDatos .and. oBrowse<>Nil oBrowse:Zap() endif endif */ ::oQuery:Query( ::cSelect , , oLabelResultado ) if ::oQuery:lError msginfo( ::oQuery:cError ) endif ::nSeg := Seconds() - ::nSeg if oLabelResultado<>Nil oLabelResultado:cText := "Tiempo: "+alltrim(str(::nSeg))+"seg. Registros: "+alltrim(str(::oQuery:nRows)) endif if( ::lDatos := len(::oQuery:aRes)>0) if len(::aFields)=0 FOR EACH x IN ::oQuery:aStruct aadd( ::aFields, x[1] ) NEXT endif // TRY //// MsgInfo(Len(::oQuery:aRes)) //// MsgInfo(Len(::oQuery:aRes[1])) // MsgInfo("Serie:"+CRLF+::oQuery:aRes[1][7]) // MsgInfo("Len: "+Str(Len(::oQuery:aRes[1][7]))) // CATCH // // END ::oMem := oMemArraycreate( "oMemQuery", ::oQuery:aRes , ::aFields, .F. ) // WITH OBJECT ::oMem := TMemDataSet():Create() // // :cName := "oMemQuery" // :Open( ::oQuery:aRes , ::aFields ) // END else * msginfo("No existen datos en la consulta","¡Atención!") endif if oBrowse<>Nil .and. ::lDatos if lCargo oBrowse:SetArray( fDatas( oBrowse, ::oMem ) , HeadersBrw(oBrowse) ) else if lTitulosField oBrowse:reset() oBrowse:SetArray( ::oMem:aData, ::aFields , .T. ) oBrowse:lAutoOrder := .T. else ::SetBrowse(oBrowse) endif endif else if !::lDatos .and. oBrowse<>Nil oBrowse:Zap() endif endif /* if oBrowse<>Nil .and. ::lDatos if lTitulosField oBrowse:reset() oBrowse:SetArray( fDatas( oBrowse, ::oMem ) , ::oMem:aFields , .T. ) oBrowse:lAutoOrder := .T. else ::SetBrowse(oBrowse) endif else if !::lDatos .and. oBrowse<>Nil oBrowse:Zap() endif endif */ Return Self METHOD SetBrowse(oBrowse) CLASS TMySQLquery Local aHeader:={}, x if oBrowse<>Nil ::oBrw := oBrowse if ::lDatos //::oBrw:reset() ::oBrw:SetArray( ::oMem:aData, , .T.) ::oBrw:lAutoOrder := .T. /* FOR EACH x IN ::oBrw:oHeader:aItems aadd( aHeader, x:cText ) NEXT ::oBrw:SetArray( ::oMem:aData, aHeader , .T.) ::oBrw:lAutoOrder := .T. */ endif endif Return Nil METHOD SetBrowseAll(oBrowse,aFields) CLASS TMySQLquery if oBrowse<>Nil ::oBrw := oBrowse if ::lDatos ::oBrw:SetArray( ::oMem:aData , aFields, .T.) endif endif Return Nil // 1=Design, 2=Preview, 3=Print METHOD Imprimir( cLst, cTitle , ntipoImp , lEtiqueta , oForm,; lExport, cPathPictureFile, cNamePictureFile, cTypePictureExport ) CLASS TMySQLquery Local oLL, oRuptura Local nResult := 0 Local lEndRS := .f. Local nEtiquetas, xx, oMemEtiquetaInicial DEFAULT cLst TO ".\informe.lst" DEFAULT lEtiqueta TO .F. DEFAULT cTitle TO "Sin Título" DEFAULT oForm TO application:oMainform DEFAULT lExport TO .f. if ::xEtiquetasImprimir==NIL ::xEtiquetasImprimir := {|oMem,aDef| 1 } endif if ::oMem=nil msginfo("No hay datos para imprimir") return -99 // Salir cancelando, no se ha imprimido //return nResult endif *bNetiquetas := {|oMem| 4 } WITH OBJECT oLL := TLL():New() *msginfo( seconds()-nseg ) * logdebug( seconds()-nseg ) :SetTypeList( !lEtiqueta ) // Tipo Listado (Con líneas) //:NewJob(oForm:handle) // Si queremos pegarlo a un form :NewJob() //-------- Prueba a exportar BMP ------- if !(cTypePictureExport==NIL) lExport := .f. :oExport:exportON() :oExport:filePath := cPathPictureFile :oExport:filename := cNamePictureFile :oExport:setTypePicture( cTypePictureExport ) :oExport:pictureResolution := "96" //Para impresora son 300 ppp :oExport:pictureBitsPerPixel := "24" //"24" //"4" //"24" //"1" // 1:Monochrome 4:16 colors 8:256 colors 24:24bit True Color // 32:32bit True Color Default: 8 :oExport:exportSilenciosoON() endif //-------------------------------------- *logdebug( "NewJob "+str(seconds()-nseg) ) :InitOptionDef() :NoSeparaFooter() :lPreview := (ntipoImp==2) :cNameInforme := cLst //".\InffichaCli.lst" :cTitle := cTitle //"Informe Ficha del Cliente" :create() // Nuevo para rapidéz :lAskIniEti := .T. // .F. Si No queremos pregunte etiqueta inicial mientras depuramos // Envía 1º registro de todos if ::bPreImprimir<>Nil eval( ::bPreImprimir , oLL ) endif if ::oMemPublics<>Nil ::oMemPublics:Gotop() :SendRegistro( ::oMemPublics ) endif if ::oMemPublics2<>Nil ::oMemPublics2:Gotop() :SendRegistro( ::oMemPublics2 ) endif if ::oMemPublics3<>Nil ::oMemPublics3:Gotop() :SendRegistro( ::oMemPublics3 ) endif if ::oMemPublics4<>Nil ::oMemPublics4:Gotop() :SendRegistro( ::oMemPublics4 ) endif if ::oMemPublics5<>Nil ::oMemPublics5:Gotop() :SendRegistro( ::oMemPublics5 ) endif *logdebug( "Después mem "+str(seconds()-nseg) ) ::oMem:Gotop() :SendRegistro( ::oMem ) if lEtiqueta *LogDebug( ::xEtiquetasImprimir, ValType(::xEtiquetasImprimir) ) Do case case valtype(::xEtiquetasImprimir)=="N" ::xEtiquetasImprimir := &("{|oMem,aDef|"+alltrim(str(::xEtiquetasImprimir))+"}") case valtype(::xEtiquetasImprimir)=="C" ::xEtiquetasImprimir := &("{|oMem,aDef|"+alltrim(::xEtiquetasImprimir)+"}") Endcase *LogDebug( "Codeblock posterior:",::xEtiquetasImprimir) oMemEtiquetaInicial := ::OMem:clone() if ::lRS if ::oRS:next() ::oMem := ::oRS:registro() else lEndRS := .T. endif else ::oMem:Skip() endif :nLineasPrint := 1 endif *logdebug( "Después SendRegistro1 "+str(seconds()-nseg) ) oRuptura := TRuptura():new( Self, oLL, ::cClaveRuptura ) *logdebug( "Crea Ruptura "+str(seconds()-nseg) ) If ntipoImp==1 :Design() Else // Queremos que nos muestre el progreso y poder cancelar if :InitBoxProgress(lExport) // Antes de Empezar a Enviar Datos * logdebug( "Antes LlPrint "+str(seconds()-nseg) ) :nResultPrint := LlPrint(:hJob) *msginfo( "Resultado LlPrint(:hJob)"+ str(:nResultPrint) ) // Gestión del Número de etiquetas del primer registro //------------------------------------------------------- nEtiquetas := 1 if lEtiqueta nEtiquetas := eval( ::xEtiquetasImprimir, oMemEtiquetaInicial, ::aDef ) endif For xx=1 to nEtiquetas-1 :printRegistro( oMemEtiquetaInicial ) Next //------------------------------------------- *logdebug( "Después LlPrint "+str(seconds()-nseg) ) Do While :nResultPrint=0 .and. !::oMem:Eof() .and. !lEndRS *:SendRegistro( ::oMem ) // Gestión del Número de etiquetas //------------------------------------------- nEtiquetas := 1 if lEtiqueta nEtiquetas := eval( ::xEtiquetasImprimir, ::oMem , ::aDef) endif For xx=1 to nEtiquetas :PrintRegistro( ::oMem ) Next //------------------------------------------- *if lEtiqueta * :SendRegistro( ::oMem ) *else *:PrintRegistro( ::oMem ) *endif *sleep(400) if :lCanceled exit endif if ::lRS if ::oRS:next() ::oMem := ::oRS:registro() else lEndRS := .T. endif else ::oMem:Skip() endif oRuptura:checkRuptura() // En cada ruptura manda unos datos a la cabecera Enddo nResult := :nResultPrint *logdebug( "Antes Printend "+str(seconds()-nseg) ) :PrintEnd() // Fin Impresión (Obligatorio) *logdebug( "Después Printend "+str(seconds()-nseg) ) if nResult<>0 msgInfo( "No existen datos a Mostrar!! (Código Incidencia: "+alltrim(str(nResult))+")" ) else iif(:nLineasPrint=0,msgInfo( "No existen datos a Mostrar!!" ),NIL) endif endif Endif :EndJob() if ::lRS ::oRS:close() endif * logdebug( "Después endjob "+str(seconds()-nseg) ) END Return nResult * clicom:oMemDatareg oFotos:nombrevar clicom:Id * oFotos oFotos:numerofoto oFotos:nombreFile (Recuperar foto a disco) METHOD AddFieldToMem( oMem, cNameFieldMemToRelation,; oDataSet, cNameFieldDataRelation , cFieldValorToAdd , bAction ) Local nFieldMem,nFieldAdd,cNameBusca, cValue WITH OBJECT oMem :cargo := {} nFieldMem := :FieldPos(cNameFieldMemToRelation) nFieldAdd := oDataSet:oMemDataReg:FieldPos( cFieldValorToAdd ) :Gotop() Do While !:Eof() cNameBusca := :aFields[ nFieldMem]:Value if oDataSet:Locate( "", cNameFieldDataRelation+"='"+alltrim(ToString(cNameBusca))+"'") cValue := "C:\"+oDataSet:oMemDataReg:FieldGet( nFieldAdd ) *cValue := "C:\"+oDataSet:oMemDataReg:VarGet( nFieldAdd ) aadd( :cargo, cValue ) if bAction<>Nil eval( bAction , oDataSet ) endif else aadd( :cargo,"" ) endif :Skip() Enddo END Return Nil //------------------------------------------------------------------------------------------------- /* * Clase Rutura para enviar en la cabecera unos datos según un prg o método * --------------------------------------------------------------------------------------------------*/ CLASS TRuptura PRIVATE: DATA oLL DATA claseQuery DATA claveRuptura // Separada por símbolo + DATA aClaves DATA aValoresAnt DATA nLen DATA lActiva METHOD fillAclaves() METHOD isExistRuptura() METHOD runProceso() PUBLIC: METHOD new( pClaseQuery, poLL, cClaveRuptura ) CONSTRUCTOR METHOD checkRuptura() ENDCLASS METHOD new( pClaseQuery, poLL,cClaveRuptura ) CLASS TRuptura Local x // Para que sólo mande una por cada impresión, para Totales Pie if cClaveRuptura=="DOCUMENTO" ::runProceso() cClaveRuptura := "" endif //------------------------------------------------------------- if empty( alltrim(cClaveRuptura) ) ::lActiva := .F. else ::lActiva := .T. ::oLL := poLL ::claseQuery := pClaseQuery ::claveRuptura := cClaveRuptura ::aClaves := {} ::fillAclaves() ::aValoresAnt := {} FOR EACH x IN ::aClaves aadd( ::aValoresAnt, ::claseQuery:oMem:FieldGetByName(x) ) NEXT ::runProceso() // Ejecuta la primera vez para enviar la 1ª cabecera endif return self METHOD checkRuptura() CLASS TRuptura if ::lActiva if ::isExistRuptura() ::runProceso() endif endif return nil METHOD isExistRuptura() CLASS TRuptura Local lOk := .F., i For i=1 to ::nLen if ::aValoresAnt[i]<>::claseQuery:oMem:FieldGetByName(::aClaves[i]) lOk := .T. endif ::aValoresAnt[i] := ::claseQuery:oMem:FieldGetByName(::aClaves[i]) next return lOk METHOD runProceso() CLASS TRuptura hb_execFromArray( ::claseQuery:objExterno, ::claseQuery:cMetodo, { ::claseQuery, ::oLL } ) return nil METHOD fillAclaves() CLASS TRuptura Local nToken := 1 Local palabra Do while .t. palabra := strToken( ::claveRuptura ,nToken ,"+") palabra :=strtran(palabra,";",",") If len(alltrim(palabra))<>0 aadd(::aClaves,alltrim(palabra)) Else exit Endif nToken++ Enddo ::nLen := len(::aClaves) return nil