Page 2 of 3

Re: Ads..por favor

PostPosted: Wed Aug 23, 2017 6:47 pm
by Marcelo Via Giglio
Ruben,

necesitas

ace32.lib
rddads.lib

ace32 la debes de crear a partir de ace32.dll (que viene con el cliente de ADS) yo utilice el implib de borlabd, rddads.lib viene con la distribucion de [x]harbour, luego debes de tener los Dll ace32.dll y ADSloc32.dll para trabajar de manera local y adicionalmente axcws32.dll y trabajaras cliente/servidor

Saludos

Marcelo Vía

Re: Ads..por favor

PostPosted: Wed Aug 23, 2017 7:52 pm
by D.Fernandez
Marcelo, gracias. Uso Harbour.
No puedo hacer la lib para Harbour rddads.lib, la dll la creo sin problemas.
Baje los fuentes desde acá.
https://github.com/harbour/core/tree/ma ... rib/rddads
Gracias, saludos
Ruben Dario Fernandez

Re: Ads..por favor

PostPosted: Wed Aug 23, 2017 9:12 pm
by Giovany Vecchi
Tads atualizado na versão 2017-07
Libs, utilitários, helps

https://github.com/giovanyvecchi/tAdsGit.git

Leia o Help book

Re: Ads..por favor

PostPosted: Thu Aug 24, 2017 4:40 am
by D.Fernandez
Hola Giovany, muchas gracias. No encuentro las libs para Harbour y Fivewin.

Gracias.
Saludos

Ruben Dario Fernandez

Re: Ads..por favor

PostPosted: Thu Aug 24, 2017 2:09 pm
by Giovany Vecchi

Re: Ads..por favor

PostPosted: Thu Aug 24, 2017 5:25 pm
by D.Fernandez
Giovany muchas gracias.

Hay que incluir tus prg en el programa o ya viene en las libs.?

Ya las baje.
Intentaré y si no puedo seguiré molestando por acá.
Gracias de nuevo y Saludos

Ruben Fernandez

Re: Ads..por favor

PostPosted: Thu Aug 24, 2017 8:09 pm
by Giovany Vecchi
Voce pode me adicionar no Skype

Skype:
giovany.vecchi

Re: Ads..por favor

PostPosted: Thu Aug 24, 2017 8:19 pm
by D.Fernandez
Seguro que si.

r.d.fernandez

Gracias

Re: Ads..por favor

PostPosted: Thu Aug 24, 2017 11:52 pm
by ruben Dario
Saudos
Giovany

Entonces lo Ideal seria trabajar com ADT (Lo nativo de ADS) que usar DBF , CDX ... , o hay alguna limitacion

Re: Ads..por favor

PostPosted: Fri Aug 25, 2017 3:52 am
by Giovany Vecchi
ruben Dario wrote:Saudos
Giovany

Entonces lo Ideal seria trabajar com ADT (Lo nativo de ADS) que usar DBF , CDX ... , o hay alguna limitacion

Sim, eu trabalho com ADT desde 2007. Quando comecei, usava tabelas livres, em 2009 já estava trabalhando com dicionários de dados. Tinha o xAds que era uma extensão melhorada das funções básicas, dai parti para o desenvolvimento de tAds, para trabalhar com classes. O mais difícil de criar tAds foi a diferença entre tabelas estáticas e dinâmicas, que agora esta funcionando perfeitamente. Outra vantagem é voce poder usar as mesmas classes criadas para cada tabela em diferentes conexões de vários pontos. Criar tabelas estáticas com inner, left, right, envolvendo varias tabelas para criar outra e poder executar SetOrder em qualquer coluna e posteriormente sem precisar refazer a query SQL voce disparar apenas um seek ou usando o mesmo resultado da query, fazer um filter. Muito pratico.
Estou a disposição para qualquer duvida, se precisar adicione meu skype.

Re: Ads..por favor

PostPosted: Fri Aug 25, 2017 2:06 pm
by ruben Dario
Giovany.
Saludos

Hice una prueba, pero funciona usando la clase TDatabase(), tu has tenido o has provado esta clase.

USE F_CFOP.ADT NEW ALIAS "DATOS" SHARED
oDatx := TDatabase():New()

Saludos

Re: Ads..por favor

PostPosted: Fri Aug 25, 2017 2:50 pm
by Giovany Vecchi
ruben Dario wrote:Giovany.
Saludos

