Página 1 de 1

Conexão Tabela Access x Browse()

Enviado: 15 Ago 2015 17:07
por Hasse
Boa tarde colegas.

Estou desenvolvendo um aplicativo para ler um Banco Access chamado "DP5.mdb", Tabela "T_Pacientes", Campos "NOME" e "R_ENDERECO".
Banco conectado.
Tabela aberta, devidamente testada na Procedure OpenTable. Isto verifiquei pelo código das linhas 110 a 115.
Mas os dados não aparecem no Browse(). Nas linhas 61 a 64 mostra as minhas várias tentativas e nenhuma deu certo.

Onde está o meu Erro ?

Código: Selecionar todos

*
#include "AdoXb.prg"
*
#include "MiniGUI.ch"
#include "ado.ch"
#include "set.ch"
*
REQUEST HB_GT_WIN_DEFAULT                                                  && Janela DOS - Temporário para testes.
*
*
*==================================================================================================
FUNCTION Main()
   *
   LOCAL oError      := ErrorBlock( { | oError | MyErrorFunc( oError ) } )
   LOCAL nWinWidth   := getdesktopwidth() * 0.8
   LOCAL nWinHeight  := getdesktopheight() * 0.8
   PUBLIC nBrwWidth  := nWinWidth-30
   PUBLIC nBrwHeight := nWinHeight-60
   PUBLIC caminho    := ""
   PUBLIC network    := .T.
   *
   PUBLIC StrDatabas := cCliniPath + "DP5.MDB"
   PUBLIC StrConnect := "Provider=Microsoft.ACE.OLEDB.12.0;Password='';Data Source=&StrDatabas;Persist Security Info=True"
   *
   PUBLIC oConexao, oRecSet, oBrw
   *
   REQUEST HB_LANG_PT
   REQUEST HB_CODEPAGE_PT850
   HB_LANGSELECT("PT")
   HB_CDPSELECT( "PT850" )
   *
   SET DATE TO BRIT
   SET CENTURY ON
   *
   SET DATE BRITISH
   SET CENTURY ON
   SET DELETE ON
///   SET AUTOADJUST ON                            //NOBUTTONS
   SET BROWSESYNC ON
   SET NAVIGATION EXTENDED
///   SET AUTOZOOMING ON
   *
*==================================================================================================
   DEFINE WINDOW Form_1 ; 
      AT 0,0 ; 
      WIDTH nWinWidth HEIGHT nWinHeight ; 
      TITLE 'PACIENTES' + str(nWinWidth) + STR(nWinHeight) ; 
      MAIN NOMAXIMIZE ; 
      ON INIT OpenTable() ; 
      ON RELEASE CloseTable() 
      *
      @ 10,10 BROWSE T_Pacientes ;
      WIDTH nBrwWidth   ;
      HEIGHT nBrwHeight  ;
      HEADERS { 'Nome' , 'Endere‡o' } ;
      WIDTHS { 300 , 300 } ;
      WORKAREA T_Pacientes ;
      FIELDS { 'NOME', 'R_ENDERECO' }

/*======== Testei as linhas abaixo, uma por uma, e o aplicativo aborta, sem mensagem. =======
      FIELDS { ('NOME'):value , ('R_ENDERECO'):value }
      FIELDS { 'T_Pacientes->NOME', 'T_Pacientes->R_ENDERECO' }
      FIELDS { oRecSet:Fiels('NOME'):value , oRecSet:Fiels('R_ENDERECO'):value }
      FIELDS { oConexao:Fiels('NOME'):value , oConexao:Fiels('R_ENDERECO'):value }
*/
      *
   END WINDOW
   *
   CENTER WINDOW Form_1
   *
   Form_1.T_Pacientes.SetFocus
   *
   ACTIVATE WINDOW Form_1
   *
RETURN( NIL )
*
*
*==================================================================================================
Procedure OpenTable 
   *
   IF ! FILE( 'DP5.mdb' )
      MsgStop( "Arquivo DP5 ausente ou inacess¡vel", "Erro", )
   ENDIF
   *
   PUBLIC StrDatabas := cCliniPath + "DP5.MDB"
   PUBLIC StrConnect := "Provider=Microsoft.ACE.OLEDB.12.0;Password='';Data Source=&StrDatabas;Persist Security Info=True"
   *
   PUBLIC oRecSet     := TOLEAUTO():New( "ADODB.RecordSet" )
   PUBLIC oGravarData := TOLEAUTO():New( "ADODB.Command" )
   PUBLIC oConexao    := TOleAuto():new( "ADODB.connection" )
   *
   oConexao:ConnectionString := StrConnect
   oConexao:Open()
   *
   c_SeleStr  := "SELECT  " +;
      'NOME, R_ENDERECO  ' +;
      'from T_Pacientes ' +;
      'order by NOME '
   *
   WITH Object oRecSet
       *
      :CursorLocation   := adUseClient
      :CursorType       := adOpenDynamic
      :LockType         := adLockOptimistic
      :ActiveConnection := oConexao
      :Source           := c_SeleStr
      :Open()
      *
