BlackTDN Search

quarta-feira, 22 de fevereiro de 2012

BlackTDN :: Harbour/ADVPL :: Send/GetData uma alternativa a apconnxcontrol.ocx

Vimos, em Protheus :: apconnxcontrol.ocx with Harbour e Protheus :: apconnxcontrol.ocx, PowerShell e SendMessage para envio de Mensagem a Usuário Específico, que é possível a comunicação e transferência de dados usando apconnxcontrol.ocx. Um exemplo mais completo poderá ser obtido em “integração do Protheus com C# (Luis Gustavo Pessoa Lacombe)”.

O problema com apconnxcontrol.ocx é sua instalação. Temos que garantir que estaremos utilizando, sempre, a última versão do aplicativo.

Uma alternativa, na comunicação de dados entre aplicações externas e o protheus, poderá ser a técnica desenvolvida por Roberto Lopez (criador da Harbour MiniGui e mantenedor do fórum HMG Fórum para divulgação de suas idéias) para comunicação entre aplicações da HMG.hmg A idéia básica é que cada aplicação possua um Nome (StationName) e um local para Gravação/Compartilhamento dos Dados (CommPath). Os dados são gravados em arquivos Nomeados de acordo com o Destino.Origem e são enviados e recuperados, respectivamente, através das funções SendData e GetData (funções essas muito simples de implementar em qualquer linguagem). Uma idéia bem simples, de fácil implementação e que resolve muitos problemas de comunicação de dados e que não necessita de nenhum aplicativo adicional. Além disso é extensível (poderá ter os recursos ampliados de acordo com a necessidade e, se padronizado, servir como base de comunicação com qualquer aplicação).

As funções originais SendData e GetData foram adaptadas para o Protheus e, com isso, além de servirem para comunicação de dados entre aplicações da HMG poderão ser utilizadas para comunicação entre aplicações do Protheus e aplicações externas; como o próprio Harbour.

Veremos, agora, um exemplo de SendData e GetData usando uma aplicação em Harbour e, posteriormente, o mesmo exemplo usando o Protheus como Receptor/Transmissor dos Dados. Nele termos:

  1. Como aplicação receptora:  'John_Station' e;
  2. Como aplicação transmissora: 'Roberto_Station'

Os nomes dos exemplos originais do HMG foram mantidos.

O código, para o envio dos dados, baseado no HMG:

/*
* MINIGUI - Harbour Win32 GUI library Demo
*
* Copyright 2002 Roberto Lopez <harbourminigui@gmail.com>
* http://harbourminigui.googlepages.com/
*/

#include "minigui.ch"

Function Main

    Set StationName To 'Roberto_Station'
    Set CommPath    To 'D:\totvs\p10\ndj\pdata\comm\'

    DEFINE WINDOW Form_0 ;
        AT 0,0 ;
        WIDTH 640 HEIGHT 480 ;
        TITLE 'MiniGUI Communications Demo' ;
        ICON 'DEMO.ICO' ;
        MAIN ;
        FONT 'Arial' SIZE 10

        DEFINE MAIN MENU
            POPUP 'File'
                ITEM 'SendData'    ACTION SendTest()
                ITEM 'Exit'        ACTION Form_0.Release
            END POPUP
            POPUP 'Help'
                ITEM 'About'        ACTION MsgInfo ("MiniGUI Communications Demo")
            END POPUP
        END MENU

    END WINDOW

    CENTER WINDOW Form_0

    ACTIVATE WINDOW Form_0

Return Nil

Procedure SendTest
Local aData := {} , aMultiData := {}

    aAdd ( aData , 'Juan'      )
    aAdd ( aData , 'Carlos'  )
    aAdd ( aData , 'Roberto' )

    aAdd ( aMultiData , {'John','Smith','555-5555'} )
    aAdd ( aMultiData , {'Peter','Gomez','543-8372'} )
    aAdd ( aMultiData , {'Albert','Anderson','854-8273'} )

    SendData ( 'John_Station' , 100 )

    SendData ( 'John_Station' , Date() )

    SendData ( 'John_Station' , Time() )

    SendData ( 'John_Station' , .t. )

    SendData ( 'John_Station' , aData )

    SendData ( 'John_Station' , aMultiData )

Return

e, para a recepção:

/*
* MINIGUI - Harbour Win32 GUI library Demo
*
* Copyright 2002 Roberto Lopez <harbourminigui@gmail.com>
* http://harbourminigui.googlepages.com/
*/

#include "minigui.ch"

Function Main

    Set StationName To 'John_Station'
    Set CommPath    To 'D:\totvs\p10\ndj\pdata\comm\'

    DEFINE WINDOW Form_0 ;
        AT 0,0 ;
        WIDTH 640 HEIGHT 480 ;
        TITLE 'MiniGUI Communications Demo' ;
        ICON 'DEMO.ICO' ;
        MAIN ;
        FONT 'Arial' SIZE 10

        DEFINE MAIN MENU
            POPUP 'File'
                ITEM 'GetData'     ACTION GetTest()
                ITEM 'Exit'        ACTION Form_0.Release
            END POPUP
            POPUP 'Help'
                ITEM 'About'       ACTION MsgInfo ("MiniGUI Communications Demo")
            END POPUP
        END MENU

    END WINDOW

    CENTER WINDOW Form_0

    ACTIVATE WINDOW Form_0

Return Nil

Procedure GetTest()
Local r , i

    Repeat

        r := GetData()

        If Valtype (r) == 'A'

            If Valtype ( r [1] ) != 'A'

                Aeval ( r, { |i| MsgInfo( i ) } )

            Else

                For Each i In r

                    Aeval ( i, { |j| MsgInfo( j ) } )

                Next

            EndIf

        ElseIf r # Nil

            MsgInfo( r )

        EndIf

    Until r # Nil

