Set Relation

Post Reply
Ruben Fernandez
Posts: 366
Joined: Wed Aug 30, 2006 5:25 pm
Location: Uruguay

Set Relation

Post by Ruben Fernandez »

Amigos:

Tengo 4 DBFs,
DBF 1 - tiene un campo de 12 caracteres -no se repite-
que coincide con las otras 3 DBF que si tienen mas de un registro
con el mismo numero -en caracteres-.

Como las relaciono y como lanzo el reporte con Report de FWH para
que imprima todos los registros que concidan con la DBF 1.

Muchas gracias.

Saludos

Ruben Fernandez.
User avatar
Kleyber
Posts: 581
Joined: Tue Oct 11, 2005 11:28 am
Location: São Luiz, Brasil

Post by Kleyber »

Ruben,

Una idea seria que puedas crear una función y generar un dbf temporario, donde vas a poner todos los registros resultantes de tu busqueda. Así podrias solamente usar este dbf temporario en tu reporte.

Es una idea, espero te sirva.

saludos,
Kleyber Derick

FWH / xHb / xDevStudio / SQLLIB
Ruben Fernandez
Posts: 366
Joined: Wed Aug 30, 2006 5:25 pm
Location: Uruguay

Post by Ruben Fernandez »

Kleyber:

Muchas gracias por tu sugerencia.
En realidad estaba con la intecion de probar
son set relation pero no se como en realidad.

Pruebo tu consejo.

Gracias.

Saludos

Ruben Fernandez.
R.F.
Posts: 840
Joined: Thu Oct 13, 2005 7:05 pm

Post by R.F. »

Ya estamos matando pulgas a cañonazos otra vez !!!!!

Es mucho mas rapido utilizar una relacion que crear un archivo temporal.

1) Se abren primero las bases de datos hijas, la condicion es que esten indexadas sobre el campo sobre el cual se establece la relacion:

USE hija1
SET INDEX TO....
USE hija2
SET INDEX TO
USE hija3
SET INDEX TO...

2) Se abre la base de datos padre y se relaciona sobre las hijas indicando claramente el "alias" dela hija y el campo comun en la padre, en forma de bloque de codigo y como cadena de caracteres, la base de datos padre puede estar indexada sobre cualquier criterio, no necesariamente el campo que establece la relacin:

USE padre
SET INDEX TO

padre->(DBSETRELATION(hija1,{|| campo_comun},"campo_comun"))
padre->(DBSETRELATION(hija2,{|| campo_comun},"campo_comun"))
padre->(DBSETRELATION(hija3,{|| campo_comun},"campo_comun"))

DBSETRELATION (<alias de la hija>,;
<code block con el nombre campo comun PADRE>,;
<string con el campo comun en el PADRE).

3) Para usarla en un reporte, se hace referencia al ALIAS de la hija, indicando el campo de la hija que se quiere imprimir

REPORT oReport......

COLUMN DATA padre->campo....
COLUMN DATA hija1->campo
COLUMN DATA hija2->campo
COLUMN DATA hija3->campo
.......

Y listo, no es necesario crear ninguna base de datos temporal ni crear funciones yq evayan y busquen los datos.
Saludos
R.F.
User avatar
Kleyber
Posts: 581
Joined: Tue Oct 11, 2005 11:28 am
Location: São Luiz, Brasil

Post by Kleyber »

Maestro Rene,

Como dije en mi primer post, fue solo una idea y fue la que se me ocurrió de imediato. Por supuesto tu idea es mejor y mas rapida.

Saludos,
Kleyber Derick

FWH / xHb / xDevStudio / SQLLIB
Rochinha
Posts: 309
Joined: Sun Jan 08, 2006 10:09 pm
Location: Brasil - Sao Paulo
Contact:

Post by Rochinha »

Rubens

Con uso de CDX e la funcion ORDSCOPE() és mas facil:

Code: Select all

USE arquivo
INDEX ON campo TAG apelido TO indice

Code: Select all

USE contas
INDEX ON DataReceber TAG AReceber TO contas
INDEX ON DataAPagar   TAG APagar TO contas
...
M->DataInicio := date()
M->DataFinal  := date()+60
OrdSetFocus( 1 ) // Muda foco para AReceber
OrdScope( M->DataInicio, 0 ) // Marca inicio de um conjunto
OrdScope( M->DataFinal, 1 ) // Marca Final de um conjunto
browse()
Mas rapido que indices condicionales e arquivo temporales.

O use este codigo:

Code: Select all

#include "common.ch" 
#include "inkey.ch" 
#include "fivewin.ch" 

/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ 
#include "selector.ch" 

