Vemos isso normalmente nos módulos de Recursos Humanos, a seleção de multiplas opções onde o resultado das seleções vão para um campo. Abaixo irei mostrar como usar em uma consulta padrão de um campo e o conteúdo que irá aparecer na janela de seleção trazendo as opções de uma tabela SX5 ou de um array. No Configurador, vá em Consulta Padrão, Selecione o tipo de consulta específica, de um nome para a sua consulta e clique em Avançar. Para o exemplo em questão, na próxima tela, selecione a tabela SX5, em expressão chame a função que iremos criar e neste caso é a FMULTIOP, como parâmetro iremos colocar no nome da tabela YL - Código EDI. Poderia ser qualquer outra tabela, em retorno, teremos que dar um nome, mas para a nossa consulta não será necessário, mas como é um campo obrigatório coloque uma variavel qualquer e clique em Finalizar. Abra a tabela SXB no APSDU e remova a variável do retorno, localize o campo XB_TIPO = 5, vá no campo XB_CONTEM e remova o conteúdo. No Configurador ou APSDU, vá no campo que desejar e informe o nome de sua consulta padrão.
Nota: A quantidade de registros selecionados dependerá do tamanho do campo que irá receber, então se o campo é de tamanho 6, apenas 6 registros serão selecionados. Para, retornar apenas um registro, informe no parâmetro l1Elem como verdadeiro (.T.)Exemplo: U_FMULTIOP('YL','CODIGO EDI',.T.) Trazendo opções de uma tabela SX5:
//U_FMULTIOP('05') User Function FMULTIOP(cTabela,cTitulo,l1Elem,lTipoRet) //Exemplo extraído da função GPEXFUNW, mas com pequenas modificações Local MvPar Local MvParDef:="" Private aCat:={} Default cTitulo:="" //O titulo não é obrigatório pois pode ser pegar o titulo da tabela SX5 Default lTipoRet := .T. If(Empty(cTabela)) MsgStop("Informe a tabela a ser pesquisada na SX5!"+CRLF+CRLF+"Avise ao Administrador do sistema. Função: FMULTIOP()","ERRO") Return Endif l1Elem := If (l1Elem = Nil , .F. , .T.) cAlias := Alias() // Salva Alias Anterior IF lTipoRet MvPar:=&(Alltrim(ReadVar())) // Carrega Nome da Variavel do Get em Questao mvRet:=Alltrim(ReadVar()) // Iguala Nome da Variavel ao Nome variavel de Retorno EndIF dbSelectArea("SX5") If dbSeek(xFilial("SX5")+"00"+cTabela) cTitulo := Alltrim(Left(X5Descri(),20)) Endif If dbSeek(xFilial("SX5")+cTabela) CursorWait() aCat := {} While SX5->(!Eof()) .AND. SX5->X5_FILIAL == XFilial("SX5") .AND. SX5->X5_Tabela == cTabela Aadd(aCat,Left(SX5->X5_Chave,1) + " - " + Alltrim(X5Descri())) MvParDef+=Left(SX5->X5_Chave,1) dbSkip() Enddo CursorArrow() Else Help('',1,'FMULTIOP',,'As opções não foram inseridas!',1,0) Endif IF lTipoRet IF f_Opcoes(@MvPar,cTitulo,aCat,MvParDef,12,49,l1Elem) // Chama funcao f_Opcoes (padrão Protheus) &MvRet := mvpar // Devolve Resultado EndIF EndIF dbSelectArea(cAlias) // Retorna Alias Return( IF( lTipoRet , .T. , MvParDef ) )Sintaxe da função f_Opcoes()
Function f_Opcoes( uVarRet ,; //Variavel de Retorno cTitulo ,; //Titulo da Coluna com as opcoes aOpcoes ,; //Opcoes de Escolha (Array de Opcoes) cOpcoes ,; //String de Opcoes para Retorno nLin1 ,; //Nao Utilizado nCol1 ,; //Nao Utilizado l1Elem ,; //Se a Selecao sera de apenas 1 Elemento por vez nTam ,; //Tamanho da Chave nElemRet ,; //No maximo de elementos na variavel de retorno lMultSelect ,; //Inclui Botoes para Selecao de Multiplos Itens lComboBox ,; //Se as opcoes serao montadas a partir de ComboBox de Campo ( X3_CBOX ) cCampo ,; //Qual o Campo para a Montagem do aOpcoes lNotOrdena ,; //Nao Permite a Ordenacao lNotPesq ,; //Nao Permite a Pesquisa lForceRetArr ,; //Forca o Retorno Como Array cF3 ; //Consulta F3 )Continua página 2 Trazendo opções de um ARRAY: Na função que criei, passo como parâmetro o titulo e as opções. As opções serão incluídas dentro de um array. A quantidade de opções incluindo direto como parâmetro irá depender do espaço disponível no campo XB_CONTEM, para poucas opções não é necessário incluí-las no fonte, com isso fica mais dinâmico. Note na imagem acima que o quadro "Máx.Elem.p/Seleção" está com 1, neste caso, determinei que apenas 1 registro será selecionado. O parâmetro responsável para isso é o l1Elem, se ele estiver como verdadeiro (.T.), apenas um registro será selecionado por vez.
//U_FSELARRA("Tipo de CT-e",x3CboxToArray("F1_TPCTE")[1]) //A função x3CboxToArray irá buscar o conteudo do campo X3_CBOX do campo F1_TPCTE e converterá em um array //OU //U_FSELARRA("Opções",{"1 - Opcao 1","2 - Opcao 2","3 - Opcao 3"}) User Function FSELARRA(cTitulo,aOpcoes,l1Elem,lTipoRet) /* cTitulo = Titulo da Janela aOpcoes = Opções que irão aparecer para serem selecionados l1Elem = Definie se a seleção será de apenas de 1 elemento lTipoRet= Define o tipo de retorno */ Local MvParDef:="" Local MvPar := "" Local i Private aCat:=aOpcoes Default cTitulo :="" Default lTipoRet := .T. l1Elem := If (l1Elem = Nil , .F. , .T.) //Definie se a seleção será de apenas de 1 elemento, .F. mais de um elemento cAlias := Alias() // Salva Alias Anterior if Len(aOpcoes)==0 Help('',1,'FSELARRA',,'As opções não foram inseridas!',1,0) Return Endif IF lTipoRet MvPar:=&(Alltrim(ReadVar())) // Carrega Nome da Variavel do Get em Questao mvRet:=Alltrim(ReadVar()) // Iguala Nome da Variavel ao Nome variavel de Retorno EndIF For i := 1 To Len(aCat) MvParDef+=Left(aCat[i],1) Next IF f_Opcoes(@MvPar,cTitulo,aCat,MvParDef,12,49,l1Elem) // Chama funcao f_Opcoes &MvRet := mvpar EndIF dbSelectArea(cAlias) // Retorna Alias Return( IF( lTipoRet , .T. , MvParDef ) )Continua página 3 É possível também definir qual campo receberá o retorno, independente do campo que está chamando a janela de opções Para isso, na função, inclua o seu campo Exemplo: U_FMULTIOP('Titulo','YL',,,"EEC_CAMPO")
User Function FMULTIOP(cTitulo,cTabela,l1Elem,lTipoRet,cCampo) Return( IF( lTipoRet , .T. , MvParDef ) )Substitua: MvPar:=&(Alltrim(ReadVar())) mvRet:=Alltrim(ReadVar()) Por: __ReadVar := cCampo MvPar :=&(__ReadVar) E substitua: If f_Opcoes(@MvPar,cTitulo,aCat,MvParDef,12,49,l1Elem) &MvRet := mvpar EndIf Por: If f_Opcoes(@MvPar,cTitulo,aCat,MvParDef,12,49,l1Elem) &(__ReadVar) := mvpar EndIf Com isso, pode-se usar um gatilho em um campo para chamar a função e ao sair da tela ela preencher um outro campo