Página 5 de 6

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 07 Jan 2015 21:30
por rochinha
Amiguinhos,

Hasse, volte ao inicio da discussão e veja minha quinta postagem onde apresento um código de exemplo( CUSTOMER.PRG ).

Para manipular campos usando ADOxB voce deve usar a função ADOField():

Código: Selecionar todos

...
?  ADOField( "NomeDoCampo" ), ...
...

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 08 Jan 2015 17:27
por Hasse
Boa tarde Rochinha.
Creia-me, antes de colocar a minha postagem anterior, fiz tantos testes com os co0mandos ADO que já nem sei mais quantos,
e sempre tem algum detalhe que não funciona.
Abaixo segue a parte inicial do código. Vejamos:

Código: Selecionar todos

**
#include "adoXb.ch"
#include "AdoXb.prg"
*
#Include 'Inkey.ch'
#Include 'i_keybd.ch'
#include "MiniGUI.ch"
#include "ado.ch"
#include "set.ch"
#include "common.ch"
#include "directry.ch"
#include "fileio.ch"
#include "hbcompat.ch"
#include "hbwin.ch"
*
*STATIC oWnd, oClients, oClient, oName
*STATIC cName
*STATIC oSplit
*
REQUEST HB_GT_WIN_DEFAULT                                                 && Janela DOS - Temporário para testes.
*
*
*==================================================================================================
FUNCTION Main()
   *
   LOCAL oError       := ErrorBlock( { | oError | MyErrorFunc( oError ) } )
   *
   REQUEST HB_LANG_PT
   REQUEST HB_CODEPAGE_PT850
   HB_LANGSELECT("PT")
   HB_CDPSELECT( "PT850" ) //pt850
   *
   SET DATE TO BRIT
   SET CENTURY ON
   *
   Clear
   *
   PUBLIC StrDatabas := "C:\Teste\Small_ajustado.gdb"
   PUBLIC StrConnect := "DRIVER=Firebird/InterBase(r) driver; UID=sysdba; PWD=masterkey; DBNAME="+StrDatabas
   *
   // Necessária para criar objetos e variaveis visíveis o tempo todo
   ADOSetRDD( "ACCESS" )
   *
   ADOSetRDD( "FIREBIRD" )                // ADOGDB
   ADORDDDefault( "FIREBIRD" )            // ADOGDB
   cADORDD := "FIREBIRD"
   *
   SET_CORES()
   *
   Clear
   *
   ADO CONNECT StrConnect
   *
   ? "Is ADOConnected:>   "
   ?? ADOConnected()
   *
   ADO USE CliFor
   ? "ADOAreas:=>", Str( ADOAreas(), 04 ), "=           ADOAlias:=>", ADOAlias()
   
   WAIT
/*
Resposta do print acima:
Is ADOConnected:>   .T.
ADOAreas:=>    1 =           ADOAlias:=> CliFor
Press any key to continue...
*/
Então o sistema está conectado ao GDB e a tabela CLIFOR aberta. Esta tabela tem mais de 50 campos, mas para efeito de testes
vamos acessar somente as 3 primeiras colunas (com LEFT para caber na tela).
Como já relatado anteriormente,o ADOEof() não funciona. Entra em loop infinito quando chega no último registro.
WHILE ! ADOEof()
? Alltrim( Str( ADORecno() ) ),Left( ADOFIELD("NOME"), 20 ), Left( ADOFIELD( "CIDADE" ), 15 ), ADOFIELD( "CGC" )
ADOSkip()
ENDDO
Desativei essa rotina acima e estou usando a seguinte, que é uma gambiarra mas que, para os propósitos atuais funciona bem.

Código: Selecionar todos

WHILE .T.
   ? Alltrim( Str( ADORecno() ) ),Left( ADOFIELD("NOME"), 20 ), Left( ADOFIELD( "CIDADE" ), 15 ), ADOFIELD( "CGC" )
   IF ADORecno() = ADORecCount()
      EXIT
   ENDIF
  ADOSKIP()
ENDDO
RETURN( NIL )
Usando esta rotina de listagem acima, irei anexar alguma funções descritas no ADOxb.prg e relatar as dificuldades que encontrei.