/* 
static clientes := {}, nRegiao 
function main 
   USE CLIENTES NEW 
   USE FORNEC NEW 
   @ clientes SELECT clientes->nome, clientes->endereco, clientes->bairro, clientes->estado ; 
              FROM clientes ; 
              FOR clientes->estado='SP' ; 
              TO tempo1 
              BROWSE() 
   @ clientes SELECT clientes->nome, clientes->endereco, clientes->bairro, clientes->estado ; 
              FROM clientes ; 
              FOR clientes->estado='CE' ; 
              TO tempo2 
              BROWSE() 
   @ clientes SELECT clientes->regiao ; 
              FROM clientes ; //              INDEX ON regiao+dtoc(datacad) 
              TO tempo3 ; 
              SUMMARY nRegiao 
              BROWSE() 
   CLOSE DATA 
   return 
   */ 

/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ 
Procedure SELECTOR(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, ; 
   Arg9, Arg10, Arg11, Arg12) 

   Local Local1, Local2, Local3, Local4, Local5, Local6, Local7, ; 
      Local8, Local9, Local10, Local11, Local12, Local13, Local14, ; 
      Local15, Local16, Local17, Local18, Local19, Local20, Local21, ; 
      Local22, Local23 
   Local1:= Len(Arg1) 
   Local6:= {} 
   Local7:= ISARRAY(Arg3) 
   Local14:= {} 
   Local15:= .F. 
   Local17:= "" 
   Local19:= !(ISNIL(Arg10)) 
   If recco()=0 
      msgrun('Arquivo vazio ou area sem uso','Selector Error') 
      //return 
   EndIf 
   If (ISNIL(Arg2)) 
      Local10:= Select() 
   Else 
      If (ISNUMBER(Arg2)) 
         Local10:= Arg2 
      ElseIf (ISCHARACTER(Arg2)) 
         Local10:= Select(Arg2) 
      EndIf 
      Select (Local10) 
   EndIf 
   If (Local7) 
      Local11:= Select(Arg3[1]) 
   EndIf 
   If (ISNIL(Arg7)) 
      Arg7:= "TEMP.DBF" 
      Default Arg8 To "temp" 
   ElseIf (ISNIL(Arg8)) 
      Arg8:= SubStr(Arg8:= SubStr(Arg7, rat("\", Arg7) + 1), 1, ; 
         At(".", Arg8 + ".") - 1) 
   EndIf 
   Default Local16 To IIf((Local8:= rat(".", Arg7)) > rat("\", ; 
      Arg7), SubStr(Arg7, 1, Local8 - 1), Arg7) + ".NTX" 
   Local23:= RecNo() 
   Goto LastRec() + 1 
   If (Local7) 
      (Local11)->(dbGoto(LastRec() + 1)) 
   EndIf 
   For Local9:= 1 To Local1 
      Local2:= eval(Arg1[Local9][1]) 
      Local4:= ValType(Local2) 
      Local3:= Transform(Local2, "") 
      Local5:= Len(Local3) 
      AAdd(Local6, {IIf((Local8:= At("->", Arg1[Local9][2])) == 0, ; 
         Arg1[Local9][2], SubStr(Arg1[Local9][2], Local8 + 2)), ; 
         Local4, IIf(Arg1[Local9][3] != Nil, Arg1[Local9][3], ; 
         IIf(Local4 == "D", 8, Local5)), IIf(Arg1[Local9][4] != Nil, ; 
         Arg1[Local9][4], IIf(Local4 == "N" .AND. (Local8:= At(".", ; 
         Local3)) > 0, Local5 - Local8, 0))}) 
      If (Arg1[Local9][5] == "G") 
         If (!Local15) 
            Local15:= .T. 
         Else 
            Local17:= Local17 + "+" 
         EndIf 
         Do Case 
         Case Local4 == "C" 
            Local17:= Local17 + Local6[Local9][1] 
         Case Local4 == "N" 
            Local17:= Local17 + ("Str(" + Local6[Local9][1] + ")") 
         Case Local4 == "D" 
            Local17:= Local17 + ("DToS(" + Local6[Local9][1] + ")") 
         Case Local4 == "L" 
            Local17:= Local17 + ("Iif(" + Local6[Local9][1] + ; 
               [,"1","0")]) 
         EndCase 
         AAdd(Local14, Arg1[Local9][1]) 
      ElseIf (Arg1[Local9][6] .AND. Local19 .AND. !Arg9) 
         AAdd(Arg10, 0) 
      EndIf 
   Next 
   Goto Local23 
   If (Arg9) 
      Local12:= Select(Arg8) 
   Else 
      dbcreate(Arg7, Local6) 
      dbUseArea(.T., Nil, Arg7, Arg8, .F.) 
      Local12:= Select() 
      If (Local15) 
         dbCreateIndex(Local16, Local17, &("{||" + Local17 + "}")) 
      EndIf 
      Select (Local10) 
   EndIf 
   If (!Arg6) 
      Goto Top 
   EndIf 
   If (Local7) 
      Do While (!EOF() .AND. !(Local11)->(dbSeek(Local13:= ; 
            (Local10)->(eval(Arg3[2])), .F.))) 
         dbSkip() 
      EndDo 
   EndIf 
   Do While (!EOF() .AND. (ISNIL(Arg5) .OR. eval(Arg5))) 
      If (ISBLOCK(Arg11)) 
         eval(Arg11) 
      EndIf 
      If (ISNIL(Arg4) .OR. eval(Arg4)) 
         Local18:= .F. 
         If ((Local21:= "", aeval(Local14, { |_1| Local21:= Local21 ; 
               + tostring(eval(_1)) }), !Local15 .OR. ; 
               !(Local12)->(dbSeek(Local21, .F.)))) 
            (Local12)->(dbAppend()) 
            Local18:= .T. 
         EndIf 
         Local20:= 0 
         For Local9:= 1 To Local1 
            If (Arg1[Local9][6]) 
               Local20++ 
            EndIf 
            If (!Local15 .OR. Local18 .OR. Arg1[Local9][5] $ "TA") 
               Local2:= eval(Arg1[Local9][1]) 
               If (Arg1[Local9][5] == "T") 
                  (Local12)->(fieldput(Local9, fieldget(Local9) + ; 
                     Local2)) 
               ElseIf (Arg1[Local9][5] == "A" .AND. !Local18) 
                  (Local12)->(fieldput(Local9, (fieldget(Local9) + ; 
                     Local2) / 2)) 
               Else 
                  (Local12)->(fieldput(Local9, Local2)) 
               EndIf 
               If (Arg1[Local9][6] .AND. Local19) 
                  Arg10[Local20]:= Arg10[Local20] + Local2 
               EndIf 
            EndIf 
         Next 
      EndIf 
      //If (((Local11)->(dbSkip()), !Local7 .OR. (Local11)->(EOF() .OR. !(Local13 == eval(Arg3[3]))))) 
         dbSkip() 
         If (Local7) 
            Do While (!EOF() .AND. !(Local11)->(dbSeek(Local13:= ; 
                  (Local10)->(eval(Arg3[2])), .F.))) 
               dbSkip() 
            EndDo 
         EndIf 
      //EndIf 
   EndDo 
   Select (Local12) 
   Goto Top 
   Return 

Static Function TOSTRING(Arg1) 
   Local Local1 
   Local1:= ValType(Arg1) 
   If (Local1 == "N") 
      Arg1:= Str(Arg1) 
   ElseIf (Local1 == "D") 
      Arg1:= DToS(Arg1) 
   ElseIf (Local1 == "L") 
      Arg1:= IIf(Arg1, "1", "0") 
   EndIf 
   Return Arg1


Selector.CH

Code: Select all

#ifndef _SELECTOR_CH 
#define _SELECTOR_CH 

/*----------------------------------------------------------------------------// 
!short: SELECTOR  */ 

#xcommand REDEFINE SELECTOR [ <oSelec> VAR ] <nVar> ; 
               [ ID <nId> ] ; 
               [ ORIGIN ANGLE <nAngle1> ] ; 
               [ LAST ANGLE <nAngle2> ] ; 
               [ RANGE <nMin>, <nMax> ] ; 
               [ MARKS <nMarks> ] ; 
               [ <lExact: EXACT > ] ; 
               [ <dlg: OF,WINDOW,DIALOG > <oWnd> ] ; 
               [ ON CHANGE <uChange> ] ; 
               [ ON THUMBPOS <uPos> ] ; 
               [ <color: COLOR,COLORS > <nClrFore> [,<nClrBack> [,<nClrBtn> ] ] ] ; 
               [ MESSAGE <cMsg> ] ; 
               [ <update: UPDATE >  ] ; 
      => ; 
          [ <oSelec> := ] TSelector():Redefine( <nId>, bSETGET(<nVar>), ; 
             [<nAngle1>], [<nAngle2>], ; 
             <nMin>, <nMax>, <nMarks>, <.lExact.>, ; 
             [<oWnd>], [\{|nVar|<uChange>\}], [\{|nVar|<uPos>\}], ; 
             <cMsg>, <nClrFore>, <nClrBack>, <nClrBtn>, <.update.> ) 

#xcommand @ <nRow>, <nCol> SELECTOR [ <oSelec> VAR ] <nVar> ; 
               [ ORIGIN ANGLE <nAngle1> ] ; 
               [ LAST ANGLE <nAngle2> ] ; 
               [ RANGE <nMin>, <nMax> ] ; 
               [ MARKS <nMarks> ] ; 
               [ <lExact: EXACT > ] ; 
               [ SIZE <nWidth>, <nHeight> ] ; 
               [ <lPixel: PIXEL > ] ; 
               [ <dlg: OF,WINDOW,DIALOG > <oWnd> ] ; 
               [ ON CHANGE <uChange> ] ; 
               [ ON THUMBPOS <uPos> ] ; 
               [ <color: COLOR,COLORS > <nClrFore> [,<nClrBack> [,<nClrBtn> ] ] ] ; 
               [ MESSAGE <cMsg> ] ; 
               [ <design: DESIGN >  ] ; 
               [ <update: UPDATE >  ] ; 
      => ; 
          [ <oSelec> := ] TSelector():New( <nRow>, <nCol>, bSETGET(<nVar>), ; 
             [<nAngle1>], [<nAngle2>], ; 
             <nMin>, <nMax>, <nMarks>, <.lExact.>, ; 
             [<oWnd>], [\{|nVar|<uChange>\}], [\{|nVar|<uPos>\}], ; 
             <nWidth>, <nHeight>, <.lPixel.>, <cMsg>, ; 
             <nClrFore>, <nClrBack>, <nClrBtn>, <.design.>, <.update.> ) 
#endif 
ACC69
Posts: 619
Joined: Tue Dec 12, 2006 7:34 pm
Contact:

Post by ACC69 »

RF wrote:Ya estamos matando pulgas a cañonazos otra vez !!!!!

Es mucho mas rapido utilizar una relacion que crear un archivo temporal.

1) Se abren primero las bases de datos hijas, la condicion es que esten indexadas sobre el campo sobre el cual se establece la relacion:

