Página 1 de 4

Browse pra ADO

Enviado: 09 Dez 2019 12:33
por JoséQuintas
Em console, meu browse pra ADO ficou excelente, usando o tbrowse.

Lembro que HWGUI tem browse estilo tbrowse, mas não lembro se está preso a DBF.
Ao mesmo tempo, lembro que o da HMG é totalmente preso a DBF.

Só estou me adiantando, porque vai ser uma etapa futura, mas....
Qual LIB gráfica tem um browse que poderia ser usado com ADO?

Necessidade: igual tbrowse, com opção de Picture e cores, já tá bom, opção de usar imagens no browse fica pra mais futuro ainda.

Browse pra ADO

Enviado: 09 Dez 2019 12:42
por JoséQuintas
Faltou acrescentar:

Quando falo de browse/grid, é apenas a navegação.
Nada daquela coisa de ficar editando no próprio browse/grid, porque isso só interessa pra Excel.
Chamada de função sim, mas edição não.

Browse pra ADO

Enviado: 09 Dez 2019 20:54
por MSDN
Quintas, falo pela MiniGUI Extended :
Browse = funciona somente com DBF
Grid = funciona com DBF e ADO ( array )
TSBrowse = funciona com DBF, ADO ( array ), mesmo estilo do Tbrowse do Clipper, pode mudar tudo, fonte, largura, altura, cor de cima, de baixa, do lado, aceita alcool, gasolina, vale transporte, é p...das galáxias !

Browse pra ADO

Enviado: 09 Dez 2019 21:24
por JoséQuintas
MSDN escreveu:TSBrowse = funciona com DBF, ADO ( array ), mesmo estilo do Tbrowse do Clipper, pode mudar tudo, fonte, largura, altura, cor de cima, de baixa, do lado, aceita alcool, gasolina, vale transporte, é p...das galáxias !
Na verdade, o outro que era ruim mesmo kkkk

Isso de poder mudar tudo.... não chama a atenção, porque em ambiente gráfico é relativamente normal (ou deveria ser).
A questão é: é flexível? aceita funções de usuário?

Browse pra ADO

Enviado: 11 Dez 2019 15:22
por Itamar M. Lins Jr.
Ola!
TSBrowse = funciona com DBF, ADO ( array ), mesmo estilo do Tbrowse do Clipper, pode mudar tudo, fonte, largura, altura, cor de cima, de baixa, do lado, aceita alcool, gasolina, vale transporte, é p...das galáxias !
A Hwgui faz isso tudo.
A SQLMIX, faz exatamente o que vc está lá perguntado do ADO em outro post, recordset. Esse é o problema resolvido pelo SQLMIX. Usamos SQL para ler e gravar nos motores (MySQL, Postgree...) mas para manipular usamos comandos do DBF. Nisso aproveitamos TSBROWSE, HWGUI BROWSE, Minigui browse... etc.
Ou usamos array, caso acesso nativo.

Código: Selecionar todos

#define	BRW_ARRAY               1
#define	BRW_DATABASE            2
...
#xcommand @ <x>,<y> BROWSE [ <oBrw> ]  ;
            [ <lArr: ARRAY> ]          ;
            [ <lDb: DATABASE> ]        ;
            [ OF <oWnd> ]              ;
            [ ID <nId> ]               ;
            [ SIZE <width>, <height> ] ;

Código: Selecionar todos

/*
 * $Id: grid_2.prg,v 1.1 2004/04/05 14:16:35 rodrigo_moreno Exp $
 *
 * HWGUI - Harbour Win32 GUI library source code:
 * HGrid class
 *
 * Copyright 2002 Alexander S.Kresin <alex@belacy.belgorod.su>
 * www - http://kresin.belgorod.su
 * Copyright 2004 Rodrigo Moreno <rodrigo_moreno@yahoo.com>
 *
 * This Sample use Postgres Library, you need to link libpq.lib and libhbpg.lib
 *
*/

#include "windows.ch"
#include "guilib.ch"
#include "common.ch"

#translate hwg_ColorRgb2N( <nRed>, <nGreen>, <nBlue> ) => ( <nRed> + ( <nGreen> * 256 ) + ( <nBlue> * 65536 ) )

Static oMain, oForm, oFont, oGrid, oServer, oQuery

Function Main()

        ConnectGrid()
        
        INIT WINDOW oMain MAIN TITLE "Grid Postgres Sample Using TPostgres" ;
             AT 0,0 ;
             SIZE hwg_Getdesktopwidth(), hwg_Getdesktopheight() - 28

                MENU OF oMain
                        MENUITEM "&Exit"   ACTION oMain:Close()
                        MENUITEM "&Demo" ACTION Test()
                ENDMENU

        ACTIVATE WINDOW oMain
        
        oServer:Close()
        
Return Nil

Function Test()
        PREPARE FONT oFont NAME "Courier New" WIDTH 0 HEIGHT -11
        
        INIT DIALOG oForm CLIPPER NOEXIT TITLE "Postgres Sample";
             FONT oFont ;
             AT 0, 0 SIZE 700, 425 ;
             STYLE DS_CENTER + WS_VISIBLE + WS_POPUP + WS_VISIBLE + WS_CAPTION + WS_SYSMENU
                
             @ 10,10 GRID oGrid OF oForm SIZE 680,375;
                     ITEMCOUNT oQuery:Lastrec() ;
                     COLOR hwg_ColorC2N('D3D3D3');
                     BACKCOLOR hwg_ColorRgb2N(220,220,220) ;
                     ON DISPINFO {|oCtrl, nRow, nCol| valtoprg(oQuery:FieldGet( nRow, nCol )) } 

             ADD COLUMN TO GRID oGrid HEADER "Column 1" WIDTH  50
             ADD COLUMN TO GRID oGrid HEADER "Column 2" WIDTH 200
             ADD COLUMN TO GRID oGrid HEADER "Column 3" WIDTH 100
                                                              
             @ 620, 395 BUTTON 'Close' SIZE 75,25 ON CLICK {|| oForm:Close() }                            
             
        ACTIVATE DIALOG oForm