Hice una prueba, pero funciona usando la clase TDatabase(), tu has tenido o has provado esta clase.

USE F_CFOP.ADT NEW ALIAS "DATOS" SHARED
oDatx := TDatabase():New()

Saludos

Oi Rubens
Quando eu usava fivewin para clipper, usei a classe tDatabase, mais não fui adiante. Logo em 2003 parti para fw+harbour e tive problemas com rddcdx que ja usava. Então comecei a usar rddads com dbf.
Minha experiencia com ads é desde 2003. tAds ja foi reconstruido de forma muito diferente 3 vezes, mais agora ja esta de forma definitiva.
A muitas diferenças de tDatabase para tAds. A logica que criei foi copiado de C Sharp que disponibiliza a opção de trabalhar com as tabelas por classes e não só como objetos. cada tabela pode ser uma classe com seus methods e datas privadas.
Veja um exemplo meu de uma classe de tabela de tAds abaixo

Code: Select all  Expand view
//Classe gerada por TAds 09/06/2014 - 15:54:21
#Include "Fivewin.ch"
#Include "TAds.ch"

CLASS DB_DEVEDOR from TAds

  Data cTableName     Init "DEVEDOR"
  Data nCache
  Data aTableInfo     Init {}
  Data aColumnsInfo   Init {}
  Data aIndexInfo     Init {}
  Data lConnected     Init .F.

  METHOD OpenRdd(f_nConexao,;    // Numero da Conexão - Default tAds_GetConnectionDefault()
              f_nCache);         // Numero de registros em Cache - Default nCacheAds()
              Constructor

  METHOD End()

  Method DB_DEVEDOR_SeekDocumento(f_cCpfCnpj,f_nOpcDoc,f_lFormat)
  Method DB_DEVEDOR_FilterDocumento(f_cCpfCnpj,f_nOpcDoc,f_lFormat)
  Method DB_DEVEDOR_SeekCodigo(f_nCodigo)
  Method DB_DEVEDOR_DocumentoValido(f_nCodigo)
  Method DB_DEVEDOR_Descricao(f_nCodigo)
  Method DB_DEVEDOR_FindNomeDoc(f_nTpPessoa, f_cNomeDevedor, f_cCnpj, f_cCpf)

ENDCLASS
//-----------------------------------------------------------------------------
METHOD OpenRdd(f_nConexao,f_nCache) Class DB_DEVEDOR

  Default f_nCache := nCacheAds()

  ::nCache        := f_nCache
  ::nTpCallRdd    := 2
  ::NewRdd(::cTableName,f_nConexao,::nCache)
  If ::nOpenStatus == 0
    ::lConnected := .T.
  EndIf

RETURN Self
//-----------------------------------------------------------------------------
METHOD End() Class DB_DEVEDOR

   If ::lConnected
   ::Super:End()
   EndIf

   Self := Nil

RETURN Nil
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
Method DB_DEVEDOR_SeekDocumento(f_cCpfCnpj,f_nOpcDoc,f_lFormat) Class DB_DEVEDOR
  Local cRetDoc := "", cCampoPesquisa := "CPF", lFound := .F.
 
  Default f_lFormat := .F.
 
  If f_lFormat
    f_cCpfCnpj := DOC_CPF_CNPJ_FORMAT(f_cCpfCnpj,f_nOpcDoc)
  EndIf
 
  f_cCpfCnpj := StrTran(f_cCpfCnpj," ","")
 
  If f_nOpcDoc == 1 // CPF
    cCampoPesquisa := "CPF"
  ElseIf f_nOpcDoc == 2 // CNPJ
    cCampoPesquisa := "CGC"
  EndIf

  lFound := ::Seek(f_cCpfCnpj,cCampoPesquisa)
 
