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.