Código: Selecionar todos

   ADOLocate( 'NOME = "Maria"' )
   ?  ADOFound(), "-", ADORecno(), "-", ADOField( 'NOME' ), ADOField( "CGC" )
   ADOLocate( 'NOME = "Maria*"' )
   ?  ADOFound(), "-", ADORecno(), "-", ADOField( 'NOME' ), ADOField( "CGC" )
   ADOFind( "NOME = 'Maria'" )
   ?  ADOFound(), "-", ADORecno(), "-", ADOField( 'NOME' ), ADOField( "CGC" )
   ADOFind( "NOME = 'Maria*'" )
   ?  ADOFound(), "-", ADORecno(), "-", ADOField( 'NOME' ), ADOField( "CGC" )
   ADOFind( "NOME like 'Adriane Maria'" )
   ?  ADOFound(), "-", ADORecno(), "-", ADOField( 'NOME' ), ADOField( "CGC" )
   wait
   WHILE .T.
      ? Alltrim( Str( ADORecno() ) ),Left( ADOFIELD("NOME"), 20 ), Left( ADOFIELD( "CIDADE" ), 15 ), ADOFIELD( "CGC" )
      IF ADORecno() = ADORecCount()
         EXIT
      ENDIF
      ADOSKIP()
      IF ADORecno() = 10
         WAIT
      ENDIF
   ENDDO
Veja o print gerado até no WAIT da linha 11:
.T. - 1 - Adalzira Muller Hefter 969.985.049-34
.T. - 1 - Adalzira Muller Hefter 969.985.049-34
.T. - 1 - Adalzira Muller Hefter 969.985.049-34
.T. - 1 - Adalzira Muller Hefter 969.985.049-34
.T. - 1 - Adalzira Muller Hefter 969.985.049-34
Press any key to continue...
Em todos os casos o ADOFound() informa que encontrou o alvo, pois tem mais de 20 Maria cadastradas, mas o apontador não foi deslocado para lá, e desta forma sempre o primeiro registro da tabela é apresentado.

O loop de listagem seguinte inicia no primeiro registro também.

Tenho mais uma dezena de dificuldades, mas acredito que uma vez solucionados e apontados os meus erros, os demais também serão corrigidos.

Me perdoe o tamanho desta mensagem, mas foi a única maneira de apresentar o problema todo. Caso haja necessidade posso enviar o arquivo GDB.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 22 Ago 2015 10:25
por Hasse
Bom dia Rochinha.

Mais uma vez necessito dos teus conhecimentos e gentileza.

Numa conexão com o ACCESS, via ADO, tenho como retorno um objeto tipo "oRecordSet".

Há alguma forma de conectar este objeto ao BROWSE ou GRID diretamente ?

Testei fazer o trabalho em 2 passos e funcionou, ou seja, ler o BD do ACCESS, arquivar os dados em ARRAY e em seguida conectar ao GRID, mas esta solução não satisfaz aos meus propósitos, já que não haverá atualização automática dos dados.

Caso esta conexão não seja possível, você tem alguma sugestão de uso de outra opção ?

Li no Fórum, que colegas elogiam muito o SQLMIX. Ele permite esta conexão direta ?

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 22 Ago 2015 11:32
por JoséQuintas
Num resumo:
A vantagem do SQL é trazer tudo pronto, menos consultas ao servidor/banco de dados.
O que está querendo é consultar o tempo todo, justamente o contrário do SQL.

É como querer um carro pra andar a pé, fica complicado até sugerir alguma coisa.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 22 Ago 2015 12:14
por rochinha
Amiguinhos,

Hasse, diferentemente do DBF que atua de forma mais automatica você deverá criar esta automatização.

Os recordsets são snapshots, fotografias de um trecho do banco de dados parecido com nossos dbfs temporários, mas no caso de um DBF temporário o que acontece no principal não aparece nele até que seja recriado, ou seja, limpa e appendado os dados refeitos.

Já os recordsets possuem esta característica idêntica, mas o motor se encarrega disto, mas o usuário precisa disparar a ação, através de comandos REQUERY.

Os recordsets trabalham de dois modos de atualização, sendo imediata ou por lote, resta estudar sobre o assunto.

Portanto esta ação de REQUERY precisa ser automatizada em sua aplicação..

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 23 Ago 2015 09:51
por Hasse
Bom dia Quintas e Rochinha.

Humm !!!! Alguns conhecimentos a mais.... Obrigado.

Realmente deu para entender. Terei que decidir se continuo com a ideia de implementar um BROWSE ou GRID.

No caso do REQUERY, como se automatiza este procedimento ?
Quais os passos e procedimentos ?
A Tabela disponibiliza uma flag que indicaria ao meu BROWSE ou GRID que os dados precisam ser atualizados ?

Caso este procedimento NÃO se mostre razoavelmente exequível, prático e confiável, terei que abandonar a ideia de BROWSE ou GRID.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 24 Ago 2015 08:40
por rochinha
Amiguinhos,

Hasse, o método REQUERY faz parte da classe RECORDSET, portanto se você criou um recordset de nome oRecordset bastará comandar oRecordset:Requery()

Você pode acrescentar uma ação ou botão para acionar este recurso ou colocár uma chamada após algum comando como Append ou Update.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 24 Ago 2015 09:12
por Hasse
Ok. Muito bom mesmo.