Return lFound
//-----------------------------------------------------------------------------
Method DB_DEVEDOR_FilterDocumento(f_cCpfCnpj,f_cNomeDevedor,f_nOpcDoc,f_lFormat) Class DB_DEVEDOR
  Local cRetDoc := "", cCampoPesquisa := "CPF", lFound := .F.
  Local cAof := "", aVarsFormat := {}, nDevedoresQtaFind := 0, nDevedorRecFound := 0
 
  Default f_lFormat := .F.
 
  If f_lFormat
    f_cCpfCnpj := DOC_CPF_CNPJ_FORMAT(f_cCpfCnpj,f_nOpcDoc)
  EndIf
 
  f_cCpfCnpj := StrTran(f_cCpfCnpj," ","")
 
  If f_nOpcDoc == 1 // CPF
    cCampoPesquisa := "CPF"
  ElseIf f_nOpcDoc == 2 // CNPJ
    cCampoPesquisa := "CGC"
  EndIf
 
  aadd(aVarsFormat,{"_cCpfCnpj_",f_cCpfCnpj})
 
  cAof := cCampoPesquisa + "==_cCpfCnpj_"
  ::Filter(cAof,aVarsFormat)
 
  nDevedoresQtaFind := ::KeyCount()
 
  if nDevedoresQtaFind == 0
    lFound := .F.

  ElseIf nDevedoresQtaFind == 1
    ///If ::VarGetAlltrim("NOME") == AllTrim(f_cNomeDevedor)
    If TXT_DIF_COMPARE(::VarGetAlltrim("NOME"),AllTrim(f_cNomeDevedor)) > 60
      lFound := .T.
      nDevedorRecFound := ::Recno()
    Else
      lFound := .F.
    EndIf
    //? nDevedoresQtaFind, ::VarGetAlltrim("NOME"), AllTrim(f_cNomeDevedor), lFound, TXT_DIF_COMPARE(::VarGetAlltrim("NOME"),AllTrim(f_cNomeDevedor))

  ElseIf nDevedoresQtaFind > 1

    Do While !::Eof()

      ///If ::VarGetAlltrim("NOME") == AllTrim(f_cNomeDevedor)
      If TXT_DIF_COMPARE(::VarGetAlltrim("NOME"),AllTrim(f_cNomeDevedor)) > 60
        lFound := .T.
        nDevedorRecFound := ::Recno()
        Exit
      Else
        lFound := .F.
      EndIf
      //? "WHILE", nDevedoresQtaFind, ::VarGetAlltrim("NOME"), AllTrim(f_cNomeDevedor), lFound, TXT_DIF_COMPARE(::VarGetAlltrim("NOME"),AllTrim(f_cNomeDevedor))

      ::Skip()      

    EndDo
 
  EndIf

  ::ClearFilter()
  If nDevedorRecFound > 0
    ::GoTo(nDevedorRecFound)
  EndIf

  ///? "ESCOLHIDO", nDevedoresQtaFind, ::VarGetAlltrim("NOME"), AllTrim(f_cNomeDevedor), lFound, TXT_DIF_COMPARE(::VarGetAlltrim("NOME"),AllTrim(f_cNomeDevedor))

 
Return lFound
//-----------------------------------------------------------------------------
Method DB_DEVEDOR_SeekCodigo(f_nCodigo) Class DB_DEVEDOR
  Local lFound := .F.
 
  If f_nCodigo == -1
    f_nCodigo := ::VarGet("NCODIGO")
  EndIf

  If ::VarGet("NCODIGO") != f_nCodigo
    lFound := ::Seek(f_nCodigo,"NCODIGO")
  Else
    lFound := .T.
  EndIf

Return lFound
//-----------------------------------------------------------------------------
Method DB_DEVEDOR_DocumentoValido(f_nCodigo,f_lDataLoad) Class DB_DEVEDOR
  Local cDocumento := "", cVirgula := "", cTmpCpfCnpj := "", cTmpRgIe := ""

  Default f_lDataLoad := .F.

  ::DB_DEVEDOR_SeekCodigo(f_nCodigo)
 
  IF ::VarGet("NPESSOA") == 1
    cDocumento := ::VarGet("CPF")
  ELSE
    cDocumento := ::VarGet("CGC")
  ENDIF

  If f_lDataLoad
    ::DataLoad()
  EndIf

Return cDocumento
//-----------------------------------------------------------------------------
Method DB_DEVEDOR_Descricao(f_nCodigo) Class DB_DEVEDOR
  Local lFound := .F., cRetDescricao := ""
 
  If f_nCodigo == -1
    f_nCodigo := ::VarGet("NCODIGO")
  EndIf

  If ::VarGet("NCODIGO") != f_nCodigo
    lFound := ::Seek(f_nCodigo,"NCODIGO")
  Else
    lFound := .T.
  EndIf

  If !lFound
    cRetDescricao := "ERRO, DEVEDOR NÃO ENCONTRADO"
  Else
    cRetDescricao := ::VarGetRtrim("NOME")
  EndIf

