BlackTDN :: RLeg ~ Desvendando a Função ParamBox
Para quem precisar desenvolver uma interface de entrada de dados, coisa rápida, e não quer ter aquele trabalhão danado que todos já sabemos, o Protheus tem uma função que ajuda muito, é uma interface semelhante a função Pergunte, porém com muito mais opção de objeto de entrada de dados, alias até colocar o scrollbox desta interface com todos os objetos em outra MsDialog ou Wizard é simples. Vejam o exemplo abaixo, boa sorte! Rleg.
//----------------------------------------------------------
// Função exemplo utilizando a função ParamBox()
//----------------------------------------------------------
User Function xParamBox()
Local aRet := {}
Local aParamBox := {}
Local aCombo := {"Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"}
Local i := 0  
Private cCadastro := "xParambox"
// --------------------------------------------------------------
// Abaixo está a montagem do vetor que será passado para a função
// --------------------------------------------------------------  
aAdd(aParamBox,{1,"Produto",Space(15),"","","SB1","",0,.F.}) // Tipo caractere
aAdd(aParamBox,{1,"Valor",0,"@E 9,999.99","mv_par02>0","","",20,.F.}) // Tipo numérico
aAdd(aParamBox,{1,"Data"  ,Ctod(Space(8)),"","","","",50,.F.}) // Tipo data
// Tipo 1 -> MsGet()
//           [2]-Descricao
//           [3]-String contendo o inicializador do campo
//           [4]-String contendo a Picture do campo
//           [5]-String contendo a validacao
//           [6]-Consulta F3
//           [7]-String contendo a validacao When
//           [8]-Tamanho do MsGet
//           [9]-Flag .T./.F. Parametro Obrigatorio ?  
aAdd(aParamBox,{2,"Informe o mês",1,aCombo,50,"",.F.})
// Tipo 2 -> Combo
//           [2]-Descricao
//           [3]-Numerico contendo a opcao inicial do combo
//           [4]-Array contendo as opcoes do Combo
//           [5]-Tamanho do Combo
//           [6]-Validacao
//           [7]-Flag .T./.F. Parametro Obrigatorio ?
// Cuidado, há um problema nesta opção quando selecionado a 1ª opção.  
aAdd(aParamBox,{3,"Mostra deletados",1,{"Sim","Não"},50,"",.F.})
// Tipo 3 -> Radio
//           [2]-Descricao
//           [3]-Numerico contendo a opcao inicial do Radio
//           [4]-Array contendo as opcoes do Radio
//           [5]-Tamanho do Radio
//           [6]-Validacao
//           [7]-Flag .T./.F. Parametro Obrigatorio ?  
aAdd(aParamBox,{4,"Marca todos ?",.F.,"Marque todos se necessário for.",90,"",.F.})
// Tipo 4 -> Say + CheckBox
//           [2]-Descricao
//           [3]-Indicador Logico contendo o inicial do Check
//           [4]-Texto do CheckBox
//           [5]-Tamanho do Radio
//           [6]-Validacao
//           [7]-Flag .T./.F. Parametro Obrigatorio ?  
aAdd(aParamBox,{5,"Marca todos ?",.F.,50,"",.F.})
// Tipo 5 -> Somente CheckBox
//           [2]-Descricao
//           [3]-Indicador Logico contendo o inicial do Check
//           [4]-Tamanho do Radio
//           [5]-Validacao
//           [6]-Flag .T./.F. Parametro Obrigatorio ?  
aAdd(aParamBox,{6,"Buscar arquivo",Space(50),"","","",50,.F.,"Todos os arquivos (*.*) |*.*"})
// Tipo 6 -> File
//           [2]-Descricao
//           [3]-String contendo o inicializador do campo
//           [4]-String contendo a Picture do campo
//           [5]-String contendo a validacao
//           [6]-String contendo a validacao When
//           [7]-Tamanho do MsGet
//           [8]-Flag .T./.F. Parametro Obrigatorio ?
//           [9]-Texto contendo os tipos de arquivo, exemplo: "Arquivos .CSV |*.CSV"
//           [10]-Diretorio inicial do cGetFile
//           [11]-Número relativo a visualização, podendo ser por diretório ou por arquivo (0,1,2,4,8,16,32,64,128)  
aAdd(aParamBox,{7,"Monte o filtro","SX5","X5_FILIAL==xFilial('SX5')"})
// Tipo 7 -> Montagem de expressao de filtro
//           [2]-Descricao
//           [3]-Alias da tabela
//           [4]-Filtro inicial  
aAdd(aParamBox,{8,"Digite a senha",Space(15),"","","","",80,.F.})
// Tipo 8 -> MsGet Password
//           [2]-Descricao
//           [3]-String contendo o inicializador do campo
//           [4]-String contendo a Picture do campo
//           [5]-String contendo a validacao
//           [6]-Consulta F3
//           [7]-String contendo a validacao When
//           [8]-Tamanho do MsGet
//           [9]-Flag .T./.F. Parametro Obrigatorio ?  
aAdd(aParamBox,{9,"Texto aleatório, apenas demonstrativo.",150,7,.T.})
// Tipo 9 -> Somente uma mensagem, formato de um título
//           [2]-Texto descritivo
//           [3]-Largura do texto
//           [4]-Altura do texto
//           [5]-Valor lógico sendo: .T. => fonte tipo VERDANA e .F. => fonte tipo ARIAL  
aAdd(aParamBox,{10,"Cliente",Space(6),"SA1",40,"C",6,".T."})
// Tipo 10 -> Range de busca
//            [2] = Título
//            [3] = Inicializador padrão
//            [4] = Consulta F3
//            [5] = Tamanho do GET
//            [6] = Tipo do dado, somente (C=caractere e D=data)
//            [7] = Tamanho do espaço
//            [8] = Condição When  
aAdd(aParamBox,{11,"Informe o motivo","",".T.",".T.",.T.})
// Tipo 11 -> MultiGet (Memo)
//            [2] = Descrição
//            [3] = Inicializador padrão
//            [4] = Validação
//            [5] = When
//            [6] = Campo com preenchimento obrigatório .T.=Sim .F.=Não (incluir a validação na função ParamOk)  
// Parametros da função Parambox()
// -------------------------------
// 1 - < aParametros > - Vetor com as configurações
// 2 - < cTitle >      - Título da janela
// 3 - < aRet >        - Vetor passador por referencia que contém o retorno dos parâmetros
// 4 - < bOk >         - Code block para validar o botão Ok
// 5 - < aButtons >    - Vetor com mais botões além dos botões de Ok e Cancel
// 6 - < lCentered >   - Centralizar a janela
// 7 - < nPosX >       - Se não centralizar janela coordenada X para início
// 8 - < nPosY >       - Se não centralizar janela coordenada Y para início
// 9 - < oDlgWizard >  - Utiliza o objeto da janela ativa
//10 - < cLoad >       - Nome do perfil se caso for carregar
//11 - < lCanSave >    - Salvar os dados informados nos parâmetros por perfil
//12 - < lUserSave >   - Configuração por usuário  
// Caso alguns parâmetros para a função não seja passada será considerado DEFAULT as seguintes abaixo:
// DEFAULT bOk   := {|| (.T.)}
// DEFAULT aButtons := {}
// DEFAULT lCentered := .T.
// DEFAULT nPosX  := 0
// DEFAULT nPosY  := 0
// DEFAULT cLoad     := ProcName(1)
// DEFAULT lCanSave := .T.
// DEFAULT lUserSave := .F.  
If ParamBox(aParamBox,"Teste Parâmetros...",@aRet)
   For i:=1 To Len(aRet)
      MsgInfo(aRet[i],"Opção escolhida")
   Next 
