Page 1 of 1
HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Fri Apr 24, 2020 5:45 pm
by xmanuel
Pues si, otra alegría que me llevo con HDORDD.
Se trata de importar datos de una tabla de una conexión remota a una tabla de una conexión local.
Esto es solo un ejemplo pero he hecho pruebas usando motores de bases de datos distintos como por ejemplo MySQL a SQLite o de SQLServer a MariaDB
Tambien de una dbf de toda la vida a una tabla de MySQL.
jajaja me está gustando.
Os dejo un ejemplito de importación de una tabla de una conexión remota a una local (la url, la he cambiado porque el servidor no es mio)
Code: Select all
/*
* Proyecto: hdo_general
* Fichero: ej48.prg
* Descripción: Ejemplo de uso de de dos conexiones una local y otra remota.
* Se hace una importacion de la tabla remota a la local
* Autor: Manu Exposito
* Fecha: 24/04/2020
*/
#include "hdo.ch"
REQUEST HDO
REQUEST RDLMYSQL
REQUEST RDLMYSQLN // Prueba tiempos con el nativo, para conexiones lentas debe ser masrapido
procedure main
local l, n
local oHDOL := THDO():new( "mysql" )
local oHDOR := THDO():new( "mysqln" ) // Prueba tiempos con el nativo
if oHDOR:connect( "hdo_demo", "lejos.ddns.net", "hdo_demo", "hdo_demo" ) .and. ;
oHDOL:connect( "hdodemo", "localhost", "root", "root" )
? "Conectado a una base de datos remota y otra local"
// Abro las dos tablas
USE devices NEW ALIAS dev_r VIA "HDO" OF oHDOR // Remoto
USE devices NEW ALIAS dev_l VIA "HDO" OF oHDOL // Local
// Miro el contenido de las dos tablas con el browse estandar
dev_r->( Browse() )
dev_l->( Browse() )
// Cuento el numero de columnas para recorrerlas
l := dev_r->( FCount() )
// Me voy al principio de la priemera tabla (la remota)
dev_r->( DBGoTop() )
// Comienzo la importacion
while !dev_r->( Eof() )
dev_l->( DBAppend() )
for n := 1 to l
dev_l->( FieldPut( n, dev_r->( FieldGet( n ) ) ) )
next
dev_l->( DBCommit() )
dev_r->( DBSkip() )
end
dev_l->( Browse() )
// No olvidar cerrar las tablas
CLOSE dev_r
CLOSE dev_l
endif
// No olvidad cerra la conexion
oHDOR:free()
oHDOL:free()
Alert( "Se termino" )
return
Os seguiré informando.
Si alguien quiere contribuir... yo ahí lo dejo
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Fri Apr 24, 2020 9:54 pm
by xmanuel
Si la tabla no existe en el servidor también se puede crear
Mirad el ejemplo
Code: Select all
#include "hdo.ch"
REQUEST HDO
REQUEST RDLMYSQL
REQUEST RDLMYSQLN // Prueba tiempos con el nativo, para conexiones lentas debe ser masrapido
procedure main
local l, n, aStruct
local oHDOL := THDO():new( "mysql" )
local oHDOR := THDO():new( "mysqln" ) // Prueba tiempos con el nativo
if oHDOR:connect( "hdo_demo", "vork.ddns.net", "hdo_demo", "hdo_demo" ) .and. ;
oHDOL:connect( "hdodemo", "localhost", "root", "root" )
? "Conectado a una base de datos remota y otra local"
HDORDD_DefaultConnect( oHDOL ) // Asigna objeto conexion por defecto para los USE y DbDreate sin OHDO
// Abro las dos tablas
USE devices NEW ALIAS dev_r VIA "HDO" OF oHDOR // Remoto
aStruct := dev_r->( DBStruct() )
DbCreate( "Devices", aStruct, "HDO" )
// Si no se quiere crear una conexion por defecto podemos usar esta
// HDO_DbCreate( oHDOL, "Devices", aStruct, "HDO" )
USE devices NEW ALIAS dev_l VIA "HDO" // Local, si no se pone OF toma la conexion por defecto
// USE devices NEW ALIAS dev_l VIA "HDO" OF oHDOL // Local directa con OF
// Miro el contenido de las dos tablas con el browse estandar
dev_r->( Browse() )
dev_l->( Browse() )
// Cuento el numero de columnas para recorrerlas
l := dev_r->( FCount() )
// Me voy al principio de la priemera tabla (la remota)
dev_r->( DBGoTop() )
// Comienzo la importacion
while !dev_r->( Eof() )
dev_l->( DBAppend() )
for n := 1 to l
dev_l->( FieldPut( n, dev_r->( FieldGet( n ) ) ) )
next
dev_l->( DBCommit() )
dev_r->( DBSkip() )
end
dev_l->( Browse() )
// No olvidar cerrar las tablas
CLOSE dev_r
CLOSE dev_l
endif
// No olvidad cerra la conexion
oHDOR:free()
oHDOL:free()
Alert( "Se termino" )
return
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sat Apr 25, 2020 6:35 am
by jvtecheto
Hola Manu.
Que tipo de colaboración necesitas?
Si es de testeo, pruebas yo me ofrezco.
Enhorabuena por tus progresos.
Jose.
Enviado desde mi POCOPHONE F1 mediante Tapatalk
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sat Apr 25, 2020 6:43 am
by MOISES
Hola:
¿Ya está acabado el rdd?
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sat Apr 25, 2020 9:48 am
by xmanuel
En este ejemplo se puede ver como es posible usar sentencias SQL creadas por nosotros mismos.
En el ejemplo de a continuación uso between para emular un scope:
Code: Select all
//-- Includes ----------------------------------------------------------------//
#include "hdo.ch"
#include "ejforall.ch"
//-- Modulo principal --------------------------------------------------------//
procedure main
local oDb := THDO():new( _DBMS )
SET DATE FORMAT TO "DD/MM/YYYY"
cls
if oDb:connect( _DB, _CONN )
oDb:setAttribute( HDO_ATTR_DEF_TINY_AS_BOOL, .t. ) // Para MySQL
// A partir de aquí como una DBF
USE "SELECT id, first, hiredate, married, age FROM test WHERE id BETWEEN 20 and 100" NEW ALIAS mi VIA "HDO" OF oDb
Browse()
CLOSE mi
else
msg( "No se pudo conectar..." )
endif
// Liberamos la memoria de la conexion
oDb:Free()
msg( "Fin" )
return
//-- Modulos auxiliares ------------------------------------------------------//
Esto hace un scope del id 20 al 100.
[img]
[/img]
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sat Apr 25, 2020 9:55 am
by xmanuel
Hola Moisés te relaciono a continuación lo que está hecho y lo que no fíjate en la LEYENDA:
Code: Select all
--------------------------------------------------------------------------------
Leyenda
--------------------------------------------------------------------------------
X -> Hecho
P -> Hecho parcialmente
S -> Super Hecho
X? -> Hecho pero hay que definir comportamiento
? -> Hay que hacerlo o no
N -> No hecho porque no es necesario
-> Sin hacer
--------------------------------------------------------------------------------
Movement and positioning methods
--------------------------------------------------------------------------------
X bof; Determine logical beginning of file.
X eof; Determine logical end of file.
S found; Determine outcome of the last search operation.
X goBottom; Position cursor at the last record.
X go; Position cursor at a specific physical record.
X goToId; Position the cursor to a specific, physical identity.
X goTop; Position cursor at the first record.
P seek; <---
X skip; Reposition cursor relative to current position.
X skipFilter; -Reposition cursor respecting any filter setting.
X skipRaw; Reposition cursor, regardless of filter.
Data management
--------------------------------------------------------------------------------
S addField; Add a field to the WorkArea.
X append; Append a record to the WorkArea.
S createFields; -Add all fields defined in an array to the WorkArea.
X? deleterec; Delete a record.
X? deleted; Determine deleted status for a record.
S fieldCount; -Determine the number of fields in the WorkArea.
N fieldDisplay;
S fieldInfo; -Retrieve information about a field.
S fieldName; -Determine the name associated with a field number.
X flush; Write data buffer to the data store.
N getRec;
X getValue; Obtain the current value of a field.
N getVarLen; Obtain the length of a field value.
S goCold; Perform a write of WorkArea memory to the data store.
N goHot; Mark the WorkArea data buffer as hot.
N putRec; Replace the current record.
X putValue; Assign a value to a field.
X? recall; Undelete the current record.
X reccount; Obtain number of records in WorkArea.
recInfo; <---
X recno; Obtain physical row number at current WorkArea cursor position.
X recId; Obtain physical row ID at current WorkArea cursor position.
S setFieldExtent; Establish the extent of the array of fields for a WorkArea.
WorkArea/Database management
--------------------------------------------------------------------------------
S alias; -Obtain the alias of the WorkArea.
X close; Close the table in the WorkArea.
X create; Create a data store in the specified WorkArea. <---
info; Retrieve information about the current driver (DBI). <---
X newarea; Clear the WorkArea for use.
X open; Open a data store in the WorkArea.
S release; -Release all references to a WorkArea.
N structSize; Retrieve the size of the WorkArea structure.
X sysName; Obtain the name of replaceable database driver (RDD) subsystem.
S dbEval; -Evaluate code block for each record in WorkArea.
X? pack; Remove records marked for deletion from a database.
N? packRec;
N sort; Physically reorder a database.
N trans; Copy one or more records from one WorkArea to another.
N transRec; Copy a record to another WorkArea.
X zap; Physically remove all records from data store.
Relational Methods
--------------------------------------------------------------------------------
N childEnd; Report end of relation.
N childStart; Report initialization of a relation.
N childSync; Post a pending relational movement.
N syncChildren; -Force relational movement in child WorkAreas.
N clearRel; Clear all relations in the specified WorkArea.
N forceRel; Force relational seeks in the specified WorkArea.
N relArea; -Obtain the workarea number of the specified relation.
N relEval; -Evaluate a block against the relation in specified WorkArea.
N relText; -Obtain the character expression of the specified relation.
N setRel; -Set a relation in the parent file.
Order Management
--------------------------------------------------------------------------------
orderListAdd;
orderListClear;
orderListDelete;
X orderListFocus;
orderListRebuild;
orderCondition;
orderCreate;
orderDestroy;
orderInfo; -Retrieve information about the current order that SELF could not.
Filters and Scope Settings
--------------------------------------------------------------------------------
X clearFilter; -Clear the active filter expression.
S clearLocate; -Clear the active locate expression.
clearScope;
countScope;
S filterText; -Return filter condition of the specified WorkArea.
scopeInfo;
X setFilter; Set the filter condition for the specified WorkArea.
S setLocate; -Set the locate scope for the specified WorkArea.
setScope;
skipScope;
X locate; Reposition cursor to positions set by setLocate
Miscellaneous
--------------------------------------------------------------------------------
S compile; -Compile a character expression.
S error; -Raise a runtime error.
S evalBlock; -Evaluate a code block.
Network operations
--------------------------------------------------------------------------------
rawlock; Perform a low-level network lock in the specified WorkArea.
lock; Perform a network lock in the specified WorkArea.
unlock; Release network locks in the specified WorkArea.
Memofile functions
--------------------------------------------------------------------------------
N closeMemFile; Close a memo file in the WorkArea.
N createMemFile; Create a memo file in the WorkArea.
N getValueFile;
N openMemFile; Open a memo file in the specified WorkArea.
N putValueFile;
Database file header handling
--------------------------------------------------------------------------------
N readDBHeader; Read the database file header record in the WorkArea.
N writeDBHeader; Write the database file header record in the WorkArea.
Non WorkArea functions
--------------------------------------------------------------------------------
init; init RDD after registration
exit; unregister RDD
drop; remove table or index <---
exists; check if table or index exists <---
rename; rename table or index <---
rddInfo; RDD info <---
Special and reserved methods
--------------------------------------------------------------------------------
N whoCares;
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sat Apr 25, 2020 9:59 am
by xmanuel
Gracias Jose.
Ya hay un grupo que la prueba.
Si quieres ponte en contacto conmigo.
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sat Apr 25, 2020 2:36 pm
by MOISES
Manuel:
Estas son las funciones del RDD:
Code: Select all
aADOFunc[ UR_INIT ] := (@ADO_INIT())
aADOFunc[ UR_EXIT ] := (@ADO_EXIT())
aADOFunc[ UR_INFO ] := (@ADO_INFO())
aADOFunc[ UR_NEW ] := (@ADO_NEW())
aADOFunc[ UR_CREATE ] := (@ADO_CREATE())
aADOFunc[ UR_CREATEFIELDS ] := (@ADO_CREATEFIELDS())
aADOFunc[ UR_OPEN ] := (@ADO_OPEN())
aADOFunc[ UR_CLOSE ] := (@ADO_CLOSE())
aADOFunc[ UR_BOF ] := (@ADO_BOF())
aADOFunc[ UR_EOF ] := (@ADO_EOF())
aADOFunc[ UR_DELETED ] := (@ADO_DELETED())
aADOFunc[ UR_SKIPRAW ] := (@ADO_SKIPRAW())
aADOFunc[ UR_SKIPFILTER ] := (@ADO_SKIPFILTER())
aADOFunc[ UR_GOTO ] := (@ADO_GOTO())
aADOFunc[ UR_GOTOID ] := (@ADO_GOTOID())
aADOFunc[ UR_GOTOP ] := (@ADO_GOTOP())
aADOFunc[ UR_GOBOTTOM ] := (@ADO_GOBOTTOM())
aADOFunc[ UR_RECNO ] := (@ADO_RECNO())
aADOFunc[ UR_RECID ] := (@ADO_RECID())
aADOFunc[ UR_RECCOUNT ] := (@ADO_RECCOUNT())
aADOFunc[ UR_GETVALUE ] := (@ADO_GETVALUE())
aADOFunc[ UR_PUTVALUE ] := (@ADO_PUTVALUE())
aADOFunc[ UR_DELETE ] := (@ADO_DELETE())
aADOFunc[ UR_RECALL ] := (@ADO_RECALL())
aADOFunc[ UR_APPEND ] := (@ADO_APPEND())
aADOFunc[ UR_FLUSH ] := (@ADO_FLUSH())
aADOFunc[ UR_ORDINFO ] := (@ADO_ORDINFO())
aADOFunc[ UR_RECINFO ] := (@ADO_RECINFO())
aADOFunc[ UR_FIELDINFO ] := (@ADO_FIELDINFO())
aADOFunc[ UR_FIELDNAME ] := (@ADO_FIELDNAME())
aADOFunc[ UR_ORDLSTFOCUS ] := (@ADO_ORDLSTFOCUS())
aADOFunc[ UR_PACK ] := (@ADO_PACK())
aADOFunc[ UR_RAWLOCK ] := (@ADO_RAWLOCK())
aADOFunc[ UR_LOCK ] := (@ADO_LOCK())
aADOFunc[ UR_UNLOCK ] := (@ADO_UNLOCK())
aADOFunc[ UR_SETFILTER ] := (@ADO_SETFILTER())
aADOFunc[ UR_CLEARFILTER ] := (@ADO_CLEARFILTER())
aADOFunc[ UR_FILTERTEXT ] := (@ADO_FILTERTEXT())
aADOFunc[ UR_ZAP ] := (@ADO_ZAP())
aADOFunc[ UR_SETLOCATE ] := (@ADO_SETLOCATE())
aADOFunc[ UR_LOCATE ] := (@ADO_LOCATE())
aADOFunc[ UR_FOUND ] := (@ADO_FOUND())
aADOFunc[ UR_FORCEREL ] := (@ADO_FORCEREL())
aADOFunc[ UR_RELEVAL ] := (@ADO_RELEVAL())
aADOFunc[ UR_CLEARREL ] := (@ADO_CLEARREL())
aADOFunc[ UR_RELAREA ] := (@ADO_RELAREA())
aADOFunc[ UR_RELTEXT ] := (@ADO_RELTEXT())
aADOFunc[ UR_SETREL ] := (@ADO_SETREL())
aADOFunc[ UR_ORDCREATE ] := (@ADO_ORDCREATE())
aADOFunc[ UR_ORDDESTROY ] := (@ADO_ORDDESTROY())
aADOFunc[ UR_ORDLSTADD ] := (@ADO_ORDLSTADD())
aADOFunc[ UR_ORDLSTCLEAR ] := (@ADO_ORDLSTCLEAR())
aADOFunc[ UR_ORDLSTREBUILD ]:= (@ADO_ORDLSTREBUILD())
aADOFunc[ UR_DBEVAL ] := (@ADO_DBEVAL())
aADOFunc[ UR_EVALBLOCK ] := (@ADO_EVALBLOCK())
aADOFunc[ UR_SEEK ] := (@ADO_SEEK())
aADOFunc[ UR_TRANS ] := (@ADO_TRANS())
Y estos los data:
Code: Select all
oRecordSet := NIL
aWAData[ WA_BOF ] := .F.
aWAData[ WA_EOF ] := .F.
aWAData[WA_INDEXES] := {}
aWAData[WA_INDEXEXP] := {}
aWAData[WA_INDEXFOR] := {}
aWAData[WA_INDEXACTIVE] := 0
aWAData[WA_LOCKLIST] := {}
aWAData[WA_FILELOCK] := .F.
aWAData[WA_INDEXUNIQUE] := {}
aWAData[WA_OPENSHARED] := NIL
aWAData[WA_SCOPES] := {}
aWAData[WA_SCOPETOP] := {}
aWAData[WA_SCOPEBOT] := {}
aWAData[WA_ISITSUBSET] := .F.
aWAData[WA_FOUND] := .F.
aWAData[WA_LASTRELKEY] := NIL
aWAData[WA_FILTERACTIVE] := NIL
aWAData[WA_FIELDRECNO] := NIL
aWAData[WA_SCOPEINFO] := NIL
aWAData[WA_TLOCKS] := {}
aWAData[WA_FILEHANDLE ] := NIL
aWAData[WA_LOCKSCHEME ] := ADOFORCELOCKS() //no lock type 999
aWAData[WA_CFILTERACTIVE ] := ""
aWAData[WA_LREQUERY] := .F.
aWAData[WA_RECORDSET] := NIL //18.6.15 cleaning
aWAData[WA_RECCOUNT] := NIL //27.06.5
aWAData[WA_ABOOKMARKS] := {}
aWAData[WA_INDEXDESC] := {}
aWAData[WA_FIELDDELETED] := NIL
aWAData[WA_TABLEINDEX] := NIL
aWAData[WA_BAGINDEXES] := {}
Por favor, ¿podrías indicarnos que falta?
Muchas gracias.
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sat Apr 25, 2020 8:00 pm
by xmanuel
Te estás haciendo un lío...
Los RDD funcionan casi como clases y tienen herencia.
Verás, hay funciones que tienes que implementar porque si no no funciona el RDD ya que en la RDD padre solo están definidas pero no implementadas y otras que no son necesarias porque las implementa el RDD padre.
Luego el sistema de RDD define una serie de estructuras que están compuestas por miembros que utiliza el RDD internamente.
El UsrRDD te da la posibilidad de guardar información en 2 ITEMs de Harbour uno para el sistema de RDD y otro para el Área de trabajo o sea dos variables que pueden ser un array.
Eso es lo que hace la ADORDD, no tiene datas si no un array con n posiciones donde se estan guardando la informacion que necesita para su funcionamiento.
En lo que yo te he puesto al principio hay una leyenda:
--------------------------------------------------------------------------------
Leyenda
--------------------------------------------------------------------------------
X -> Hecho
P -> Hecho parcialmente
S -> Super Hecho
X? -> Hecho pero hay que definir comportamiento
? -> Hay que hacerlo o no
N -> No hecho porque no es necesario
-> Sin hacer
--------------------------------------------------------------------------------
Y luego en cada funcion dek HDORDD esta precedida por una X, P, S, etc o nada si no está hecho..
Por ejemplo estas son las funciones de movimiento:
Movement and positioning methods
--------------------------------------------------------------------------------
X bof; Determine logical beginning of file. <---------------------------------------------- tiene una X o sea esta hecha
X eof; Determine logical end of file.
S found; Determine outcome of the last search operation. <------------------------------tiene una S o sea la impleneta el super y funciona
X goBottom; Position cursor at the last record.
X go; Position cursor at a specific physical record.
X goToId; Position the cursor to a specific, physical identity.
X goTop; Position cursor at the first record.
P seek; <--------------------------------------------------tiene una P porque está parcialmente (solo funciona con valores exactos y no búsquedas blandas
X skip; Reposition cursor relative to current position.
X skipFilter; -Reposition cursor respecting any filter setting.
X skipRaw; Reposition cursor, regardless of filter.
Espero haberte ayudado
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sat Apr 25, 2020 8:37 pm
by Antonio Mart.
A muchos nos vendría muy bien este Rdd para darle vidilla a nuestros programas.
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sat Apr 25, 2020 8:56 pm
by xmanuel
A ver... quiero saber algo y quiero que me ayudéis todos.
Exactamente que funciones de la RDD usáis habitualmente en vuestros programas a ver si se pueden implementar.
Quiero decir que el mundo SQL es diferente al de las DBF tanto funcional como conceptualmente...
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sun Apr 26, 2020 8:37 am
by MOISES
Por ejemplo, aquí va una muestra:
Code: Select all
Append blank
CLIENTES->( OrdScope( 1, Nil ) )
COUNT TO nDuplicados FOR FIELD->NUMERO == nNumero
COUNT TO nRegistros
DBCLEARFILTER
DbDelete
DbDelete()
DbGoBottom()
Dbgoto( nregistro )
Dbseek( nCodigo )
dbSelectArea
DbSetOrder(1)
DBSKIP
DBSKIP()
DELETE ALL FOR EMPTY( FIELD->CODIGO ) .AND. EMPTY( FIELD->NOMBRE )
EOF
FIELD->CODIGO
Fieldget
Fieldput
FOUND()
INDEX ON FIELD->FAMILIA+FIELD->CODIGO TAG ARTICULOS1 FOR !Deleted()
INDEX ON FIELD->SERIE + StrZero (FIELD->NUMERO,20 ) TAG FACTURAS1 FOR !Deleted()
indexord()
LOCATE FOR ALLTRIM(CLIENTES->NOMBRE) = ALLTRIM(CNOMBRE) .AND. ALLTRIM(CLIENTES->APELLIDOS) = ALLTRIM(CAPELLIDOS)
OrdSetFocus(“CLIENTES2”)
RECNO()
REPLACE
SELECT()
SELECT(“CLIENTES”)
SET FILTER
SET SCOPE TO ( cSERIE + StrZero( NUMERO_ORI,20 ) )
SUM CLIENTES->IMPORTE TO Ntotal
UNLOCK ALL
ZAP
Muchas gracias.
Re: HDORDD. Importando datos desde dos conexiones diferentes.
Posted: Sun Apr 26, 2020 11:49 am
by xmanuel
si Append blank
si CLIENTES->( OrdScope( 1, Nil ) )
? COUNT TO nDuplicados FOR FIELD->NUMERO == nNumero
? COUNT TO nRegistros
si DBCLEARFILTER
si DbDelete
si DbDelete()
si DbGoBottom()
si Dbgoto( nregistro )
si Dbseek( nCodigo )
si dbSelectArea
si DbSetOrder(1)
si DBSKIP
si DBSKIP()
? DELETE ALL FOR EMPTY( FIELD->CODIGO ) .AND. EMPTY( FIELD->NOMBRE )
si EOF
si FIELD->CODIGO
si Fieldget
si Fieldput
si FOUND()
? INDEX ON FIELD->FAMILIA+FIELD->CODIGO TAG ARTICULOS1 FOR !Deleted()
? INDEX ON FIELD->SERIE + StrZero (FIELD->NUMERO,20 ) TAG FACTURAS1 FOR !Deleted()
? indexord()
? LOCATE FOR ALLTRIM(CLIENTES->NOMBRE) = ALLTRIM(CNOMBRE) .AND. ALLTRIM(CLIENTES->APELLIDOS) = ALLTRIM(CAPELLIDOS)
si OrdSetFocus(“CLIENTES2”)
si RECNO()
? REPLACE
si SELECT()
si SELECT(“CLIENTES”)
si SET FILTER
? SET SCOPE TO ( cSERIE + StrZero( NUMERO_ORI,20 ) )
? SUM CLIENTES->IMPORTE TO Ntotal
? UNLOCK ALL
si ZAP
La "?" no significa que no esté si no que no lo he probado aún. En cuanto a lo indices el concepto en SQL es ordenancion de un reultado y lo que he implementado es el OrdSetFocus( xCol ) donde xCol puede ser el numero de columna o campo o el nombre, por ejemplo OrdSetFocus( 1 ) o OrdSetFocus( "ID" ) pero que tambien se puede hacer una cadena con la lista de ordenacion de las columnas: OrdSetFocus( "3, 5, 2" ) que ordenaria primero por la columna 3 5 y 2 o tambien OrdSetFocus( "fNacimiento, cNom, nHijos" ) o sea por el nombre de las columnas sean del tipo que sean olvidate de str(), dtos() etc SQL sabe hacerlo
Ademas dbsetorder( 5 ) funciona como siempre.
El DbSeek() puede hacer uso de comodines "*" osea podría decirle que busque en el orden activo todo lo que empiece por EXPO asi DbSeek( "EXPO*" ) o lo que contenga EXPO DbSeek( "*EXPO*" ) o todos los manueles que contengas EXPO Dbseek( "Manuel *EXPO*" )
Por otro lado HDORDD admite sentencias SQL en el USE así que podriamos hacer cosas como esta:
Esto: COUNT TO nDuplicados FOR FIELD->NUMERO == nNumero -> USE "SELECT Count( NUMERO ) FROM TuTabla WHERE NUMERO == nNumero"
Esto SUM CLIENTES->IMPORTE TO Ntota -> USE "SELECT Sum( IMPORTE ) FROM TuTabla"
Realmente todas y digo todas las sentencias DBF tienen su correspondiente SQL mejorada y más fácil...
No sé, pregunta y yo te respondo...