Assim bem fácil implementar a atualização.

Obrigado.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 24 Ago 2015 14:51
por JoséQuintas
Tem que lembrar o seguinte também:
O usuário consulta na tela... fica lá parado.
Se outro alterar, a tela não é atualizada automaticamente, nem mesmo se usar DBF.

Em que momento atualizar o browse/grid?
Talvez tenha atualização de tela que acostumamos com DBF, e só por isso queremos igual.
Se pensar direito, é até normal que o usuário tenha que refazer a pesquisa.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 24 Ago 2015 16:44
por Hasse
Valeu a lembrança Quintas.
Este teu procedimento é que faz com que este Fórum seja tão bom.
Nota-se que há pessoas que procuram dar do seu melhor. E isto é impagável.

Na realidade estou bem familiarizado com este detalhe. Eu uso o TBrowse() (ainda em modo console) e programei um refresh dos dados a cada 5 segundos.

Também estou ciente que, quando um determinado terminal abre uma tela de edição de dados e quando há alguma alteração na base de dados ela não será atualizada na tela de edição, mesmo que o TBrowse() já tenha se atualizado.

A grande maioria das telas de edição no universo dos meus clientes, quando há alguma edição, ela é feita a partir de um determinado terminal, justamente para evitar problemas.

Entretanto, há DUAS telas de edição críticas. Nestas, assim que a tela de edição é aberta, eu bloqueio o registro e assim evita-se que haja alguma alteração que fuja do controle. Esta tela de edição, caso ela fique inativa por 15 segundo será fechada automaticamente, e assim liberando o bloqueio do registro.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 17 Out 2015 13:54
por rochinha
Amiguinhos,

Em resumo o computador somente computa, o usuario somente usa, ou seja, os dois so fazem o que o programador estipulou. Ao automatizar damos vida propria ao computador liberando a produtividade do usuario.

Hasse,
1-Voce esta usando ADO em producao(interrogacao)
2-Voce se baseou no ADOxB(interrogacao)

No caso uma tela, com um browse principal e outro browse(ex: clientes(principal) e venda(sub-browse)) como voce esta vinculando os registros do sub-browse com o browse, tipo o que fazemos com set filter, set relation ou set scope(interrogacao)

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 17 Out 2015 14:58
por Hasse
Boa tarde caro Rochinha.

Na realidade a minha aplicação não tão complicada assim.

Uso relacionamento de dados, mas é somente para a obtenção de dados de 2 tabelas diferentes, mas que não são enviadas para o TBrowse().

Uso algo semelhante conforme a figura Anexa, onde a coluna bem à direita, dentro de um retângulo vertical, lista os códigos dos exames requisitados para o paciente, neste caso, ROLAND KLUG. Os dados da Requisição do ROLAND KLUG estão num TBROWSE. O arquivo das Requisições estão relacionadas (SET RELATION) com o arquivo de Exames, mas a impressão dos respectivos códigos na tela é feito por um FOR/NEXT, já que ali não há edição. O resultado é muito rápido. A construção da tela é tão rápida que não se percebe. Este aplicativo está rodando em monitor. Neste caso não posso usar o SET FILTER porque a base de dados é muito grande. O arquivo de Requisições tem em torno de 960.000 registros, e o de Exames tem ao redor de 6.000.000 de registros (são 6 minhões mesmo !!!).

Em relação ao ADO. Uso o ADOxB para abrir e ler um Banco Oracle e inserir os dados lidos no arquivo de Requisições e Exames, sem qualquer edição manual. Este aplicativo roda em modo gráfico, mas é uma telazinha muito pequena, de 3 linhas e umas 25/30 colunas. A edição, caso haja necessidade é feita no TBrowse() de Requisições.

Espero que a minha explanação tenha sido clara suficiente.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 17 Out 2015 18:24
por rochinha
Amiguinhos,

Hasse,
Espero que a minha explanação tenha sido clara suficiente.
Com certeza foi sim. Obrigado.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 09 Jun 2016 12:46
por Kapiaba
Bom dia Rochinha, links estão quebrados, preciso do Firbird para ODBC, para abrir um banco do Firebird. .GBD.

Obg. abs.

*** ADOxb - BIblioteca de funções de Acesso SQL ***

Enviado: 09 Jun 2016 20:30
por Hasse
Este link funciona. Acabei de testar.

Você precisa do ODBC para Firebird. Há 2 versões: para 32 e para 64 bit.

http://www.firebirdsql.org/en/odbc-driver/

Se você tiver dificuldades com a configuração do ODBC, eu tenho um passo-a-passo para ODBC for Oracle. Claro que deve haver algumas diferenças, mas por analogia creio que você poderá ter sucesso.