1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

  2. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

Duvida Usar Classes

Discussão em 'Progress 4GL' iniciado por Marcelo Torres, Outubro 21, 2020.

  1. Marcelo Torres

    Marcelo Torres Sem Pontuação

    Senhores, agradeço muito a ajuda de vocês.

    Na verdade estou querendo estudar a respeito de classes no Progress e já fazendo alguma coisa.

    A minha dúvida é como instanciar a classe estando ela noutro arquivo.

    Richard, você deu algumas sugestões que pretendo colocar em prática.

    Você disse:
    using totvs.cadastro.*.
    define variable cliente as Cliente no-undo.

    Só pra ver se eu entendi (me corrija se estiver errado).
    Se eu tiver um arquivo chamado "teste.cls" (numa pasta chamada "totvs") eu poderia fazer:
    using totvs.teste.*.

    E dentro deste arquivo "teste.cls" houvesse uma definição de classe qualquer, eu já poderia usar dentro do meu fonte que já funcionaria.


    Mais uma vez, obrigado (Richard e Renan).
  2. Marcelo Torres

    Marcelo Torres Sem Pontuação

    Senhores, agradeço muito a ajuda de vocês.

    Na verdade estou querendo estudar a respeito de classes no Progress e já fazendo alguma coisa.

    A minha dúvida é como instanciar a classe estando ela noutro arquivo.

    Richard, você deu algumas sugestões que pretendo colocar em prática.

    Você disse:
    using totvs.cadastro.*.
    define variable cliente as Cliente no-undo.

    Só pra ver se eu entendi (me corrija se estiver errado).
    Se eu tiver um arquivo chamado "teste.cls" (numa pasta chamada "totvs") eu poderia fazer:
    using totvs.teste.*.

    E dentro deste arquivo "teste.cls" houvesse uma definição de classe qualquer, eu já poderia usar dentro do meu fonte que já funcionaria.


    Mais uma vez, obrigado (Richard e Renan).
  3. Marcelo Torres

    Marcelo Torres Sem Pontuação

    Atualização:

    Fiz um arquivo chamado TesteClasse.cls com o seguinte:
    Código:
    CLASS TesteClasse ABSTRACT:
        DEFINE PUBLIC PROPERTY ValorMinimo AS INTEGER INITIAL 0 NO-UNDO
            GET.
            SET.
    
        DEFINE PUBLIC PROPERTY ValorMaximo AS INTEGER INITIAL 0 NO-UNDO
            GET.
            SET.
    
        CONSTRUCTOR PUBLIC TesteClasse ():
           ASSIGN ValorMinimo = 10.
           ASSIGN ValorMaximo = 1000.
        END CONSTRUCTOR.
    END CLASS.
    Eu vi que o nome da classe tem de ser, obrigatoriamente, o mesmo nome do arquivo.

    Tento compilar o arquivo TesteClasse.cls e tenho o seguinte erro:
    Nome da classe no comando CLASSE 'TesteClasse' precisa coincidir com o padrão do nome do arquivo 'classes/TesteClasse.cls'

    Se eu tento usar a classe sem compilar o arquivo, fazendo o seguinte:
    Código:
    USING classes.TesteClasse.*.
    
    DEFINE VARIABLE testeClasse AS TesteClasse NO-UNDO.
    Tenho o seguinte erro:
    Datatype inválido especificado: TesteClasse. Especifique um datatype como 'caractere' ou o nome de uma classe.

    Agradeço qualquer orientação.
  4. bootstrapmaster

    bootstrapmaster Moderator Moderador Equipe de Suporte

    De novo, desculpe, fui muito superficial na minha explicação:
    Primeiro vamos organizar as classes dentro de pastas ok ?
    Tenho aqui o seguinte, t: (onde ficam os programas do datasul e os meus especificos).
    Tenho dentro de t: ems2, ems5, fnd .... _custom que é minha pasta de especificos
    Nessa _custom, tenho uma estrutura de pastas imitando a do datasul, acredito que quase todos fazem isso, então eu tenho ems2, ems5, hcm2 e tenho a pasta totvs onde ficam as minhas classes.
    Agora eu divido por assunto, tenho ContasAPagar, ContasAReceber, Producao, faturamento, custos e assim por diante
    em faturamento tenho classes tipo:
    ImpressaoDANFE.cls, GerarNFs.cls, então o primeiro passo é ....

    using totvs.faturamento.*.
    isso diz que eu quero ter acesso a todas as classes do PACKAGE totvs.faturamento

    Agora eu declaro as classes ....
    define variable impressao as ImpressaoDANFE no-undo.
    define variable gerarNFs as GerarNFs no-undo.


    depois instancio elas ....

    assign impressao = new ImpressaoDANFE()
    gerarNFS = new GerarNFS().

    tem uma alternativa, se vc não quiser usar o using, tem que dar o caminho completo da classe ....
    define variable impressao as totvs.faturamento.ImpressaoDANFE no-undo.

    assign impressao = new totvs.faturamento.ImpressaoDANFE().

    agora um exemplo de classe, veja que tenho uma include chamada error.i e instancio uma classe ExceptionControl como error, essa é o tratamento de erros que mencionei anteriormente.

    Essa classe em particular eu uso para transformar browse de dados em browse editavel, mudar a linha de fundo e caracteres de um browse, ainda está sendo aperfeiçoada, mas conforme vou precisando de recursos vou colocando.

    Código:
    /*  ------------------------------------------------------------
        programa .: utils.outros.Browse.cls
        autor ....: richard edgar - imesul
        data .....: 04/01/2020
        descricao : O que puder ser aplicado em um browse genericamente
                    falando.
        ------------------------------------------------------------ */
        {grid2/error.i}
    
        class grid2.utils.outros.Browse:
            define variable error        as ExceptionControl no-undo.
            define variable handleBrowse as handle           no-undo.
            define variable queryString  as character        no-undo.
    
            define temp-table ttHandles no-undo
                field sequencia    as integer
                field handleColuna as handle
                field chave        as logical
                field ignorar      as logical
                index principal sequencia.
    
            constructor public Browse():
                assign error        = ExceptionControl:getInstance()
                       handleBrowse = ?
                       queryString  = ''.
                empty temp-table ttHandles.
            end constructor.
    
            method public void setHandleBrowse(campo as handle):
                if not valid-handle(campo) then error:throwException('Browse','Erro handle browse','Handle informado invalido').
                assign handleBrowse = campo.
                preencherTempTable(campo).
            end method.
    
            method public void setCampoChave(campo as character):
                for each ttHandles:
                    if ttHandles.handleColuna:name = campo then assign ttHandles.chave = yes.
                end.
            end method.
    
            method public void setCampoIgnorar(campo as character):
                for each ttHandles:
                    if ttHandles.handleColuna:name = campo then assign ttHandles.ignorar = yes.
                end.
            end method.
    
            method public void setQueryString(campo as character):
                assign queryString = campo.
            end method.
    
            method private void preencherTempTable(campo as handle):
                define variable contador as integer no-undo.
                empty temp-table ttHandles.
                repeat contador = 1 to campo:num-columns:
                    create ttHandles.
                    assign ttHandles.sequencia    = contador
                           ttHandles.handleColuna = campo:get-browse-column(contador):handle
                           ttHandles.chave        = no
                           ttHandles.ignorar      = no.
                end.
            end method.
    
            method public void setBgcolor(cor as integer):
                for each ttHandles no-lock:
                    assign ttHandles.handleColuna:bgcolor = cor.
                end.
            end method.
    
            method public void setFgcolor(cor as integer):
                for each ttHandles no-lock:
                    assign ttHandles.handleColuna:fgcolor = cor.
                end.
            end method.
    
            method public void setReadOnly(campo as logical):
                if campo then handleBrowse:refresh() no-error.
                if campo then apply 'tab' to handleBrowse.
                assign handleBrowse:read-only = campo.
                for each ttHandles no-lock:
                    assign ttHandles.handleColuna:read-only = campo no-error.
                    if ttHandles.ignorar then assign ttHandles.handleColuna:read-only = yes.
                end.
            end method.
    
            method public void modifyRow():
                setReadOnly(no).
                for each ttHandles no-lock:
                    if ttHandles.chave then assign ttHandles.handleColuna:read-only = yes.
                end.
                for each ttHandles no-lock:
                    if not ttHandles.handleColuna:read-only then do:
                        apply 'entry' to ttHandles.handleColuna.
                        leave.
                    end.
                end.
            end method.
    
            method public void modifyRow(listaCampos as character):
                define variable contador as integer no-undo.
    
                assign handleBrowse:read-only = no.
                for each ttHandles no-lock:
                    assign ttHandles.handleColuna:read-only = yes no-error.
                end.
                repeat contador = 1 to num-entries(listaCampos):
                    for each ttHandles no-lock:
                        if ttHandles.handleColuna:name = entry(contador, listaCampos) then do:
                            assign ttHandles.handleColuna:read-only = no no-error.
                        end.
                    end.
                end.
    
                for each ttHandles no-lock:
                    if not ttHandles.handleColuna:read-only then do:
                        apply 'entry' to ttHandles.handleColuna.
                        leave.
                    end.
                end.
            end method.
    
            method public void reposition(campo as rowid):
                if trim(queryString) <> '' then do:
                    handleBrowse:query:query-prepare(queryString).
                    handleBrowse:query:query-open.
                end.
                handleBrowse:query:reposition-to-rowid(campo).
            end method.
    
            method public void newRow(campo as rowid):
                setReadOnly(no).
                this-object:reposition(campo).
                handleBrowse:query:reposition-to-rowid(campo).
                for each ttHandles no-lock:
                    if not ttHandles.handleColuna:read-only then do:
                        apply 'entry' to ttHandles.handleColuna.
                        leave.
                    end.
                end.
            end method.
        end class.
    
    
    
  5. Renan Cano

    Renan Cano Membro Participativo

    Olá @Marcelo Torres e @bootstrapmaster .

    Então Marcelo como o Richard explicou se no seu propath vc definiu a pasta _custom por exemplo.
    Ai se vc criar alguma outra pasta para por as classes elas devem ser informadas no codigo no nome da classe.

    Ex: Dentro da _custom supomos que foi criado uma pasta chamado classes, o codigo deve ser algo como isso:

    CLASS classes.nome_classe:

    Ex2: Se vc criou mais duas pastas como classes e cl_meuprograma, a definicão ficaria:
    CLASS classes.cl_meuprograma.nome_classe.

    Usando seu exemplo para ficar mais facil o entendimento, eu fiz uma classe de forma simplificada que recebe um valor Minimo e Maximo ja no momento que instaciamos o objeto e possui dois metodos, um para modificar esses valores que vem da construção e outro para exibir.

    Arquivo (testeClasse.cls), salvo na pasta classes que está dentro da _custom definido no propath.

    Código:
    CLASS classes.testeClasse:
    
        //Variaveis que representam os atributos
        DEF VAR valorMinimo AS INTEGER INITIAL 0 NO-UNDO.
        DEF VAR valorMaximo AS INTEGER INITIAL 0 NO-UNDO.
    
        //Construtor, para instaciar esse objeto é obrigatorio passar os parametros valor minimo e maximo
        //Para iniciar um objeto sem parametros basta remover o metodo construtor
        CONSTRUCTOR PUBLIC testeClasse(p1 AS INT,p2 AS INT):
    
            ASSIGN valorMinimo = p1.
            ASSIGN valorMaximo = p2.
    
        END CONSTRUCTOR.
    
        //Exemplos de metodos
        METHOD PUBLIC VOID alteraValores(p1 AS INT, p2 AS INT):
    
            ASSIGN valorMinimo = p1.
            ASSIGN valorMaximo = p2.
    
        END METHOD.
    
        METHOD PUBLIC VOID exibeValores():
    
            MESSAGE "Valor Minimo: " + STRING(valorMinimo) SKIP
                    "Valor Maximo: " + STRING(valorMaximo) VIEW-AS ALERT-BOX.
         
        END METHOD.
    
    END CLASS.
    Arquivo (meu_programa.p)

    Código:
    USING .classes.*.
    
    //Definindo a variavel que vai receber o objeto
    DEF VAR valores AS testeClasse NO-UNDO.
    
    //Instanciando o Objeto e passando os parametros do metodo construtor
    valores = NEW testeClasse(10, 100).
    
    //Exibindos valores(atributos) que vieram do metodo construtor
    valores:exibeValores().
    
    //Alterando valores(atributos)
    valores:alteraValores(50, 500).
    
    //Exibindo os valores depois da alteração
    valores:exibeValores().
    
    Faça uns testes ai e nos diga como conseguiu evoluir.
  6. Renan Cano

    Renan Cano Membro Participativo

    Só uma correção no segundo codigo depois do USING remove o ponto que eu deixei sem querer antes de classes.*.

Compartilhe esta Página