Preencher o aCols de uma tela padrão | Ti Responde 048

No vídeo de hoje, vamos demonstrar em como replicar informações em várias linhas de uma tela que utiliza aCols.

A dúvida de hoje foi do grande Gilberto, onde ele perguntou como poderia fazer um recurso onde replicasse uma informação em todas as linhas de uma tela que usa aCols.

Pensando nisso montamos um exemplo onde ao clicar em Outras Ações, existe uma opção para replicar a informação em todas as linhas (foi usado como exemplo a tela de Documento de Entrada – MATA103).

E abaixo o código fonte desenvolvido para exemplificar:

 

//Bibliotecas
#Include "TOTVS.ch"

/*/{Protheus.doc} User Function MA103BUT
Ponto de Entrada para adicionar uma opção dentro do outras ações do Documento de Entrada
@type  Function
@author Atilio
@since 26/07/2021
@see https://tdn.totvs.com/pages/releaseview.action?pageId=102269141
/*/

User Function MA103BUT()
	Local aArea   := FWGetArea()
	Local aAreaF1 := SF1->(FWGetArea())
	Local aAreaD1 := SD1->(FWGetArea())
	Local aBotao  := {}
	
	aAdd( aBotao, { "BUDGETY"  , { || u_zVid0048()  } , "* Alt. Alíquota IPI" } )

	FWRestArea(aAreaD1)
	FWRestArea(aAreaF1)
	FWRestArea(aArea)
Return aBotao

/*/{Protheus.doc} User Function zVid0048
Função que altera a alíquota do IPI de todas as linhas, conforme digitado numa tela de parâmetro
@type  Function
@author Atilio
@since 26/07/2021
@version version
/*/

User Function zVid0048()
	Local aArea    := GetArea()
	Local nBkp     := n
    Local cCampo   := "D1_IPI"
	Local nPosAliq := GDFieldPos(cCampo)
	Local nAliqNov := 0
	Local cVldSis  := GetSX3Cache(cCampo, "X3_VALID")
	Local cVldUsr  := GetSX3Cache(cCampo, "X3_VLDUSER")
	Local aPergs   := {}
	Local nAtual   := 0
	Local lValidou := .T.
	
	//Adiciona os parâmetros que serão exibidos
	aAdd(aPergs, {1, "Aliq. ICMS",  nAliqNov,  PesqPict("SD1", cCampo), "Positivo()", "", ".T.", 80,  .T.})
	
	//Se a pergunta for confirmada
	If ParamBox(aPergs, "Informe os parâmetros", , , , , , , , , .F., .F.)
		nAliqNov := MV_PAR01
	
		//Percorre todas as linhas da grid
		For nAtual := 1 To Len(aCols)
			lValidou := .T.

			//Altera a linha posicionada na memória
			n := nAtual

			//Altera o ReadVar da Memória
			__ReadVar  := "M->" + cCampo
			M->D1_IPI := nAliqNov

			//Chama a validação do sistema
			If ! Empty(cVldSis)
				lValidou := &(cVldSis)
			EndIf

			//Chama a validação de usuário
			If ! Empty(cVldUsr) .And. lValidou
				lValidou := &(cVldUsr)
			EndIf

			//Se deu certo as validações
			If lValidou
				//Altera a informação de alíquota direto no aCols
				aCols[n][nPosAliq] := nAliqNov

				//Chama gatilho caso exista
				If ExistTrigger(cCampo)
					RunTrigger( ;
						2,;           //nTipo (1=Enchoice; 2=GetDados; 3=F3)
						n,;           //Linha atual da Grid quando for tipo 2
						Nil,;         //Não utilizado
						,;            //Objeto quando for tipo 1
						cCampo;       //Campo que dispara o gatilho
					)
				EndIf
			EndIf
		Next
	EndIf

	n := nBkp
	GetDRefresh()
	RestArea(aArea)	
Return

Bom pessoal, por hoje é só.

Abraços e até a próxima.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