Return Nil

Function ConnectGrid()
    Local cHost := 'Localhost'

    Local cDatabase := 'test'

    Local cUser := 'Rodrigo'

    Local cPass := 'moreno'

    Local oRow, i

    

    oServer := TPQServer():New(cHost, cDatabase, cUser, cPass)



    if oServer:NetErr()

        ? oServer:Error()

        quit

    end

    
    if oServer:TableExists('test')

        oServer:DeleteTable('Test')
    endif        

    

    oServer:CreateTable('Test', {{'col1', 'N', 6, 0},;

                                 {'col2', 'C', 40,0},;

                                 {'col3', 'D', 8, 0}})
        
    oQuery := oServer:Query('SELECT * FROM test')
                                     
    For i := 1 to 100
        oRow := oQuery:blank()
        
        oRow:Fieldput(1, i)
        oRow:Fieldput(2, 'teste line ' + str(i))
        oRow:Fieldput(3, date() + i)
        
        oQuery:Append(oRow)
    Next  
    
    oQuery:refresh()                                              
    
return nil        

Por exemplo, para "PULAR" registro no ADO é "MOVENEXT" usando DBF(array ou não) é SKIP/DBSKIP().
Para INCLUIR usando SQLMIX é "INSERT INTO...", atualizar é "UPDATE..." afinal de contas quem quer ficar usando no ADO, append,replace... Nem faz sentido usar assim também com o resultado na forma de DBF. (lembrando que o DBF é um ARRAY). Não é um arquivo, "clientes.dbf" que fica gravado no HD.

Saudações,
Itamar M. Lins Jr.

Browse pra ADO

Enviado: 11 Dez 2019 16:39
por JoséQuintas
Itamar M. Lins Jr. escreveu:A SQLMIX, faz exatamente o que vc está lá perguntado do ADO em outro post, recordset.
O problema é que os "neguinhos" fazem acesso ao recordset pra usar junto com o banco de dados.

A porr... do recordset é como um arquivo temporário, tem vida própria.

Esse é o principal problema das tranqueiras feitas pra Harbour + ADO, ficam presas a um banco de dados específico, quando deveriam usar diretamente o recordset sem vínculo nenhum a NADA, a não ser o ADO.

O ADO é um array, é um "DBF" na memória, é sei lá o que... mas é ele sozinho.
Vincular isso a banco de dados é justamente deixar limitado.

A alternativa é um browse sem vínculo a nada, igual tbrowse, que pode ser usado pra qualquer coisa.
O browse não precisa fazer SKIP, GO TOP, GO BOTTOM.... assim como o tbrowse também não faz.

Por causa disso, os "neguinhos" acabam criando browse pra dbf, browse pra ADO, browse pra array, browse pra PQP....

Browse pra ADO

Enviado: 11 Dez 2019 19:05
por asimoes
Quintas tá nervoso, kkk
Olha o coração!

Browse pra ADO

Enviado: 14 Abr 2020 01:44
por cjp
Pessoal, ainda estou engatinhando nesse browse com ado.

Fui tentar fazer uma restrição de campos para exibir, mas não funcionou.

Acresci esta parte:

Código: Selecionar todos

oTBrowse := { ;
   { "DATA", { || Pad( oRS:Fields( "DATA" ):Value, 10 ) } }, ;
   { "PRIORIDADE",  { || Pad( oRS:Fields( "PRIORIDADE" ):Value, 1 ) } }, ;
   { "NRTAREFA", { || Pad( oRS:Fields( "NRTAREFA" ):Value, 5 ) } }, ;
   { "TAREFA", { || Pad( oRS:Fields( "TAREFA" ):Value, 35 ) } }, ;
   }
Pensei que assim restringiria a exibição a estes campos, mas não funcionou.

Segue o código:

Código: Selecionar todos

function consado(sql)
         #include "tbrowse.ch"
		 local cSair :="N"
         LOCAL oTBrowse, nKey, oRs, oColumn, I, nLen
		 local vez :=0
         LOCAL oConexao := conectado(nProvTar)
		 
		 keysec(27,1000,-1,.t.)
		 
         oConexao:Open()
   
         do while .t.
                  oRS := oConexao:Execute( sql )
	  
             if oRS:Eof()
	            @ 22,25 say "Não há nenhum item   "
		        inkey(11)
	            return .f.
	         endif