Return

(Olha que interessante: Harbour suporta Repeat/Until)

Executando os exemplos do HMG teremos:

image

image

Os dados serão gravados em: D:\totvs\p10\ndj\pdata\comm conforme definição

image

e agora; usando GetDada:

image

image

image image image image image image

A cada dado obtido o arquivo que o originou é excluído até que todos os dados tenham sido recuperados e todos os arquivos excluídos.

image

Agora, o mesmo exemplo no Protheus:

Vou usar o Programa SendData em Harbour para Enviar os Dados e U_HBDataEx para recuperá-los a partir do Protheus.

image

image

image

image

e mostrar a saída no Browser:

image

O código do Exemplo de GetData, no Protheus, poderá ser obtido em: Source path: svn/trunk/harbour/samples/MiniGUI/comm/U_HBDataEx.prg ou através do svn/update em sua cópia local. O exemplo depende de: NDJLIB023.prg e NDJ.CH

No Exemplo abaixo, o Protheus Envia e Recebe os Dados. A opção de “Reenviar” é para o teste com captura pelo Harbour dos dados gerados pelo Protheus.

#INCLUDE "NDJ.CH"

#DEFINE HBDataExCommPath    "D:\totvs\p10\ndj\pdata\comm"

/*/
    Procedure:  HBDataEx
    Autor:      Marinaldo de Jesus
    Data:       22/02/2012
    Descricao:  Exemplo de Uso de GetData e SendData
    Sintaxe:    U_HBDataEx
/*/
USER PROCEDURE HBDataEx()
    MsgRun( "Aguarde...." , "Enviando Dados" , { || HBSDataEx() } )
    MsgRun( "Aguarde...." , "Obtendo Dados"  , { || HBGDataEx() } )
    IF MsgNoYes( "Reenviar os Dados" )
        MsgRun( "Aguarde...." , "Enviando Dados" , { || HBSDataEx() } )
    EndIF   
Return

/*/
    Procedure:  HBGDataEx
    Autor:      Marinaldo de Jesus
    Data:       22/02/2012
    Descricao:  Exemplo de Uso da GetData
    Sintaxe:    HBGDataEx
/*/
Static Procedure HBGDataEx()

    Local aData
    Local oData

    Set StationName To "John_Station"
    Set CommPath    To HBDataExCommPath

    aData    := StaticCall( NDJLIB023 , GetAllData )
    oData    := U_TVarInfoNew( aData , "HbGetData" )
    oData:Save(.T.,.F.)
    oData:Show()
    Sleep( 3000 ) //Wait 3 seconds to erase files

    oData:Close( .T. , .T. )

    oData := NIL

Return

/*/
    Procedure:  HBSDataEx
    Autor:      Marinaldo de Jesus
    Data:       22/02/2012
    Descricao:  Exemplo de Uso da SendData
    Sintaxe:    HBSDataEx
/*/
Static Procedure HBSDataEx()

    Local aData
    Local aMultData
    Local cDest    := "John_Station"

    Local nI
    Local nF        := 20
    Local nB
    Local nT

    Set StationName To "Robert_Station"
    Set CommPath    To HBDataExCommPath

    StaticCall( NDJLIB023 , SendData , cDest , "Olá" )
    StaticCall( NDJLIB023 , SendData , cDest , 123456.789 )
    StaticCall( NDJLIB023 , SendData , cDest , .T. )
    StaticCall( NDJLIB023 , SendData , cDest , .F. )
    StaticCall( NDJLIB023 , SendData , cDest , Date() )
    StaticCall( NDJLIB023 , SendData , cDest , Dtos(Date()) )

    aData    := {;
                     { "Naldo"     , Date() , .T. , 1500.00                        },;
                     { "OverFail"  , Date() - 100 , .F.            , 1500.00 * 4   },;
                     { "RLeg"      , Date() + 100 , .F. .or. .T.  , 1500.00 / 2   },;
                     { "OBona"     , Date() - 100 , .T. .and. .F. , 1500.00 * 100 },;
                     { "LF Altran" , Date() + 100 , .T. .and. .F. , 1500.00 * 2   },;
                     { "C Regazzo" , Date() - 100 , .T. .and. .F. , 1500.00 / 4   };
                }

    StaticCall( NDJLIB023 , SendData , cDest , aClone( aData ) )
    aMultData    := Array(0)
    nT           := Len( aData )

    For nI := 1 To nF
        For nB := 1 To nT
            aData[nB][1] := Embaralha( aData[nB][1] , 0 )
            aData[nB][2] := aData[nB][2] + nI
            aData[nB][3] := !( aData[nB][3] )
            aData[nB][4] += ( nB * nI )
            aAdd( aMultData , aClone( aData[nB] ) )
        Next nB   
    Next nI

    StaticCall( NDJLIB023 , SendData , cDest , aMultData )
    aSize( aMultData , 0 )
    aMultData := NIL

Return

Static Function __Dummy( lRecursa )
    Local oException
    TRYEXCEPTION
        lRecursa := .F.
        IF !( lRecursa )
            BREAK
        EndIF
        lRecursa    := __Dummy( .F. )
        SYMBOL_UNUSED( __cCRLF )
    CATCHEXCEPTION USING oException
    ENDEXCEPTION
Return( lRecursa )

image

image

[]s

иαldσ dj

Um comentário:

  1. Bom artigo. Legal ver que existem várias possibilidades de integração do Protheus com outras linguagens. Parabéns.

    ResponderExcluir