Amiguinho,
Não existe meio fácil, com certeza, mas a impossibilidade pode existir no seu caso.
Vejamos:
Em primeiro lugar necessita-se acesso a bases de dados não-nativas ao Harbour.
Bom, se sua versão esta atualizada de forma que os motores de RDD existam às pencas com certeza voce poderá usar um RDD apropriado.
O Harbour a anos vem implementando o RDDADO e os exemplos de uso são muito simples, senão banais.
No primeiro exemplo voce visualiza um esqueleto(não sei se totalmente funcional pois é um trecho de minha aplicação) usando este RDD:
/*
* $Id: access2.prg 14908 2010-06-26 08:32:23Z vszakats $
*/
/* Testing dbCreate() with Access database engine */
#include "adordd.ch"
// Este trecho foi tirado do ADORDD.PRG por
// causa de uns erros na compilação
THREAD STATIC t_cTableName
THREAD STATIC t_cEngine
THREAD STATIC t_cServer
THREAD STATIC t_cUserName
THREAD STATIC t_cPassword
THREAD STATIC t_cQuery := ""
REQUEST ADORDD
REQUEST DBFCDX
PROCEDURE Main()
SET DATE ANSI
SET CENTURY ON
dbSelectArea( 1 )
USE sercaixa.mdb VIA "ADORDD" TABLE "produto"
dbSelectArea( 2 )
USE estoque VIA "DBFCDX"
dbSelectArea( 2 )
dbGotop()
nEstoqueItem := 0
do while .not. eof()
if estoque->idlinha < 1
dbSkip()
loop
endif
nEstoqueItem := nEstoqueItem + 1
m->grupo := 1 // estoque->idcategory
m->subgrupo := TipoDoValor( "N", estoque->idlinha )
m->codigo := TipoDoValor( "N", nEstoqueItem ) // estoque->iditem
m->codigo_barras := TipoDoValor( "C", estoque->resumido )
m->descricao := TipoDoValor( "C", estoque->descricao )
m->unidade := TipoDoValor( "C", estoque->unidade )
m->cst_s := TipoDoValor( "C", estoque->idtributo )
m->tributacao := "01" // estoque->
m->icms := 18 // estoque->
m->moeda := "R$" // estoque->
m->casa_decimal_c:= 2 // estoque->
m->preco_custo := TipoDoValor( "N", estoque->unitario )
m->casa_decimal_v:= 2 // estoque->
m->preco_vista := TipoDoValor( "N", estoque->valorvenda )
m->preco_prazo := TipoDoValor( "N", estoque->valorvenda )
m->permite_venda := -1 // iif(estoque->vendavel="N",-1,0)
m->controla_lote := -1
m->ativo := iif(TipoDoValor( "C", estoque->inativo )="X",0,-1)
m->tipo_venda := "Q"
dbSelectArea( 1 )
//? nEstoqueItem
APPEND BLANK
sercaixa->grupo := m->grupo
sercaixa->subgrupo := m->subgrupo
sercaixa->codigo := m->codigo
sercaixa->codigo_barras := m->codigo_barras
sercaixa->descricao := m->descricao
sercaixa->unidade := m->unidade
sercaixa->cst_s := m->cst_s
sercaixa->tributacao := m->tributacao
sercaixa->icms := m->icms
sercaixa->moeda := m->moeda
sercaixa->casa_decimal_c := m->casa_decimal_c
sercaixa->preco_custo := estoque->unitario
sercaixa->casa_decimal_v := m->casa_decimal_v
sercaixa->preco_vista := m->preco_vista
sercaixa->preco_prazo := m->preco_prazo
sercaixa->permite_venda_prazo := m->permite_venda
sercaixa->controla_lote := m->controla_lote
sercaixa->ativo := m->ativo
sercaixa->tipo_venda := m->tipo_venda
dbSelectArea( 2 )
dbSkip()
enddo
dbSelectArea( 1 )
dbGoTop()
Browse()
RETURN
Function TipoDoValor( _tipo_, _valor_ )
if ValType( _valor_ ) <> _tipo_
if _tipo_ = "C"
if ValType( _valor_ ) <> "C"
_valor_ := ""
endif
endif
if _tipo_ = "N"
if ValType( _valor_ ) <> "N"
_valor_ := 0
endif
endif
if _tipo_ = "D"
if ValType( _valor_ ) <> "D"
_valor_ := CTOD(" / / ")
endif
endif
if _tipo_ = "L"
if ValType( _valor_ ) <> "L"
_valor_ := .F.
endif
endif
if _tipo_ = "M"
if ValType( _valor_ ) <> "M"
_valor_ := ""
endif
endif
endif
return _valor_
#include "adordd.prg"
No exemplo abaixo faço uso do ADOxB amplamente discutido aqui no forum e quisá no mundo:
//#Include "ADOxB.ch"
#command ADO CONNECT <StrDriver> => ADOCONNECT( <StrDriver> )
#command ADO DISCONNECT => ADODISCONNECT()
#command ADO APPEND BLANK => ADOAPPEND()
#command ADO EDIT => ADOEDIT()
#command ADO COMMIT [<save:SAVE>] => ADOCOMMIT( [<.save.>] )
#command ADO SKIP => ADOSKIP( 1 )
#command ADO SKIP <num> => ADOSKIP( <num> )
#command ADO DELETE => ADODELETE()
#command ADO UPDATE => ADOUPDATE()
#command ADO REPLACE <f1> WITH <v1> => ADOREPLACE( <(f1)>, <v1> )
#command ADO GOTOP => ADOGOTOP()
#command ADO GOBOTTOM => ADOGOBOTTOM()
#command ADO SET FILTER TO => ADOSETFILTER()
#command ADO SET FILTER TO <xpr> => ADOSETFILTER( <xpr> )
#command ADO SAVE <(CfILE)> => ADOSAVE( <(CfILE)> )
#command ADO EXECUTE <Sql> => ADOEXECUTE( <Sql> )
#command ADO LOCATE <xpr> => ADOLOCATE( <xpr> )
#command ADO REGLOCK => ADOREGLOCK()
#command ADO CLOSE => ADOCLOSE()
#command ADO CLOSE ALL => ADOCLOSEALL()
#command ADO SELECT <(cRecordSet)> => ADOSELECT( <(cRecordSet)> )
#command ADO USE <(StrDatabase)> => ADOUSE( <(StrDatabase)> )
//#command ADO USE => ADOUSE()
//#command ADO SORT ON [<(cF)>][<(x)>]=> ADOSORT( [<(cF)>][, <(x)>] )
#xcommand ADO SQL DELETE <*cSQL*> => ADOEXECUTE( 'DELETE '+ <(cSQL)> )
#xcommand ADO SQL INSERT <*cSQL*> => ADOEXECUTE( 'INSERT '+ <(cSQL)> )
#xcommand ADO SQL UPDATE <*cSQL*> => ADOEXECUTE( 'UPDATE '+ <(cSQL)> )
#xcommand ADO SQL ALTER <*cSQL*> => ADOEXECUTE( 'ALTER ' + <(cSQL)> )
#xcommand ADO SQL CREATE <*cSQL*> => ADOEXECUTE( 'CREATE '+ <(cSQL)> )
#xcommand ADO SQL DROP <*cSQL*> => ADOEXECUTE( 'DROP ' + <(cSQL)> )
#xcommand ADO SQL RENAME <*cSQL*> => ADOEXECUTE( 'RENAME '+ <(cSQL)> )
#xcommand ADO SQL UPDATE <*cSQL*> => ADOEXECUTE( 'UPDATE '+ <(cSQL)> )
#xcommand ADO SQL GRANT <*cSQL*> => ADOEXECUTE( 'GRANT ' + <(cSQL)> )
#xcommand ADO SQL REVOKE <*cSQL*> => ADOEXECUTE( 'REVOKE '+ <(cSQL)> )
static oWnd, oClients, oClient, oName, oCursor
static cName
static oSplit
//REQUEST ADORDD
function main()
SET DATE ANSI
SET CENTURY ON
ADOSetRDD( "ACCESS" )
StrDatabase := ".\sercaixa.mdb"
StrConnection := "Provider= MicroSoft.Jet.OLEDB.4.0;Data Source="+StrDatabase+";"
ADO CONNECT StrConnection
oCursor:=CreateObject("ADODB.Recordset")
ADO USE produto
ADO SELECT produto
? " Areas abertas: " + StrZero( len(aRecordSet), 2 ), ;
" Tabela Area 1: " + aRecordSet[1], ;
" Area selecionada: " + StrZero( nRecordSet, 2 ), ;
" Area atual: " + StrZero( ADOSelect(), 2 ), ;
" Registro atual: " + StrZero( ADORecno(), 4 ), ;
"Total de registros: " + StrZero( ADORecCount(), 4 )
USE estoque SHARED NEW
//ADO SELECT produto
//ADO GOTOP
//WBrowseRecordSet( "DESCRICAO", ADOAlias() )
//ADO GOTOP
//if .not. ADOEOF()
// do while .not. ADOEOF()
// ADO DELETE
// ADO SKIP
// enddo
//endif
dbSelectArea( "estoque" )
dbGotop()
browse()
dbGotop()
nEstoqueItem := 0
do while .not. eof()
if estoque->idlinha < 1
dbSkip()
loop
endif
nEstoqueItem := nEstoqueItem + 1
m->grupo := 1 // estoque->idcategory
m->subgrupo := TipoDoValor( "N", estoque->idlinha )
m->codigo := TipoDoValor( "N", nEstoqueItem ) // estoque->iditem
m->codigo_barras := TipoDoValor( "C", estoque->resumido )
m->descricao := TipoDoValor( "C", estoque->descricao )
m->unidade := TipoDoValor( "C", estoque->unidade )
m->cst_s := TipoDoValor( "C", estoque->idtributo )
m->tributacao := "01" // estoque->
m->icms := 18 // estoque->
m->moeda := "R$" // estoque->
m->casa_decimal_c:= 2 // estoque->
m->preco_custo := TipoDoValor( "N", estoque->unitario )
m->casa_decimal_v:= 2 // estoque->
m->preco_vista := TipoDoValor( "N", estoque->valorvenda )
m->preco_prazo := TipoDoValor( "N", estoque->valorvenda )
m->permite_venda := -1 // iif(estoque->vendavel="N",-1,0)
m->controla_lote := -1
m->ativo := iif(TipoDoValor( "C", estoque->inativo )="X",0,-1)
m->tipo_venda := "Q"
ADO SELECT produto
ADO APPEND BLANK
ADO REPLACE "grupo" WITH m->grupo
ADO REPLACE "subgrupo" WITH m->subgrupo
ADO REPLACE "codigo" WITH m->codigo
ADO REPLACE "codigo_barras" WITH m->codigo_barras
ADO REPLACE "descricao" WITH m->descricao
ADO REPLACE "unidade" WITH m->unidade
ADO REPLACE "cst_s" WITH m->cst_s
ADO REPLACE "tributacao" WITH m->tributacao
ADO REPLACE "icms" WITH m->icms
ADO REPLACE "moeda" WITH m->moeda
ADO REPLACE "casa_decimal_c" WITH m->casa_decimal_c
ADO REPLACE "preco_custo" WITH estoque->unitario
ADO REPLACE "casa_decimal_v" WITH m->casa_decimal_v
ADO REPLACE "preco_vista" WITH m->preco_vista
ADO REPLACE "preco_prazo" WITH m->preco_prazo
ADO REPLACE "permite_venda_prazo" WITH m->permite_venda
ADO REPLACE "controla_lote" WITH m->controla_lote
ADO REPLACE "ativo" WITH m->ativo
ADO REPLACE "tipo_venda" WITH m->tipo_venda
ADO UPDATE
dbSelectArea( "estoque" )
dbSkip()
enddo
ADO SELECT produto
dbGoTop()
WBrowseRecordSet( "DESCRICAO", ADOAlias() )
oADOConection:Close()
RETURN
function WBrowseRecordSet( cStrField, cStrAlias )
LOCAL oDlg, oBrw, nRec
DEFINE DIALOG oDlg SIZE 300, 300
@ 0, 0 LISTBOX oBrw FIELDS ADOField( cStrField ) ;
HEADERS cStrAlias ;
ON RIGHT CLICK ( nRec := ADORecno(),;
oBrw:Report( "ADO Exemplo", .T. ),;
ADOGotop(),;
ADOSkip( 0 ) )
oBrw:bLogicLen := { || ADORecCount() }
oBrw:bGoTop := { || ADOGotop() }
oBrw:bGoBottom := { || ADOGoBottom() }
oBrw:bSkip := { | nSkip | ADOSkip( nSkip ) }
oBrw:cAlias := "ARRAY"
ACTIVATE DIALOG oDlg;
ON INIT oDlg:SetControl( oBrw );
CENTER
RETURN NIL
Function TipoDoValor( _tipo_, _valor_ )
if ValType( _valor_ ) <> _tipo_
if _tipo_ = "C"
if ValType( _valor_ ) <> "C"
_valor_ := ""
endif
endif
if _tipo_ = "N"
if ValType( _valor_ ) <> "N"
_valor_ := 0
endif
endif
if _tipo_ = "D"
if ValType( _valor_ ) <> "D"
_valor_ := CTOD(" / / ")
endif
endif
if _tipo_ = "L"
if ValType( _valor_ ) <> "L"
_valor_ := .F.
endif
endif
if _tipo_ = "M"
if ValType( _valor_ ) <> "M"
_valor_ := ""
endif
endif
endif
return _valor_
#include "adoxb.prg"
Perceba que no final dos exemplos eu incluo o código extra através de
include.
Analise o código, pesquise aqui no forum por ADOxB/Rochinha e com certeza voce conseguirá resultado.