Pular para o conteúdo principal

Postagem em destaque

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️ Olá pessoal, Espero que este post encontre todos vocês bem! É com grande entusiasmo que compartilho que estou expandindo meus serviços como Desenvolvedor AdvPL para novos desafios e colaborações. Com mais de duas décadas de experiência sólida, minha jornada profissional tem sido enriquecedora, com a oportunidade de participar de projetos empolgantes ao longo dos anos. Agora, estou ansioso para trazer minha experiência e habilidades para novas equipes e projetos, trabalhando de forma remota. Minha expertise abrange não apenas AdvPL, mas também outras tecnologias-chave, incluindo JS, SQL, Infraestrutura e Otimização de Processos. Acredito que essa combinação de conhecimentos me permite oferecer soluções abrangentes e eficazes para uma variedade de necessidades de desenvolvimento. Acredito que a tecnologia tem o poder de transformar negócios e impulsionar o sucesso, e estou comprometido em ajudar meus clientes a alcançar seu

Protheus :: Advpl :: Duelo de Titãs :: Harbour x ADVPL (You Win!)

Nos episódios anteriores…

  1. Protheus :: Advpl :: Duelo de Titãs :: Harbour x ADVPL ; e

  2. Protheus :: Advpl :: Duelo de Titãs :: Harbour x ADVPL (Round 2, Figth!)

iniciamos o processo de compatibilização de Código Harbour com ADVPL

e…

Finalizando este “combate” tornarmos-nos vencedores!

Protheus, em detrimento a incompetência deste que vos escreve na implementação  descente de Hash (à moda Harbour e em apenas 1 dia), executou com presteza as classes para a geração dos arquivos xml compatíveis com o Microsoft Excel.

Usaremos U_hbXMLTest() para comprovar “a competência” do Protheus nesse sentido.

image[19]

image_thumb[14]

image_thumb[15]

Os exemplos gerados pelo Protheus … :

image_thumb[24]

image_thumb[23]

image_thumb[22]

… são “exatamente” iguais aos gerados pelo Harbour, exceto pela Data de Geração e, no exemplo 3, a implementação do método border (que funciona no Protheus e no Harbour Não)

image_thumb[26]

Compilando as Classes Harbour/Protheus usando hbmk2

image_thumb[68]
para a geração da libhbxlsxml.a que será utilizada pelos programas de testes

image_thumb[70]

e compilado os programas para o mesmo teste no Harbour…

image_thumb[72]

image_thumb[74]

image_thumb[76]

Obteremos os executáveis:

image_thumb[78]

sem crítica, sem erro… tudo OK. Vamos executá-los e , usando apdiff.exe ou WinMerge, vamos comparar os arquivos gerados por ambas aplicações

image_thumb[80]

image_thumb[48]

Os arquivos gerados pelo Protheus estão em %temp%

image_thumb[50]

Já os do Harbour em:

image_thumb[52]

Veremos que, para o exemplo1.xml a única diferença entre o arquivo gerado pelo Harbour e o gerado pelo Protheus é a Hora em que foram criados

image_thumb[54]

Já, para o exemplo2.xml, além da Diferença na data da Criação

image_thumb[56]

Teremos a diferença no formato da Data. No Harbour, para o Exemplo2, SET CENTURY não está ativo e o formato está como mm/dd/yy e no Protheus dd/mm/yyyy algo facilmente contornável.

image_thumb[58]

As diferenças apontadas no exemplo3.xml são um pouco maiores, teremos, além da data da geração , a tag Border.

image_thumb[60]

Desabilitando Border no Protheus teremos, para o Exemplo3.xml o mesmo resultado.

image_thumb[64]

image_thumb[66]

Às explicações e explanações do como e, depois, “vambora” tornar as classes 100% ADVPL.

[]s

иαldσ dj