Endif  
Return
/*****
 *
 * Se caso for utilizar a ParamBox() em um ponto de entrada, e 
 * esta rotina utilizar a Pergunte(), cuidado, ambas funções atribuem valores
 * as variáveis Public MV_PAR??, e isso pode conflitar os valores, 
 * por este motivo deve-se savar o conteúdo destas variáveis da seguinte maneira:
 * 
 * For nMv := 1 To 40
 *    aAdd( aMvPar, &( "MV_PAR" + StrZero( nMv, 2, 0 ) ) )
 * Next nMv
 *
 * E depois poderá restaura-la da seguinte maneira:
 *
 * For nMv := 1 To Len( aMvPar )
 *    &( "MV_PAR" + StrZero( nMv, 2, 0 ) ) := aMvPar[ nMv ]
 * Next nMv
 *
 * O limitador do For/Next é até 40 ou 60 porquê o Protheus têm no máximo
 * 40 ou 60 perguntas dependendo da versão.
 *
 */
Parabéns! Simples e direto, era o que eu estava precisando!
ResponderExcluirValeu ;)
Para conhecimento o ParamBox grava as informações em arquivos ???????_nomedoparametro.prb na pasta profile.
ResponderExcluirSalvou minha vida.... ameiii
ResponderExcluirObrigada
Luciana
Muito Bom!!!!
ResponderExcluirMe poupou MUUIITO Trabalho.
Obrigado mesmo.
Eu quero colocar um Parambox onde o usuário vai poder selecionar varios registros de uma tabela, em vez de usar o padrão DE->ATE, pois existem casos que estão dentro de um range e este não deseja selecionar.
ResponderExcluirEx.: Tem a tabela de clientes SA1 e eu quero selecionar o cliente 000001 e o cliente 000010 , mas não quero os clientes que estão no meio.
Tem como ter um parambox onde eu possa escolher um registro, ai escolho outro e outro e vai separando por virgula ou ponto e vírgula?
Grato.
Cara, você conseguiu fazer isso? Porque eu to tentando fazer exatamente isso e não to conseguindo.
ExcluirPode ser usado o Tipo 10 -> Range de busca.
ExcluirMuy útil el conocimiento del ParamBox, ¿pero como se graba la información en las tablas?
ResponderExcluirMil gracias por tu conocimiento!!
Legal... mas tem como colocar o parambox no TReport ?
ResponderExcluirMuriloSwis, conseguiu alguma resposta sobre sua pergunta? Estou com a mesma dúvida.
ExcluirBoa...
ResponderExcluirBoa tarde, fiz uma rotina utilizando o Parambox para jogar um conteúdo no parâmetro MV_DATAFIN, porem, um usuário clicou no botão salvar do parambox e ele não retorna mais o conteúdo que esta gravado no parâmetro, já pegaram algo parecido ?
ResponderExcluirUser Function ADZTRVMOV()
Local cData := GetMV("MV_DATAFIN")
Local aRet := {}
Local aParamBox := {}
If MsgYesNo("Deseja informar a data de fechamento fiscal ?","Adezan")
aAdd(aParamBox,{1,"Data" ,cData,"","","","",50,.F.}) // Tipo data
If ParamBox(aParamBox,"Data de fechamento fiscal",@aRet)
PutMV("MV_DATAFIN",DtoS(aRet[01]))
MsgAlert("Sr(a) " +cUserName+ ", manutenção efetuada com sucesso","Adezan")
EndIf
EndIf
Return
Estou com esse mesmo problema. Ficou gravado.
ExcluirEu consegui resolver passando o parâmetro lCanSave := .f.
ExcluirParamBox(aParamBox,"Título",@aRetPar,/*bOk*/,/*aButtons*/,/*lCentered*/,/*nPosX*/,/*nPosY*/,/*oDlgWizard*/,/*cLoad*/,lCanSave,/*lUserSave*/)
Excelente post. Obrigado.
ResponderExcluirÉ possivel via ParamBox carragar as variáveis sem mostrar para o usuário, como o pergunte(cperg,.f.) ?
ResponderExcluirEsse artigo salvou!!
ResponderExcluirParece q não tem mais a documentação do Parambox no TDN, sei lá se descontinuaram no Lobo Guará, mas não to achando de jeito nenhum. Esse artigo vale muito!
Abs.
Recomendo muito essa página. Boa d+
ResponderExcluirÓtimo exemplo, muito obrigado
ResponderExcluirNa opção Tipo 2 -> Combo como deve ser incluída a opção [6]-Validacao?
ResponderExcluirtentei de todas as formas e não funciona.
Por favor, para o tipo 6, passando o último parâmetro como 128, eu consigo selecionar somente o diretório que quero salvar (sem precisar selecionar um arquivo) mas somente no servidor. Tem algum valor para permitir somente diretório, incluindo diretórios locais? Obrigado.
ResponderExcluirGETF_RETDIRECTORY+GETF_LOCALHARD
Excluircom a versão Web do smartclient, caso o usuário use a versão dark, as letras ficam apagadas por estarem fixas.
ResponderExcluir