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.
Set Relation
-
- Posts: 366
- Joined: Wed Aug 30, 2006 5:25 pm
- Location: Uruguay
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.
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.
Rubens
Con uso de CDX e la funcion ORDSCOPE() és mas facil:
Mas rapido que indices condicionales e arquivo temporales.
O use este codigo:
Selector.CH
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()
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
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 foroRF 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.
Saludos
Adriano C. C.
acc69@hotmail.com
-
- Posts: 366
- Joined: Wed Aug 30, 2006 5:25 pm
- Location: Uruguay