Comentários

  1. ...será um ADEUS ao TREPORT!?

    Meus testes dirão!

    ResponderExcluir
  2. Na realidade + uma opção. Mas teríamos que implementar as "tags" para tratamento de impressão. Na versão ADVPL isso estará disponível. as Classes Harbour (baseadas na original em PHP) serão apenas referência e inspiração para as Classes em ADVPL.

    []s

    иαldσ dj

    ResponderExcluir
  3. Naldo,

    você ja tentou chamar a execucao de um TReport a partir de um webservice?

    Qual a minha ideia:
    Desenvolver um relatorio que tanto possa ser acessado por dentro do sistema, quanto de uma interface web. No caso da interface web, seria nossa intranet passando os mesmos parametros para geracao de um excel ou PDF, que seria armazenado em uma pasta dentro do siga para posterior download pelo usuario atraves do site.

    Seria viavel? Eu já tentei de várias formas fazer funcionar, mas sempre da erro.

    Mais um super desafio para o SUPER NALDO.

    ResponderExcluir
    Respostas
    1. Ismael, é possivel sim. Quais as formas que você tentou e quais os erros apresentados?

      Excluir
    2. Interessante, este item.
      Já tentei fazer algo parecido. No entanto, alguns tratamentos nos parâmetros inviabilizaram a ideia. Por exemplo, tratar os relatórios que o usuário tem acesso, restrição de campos, filiais. Mas seria bem, interessante. Até para economizar licenças.

      Por fim, fizemos um página que consulta a base direta e mostra os dados.

      Excluir
  4. Este eh o fonte que estou usando para testes

    #INCLUDE "PROTHEUS.CH"
    #INCLUDE "RWMAKE.CH"
    #INCLUDE "TBICONN.CH"
    User Function TESTE01(_xProdIni,_xProdFim)

    Private _lJob := .F.
    Private cPerg := Padr("TESTE01",10)

    If _xProdIni != Nil
    _lJob := .T.
    EndIf
    If Select("SX6") == 0
    RpcSetType(3)
    RpcSetEnv("01","01")
    EndIf

    Private oReport := ReportDef()

    If !_lJob

    Private aRegs := {}

    AADD(aRegs,{cPerg,"01","Produto de ?","","","mv_ch1","C",16,0,0,"G","","mv_par01","","","","","","","","","","","","","","","","","","","","","","","","","SB1",""})
    AADD(aRegs,{cPerg,"02","Produto ate ?","","","mv_ch2","C",16,0,0,"G","","mv_par02","","","","","","","","","","","","","","","","","","","","","","","","","SB1",""})

    U_SIDCRIAPER(cPerg,aRegs)
    pergunte(cPerg,.F.)
    oReport:PrintDialog()

    Else

    oReport:lPreview:= .f.
    oReport:lPrtParamPage:= .f.
    oReport:lXlsHeader:= .t.
    oReport:lEdit:= .f.
    oReport:nDevice:= 4
    oReport:nEnvironment:= 1
    oReport:nRemoteType:= 1
    oReport:cFile:= "\web\temp\TESTE_ISMAEL.pdf"
    oReport:cXlsFile:= "\web\temp\TESTE_ISMAEL.xml"
    oReport:cPathPdf:= "\web\temp\"
    oReport:cDir:= "\web\temp\"
    oReport:cReport:= "TESTE01"

    MV_PAR01 := _xProdIni
    MV_PAR02 := _xProdFim

    ReportPrint(oReport)

    Endif

    Return()
    Static Function ReportDef()

    Local oReport
    Local oSection1
    Local aOrdem := {}

    oReport := TReport():New("TESTE01","Produtos",cPerg,{|oReport| ReportPrint(oReport)},"Produtos")

    oReport:SetLandscape()
    oReport:SetTotalInLine(.F.)

    oSection1 := TRSection():New(oReport,"Produtos",{},aOrdem)
    oSection1:SetLineBreak(.f.)

    TRCell():New(oSection1,"CODIGO", ,"Codigo",,15,.F.,)
    TRCell():New(oSection1,"DESCRICAO", ,"Descricao",,60,.F.,)


    Return oReport
    Static Function ReportPrint(oReport)

    Local oSection1 := oReport:Section(1)

    dbSelectArea("SB1")
    SB1->(dbSetOrder(1))
    SB1->(dbSeek(xFilial("SB1")+MV_PAR01))

    While SB1->(!EOF()) .and. SB1->B1_COD >= MV_PAR01 .and. SB1->B1_COD <= MV_PAR02

    oSection1:Init()
    oSection1:Cell("CODIGO"):SetValue( { || SB1->B1_COD })
    oSection1:Cell("DESCRICAO"):SetValue( { || SB1->B1_DESC })
    oSection1:PrintLine()

    SB1->(dbSkip())
    End

    oSection1:Finish()
    Return

    Ja tentei diversas alternativas, instanciando varios atributos do TReport, mas em nenhum caso funcionou

    Para o fonte acima, o erro que me retorna eh

    THREAD ERROR (JOB_WS_0101, THIS) 28/08/2013 13:31:59
    variable is not an object on TRPAGE:PAGEWIDTH(REPORT10.PRW) 30/09/2009 18:45:46 line : 172

    [TOTVS build: 7.00.121227P-20130625]
    Called from TREPORT:PAGEWIDTH(REPORT01.PRW) 16/05/2013 14:59:18 line : 4006
    Called from TRSECTION:PAGEWIDTH(REPORT02.PRW) 26/06/2013 14:28:01 line : 2859
    Called from TRSECTION:CELLPOS(REPORT02.PRW) 26/06/2013 14:28:01 line : 1227
    Called from TRSECTION:PRINTLINE(REPORT02.PRW) 26/06/2013 14:28:01 line : 827
    Called from REPORTPRINT(TESTE01.PRW) 28/08/2013 13:31:32 line : 138
    Called from U_TESTE01(TESTE01.PRW) 28/08/2013 13:31:32 line : 73

    Terias algum exemplo funcionando?
    Lembrando que esta rotina TESTE01 eu rodo partir de um webservice.

    ResponderExcluir
  5. Então Naldo, esse desafio esta complicado, não é mesmo? Já quebrei muito a cabeça com ele e estou quase desistindo. Na verdade só não desisti ainda porque acredito no SUPER NALDO.

    Um forte abraço.

    ResponderExcluir
    Respostas
    1. Ismael, teoricamente se você criar um relatório, usando a TReport, que é impresso corretamente via client você conseguirá imprimi-lo via RPC.

      Excluir
    2. No seu exemplo, o erro está ocorrendo no momento que o sistema tenta obter informações das coordenadas das células. O erro poderá ser evitado se alterar a propriedade lCepPos de .T. para .F. na sua TRSection ou se adicionar uma TRPage ao seu relatório.

      Excluir
    3. Bom dia!

      Precisar dar um TREPORT():Init() quando a chamada for via JOB, pois o TRPAGE é criado pelo :Init do TREPORT e não da seção. Quando é executado via Smartclient o :Init do TREPORT deve ser executado automaticamente. No final do relatório deve-se executar o TREPORT():Finish(). Outra coisa, o :Printline() precisa ser chamado como :Printline(,,.T.), onde o .T. indice que trata-se da geração do relatório em planilha.

      Abraço.

      Excluir
  6. Naldo,
    seguindo o mesmo exemplo do Ismael, a geração de um relatório com Treport via client roda perfeitamente, porem via webservice ele não se comporta da mesma maneira, a princípio ele exige alguns tratamentos, e mesmo setando os obejetos TRPage e TMSPrinter durante a geração do relatorio ele não gera! Ja me deparei com varios erros tentando implementar a geracao via uma chamada webservice! O erro mais recente foi esse...

    array out of bounds on GETFONTSIZE(REPORT01.PRW) 16/05/2013 14:59:18 line : 4336

    Já verifiquei que o TReport tem uma propriedade aFontSize, mas mesmo via client essa propriedade se encontra vazia!
    Mas acredito que seja possivel realizar esta façanha! O que você acha!?

    ResponderExcluir
    Respostas
    1. Ricardo, depure o seu programa, quando da execução via WS, e verifique a propriedade nRemoteType do Objeto instanciado pela Classe TReport. Para aplicações NO_REMOTE o conteúdo desta propriedade deve estar igual a -1. Se for diferente desse valor o sistema se comportará de forma inesperada.

      Excluir
    2. Ricardo/Ismael,

      Considerando que existem vários procedimentos e tratamentos para impressão via WEB, pergunto: vocês já tentaram imprimir os seus relatórios via WPS - WebPrint & WebSpool?

      Excluir
    3. Estou tendo problemas para utilizar o TReport em schedule.

      Temos um relatório que utilizamos a anos aqui na empresa e gerou-se a necessidade de envio desta planilha automática por email.

      Então estou utilizando o mesmo relatório, porem se não utilizo o método printdialog() e utilizo o print() é gerado um erro;

      Exceção ocorrida: Invalid ReadMSInt in file c:\bamboo-agent-remote\xml-data\build-dir\totvstec-build131227atfs-windowsshell\lib_base\memstream.hpp at line 634


      Pilha de chamadas:
      GETFONTSIZE(4625)
      CHAR2PIX(4489)
      PRINTHEADER(1301)
      STARTPAGE(1565)
      PRINTTEXT(3354)
      PRINTTOT(540)
      REPORTPRINT(505)
      {|OREPORT| REPORTPRINT(OREPORT)}(168)
      eval(1914)
      PRINT(1914)
      U_FINR190B(113)
      SIGAIXB(228)
      __EXECUTE(513)
      FWPREEXECUTE(82)
      {|| FWPREEXECUTE('REL.BAIXAS ST JUDE', 'FINR190B()', 3, '06', 'XXXXXXXXXX') }(183)
      TWINDOW:ACTIVATE(0)
      ACTIVATE(621)
      SIGAADV(54)

      Alguém ja utilizou o TReport em job ?
      podem me passar um exemplo ?
      Sabem a razão do erro descrito acima ?

      Excluir