/*=============================== Este trecho abaixo mostra todos os registros tabela T_Pacientes.
      WHILE .NOT. :Eof()
         ? :Fields( "NOME" ):Value
         ?? " | "
         ?? :Fields( "R_ENDERECO" ):Value
         :MoveNext()
      ENDDO
*/
      *
   END WITH
   *
Return 
*
*
*==================================================================================================
PROCEDURE CloseTable 
   *
   USE 
   *
RETURN( NIL )

Conexão Tabela Access x Browse()

Enviado: 15 Ago 2015 17:09
por Hasse
Observei que há exemplos usando o TBrowse() e TSBrowse().
Porque não consigo compilar TBrowse e TSBrowse. Qual ou quais as LIB necessárias ?

Usando a MiniGui, quais as vantagens de cada uma ?

E a tal GRID, que nunca usei. Desde o tempo do Clipper, sempre usei o Browse, então preciso das instruções dos colegas, indicando em quais casos a GRID pode ser a melhor opção.

Conexão Tabela Access x Browse()

Enviado: 21 Ago 2015 15:47
por Hasse
Boa tarde mais uma vez.

Já alterei o código, usando o ADO puro em todos os comandos e funções.

Tudo funciona corretamente (pelo menos até aqui), mas não consigo fazer com que o Browse exiba os dados.
Como fazer esta conexão funcionar ?
Em um loop, consigo dar um print na tela do Command (DOS) e ver todos os registros do arquivo.

Help, Help, Help....

Conexão Tabela Access x Browse()

Enviado: 21 Ago 2015 17:54
por alxsts
Olá!

Desculpe não responder antes...

O seu problema é o seguinte: seu código faz um @ 10,10 BROWSE T_Pacientes e mais em baixo WORKAREA T_Pacientes ; Depois executa uma consulta ao banco Access com ADO, que retorna um ADO Recordset. Quando você faz WORKAREA T_Pacientes, está dizendo ao sistema que a fonte de dados do teu browse é um DBF chamado T_Pacientes. Só que este DBF não existe pois um DBF não é a mesma coisa que um ADO RecordSet.

Não conheço MiniGUI ou HMG o suficiente para dizer se é possível associar a um Browse, tsBrowse ou Grid um ADO RecordSet como fonte de dados e nem tive tempo de procurar. É possível que sim. Acho que até já vi algo no fórum da HMG.

A solução mais imediata para o caso, é trocar ADO por SQLMix. SQLMix retorna um DBF com o resultado de uma consulta, ao invés de um ADO Recordset. Procure exemplos aqui no fórum.

Outra opção é continuar com ADO mas usar o GRID e fazer este browse em um array. Teria que carregar os dados do ADO Recordset para um array, Em ADO isto é fácil:

Código: Selecionar todos

LOCAL aArray
   
   oRecSet:moveFirst()
   aArray:= oRecSet:getRows()

Conexão Tabela Access x Browse()

Enviado: 22 Ago 2015 09:28
por Hasse
Bom dia Alexandre.

Eu já estava desconfiado que o ADO não permite a conexão direta entre o BROWSE e o GRID.

Eu já havia feito o teste de conexão via Matriz (Array) e está funcionando, mas isto não me satisfaz, pelas razões:

a)-Não há uma atualização de dados em tempo real;
b)-Pelo motivo acima, haveria a necessidade de elaborar uma rotina de atualização temporizada, que passa a ser mais um ponto fatalmente trará algum problema. A Lei de Murphi certamente mostrará que é verdadeira;
c)-Atualização via comando do usuário nem pensar. Acabará esquecendo, e terei problemas para explicar.

Lembrei-me que o colega Rochinha foi quem abriu o "caminho da roça" para o uso do ADO no Fórum. Vou tentar trocar uma ideia com ele.
O seu problema é o seguinte: seu código faz um @ 10,10 BROWSE T_Pacientes e mais em baixo WORKAREA T_Pacientes ; Depois executa uma consulta ao banco Access com ADO, que retorna um ADO Recordset. Quando você faz WORKAREA T_Pacientes, está dizendo ao sistema que a fonte de dados do teu browse é um DBF chamado T_Pacientes. Só que este DBF não existe pois um DBF não é a mesma coisa que um ADO RecordSet.
Eu também fiz várias tentativas, trocando o identificador do BROWSE, mas de nada adiantou. Não funcionou.

Vou aceitar a tua sugestão para usar o SQLMIX, pois no Fórum temos várias menções ao bom desempenho desta opção. Vou procurar por exemplos e fazer os testes.

Obrigado Alexandre.