USE hija1
SET INDEX TO....
USE hija2
SET INDEX TO
USE hija3
SET INDEX TO...

2) Se abre la base de datos padre y se relaciona sobre las hijas indicando claramente el "alias" dela hija y el campo comun en la padre, en forma de bloque de codigo y como cadena de caracteres, la base de datos padre puede estar indexada sobre cualquier criterio, no necesariamente el campo que establece la relacin:

USE padre
SET INDEX TO

padre->(DBSETRELATION(hija1,{|| campo_comun},"campo_comun"))
padre->(DBSETRELATION(hija2,{|| campo_comun},"campo_comun"))
padre->(DBSETRELATION(hija3,{|| campo_comun},"campo_comun"))

DBSETRELATION (<alias de la hija>,;
<code block con el nombre campo comun PADRE>,;
<string con el campo comun en el PADRE).

3) Para usarla en un reporte, se hace referencia al ALIAS de la hija, indicando el campo de la hija que se quiere imprimir

REPORT oReport......

COLUMN DATA padre->campo....
COLUMN DATA hija1->campo
COLUMN DATA hija2->campo
COLUMN DATA hija3->campo
.......

Y listo, no es necesario crear ninguna base de datos temporal ni crear funciones yq evayan y busquen los datos.
Hola Rene buenos dias como esta maestro, en el caso mio, creo que esta más o menos complicado, pero me gustaria alguna sugerencia tuya o mas fácil o metodo que se pueda decir, te explico yo tengo un programa de contabilidad hecho a la medida de la empresa con su captura de cuenta y referencia de facturas, bueno mes a mes se hace cierre del ejercicio ejemplo enero 2007 con la base de datos creada desde inicio MOVT0107.DBF y al mismo momento se va creando nueva base de datos siguiente MOVT0207.DBF y asi sucesivamente como podras imaginar, tengo desde el año 2002 bases de datos diferentes creados por el cierre del mes contable desde MOVT0902.DBF hasta la MOVT0207.DBF del año en curso, bueno yo tengo que crear archivo temporal al pedir reportes de cuentas auxiliar inicial por ejemplo desde la cuenta: 2106-0002-1601 hasta la cuenta 2106-0002-9999 y con mes y año inicial que es 0902 hasta 0207, he ahi ese detalle que yo creo un archivo temporal para el barrido de todas las cuentas y bases de datos a imprimir o consultar , ahora usted con su experiencia hay otro metodo o forma de hacer esa busqueda mas rapida ? nunca he intentado hacer con set relacion, porque son mas de 54 bases de datos diferentes, espero sugerencias y conocimientos a todos los amigos del foro :)
Saludos
Adriano C. C.
acc69@hotmail.com
Ruben Fernandez
Posts: 366
Joined: Wed Aug 30, 2006 5:25 pm
Location: Uruguay

Post by Ruben Fernandez »

Gracias a todos:

Probare las soluciones y despues les cuento el resultado.

Muchas gracias.

Saludos

Ruben Fernandez.
Post Reply