Return cRetDescricao
//-----------------------------------------------------------------------------
Method DB_DEVEDOR_FindNomeDoc(f_nCodigoDistribuidor, f_nTpPessoa, f_cNomeDevedor, f_cCnpj, f_cCpf) Class DB_DEVEDOR
  Local nCodigoFound := 0

  If f_nCodigoDistribuidor > 0
    if ::Seek(f_nCodigoDistribuidor,"nCodDistribuidor")
      nCodigoFound := ::VarGet("NCODIGO")
      Return nCodigoFound
    EndIf
  Endif

  If f_nTpPessoa == 1 .and. Len(Strtran(f_cCpf," ","")) == 14 // Cpf

    If ::Seek(f_cCpf,"CPF",.F.,.T.)
      nCodigoFound := ::VarGet("NCODIGO")
    Endif

  ElseIf f_nTpPessoa == 2 .and. Len(Strtran(f_cCnpj," ","")) == 18 // Cnpj
 
    If ::Seek(f_cCnpj,"CGC",.F.,.T.)
      nCodigoFound := ::VarGet("NCODIGO")
    Endif

  Endif

  If nCodigoFound == 0
    //If ::Seek(f_cNomeDevedor,"NOME",.F.,.T.)
    //  nCodigoFound := ::VarGet("NCODIGO")
    //EndIf
  EndIf

  If nCodigoFound > 0 .and. ::VarGet("nCodDistribuidor") == 0
    ::rLock()
    ::VarPut("nCodDistribuidor",f_nCodigoDistribuidor)
    If AllTrim(f_cNomeDevedor) != ::VarGetAlltrim("NOME")
      ::VarPut("NOME",f_cNomeDevedor)
    EndIf
    ::UnLock()
  EndIf

Return nCodigoFound
 


Desta forma em qualquer parte do sistema j esta disponibilizado as funções que mais uso.

Ex:
oDb_Devedores := DB_DEVEDOR():OpenRdd()
odb_Devedor:DB_DEVEDOR_SeekCodigo(101)

Re: Ads..por favor

PostPosted: Fri Aug 25, 2017 4:57 pm
by ruben Dario
Giovany.
Saludos

Gracias por tu informacion, ya estoy entendiento la clase TAds, (Se abren la tablas y se navegan e insertan y modimican registro Excelente)
Te hago esta preguntas
Cuando usas este codigo

::oDs_CepSql := tAds():DsNew(1,1) // 1-Definir query com retorno de Cursors (Handle) / Usar conexão de numero 1
::oDs_CepSql:cQrySql := "Select {static} DISTINCT CIDADE, ESTADO from TB_CEP Order By CIDADE "

En el Select cual es la funcionalidad de USAR Select {static} DISTINCT .... Exactamento {static} , que pasa si se le Quita el {static}

MAnejar la clase Es Excelente.
Otra Duda, cuando se Maneja ADO (OBDC) Cuando se ingresan registros, los indices se actulizan, me parece que vi un documento que no.
Gracias

Re: Ads..por favor

PostPosted: Fri Aug 25, 2017 8:06 pm
by Giovany Vecchi
ruben Dario wrote:Giovany.
Saludos

Gracias por tu informacion, ya estoy entendiento la clase TAds, (Se abren la tablas y se navegan e insertan y modimican registro Excelente)
Te hago esta preguntas
Cuando usas este codigo

::oDs_CepSql := tAds():DsNew(1,1) // 1-Definir query com retorno de Cursors (Handle) / Usar conexão de numero 1
::oDs_CepSql:cQrySql := "Select {static} DISTINCT CIDADE, ESTADO from TB_CEP Order By CIDADE "

En el Select cual es la funcionalidad de USAR Select {static} DISTINCT .... Exactamento {static} , que pasa si se le Quita el {static}

MAnejar la clase Es Excelente.
Otra Duda, cuando se Maneja ADO (OBDC) Cuando se ingresan registros, los indices se actulizan, me parece que vi un documento que no.
Gracias


(A) - A regra para abrir as tabelas em ads tem varios termos: (Vamos fazer exemplos de abertura da tabela envolvendo apenas uma tabela)
1- Se voce abrir a tabela com RDD ex: tAds:NewRdd("CLIENTES") > Toda a tabela e indices serão abertos igual a DBUSEAREA() de forma dinamica
2- Se voce abrir apenas uma tabela envolvida com sql ex:
Code: Select all  Expand view
::oDs_CepSql  := tAds():DsNew(1,1)
  ::oDs_CepSql:cQrySql := "Select * from TB_CEP "
