Set Relation

Set Relation

Postby Ruben Fernandez » Thu Feb 15, 2007 2:41 pm

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.
Ruben Fernandez
 
Posts: 366
Joined: Wed Aug 30, 2006 5:25 pm
Location: Uruguay

Postby Kleyber » Thu Feb 15, 2007 3:27 pm

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
User avatar
Kleyber
 
Posts: 581
Joined: Tue Oct 11, 2005 11:28 am
Location: São Luiz, Brasil

Postby Ruben Fernandez » Thu Feb 15, 2007 3:56 pm

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.
Ruben Fernandez
 
Posts: 366
Joined: Wed Aug 30, 2006 5:25 pm
Location: Uruguay

Postby R.F. » Thu Feb 15, 2007 4:12 pm

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.
R.F.
 
Posts: 840
Joined: Thu Oct 13, 2005 7:05 pm

Postby Kleyber » Thu Feb 15, 2007 4:16 pm

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
User avatar
Kleyber
 
Posts: 581
Joined: Tue Oct 11, 2005 11:28 am
Location: São Luiz, Brasil

Postby Rochinha » Thu Feb 15, 2007 4:33 pm

Rubens

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

Code: Select all  Expand view
USE arquivo
INDEX ON campo TAG apelido TO indice


Code: Select all  Expand view
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  Expand view
#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  Expand view
#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
Rochinha
 
Posts: 309
Joined: Sun Jan 08, 2006 10:09 pm
Location: Brasil - Sao Paulo

Postby ACC69 » Thu Feb 15, 2007 5:03 pm

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
ACC69
 
Posts: 632
Joined: Tue Dec 12, 2006 7:34 pm

Postby Ruben Fernandez » Fri Feb 16, 2007 3:03 am

Gracias a todos:

Probare las soluciones y despues les cuento el resultado.

Muchas gracias.

Saludos

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


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 46 guests