Hoje vou mostrar uma rotina que foi desenvolvida para encontrar rapidamente um produto em um grid no Pedido de Vendas ou de Compras.
Apesar de a funcionalidade padrão existir (clicar em Outras Ações, Pesquisar, Digitar o código e clicar em confirmar – Função GDSeek), ela acaba sendo bastante extensa em ser utilizada, quando se tem um número grande de pedidos que precisam ser manipulados.
Pensando nisso, foi criado a zFindProd, onde ao colocar em um atalho, por exemplo, Ctrl+Y, é mostrado uma tela que é necessário apenas digitar parte do código e pressionar -Enter-.
Foi montado a tela se baseando nos modelos antigos que ainda usam aCols e aHeader. O Fonte trata apenas do Pedido de Venda e do Pedido de Compra, mas é possível adicionar outras rotinas que tenham o código de produto na grid.
Abaixo o código fonte completo desenvolvido.
//Bibliotecas #Include "Protheus.ch" /*/{Protheus.doc} zFindProd Função feita para agilizar a procura de produtos na grid de rotinas padrões @author Atilio @since 31/10/2018 @version undefined @type function @example Inserir em um ponto de entrada no carregamento do sistema, por exemplo: User Function AfterLogin() SetKey(K_CTRL_Y, { || u_zFindProd() }) //Ctrl + Y Return @obs Essa rotina foi feita usando o padrão de grids que usam aCols e aHeader, se for em MVC, para posicionar na linha seria algo +- assim: ... oModelPad := FWModelActive() oModelGrid := oModelPad:GetModel('XXXDETAIL') oModelGrid:GoLine(nLinhaNew) ... /*/ User Function zFindProd() Private nPosProd := 0 Private cCampo := "" Private oPai := GetWndDefault() Private aControles := oPai:aControls //Se for chamada pela tela de pedido de vendas, o campo será o C6_PRODUTO If IsInCallStack("MATA410") cCampo := "C6_PRODUTO" //Senão, se for chamada pela tela de pedido de compras, o campo será o C7_PRODUTO ElseIf IsInCallStack("MATA121") cCampo := "C7_PRODUTO" EndIf //Se houver campo, será carregado a tela If ! Empty(cCampo) //Pega a posição do aCols nPosProd := GDFieldPos(cCampo) //Chama a função de procura fProcura() Else MsgStop("Procura de Produtos não pode ser chamada!", "Atenção") EndIf Return /*---------------------------------------* | Func.: fProcura | | Desc.: Função que procura o registro | *---------------------------------------*/ Static Function fProcura() //Variáveis da tela Private oDlgPesq Private oGrpPesq Private oGetPesq Private cGetPesq := Space(TamSX3('B1_COD')[01]) Private oBtnExec //Tamanho da Janela Private nJanLarg := 500 Private nJanAltu := 065 //Criando a janela DEFINE MSDIALOG oDlgPesq TITLE "zFindProd - Pesquisa de Produtos" FROM 000, 000 TO nJanAltu, nJanLarg COLORS 0, 16777215 PIXEL //Grupo Fórmula com o Get @ 003, 003 GROUP oGrpPesq TO (nJanAltu/2)-3, (nJanLarg/2)-1 PROMPT "Produto: " OF oDlgPesq COLOR 0, 16777215 PIXEL @ 010, 006 MSGET oGetPesq VAR cGetPesq SIZE (nJanLarg/2)-29, 013 OF oDlgPesq COLORS 0, 16777215 VALID (fConfirma()) PIXEL oGetPesq:cPlaceHold := "Insira o código do Produto ou um trecho do código..." @ 010, (nJanLarg/2)-21 BUTTON oBtnExec PROMPT "OK" SIZE 016, 015 OF oDlgPesq ACTION(fConfirma()) PIXEL //Ativando a janela ACTIVATE MSDIALOG oDlgPesq CENTERED Return /*---------------------------------------* | Func.: fConfirma | | Desc.: Efetua a busca na grid | *---------------------------------------*/ Static Function fConfirma() Local nLinNov := 0 Local cPesquisa := Alltrim(cGetPesq) //Primeiro tenta encontrar exatamente igual nLinNov := aScan(aCols, {|x| AllTrim(x[nPosProd]) == cPesquisa}) //Se não encontrou, busca pelo trecho If nLinNov == 0 nLinNov := aScan(aCols, {|x| cPesquisa $ AllTrim(x[nPosProd])}) Endif //Se mesmo assim não encontrou, mostra mensagem If nLinNov == 0 MsgStop("Trecho '" + cPesquisa + "' não foi encontrado!", "Atenção") //Do contrário, posiciona na linha correta e encerra a tela Else fPosiciona(nLinNov) oDlgPesq:End() EndIf Return /*---------------------------------------* | Func.: fPosiciona | | Desc.: Posiciona na linha correta | *---------------------------------------*/ Static Function fPosiciona(nLinhaNew) Local nAtual := 0 Local oGrid //Percorrendo os objetos criados da tela For nAtual := 1 To Len(aControles) //Se tiver Colunas, é uma grid If Type("aControles[" + cValToChar(nAtual) + "]:aColumns") != "U" //Se tiver o mesmo número de colunas que o aHeader If Len(aControles[nAtual]:aColumns) == Len(aHeader) //Pega a Grid oGrid := aControles[nAtual] //Muda a Linha atual n := nLinhaNew oGrid:nAt := n //Atualiza a grid oGrid:Refresh() oGrid:SetFocus() EndIf EndIf Next Return
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Excelente recurso. Obrigado Atílio.
Eu que agradeço pelo comentário Armando. Abraços.