oTBrowse := { ;
   { "DATA", { || Pad( oRS:Fields( "DATA" ):Value, 10 ) } }, ;
   { "PRIORIDADE",  { || Pad( oRS:Fields( "PRIORIDADE" ):Value, 1 ) } }, ;
   { "NRTAREFA", { || Pad( oRS:Fields( "NRTAREFA" ):Value, 5 ) } }, ;
   { "TAREFA", { || Pad( oRS:Fields( "TAREFA" ):Value, 35 ) } }, ;
   }

   
      cls
      oTBrowse := TBrowseDB():new( 05, 3, MaxRow() - 7, MaxCol() - 2 )

      oTBrowse:goTopBlock    := { || oRs:moveFirst() }
      oTBrowse:goBottomBlock := { || oRs:moveLast() }
      oTBrowse:skipBlock     := { | n | ADORecordSetSkipper( oRs, n ) }
      oTBrowse:HeadSep       := Chr(196)
      oTBrowse:ColSep        := Chr(179)
      oTBrowse:FootSep       := ""
	  
      nLen := oRs:fields():count() - 1
      FOR i := 0 TO nLen
         oColumn       := TBColumnNew( oRs:fields(i):name(), ADORecordSetFieldBlock( oRs, i ) )
		 IF ValType( oRs:Fields(i):Value ) == "D"
            nFieldLen := Len( Dtoc( Date() ) )
         ELSE
            nFieldLen := Min( oRs:Fields(I):DefinedSize, 50 )
         ENDIF
         oColumn:Width := Max( nFieldLen, Len( oRs:fields(i):name ) )
         oTBrowse:addColumn( oColumn )
      NEXT
	  
	  if procname(1)="CONSATIVSQL"
         @ 0,1 say "Arquivo em edição: "+alias()
         @ maxrow()-2,1 say "Tempo trabalhado: "+alltrim(str(tpt))+"; tempo computado: "+alltrim(str(tpc))+"; tecle Enter sobre nrtarefa para abrir a tarefa"
		 @ maxrow(),1 say "Alt-P-procura/filtra; Alt-M-mostra estrutura; F2-acresce registros; Alt-C-conta registros"
	  endif
	  
	  @ 5,5 say "Abrindo consulta..."
	  
   DO WHILE .T.
      oTBrowse:forceStable()
      oTBrowse:refreshCurrent()
      nKey := Inkey(0)
	  if nkey == 13 //K_ENTER
		 arq=oRs:Fields("nrtarefa"):Value
	     chmfunc("entersql",,"S")
		 if procname(1)="CONSEXPR" .or. procname(2)="CONSEXPR"
		    cSair="S"
		 endif
		 exit
	  elseif nkey == 27
	     cSair="S"
		 exit
	  endif
      IF oTBrowse:applyKey( nKey ) == TBR_EXIT
	     cSair="S"
         EXIT
      ENDIF
   ENDDO
   
   if cSair="S"
      exit
   endif
   enddo

   oRs:Close()
   oConexao:Close()
   if cSair="S" .or. procname(1)="CONSEXPR" .or. procname(2)="CONSEXPR"
      return .f.
   endif
return .t.

Alguém pode me ajudar?

Browse pra ADO

Enviado: 14 Abr 2020 10:49
por Fernando queiroz
JoséQuintas escreveu:
Itamar M. Lins Jr. escreveu:A SQLMIX, faz exatamente o que vc está lá perguntado do ADO em outro post, recordset.
O problema é que os "neguinhos" fazem acesso ao recordset pra usar junto com o banco de dados.

A porr... do recordset é como um arquivo temporário, tem vida própria.

Esse é o principal problema das tranqueiras feitas pra Harbour + ADO, ficam presas a um banco de dados específico, quando deveriam usar diretamente o recordset sem vínculo nenhum a NADA, a não ser o ADO.

O ADO é um array, é um "DBF" na memória, é sei lá o que... mas é ele sozinho.
Vincular isso a banco de dados é justamente deixar limitado.

A alternativa é um browse sem vínculo a nada, igual tbrowse, que pode ser usado pra qualquer coisa.
O browse não precisa fazer SKIP, GO TOP, GO BOTTOM.... assim como o tbrowse também não faz.

Por causa disso, os "neguinhos" acabam criando browse pra dbf, browse pra ADO, browse pra array, browse pra PQP....
Quintas sou iniciante , mas como parti para a HWGUI e MARIADB nem sei se uso ADO mas a coisa flui de uma forma tao normal que nao senti diferenca em ser DATABASE ou ARRAY

a navegação é normal como no DBF , a diferença é de onde vem os campos,

Código: Selecionar todos

******************************************************************
STATIC FUNCTION CARREGA_CLIENTES( oServer, cAlvo_Consulta )
******************************************************************
LOCAL aResult :={};
	, oQuery;
	, cQuery
	
	cQuery := "SELECT CLIENTES_UCLIENTE, ";
				   + "CLIENTES_NRAZ_SOC, ";
				   + "CLIENTES_CPFCGC, ";
				   + "CLIENTES_FONE, ";
				   + "CLIENTES_EMAIL, ";
				   + "CLIENTES_INSEST, ";
				   + "CLIENTES_ISENTO, ";
				   + "CLIENTES_ENDER, ";
				   + "CLIENTES_NUMERO, ";
				   + "CLIENTES_COMPLEM, ";
				   + "CLIENTES_BAIR, ";
				   + "CLIENTES_CEP, ";
				   + "CLIENTES_CODPAIS, ";
				   + "CLIENTES_PAIS, ";
				   + "CLIENTES_UF, ";
				   + "CLIENTES_CODMUN, ";
				   + "CLIENTES_CIDADE, ";
				   + "CLIENTES_CONTATO, ";
				   + "CLIENTES_QUEM_BLOQ, ";
				   + "CLIENTES_ID ";
				   + "from CLIENTES ";
				   + cAlvo_Consulta 

	oQuery := oServer:Execute(cQuery)

	DO WHILE ! oQuery:Eof()
		aAdd( aResult, {oQuery:Fields( "CLIENTES_UCLIENTE" ):Value,;
						oQuery:Fields( "CLIENTES_NRAZ_SOC" ):Value,;
						oQuery:Fields( "CLIENTES_CPFCGC" ):Value,;
						oQuery:Fields( "CLIENTES_FONE" ):Value,;
						oQuery:Fields( "CLIENTES_EMAIL" ):Value,;
						oQuery:Fields( "CLIENTES_INSEST" ):Value,;
						oQuery:Fields( "CLIENTES_ISENTO" ):Value,;
						oQuery:Fields( "CLIENTES_ENDER" ):Value,;
						oQuery:Fields( "CLIENTES_NUMERO" ):Value,;
						oQuery:Fields( "CLIENTES_COMPLEM" ):Value,;
						oQuery:Fields( "CLIENTES_BAIR" ):Value,;
						oQuery:Fields( "CLIENTES_CEP" ):Value,;
						oQuery:Fields( "CLIENTES_CODPAIS" ):Value,;
						oQuery:Fields( "CLIENTES_PAIS" ):Value,;
						oQuery:Fields( "CLIENTES_UF" ):Value,;
						oQuery:Fields( "CLIENTES_CODMUN" ):Value,;
						oQuery:Fields( "CLIENTES_CIDADE" ):Value,;
						oQuery:Fields( "CLIENTES_CONTATO" ):Value,;
						oQuery:Fields( "CLIENTES_QUEM_BLOQ" ):Value,;
						oQuery:Fields( "CLIENTES_ID" ):Value} ) 

		oQuery:MoveNext()
	ENDDO
	oQuery:Close()	
		