14 Responses

  1. JOSE EULALIO SOARES DOS SANTOS disse:

    Muito bom o artigo, parabéns! Seria legal fazer um sobre simular manter o aCols preenchido em rotinas em MVC. Existem muitos lugares que tem dificuldade em atualizar suas rotinas pq boa parte do dicionário e rotinas auxiliares estão usando aHeader e aCols e não atualizam para MVC, pois teriam que atualizar o dicionário e todas essas rotinas de uma vez só para dar certo.

  2. Alexandre Behling disse:

    Uma dica, como não muda o campo dentro do laço pode checar se tem gatilho apenas uma vez fora do laço e gravar numa variável lógica, então caso seja True é só executar o o gatilho sem precisar toda vez verificar no dicionário se tem o gatilho.

  3. Jose Cristiano disse:

    Ola boa noite tudo bem?
    Primeiramente otimo artigo muita qualidade e clareza..
    Uma duvida que percebi quando pego algum campo como D1_tes ou d1_CF que sao campos que tem pesquisa ele nao aparece para editar exemplo TES ele so aparece para digitar um caracter sendo que ele precisa ter 3 ,para esses casos tem alguma trativa ou dica de como pode tratar essa situacao?

    • Bom dia José, tudo joia graças a Deus e você?

      Opa, obrigado pelo feedback.

      Então, você diz na tela de parâmetros? Se sim, para o tipo caractere, você precisa inicializar a variável já com os espaços disponíveis para a digitação. Por exemplo, supondo que você queira 3 caracteres:

      cSuaVar := Space(3)
      

      Ou você pode simplesmente pegar o tamanho do campo no banco, exemplo:

      cSuaVar := Space(TamSX3('D1_TES')[1])
      

      E ai por fim, você coloca no seu ParamBox:

      aAdd(aPergs, {1, "TES",  cSuaVar,  "", ".T.", "SF4", ".T.", 60,  .T.})
      

      Abraços.

  4. Jose Grigorini disse:

    Ola boa noite Tudo bem?
    Primeiramente obrigado por compartilhar conhecimento .
    Dentro desse exemplo seria possível eu considerar a alíquota da linha anterior e replicar para as demais em vez de usar a que foi digitado no pergunte?

    • Bom dia José, tudo joia graças a Deus e você?

      Acha, nós que agradecemos pelo comentário.

      Então, supondo que você quer replicar as informações da alíquota da linha de número 1, o que será necessário será o seguinte:

      1. Comentar o trecho que tem do ParamBox (linhas 46 e 49 do exemplo)
      2. Antes do For, a variável nAliqNov, você atribui nela, o valor da primeira linha, algo +- assim: nAliqNov := aCols[1][nPosAliq]

      Forte abraço.

  5. CLEBERSON DA SILVA disse:

    Daniel Atilio parabén pelo conteudo,

    No meu caso preciso replicar o campo C6_NUMPCOM porem ao aplicar a sugestão que deu não valida!

    Local aArea := GetArea()
    Local nBkp := n
    Local cCampo := “C6_NUMPCOM”
    Local nPosPedCom := GDFieldPos(cCampo)
    Local nAliqNov := Space(TamSX3(‘C6_NUMPCOM’)[1])
    Local cVldSis := GetSX3Cache(cCampo, “X3_VALID”)
    Local cVldUsr := GetSX3Cache(cCampo, “X3_VLDUSER”)
    Local aPergs := {}
    Local nAtual := 0
    Local lValidou := .T.

    //Adiciona os parâmetros que serão exibidos

    aAdd(aPergs, {1, “nPedido”, nAliqNov, “”, “.T.”, “SC6”, “.T.”, 60, .T.})
    //aAdd(aPergs, {1, “Num Pedido”, nAliqNov, PesqPict(“SC6”, cCampo), “Positivo()”, “”, “.T.”, 80, .T.})

    • Bom dia Cleberson, tudo joia?

      Opa, primeiramente, obrigado pelo comentário e feedback, é muita bondade sua.

      Consultei aqui, e o campo “C6_NUMPCOM” não tem validações de campo (X3_VALID e X3_VLDUSER) e também não tem gatilhos no padrão (SX7).

      Se possível poderia detalhar o que não funcionou? Ou se houve algum erro na execução? Que daí eu tento ver se alguém já passou por isso.

      Um grande abraço.

      • cleberfiscal23 disse:

        Bom dia,

        Refazendo aqui, a alteração do campo funcionou, porem a tela aparece como um tela de busca(lupa)

      • cleberfiscal23 disse:

        Bom dia, Dan,

        neste caso, para replicar o campo com sequencial, serial possível ? exemplo, informar na primeira linha 000001 e repetir 000002, 000003….

        • Comentários (site)

          Bom dia Cleber, tudo joia?

          Você gostaria de popular um aCols de forma incremental, seria isso?

          Se for em MVC, você pode usar o AddIncrementField na sua ViewDef, agora se quiser fazer em um For … Next conforme o exemplo do vídeo, recentemente perguntaram no nosso grupo do WhatsApp algo parecido, segue a resposta que demos:

          […]
          Teriam duas formas de você fazer, uma é usando StrZero convertendo a linha atual para texto e a outra é usando a função Soma1 (para caso acontecer de chegar tipo em “99” e ir para “9A”).

          Então a lógica seria:
          1. Ter uma variável declarada antes do For com o inicial da sequência zerado, por exemplo “000”
          2. No for, você incrementa esse sequencial
          3. Ai no mesmo for, você altera sua coluna colocando esse sequencial, algo +- assim:

          //Zera o sequencial e pega o número da coluna
          cSeqAtu := “000”
          nColuna := GDFieldPos(“SEU_CAMPO”)

          //Percorre todas as linhas
          For nLinha := 1 To Len(aCols)
          //Incrementa o item
          cSeqAtu := Soma1(cSeqAtu)

          //Atualiza a coluna na grid
          aCols[nLinha][nColuna] := cSeqAtu
          Next
          […]

          Um grande abraço.

Deixe uma resposta

Terminal de Informação