Este tipo de abertura retornara uma tabela dinamica, com indices tambem. neste tipo de tabela voce pode trocar a ordem das colunas como se fosse aberto por DBUSEAREA(), efetuar REPLACE,
APPEND, DELETE ETC.

3- Abrindo uma tabela envolvida somente com sql estatico
Code: Select all  Expand view
::oDs_CepSql  := tAds():DsNew(1,1)
  ::oDs_CepSql:cQrySql := "Select {STATIC} * from TB_CEP "
Desta maneira o servidor cria uma tabela intermediaria (temp) de forma estatica. Esta tabela voce não pode efetuar REPLACE, APPEND, DELETE. Apenas consulta, mais com tAds voce podera criar
indices temporarios no resultado usando SetOrder() e depois efetuar SEEK ou trocar de ordem com o mesmo resultado sem precisar disparar DsExecute novamente.

4- Abrindo uma tabela envolvida COM sql dinamico usando ORDER BY
Code: Select all  Expand view
::oDs_CepSql  := tAds():DsNew(1,1)
  ::oDs_CepSql:cQrySql := "Select * from TB_CEP Order By CIDADE"
Neste Caso, a tabela será dinamica igual DBUSEAREA, mais somente o indice [b]CIDADE
estara a disposição, se voce for trocar de ordem o erro aparece.


(B) - Agora abrindo tabelas envolvendo varias com os flags INNER JOIN, LEFT, RIGHT, WHILE ETC.
Quando se faz uma query e na consulta tem mais de uma tabela envolvida, voce não precisa informar o parametro {STATIC}, isto porque se envolver qualquer outra tabela o sistema de advantage vai declarar a tabela como sendo estatica porque não tem como abrir dinamicamente varias consultas associadas a query ex:
1- Abrindo um resultado para tabela envolvendo 3 tabelas com inner join
Code: Select all  Expand view
 ::oDs_RecibosEventos    := tAds():DsNew(1)
  ::oDs_RecibosEventos:cQrySql := "Select  "+;
      "Tb01.*, "+;
      "Tb02.CODIGO AS EVENTOS_CODIGO, "+;
      "Tb02.DESCRICAO AS EVENTOS_DESCRICAO, "+;
      "Tb02.L_NaoFiscal AS EVENTOS_L_NaoFiscal, "+;
      "Tb03.SEQUENCIA AS CAIXA_SETO_SEQUENCIA, "+;
      "Tb03.SETOR AS CAIXA_SETO_SETOR "+;
      "From RECIB_AV AS Tb01 "+;
      "Full Join EVENTOS AS Tb02 ON Tb02.CODIGO = Tb01.N_EVENTO "+;
      "Full Join CAIXA_SETO AS Tb03 ON Tb03.SEQUENCIA = Tb01.N_SETOR_CX "+;
      "Where Tb01.DATA >= _DataInicio_ and Tb01.Data <= _DataFinal_ "+;
      "and Tb02.L_NaoFiscal = False  "+;
      "Order By Tb01.DATA, Tb01.N_SETOR_CX ;"
  ::oDs_RecibosEventos:DsAddVar("_DataInicio_",Date())
  ::oDs_RecibosEventos:DsAddVar("_DataFinal_",Date())
  ::oDs_RecibosEventos:lBufferOnSkip := .T.
 
  ::oDs_RecibosEventos:DsExecute(120) // o valor de 120 define o controle de buffer / page de carregamento da tabela estatica (120 registros)

 

Lembrando que neste resulta ainda é possivel efetuar um FILTER, ou incluir uma ordem diferente e trocar a Order By Tb01.DATA, Tb01.N_SETOR_CX sem precisar de refazer a query.

Bom, acho que deu para entender um pouco. Ads tem varias formas que não somos acustumados, por isto acho que muitos abandonaram ele por falta de entendimento.

Qualquer duvida estou a disposição. pode perguntar

Um abração ai

Re: Ads..por favor

PostPosted: Fri Aug 25, 2017 8:58 pm
by D.Fernandez
Impresionante. Gracias.

Saludos
Ruben Dario Fernandez