RETURN aResult
para pegar os dados do RECORDSET

Código: Selecionar todos

	@ 4,70 BROWSE oBrowse1 ARRAY OF oDlg SIZE 1000,497 STYLE WS_BORDER + WS_VSCROLL +WS_HSCROLL ;
			ON SIZE ANCHOR_TOPABS + ANCHOR_LEFTABS + ANCHOR_RIGHTABS + ANCHOR_BOTTOMABS ;
			ON CLICK {|| oBrowse1_onClick( oDlg, oServer ) } ;
			ON KEYDOWN {|oBrowse1,nKeyPress| oBrowse1_onKeyDown( oBrowse1,nKeyPress, oDlg, oServer ) }

		oBrowse1:oStyleHead := HStyle():New( { 0xffffff, 0xbbbbbb }, 1,, 0.4, 16759929 )
		oBrowse1:oFont := HFont():Add( '',0,-15,700,,,)
		oBrowse1:freeze := 2
		oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_NRAZ_SOC LIMIT 500" )

		oBrowse1:AddColumn( HColumn():New( "CODIGO",hwg_ColumnArBlock(),"C",09,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_UCLIENTE" ), MEMVAR->cAlvo_Consulta:="CLIENTES_UCLIENTE",obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: CODIGO") } ,,,,))
		oBrowse1:AddColumn( HColumn():New( "NOME CLIENTE",hwg_ColumnArBlock(),"C",65,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_NRAZ_SOC" ), MEMVAR->cAlvo_Consulta:="CLIENTES_NRAZ_SOC", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: NOME CLIENTE") } ,,,,))
		oBrowse1:AddColumn( HColumn():New( "CPF/CNPJ",hwg_ColumnArBlock(),"C",18,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_CPFCGC"), MEMVAR->cAlvo_Consulta:="CLIENTES_CPFCGC", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: CPF/CNPJ") } ,,,,))
		oBrowse1:AddColumn( HColumn():New( "FONE", hwg_ColumnArBlock(),"C",18,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_FONE"), MEMVAR->cAlvo_Consulta:="CLIENTES_FONE", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: FONE") } ,,,,))
		oBrowse1:AddColumn( HColumn():New('E-Mail', hwg_ColumnArBlock() ,'C',60, 0 ,.F.,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New( "Insc.Estadual",hwg_ColumnArBlock(),"C",18,0,.F.,,, ) )
		oBrowse1:AddColumn( HColumn():New( "TC",hwg_ColumnArBlock(),"C",4,0,.F., ) )
		oBrowse1:AddColumn( HColumn():New( "Logradouro",hwg_ColumnArBlock(),"C",60,0,.F., ) )
		oBrowse1:AddColumn( HColumn():New( "Numero", hwg_ColumnArBlock(),'N',9,0,.F.,1,2, ) )
		oBrowse1:AddColumn( HColumn():New( "Complemento",hwg_ColumnArBlock(),"C",60,0,.F., ) )
		oBrowse1:AddColumn( HColumn():New('Bairro', hwg_ColumnArBlock() ,'C',60, 0 ,.F.,,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('CEP', hwg_ColumnArBlock() ,'C',12, 0 ,.F.,,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Cod.Pais', hwg_ColumnArBlock() ,'C',7, 0 ,.F.,,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Pais', hwg_ColumnArBlock() ,'C',50, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('UF', hwg_ColumnArBlock() ,'C',4, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Cod.Mun.', hwg_ColumnArBlock() ,'C',7, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Municipio', hwg_ColumnArBlock() ,'C',50, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Contato', hwg_ColumnArBlock() ,'C',50, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Operador/Computador DATA/HORA', hwg_ColumnArBlock() ,'C',60, 0 ,.F.,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('CLIENTES ID', hwg_ColumnArBlock() ,'N',14, 0 ,.F.,1,2,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_ID"), MEMVAR->cAlvo_Consulta:="CLIENTES_ID", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: CHAVE ID") } ,,,,))

		bColorBlock := {|| {0,16777215,, } }		
		FOR EACH oColuna IN oBrowse1:aColumns
			oColuna:bColorBlock := bColorBlock
		NEXT
e depois colocar no BROWSE

Browse pra ADO

Enviado: 14 Abr 2020 11:08
por Fernando queiroz
cjp escreveu:Pessoal, ainda estou engatinhando nesse browse com ado.

Fui tentar fazer uma restrição de campos para exibir, mas não funcionou.

Acresci esta parte:

Código: Selecionar todos

oTBrowse := { ;
   { "DATA", { || Pad( oRS:Fields( "DATA" ):Value, 10 ) } }, ;
   { "PRIORIDADE",  { || Pad( oRS:Fields( "PRIORIDADE" ):Value, 1 ) } }, ;
   { "NRTAREFA", { || Pad( oRS:Fields( "NRTAREFA" ):Value, 5 ) } }, ;
   { "TAREFA", { || Pad( oRS:Fields( "TAREFA" ):Value, 35 ) } }, ;
   }
Pensei que assim restringiria a exibição a estes campos, mas não funcionou.

Segue o código:

Código: Selecionar todos

function consado(sql)
         #include "tbrowse.ch"
		 local cSair :="N"
         LOCAL oTBrowse, nKey, oRs, oColumn, I, nLen
		 local vez :=0
         LOCAL oConexao := conectado(nProvTar)
		 
		 keysec(27,1000,-1,.t.)
		 
         oConexao:Open()
   
         do while .t.
                  oRS := oConexao:Execute( sql )
	  
             if oRS:Eof()
	            @ 22,25 say "Não há nenhum item   "
		        inkey(11)
	            return .f.
	         endif

oTBrowse := { ;
   { "DATA", { || Pad( oRS:Fields( "DATA" ):Value, 10 ) } }, ;
   { "PRIORIDADE",  { || Pad( oRS:Fields( "PRIORIDADE" ):Value, 1 ) } }, ;
   { "NRTAREFA", { || Pad( oRS:Fields( "NRTAREFA" ):Value, 5 ) } }, ;
   { "TAREFA", { || Pad( oRS:Fields( "TAREFA" ):Value, 35 ) } }, ;
   }

   
      cls
      oTBrowse := TBrowseDB():new( 05, 3, MaxRow() - 7, MaxCol() - 2 )

      oTBrowse:goTopBlock    := { || oRs:moveFirst() }
      oTBrowse:goBottomBlock := { || oRs:moveLast() }
      oTBrowse:skipBlock     := { | n | ADORecordSetSkipper( oRs, n ) }
      oTBrowse:HeadSep       := Chr(196)
      oTBrowse:ColSep        := Chr(179)
      oTBrowse:FootSep       := ""
	  
      nLen := oRs:fields():count() - 1
      FOR i := 0 TO nLen
         oColumn       := TBColumnNew( oRs:fields(i):name(), ADORecordSetFieldBlock( oRs, i ) )
		 IF ValType( oRs:Fields(i):Value ) == "D"
            nFieldLen := Len( Dtoc( Date() ) )
         ELSE
            nFieldLen := Min( oRs:Fields(I):DefinedSize, 50 )
         ENDIF
         oColumn:Width := Max( nFieldLen, Len( oRs:fields(i):name ) )
         oTBrowse:addColumn( oColumn )
      NEXT
	  
	  if procname(1)="CONSATIVSQL"
         @ 0,1 say "Arquivo em edição: "+alias()
         @ maxrow()-2,1 say "Tempo trabalhado: "+alltrim(str(tpt))+"; tempo computado: "+alltrim(str(tpc))+"; tecle Enter sobre nrtarefa para abrir a tarefa"
		 @ maxrow(),1 say "Alt-P-procura/filtra; Alt-M-mostra estrutura; F2-acresce registros; Alt-C-conta registros"
	  endif
	  
	  @ 5,5 say "Abrindo consulta..."
	  
   DO WHILE .T.
      oTBrowse:forceStable()
      oTBrowse:refreshCurrent()
      nKey := Inkey(0)
	  if nkey == 13 //K_ENTER
		 arq=oRs:Fields("nrtarefa"):Value
	     chmfunc("entersql",,"S")
		 if procname(1)="CONSEXPR" .or. procname(2)="CONSEXPR"
		    cSair="S"
		 endif
		 exit
	  elseif nkey == 27
	     cSair="S"
		 exit
	  endif
      IF oTBrowse:applyKey( nKey ) == TBR_EXIT
	     cSair="S"
         EXIT
      ENDIF
   ENDDO
   
   if cSair="S"
      exit
   endif
   enddo

   oRs:Close()
   oConexao:Close()
   if cSair="S" .or. procname(1)="CONSEXPR" .or. procname(2)="CONSEXPR"
      return .f.
   endif
return .t.

Alguém pode me ajudar?

Código: Selecionar todos

	cQuery := "SELECT CLIENTES_UCLIENTE, ";
				   + "CLIENTES_NRAZ_SOC, ";
				   + "CLIENTES_CPFCGC, ";
				   + "CLIENTES_FONE, ";
				   + "CLIENTES_EMAIL, ";
				   + "CLIENTES_INSEST, ";
				   + "CLIENTES_ISENTO, ";
				   + "CLIENTES_ENDER, ";
				   + "CLIENTES_NUMERO, ";
				   + "CLIENTES_COMPLEM, ";
				   + "CLIENTES_BAIR, ";
				   + "CLIENTES_CEP, ";
				   + "CLIENTES_CODPAIS, ";
				   + "CLIENTES_PAIS, ";
				   + "CLIENTES_UF, ";
				   + "CLIENTES_CODMUN, ";
				   + "CLIENTES_CIDADE, ";
				   + "CLIENTES_CONTATO, ";
				   + "CLIENTES_QUEM_BLOQ, ";
				   + "CLIENTES_ID ";
				   + "from CLIENTES ";
				   + cAlvo_Consulta 

	oQuery := oServer:Execute(cQuery)

	DO WHILE ! oQuery:Eof()
		aAdd( aResult, {oQuery:Fields( "CLIENTES_UCLIENTE" ):Value,;
						oQuery:Fields( "CLIENTES_NRAZ_SOC" ):Value,;
						oQuery:Fields( "CLIENTES_CPFCGC" ):Value,;
						oQuery:Fields( "CLIENTES_FONE" ):Value,;
						oQuery:Fields( "CLIENTES_EMAIL" ):Value,;
						oQuery:Fields( "CLIENTES_INSEST" ):Value,;
						oQuery:Fields( "CLIENTES_ISENTO" ):Value,;
						oQuery:Fields( "CLIENTES_ENDER" ):Value,;
						oQuery:Fields( "CLIENTES_NUMERO" ):Value,;
						oQuery:Fields( "CLIENTES_COMPLEM" ):Value,;
						oQuery:Fields( "CLIENTES_BAIR" ):Value,;
						oQuery:Fields( "CLIENTES_CEP" ):Value,;
						oQuery:Fields( "CLIENTES_CODPAIS" ):Value,;
						oQuery:Fields( "CLIENTES_PAIS" ):Value,;
						oQuery:Fields( "CLIENTES_UF" ):Value,;
						oQuery:Fields( "CLIENTES_CODMUN" ):Value,;
						oQuery:Fields( "CLIENTES_CIDADE" ):Value,;
						oQuery:Fields( "CLIENTES_CONTATO" ):Value,;
						oQuery:Fields( "CLIENTES_QUEM_BLOQ" ):Value,;
						oQuery:Fields( "CLIENTES_ID" ):Value} ) 

		oQuery:MoveNext()
	ENDDO
	oQuery:Close()	
Voce tem de carregar um ARRAY com os dados retornados do RECORDSET , e pelo que vi nesta parte voce so carregou 1 LINHA

oTBrowse := { ;
{ "DATA", { || Pad( oRS:Fields( "DATA" ):Value, 10 ) } }, ;
{ "PRIORIDADE", { || Pad( oRS:Fields( "PRIORIDADE" ):Value, 1 ) } }, ;
{ "NRTAREFA", { || Pad( oRS:Fields( "NRTAREFA" ):Value, 5 ) } }, ;
{ "TAREFA", { || Pad( oRS:Fields( "TAREFA" ):Value, 35 ) } }, ;
}

E no BROWSE fazer assim

Código: Selecionar todos

	@ 4,70 BROWSE oBrowse1 ARRAY OF oDlg SIZE 1000,497 STYLE WS_BORDER + WS_VSCROLL +WS_HSCROLL ;
			ON SIZE ANCHOR_TOPABS + ANCHOR_LEFTABS + ANCHOR_RIGHTABS + ANCHOR_BOTTOMABS ;
			ON CLICK {|| oBrowse1_onClick( oDlg, oServer ) } ;
			ON KEYDOWN {|oBrowse1,nKeyPress| oBrowse1_onKeyDown( oBrowse1,nKeyPress, oDlg, oServer ) }

		oBrowse1:oStyleHead := HStyle():New( { 0xffffff, 0xbbbbbb }, 1,, 0.4, 16759929 )
		oBrowse1:oFont := HFont():Add( '',0,-15,700,,,)
		oBrowse1:freeze := 2
		oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_NRAZ_SOC LIMIT 500" )

		oBrowse1:AddColumn( HColumn():New( "CODIGO",hwg_ColumnArBlock(),"C",09,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_UCLIENTE" ), MEMVAR->cAlvo_Consulta:="CLIENTES_UCLIENTE",obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: CODIGO") } ,,,,))
		oBrowse1:AddColumn( HColumn():New( "NOME CLIENTE",hwg_ColumnArBlock(),"C",65,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_NRAZ_SOC" ), MEMVAR->cAlvo_Consulta:="CLIENTES_NRAZ_SOC", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: NOME CLIENTE") } ,,,,))
		oBrowse1:AddColumn( HColumn():New( "CPF/CNPJ",hwg_ColumnArBlock(),"C",18,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_CPFCGC"), MEMVAR->cAlvo_Consulta:="CLIENTES_CPFCGC", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: CPF/CNPJ") } ,,,,))
		oBrowse1:AddColumn( HColumn():New( "FONE", hwg_ColumnArBlock(),"C",18,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_FONE"), MEMVAR->cAlvo_Consulta:="CLIENTES_FONE", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: FONE") } ,,,,))
		oBrowse1:AddColumn( HColumn():New('E-Mail', hwg_ColumnArBlock() ,'C',60, 0 ,.F.,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New( "Insc.Estadual",hwg_ColumnArBlock(),"C",18,0,.F.,,, ) )
		oBrowse1:AddColumn( HColumn():New( "TC",hwg_ColumnArBlock(),"C",4,0,.F., ) )
		oBrowse1:AddColumn( HColumn():New( "Logradouro",hwg_ColumnArBlock(),"C",60,0,.F., ) )
		oBrowse1:AddColumn( HColumn():New( "Numero", hwg_ColumnArBlock(),'N',9,0,.F.,1,2, ) )
		oBrowse1:AddColumn( HColumn():New( "Complemento",hwg_ColumnArBlock(),"C",60,0,.F., ) )
		oBrowse1:AddColumn( HColumn():New('Bairro', hwg_ColumnArBlock() ,'C',60, 0 ,.F.,,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('CEP', hwg_ColumnArBlock() ,'C',12, 0 ,.F.,,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Cod.Pais', hwg_ColumnArBlock() ,'C',7, 0 ,.F.,,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Pais', hwg_ColumnArBlock() ,'C',50, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('UF', hwg_ColumnArBlock() ,'C',4, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Cod.Mun.', hwg_ColumnArBlock() ,'C',7, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Municipio', hwg_ColumnArBlock() ,'C',50, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Contato', hwg_ColumnArBlock() ,'C',50, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Operador/Computador DATA/HORA', hwg_ColumnArBlock() ,'C',60, 0 ,.F.,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('CLIENTES ID', hwg_ColumnArBlock() ,'N',14, 0 ,.F.,1,2,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_ID"), MEMVAR->cAlvo_Consulta:="CLIENTES_ID", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: CHAVE ID") } ,,,,))

Browse pra ADO

Enviado: 14 Abr 2020 11:22
por Fernando queiroz
Resumindo a Ação :
Selecione todos os campos que você vai precisar do banco de dados, mesmo os que não precisam aparecer no Browse , mas que serão usados

Código: Selecionar todos

"SELECT CLIENTES_UCLIENTE, ";
				   + "CLIENTES_NRAZ_SOC, ";
				   + "CLIENTES_CPFCGC, ";
				   + "CLIENTES_FONE, ";
				   + "CLIENTES_EMAIL, ";
				   + "CLIENTES_INSEST, ";
				   + "CLIENTES_ISENTO, ";
				   + "CLIENTES_ENDER, ";
				   + "CLIENTES_NUMERO, ";
				   + "CLIENTES_COMPLEM, ";
				   + "CLIENTES_BAIR, ";
				   + "CLIENTES_CEP, ";
				   + "CLIENTES_CODPAIS, ";
				   + "CLIENTES_PAIS, ";
				   + "CLIENTES_UF, ";
				   + "CLIENTES_CODMUN, ";
				   + "CLIENTES_CIDADE, ";
				   + "CLIENTES_CONTATO, ";
				   + "CLIENTES_QUEM_BLOQ, ";
				   + "CLIENTES_ID ";
				   + "from CLIENTES ";
depois carregue um ARRAY com os dados do RECORDSET na sequencia em que devem aparecer no BROWSE, deixando os campos que nao vao aparecer para o final

Código: Selecionar todos

	DO WHILE ! oQuery:Eof()
		aAdd( aResult, {oQuery:Fields( "CLIENTES_UCLIENTE" ):Value,;
						oQuery:Fields( "CLIENTES_NRAZ_SOC" ):Value,;
						oQuery:Fields( "CLIENTES_CPFCGC" ):Value,;
						oQuery:Fields( "CLIENTES_FONE" ):Value,;
						oQuery:Fields( "CLIENTES_EMAIL" ):Value,;
						oQuery:Fields( "CLIENTES_INSEST" ):Value,;
						oQuery:Fields( "CLIENTES_ISENTO" ):Value,;
						oQuery:Fields( "CLIENTES_ENDER" ):Value,;
						oQuery:Fields( "CLIENTES_NUMERO" ):Value,;
						oQuery:Fields( "CLIENTES_COMPLEM" ):Value,;
						oQuery:Fields( "CLIENTES_BAIR" ):Value,;
						oQuery:Fields( "CLIENTES_CEP" ):Value,;
						oQuery:Fields( "CLIENTES_CODPAIS" ):Value,;
						oQuery:Fields( "CLIENTES_PAIS" ):Value,;
						oQuery:Fields( "CLIENTES_UF" ):Value,;
						oQuery:Fields( "CLIENTES_CODMUN" ):Value,;
						oQuery:Fields( "CLIENTES_CIDADE" ):Value,;
						oQuery:Fields( "CLIENTES_CONTATO" ):Value,;
						oQuery:Fields( "CLIENTES_QUEM_BLOQ" ):Value,;
						oQuery:Fields( "CLIENTES_ID" ):Value} ) 

		oQuery:MoveNext()
	ENDDO
depois mostre no BROWSE somente o que é para ser visto
use a função hwg_ColumnArBlock() para pegar os dados do ARRAY na sequencia

Código: Selecionar todos

		oBrowse1:AddColumn( HColumn():New( "CODIGO",hwg_ColumnArBlock(),"C",09,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_UCLIENTE" ), MEMVAR->cAlvo_Consulta:="CLIENTES_UCLIENTE",obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: CODIGO") } ,,,,))
		oBrowse1:AddColumn( HColumn():New( "NOME CLIENTE",hwg_ColumnArBlock(),"C",65,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_NRAZ_SOC" ), MEMVAR->cAlvo_Consulta:="CLIENTES_NRAZ_SOC", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: NOME CLIENTE") } ,,,,))
		oBrowse1:AddColumn( HColumn():New( "CPF/CNPJ",hwg_ColumnArBlock(),"C",18,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_CPFCGC"), MEMVAR->cAlvo_Consulta:="CLIENTES_CPFCGC", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: CPF/CNPJ") } ,,,,))
		oBrowse1:AddColumn( HColumn():New( "FONE", hwg_ColumnArBlock(),"C",18,0,.F.,,,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_FONE"), MEMVAR->cAlvo_Consulta:="CLIENTES_FONE", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: FONE") } ,,,,))
		oBrowse1:AddColumn( HColumn():New('E-Mail', hwg_ColumnArBlock() ,'C',60, 0 ,.F.,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New( "Insc.Estadual",hwg_ColumnArBlock(),"C",18,0,.F.,,, ) )
		oBrowse1:AddColumn( HColumn():New( "TC",hwg_ColumnArBlock(),"C",4,0,.F., ) )
		oBrowse1:AddColumn( HColumn():New( "Logradouro",hwg_ColumnArBlock(),"C",60,0,.F., ) )
		oBrowse1:AddColumn( HColumn():New( "Numero", hwg_ColumnArBlock(),'N',9,0,.F.,1,2, ) )
		oBrowse1:AddColumn( HColumn():New( "Complemento",hwg_ColumnArBlock(),"C",60,0,.F., ) )
		oBrowse1:AddColumn( HColumn():New('Bairro', hwg_ColumnArBlock() ,'C',60, 0 ,.F.,,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('CEP', hwg_ColumnArBlock() ,'C',12, 0 ,.F.,,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Cod.Pais', hwg_ColumnArBlock() ,'C',7, 0 ,.F.,,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Pais', hwg_ColumnArBlock() ,'C',50, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('UF', hwg_ColumnArBlock() ,'C',4, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Cod.Mun.', hwg_ColumnArBlock() ,'C',7, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Municipio', hwg_ColumnArBlock() ,'C',50, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Contato', hwg_ColumnArBlock() ,'C',50, 0 ,.F.,,,,,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('Operador/Computador DATA/HORA', hwg_ColumnArBlock() ,'C',60, 0 ,.F.,,,,,,,,))
		oBrowse1:AddColumn( HColumn():New('CLIENTES ID', hwg_ColumnArBlock() ,'N',14, 0 ,.F.,1,2,,,,,,;
					{|| oBrowse1:aArray := CARREGA_CLIENTES( oServer, "ORDER BY CLIENTES_ID"), MEMVAR->cAlvo_Consulta:="CLIENTES_ID", obrowse1:Refresh(), hwg_WriteStatus( oDlg,3,"Ordem: CHAVE ID") } ,,,,))
se precisar de dados que estao no ARRAY mas nao estao aparecendo no BROWSE e so usar

oDlg:oBrowse1:aArray[ oDlg:oBrowse1:nCurrent, 20]

Neste caso estou pegando o campo CLIENTES_ID que esta na coluna 20, assim voce usa qualquer campo do array

Browse pra ADO

Enviado: 14 Abr 2020 12:24
por JoséQuintas
No meu caso, TODO registro tem um ID.
Pego os campos para o browse, somente eles, incluindo o ID.
Ao selecionar no browse, repasso o ID pra janela/função e pronto.
Se precisar, faço outro comando SQL pra puxar os detalhes.

Browse pra ADO

Enviado: 14 Abr 2020 12:45
por Fernando queiroz
JoséQuintas escreveu:No meu caso, TODO registro tem um ID.
Pego os campos para o browse, somente eles, incluindo o ID.
Ao selecionar no browse, repasso o ID pra janela/função e pronto.
Se precisar, faço outro comando SQL pra puxar os detalhes.
Sim, pode fazer dessa forma, mas no browse eu também tenho condições com dados que não aparecem no browse tipo:

Código: Selecionar todos

	bColorBlock:={|| IIF(EMPTY(oDlg1:oBrowse1:aArray[ oDlg1:oBrowse1:nCurrent, 8]),{255, 16777215 ,16777215,255 },{0,16777215,, }) }
	FOR EACH oColuna IN oBrowse1:aColumns
		oColuna:bColorBlock := bColorBlock
	NEXT
como o dado já esta no ARRAY eu não preciso ficar dando SELECT sem necessidade, mais rápido e com menor trafego de dados na rede

Browse pra ADO

Enviado: 14 Abr 2020 20:43
por Itamar M. Lins Jr.
Ola!
Ainda penso que vc não entenderam o poder do SQLMIX.
Usando SQLMIX, o acesso é nativo, não precisa ADO, ODBC... Isso é opcional.

Código: Selecionar todos

 DO WHILE ! oQuery:Eof()
      aAdd( aResult, {oQuery:Fields( "CLIENTES_UCLIENTE" ):Value,;
                  oQuery:Fields( "CLIENTES_NRAZ_SOC" ):Value,;
                  oQuery:Fields( "CLIENTES_CPFCGC" ):Value,;
                  oQuery:Fields( "CLIENTES_FONE" ):Value,;
                  oQuery:Fields( "CLIENTES_EMAIL" ):Value,;
                  oQuery:Fields( "CLIENTES_INSEST" ):Value,;
                  oQuery:Fields( "CLIENTES_ISENTO" ):Value,;
                  oQuery:Fields( "CLIENTES_ENDER" ):Value,;
                  oQuery:Fields( "CLIENTES_NUMERO" ):Value,;
                  oQuery:Fields( "CLIENTES_COMPLEM" ):Value,;
                  oQuery:Fields( "CLIENTES_BAIR" ):Value,;
                  oQuery:Fields( "CLIENTES_CEP" ):Value,;
                  oQuery:Fields( "CLIENTES_CODPAIS" ):Value,;
                  oQuery:Fields( "CLIENTES_PAIS" ):Value,;
                  oQuery:Fields( "CLIENTES_UF" ):Value,;
                  oQuery:Fields( "CLIENTES_CODMUN" ):Value,;
                  oQuery:Fields( "CLIENTES_CIDADE" ):Value,;
                  oQuery:Fields( "CLIENTES_CONTATO" ):Value,;
                  oQuery:Fields( "CLIENTES_QUEM_BLOQ" ):Value,;
                  oQuery:Fields( "CLIENTES_ID" ):Value} ) 

      oQuery:MoveNext()
   ENDDO
Isso ai em cima é totalmente desnecessário.
Já houve a demora de chegar pela rede os 1000x registros e ainda vou ter que dar um "DO WHILE .NOT. EOF()" nesses 1000x registros.
Isso não precisa usando SQLMIX. Já está em um ARRAY e o ARRAY é UM DBF ná memória.
Por favor leiam, estudem os códigos do RDD_DBFARRAY que o Przmek criou já faz tempo isso.
Que depois o Midaugas usou para criar o SQLMIX.
Functiona com MYSQL, MariaDb, MDB, Postgree, Oracle...
Já usei para vários SGBD aqui, mas apenas para importar só li as bases de dados, inclusive MSSQL.

Saudações,
Itamar M. Lins Jr.

Browse pra ADO

Enviado: 15 Abr 2020 11:56
por MSDN
Pra que pensar pequeno se pensar grande dá o mesmo trabalho ?
https://becode.com.br/o-que-e-api-rest-e-restful/
Se vc usar um carro ou ônibus ou trem, não é para todo lugar que dá pra ir usando somente esses tipos de transporte.
Se vc usar um navio, teoricamente consegue andar o mundo todo, mas não chega em certos lugares.
Mas se usar um avião e um helicóptero, chega em qualquer lugar !