Postar um comentário

Postagens mais visitadas deste blog

BlackTDN :: RLeg ~ Desvendando a Função ParamBox

Para quem precisar desenvolver uma interface de entrada de dados, coisa rápida, e não quer ter aquele trabalhão danado que todos já sabemos, o Protheus tem uma função que ajuda muito, é uma interface semelhante a função Pergunte, porém com muito mais opção de objeto de entrada de dados, alias até colocar o scrollbox desta interface com todos os objetos em outra MsDialog ou Wizard é simples. Vejam o exemplo abaixo, boa sorte! Rleg. //---------------------------------------------------------- // Função exemplo utilizando a função ParamBox() //---------------------------------------------------------- User Function xParamBox() Local aRet := {} Local aParamBox := {} Local aCombo := {"Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"} Local i := 0 Private cCadastro := "xParambox" // ---------------

BlackTDN :: Customizando a interface de Login no Protheus e by You

A publicação “ BlackTDN :: By You e sua nova tela de login ”  de nosso amigo OBona deu o que falar e, em função disso, esse que a muito não vos escreve resolveu criar uma versão onde será possível personalizar, “por completo”, a tela de login no Protheus/by You. Considerando que OBona já havia “mapeado, identificado e customizado” as imagens peguei-as emprestadas para o exemplo que se segue: O primeiro passo para a customização “total” da interface de login do Protheus/by You será implementar o “Ponto de Entrada” ChgPrDir (Diretório de impressão) . Usaremos esse PE juntamente como programa U_FindMsObject.prg (apresentado pela primeira vez em: Protheus :: ADVPL : The Container : Presents Pandora's box ). Diferente do exemplo proposto por OBona, que substitui, durante o processo de compilação, as imagens padrões do sistema (excluindo-as) por imagens customizadas (com o mesmo nome) este novo exemplo mantém, no RPO, as imagens padrões adicionando novas imagens customizadas que serã

Protheus :: Chamando Funções do Menu Diretamente e sem a Necessidade de Login

Ferne$ perguntou: "...é possível abrir alguma rotina do sistema sem solicitar login ao usuário, como por exemplo a rotina MATA010..." Sim Ferne$, é possível sim. Abaixo um Exemplo para a Chamada à função MATA010 sem a necessidade de Login no sistema. #INCLUDE "PROTHEUS.CH" #INCLUDE "TBICONN.CH" /*/ Funcao: MATA010Ex Data: 30/04/2011 Autor: Marinaldo de Jesus Descricao: Executar a Funcao MATA010 diretamente sem a necessidade de LOGIN no Protheus Sintaxe: 1 ) U_MATA010Ex ( Chamada diretamente na Tela de Entrada do Sistema ) ; ou 2 ) totvsclient.exe -q -p=u_MATA010Ex -a=01;01 -c=rnp_local -e=rnp -m -l ( Chamada Via Linha de Comando ) /*/ User Function MATA010Ex( cEmpFil ) Local aEmpFil Local bWindowInit := { || __Execute( "MATA010()" , "xxxxxxxxxxxxxxxxxxxx" , "MATA010" , "SIGAFAT" , "SIGAFAT", 1 , .T. ) } Local cEmp Local cFil Local cMod Local cModName := "SIGAFAT" DEFA