Rotina para cadastros de parâmetros em AdvPL

Rotina para cadastros de parâmetros em AdvPL

Olá pessoal…

Hoje vou mostrar uma rotina que desenvolvi para cadastro de parâmetros (SX6) no Protheus, similar ao AxCadastro ou a mBrowse.

O intuito dessa rotina, é liberar o cadastro de parâmetros aos usuários, porém ressalto, que o ideal é liberar apenas acesso à parâmetros customizados.

A rotina, ela recebe 3 parâmetros para a montagem da tela, o primeiro, são os parâmetros que estarão disponíveis para cadastro (ou seja, mesmo que o usuário tente digitar outro parâmetro, só serão aceitos os que estiverem nesse array). O segundo parâmetro, é se o cadastro de parâmetros irá utilizar combo (com a listagem de parâmetros conforme array), ou se será usado um get. O último parâmetro, define se será possível excluir o registro.

A tela principal, mostra a listagem de parâmetros.

Tela principal
Tela principal

Ao clicar em Incluir, é necessário informar todos os campos (somente a filial que não é obrigatória), e o RecNO não pode ser preenchido.

Incluindo um parâmetro
Incluindo um parâmetro

Ao clicar em Alterar, somente é possível, alterar o conteúdo e a descrição, os outros campos são bloqueados para edição.

Alteração de parâmetros
Alteração de parâmetros

Abaixo o código fonte utilizado.

//Bibliotecas
#Include "Protheus.ch"

//Constantes
#Define CLR_AZUL      RGB(058,074,119)									//Cor Azul

//Variaveis
Static COL_T1 	:= 001				//Primeira Coluna da tela
Static COL_T2 	:= 123				//Segunda Coluna da tela
Static COL_T3 	:= 245				//Terceira Coluna da tela
Static COL_T4 	:= 367				//Quarta Coluna da tela
Static ESP_CAMPO	:= 038				//Espaçamento do campo para coluna
Static TAM_FILIAL	:= FWSizeFilial()	//Tamanho do campo Filial

/*/{Protheus.doc} zCadSX6
Lista parâmetros ao usuário com as opções de incluir, alterar e excluir
@author Atilio
@since 14/11/2014
@version 1.0
	@param aParams, Array, Parâmetros que serão listados ao usuário para edição
	@param lCombo, Lógico, Define se os parâmetros serão mostrados em combo quando houver inclusão
	@param lDelet, Lógico, Define se será possível a exclusão de parâmetros
	@example
	aParams := { "MV_X_AMBOF","MV_X_USERS"}
	u_zCadSX6(aParams, .T., .T.)
/*/

User Function zCadSX6(aParams, lCombo, lDelet)
	Local aArea   := GetArea()
	Local aAreaX6 := SX6->(GetArea())
	Local nAtual  := 0
	Local nColuna := 6
	Default lCombo := .T.
	Default lDelet := .F.
	Default aParams := {}
	Private lComboPvt := lCombo
	Private aParamsPvt := {}
	Private cParamsPvt := ""
	//Tamanho da Janela
	Private aTamanho := MsAdvSize()
	Private nJanLarg := aTamanho[5]
	Private nJanAltu := aTamanho[6]
	Private nColMeio := (nJanLarg)/4
	Private nEspCols := ((nJanLarg/2)-12)/4
	COL_T1 	:= 003
	COL_T2 	:= COL_T1+nEspCols
	COL_T3 	:= COL_T2+nEspCols
	COL_T4 	:= COL_T3+nEspCOls
	//Objetos gráficos
	Private oDlgSX6
	//GetDados
	Private oMsGet
	Private aHeader 	:= {}
	Private aCols		:= {}
	//Botões
	Private aButtons	:= {}
	aAdd(aButtons,{"Incluir",    "{|| fInclui()}", "oBtnInclui"})
	aAdd(aButtons,{"Alterar",    "{|| fAltera()}", "oBtnAltera"})
	aAdd(aButtons,{"Visualizar", "{|| fVisualiza()}", "oBtnVisual"})
	If lDelet
		aAdd(aButtons,{"Excluir",    "{|| fExclui()}", "oBtnExclui"})
	EndIf
	aAdd(aButtons,{"Sair", "{|| oDlgSX6:End()}", "oBtnSair"})
	
	//Se não tiver parâmetros
	If Len(aParams) <= 0
		MsgStop("Parâmetros devem ser informados!", "Atenção")
		Return
	Else
		aParamsPvt := aParams
		cParamsPvt := ""
		
		//Percorrendo os parâmetros e adicionando
		For nAtual := 1 To Len(aParamsPvt)
			cParamsPvt += aParamsPvt[nAtual]+";"
		Next
	EndIf
	
	//Adicionando cabeçalho
	aAdd(aHeader,{"Filial", 		"ZZ_FILIAL",	"@!",	TAM_FILIAL,	0,	".F.",	".F.",	"C",	"",	""	,})
	aAdd(aHeader,{"Parâmetro", 	"ZZ_PARAME",	"@!",	010,			0,	".F.",	".F.",	"C",	"",	""	,})
	aAdd(aHeader,{"Tipo",  		"ZZ_TIPO",		"@!",	001,			0,	".F.",	".F.",	"C",	"",	""	,})
	aAdd(aHeader,{"Descrição",  "ZZ_DESCRI",	"@!",	150,			0,	".F.",	".F.",	"C",	"",	""	,})
	aAdd(aHeader,{"Conteúdo",   "ZZ_CONTEU",	"@!",	250,			0,	".F.",	".F.",	"C",	"",	""	,})
	aAdd(aHeader,{"RecNo",      "ZZ_RECNUM",	"",		018,			0,	".F.",	".F.",	"N",	"",	""	,})
	
	//Atualizando o aCols
	fAtuaCols(.T.)
	
	//Criando a janela
	DEFINE MSDIALOG oDlgSX6 TITLE "Parâmetros:" FROM 000, 000  TO nJanAltu, nJanLarg COLORS 0, 16777215 PIXEL
		oMsGet := MsNewGetDados():New(	3,;										//nTop
    										3,;										//nLeft
    										(nJanAltu/2)-33,;						//nBottom
    										(nJanLarg/2)-3,;						//nRight
    										GD_INSERT+GD_DELETE+GD_UPDATE,;		//nStyle
    										"AllwaysTrue()",;						//cLinhaOk
    										,;										//cTudoOk
    										"",;									//cIniCpos
    										,;										//aAlter
    										,;										//nFreeze
    										999999,;								//nMax
    										,;										//cFieldOK
    										,;										//cSuperDel
    										,;										//cDelOk
    										oDlgSX6,;								//oWnd
    										aHeader,;								//aHeader
    										aCols)									//aCols  
    	oMsGet:lActive := .F.
	
		//Grupo Legenda
		@ (nJanAltu/2)-30, 003 	GROUP oGrpLeg TO (nJanAltu/2)-3, (nJanLarg/2)-3 	PROMPT "Ações: " 		OF oDlgSX6 COLOR 0, 16777215 PIXEL
		//Adicionando botões
		For nAtual := 1 To Len(aButtons)
			@ (nJanAltu/2)-20, nColuna  BUTTON &(aButtons[nAtual][3]) PROMPT aButtons[nAtual][1]   SIZE 60, 014 OF oDlgSX6  PIXEL
			(&(aButtons[nAtual][3]+":bAction := "+aButtons[nAtual][2]))
			nColuna += 63
		Next
	ACTIVATE MSDIALOG oDlgSX6 CENTERED
	
	RestArea(aAreaX6)
	RestArea(aArea)
Return

/*---------------------------------------------------------------------*
 | Func:  fInclui                                                      |
 | Autor: Daniel Atilio                                                |
 | Data:  14/11/2014                                                   |
 | Desc:  Função de inclusão de parâmetro                              |
 | Obs.:  /                                                            |
 *---------------------------------------------------------------------*/

Static Function fInclui()
	Local nAtual   := oMsGet:nAt
	Local aColsAux := oMsGet:aCols
	Local nPosRecNo:= aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_RECNUM" })
	
	fMontaTela(3, 0)
Return

/*---------------------------------------------------------------------*
 | Func:  fAltera                                                      |
 | Autor: Daniel Atilio                                                |
 | Data:  14/11/2014                                                   |
 | Desc:  Função de alteração de parâmetro                             |
 | Obs.:  /                                                            |
 *---------------------------------------------------------------------*/

Static Function fAltera()
	Local nAtual   := oMsGet:nAt
	Local aColsAux := oMsGet:aCols
	Local nPosRecNo:= aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_RECNUM" })
	
	//Se tiver recno válido
	If aColsAux[nAtual][nPosRecNo] != 0
		fMontaTela(4, aColsAux[nAtual][nPosRecNo])
	EndIf
Return

/*---------------------------------------------------------------------*
 | Func:  fExclui                                                      |
 | Autor: Daniel Atilio                                                |
 | Data:  14/11/2014                                                   |
 | Desc:  Função de exclusão de parâmetro                              |
 | Obs.:  /                                                            |
 *---------------------------------------------------------------------*/

Static Function fExclui()
	Local nAtual   := oMsGet:nAt
	Local aColsAux := oMsGet:aCols
	Local nPosRecNo:= aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_RECNUM" })
	
	//Se tiver recno válido
	If aColsAux[nAtual][nPosRecNo] != 0
		fMontaTela(5, aColsAux[nAtual][nPosRecNo])
	EndIf
Return

/*---------------------------------------------------------------------*
 | Func:  fVisualiza                                                   |
 | Autor: Daniel Atilio                                                |
 | Data:  14/11/2014                                                   |
 | Desc:  Função de visualização de parâmetro                          |
 | Obs.:  /                                                            |
 *---------------------------------------------------------------------*/

Static Function fVisualiza()
	Local nAtual   := oMsGet:nAt
	Local aColsAux := oMsGet:aCols
	Local nPosRecNo:= aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_RECNUM" })
	
	//Se tiver recno válido
	If aColsAux[nAtual][nPosRecNo] != 0
		fMontaTela(2, aColsAux[nAtual][nPosRecNo])
	EndIf
Return

/*---------------------------------------------------------------------*
 | Func:  fAtuaCols                                                    |
 | Autor: Daniel Atilio                                                |
 | Data:  14/11/2014                                                   |
 | Desc:  Função que atualiza o aCols com os parâmetros                |
 | Obs.:  Como a intenção é ter poucos parâmetros, sempre ele irá      |
 |        percorrer a SX6 e adicionar no aCols                         |
 *---------------------------------------------------------------------*/

Static Function fAtuaCols(lFirst)
	Local aAreaSX6 := SX6->(GetArea())
	aCols := {}
	
	//Selecionando a tabela de parâmetros e indo ao topo
	DbSelectArea("SX6")
	SX6->(DbGoTop())
	
	//Percorrendo os parâmetros, e adicionando somente os que estão na filtragem
	While !SX6->(EoF())
		If Alltrim(SX6->X6_VAR) $ cParamsPvt
			aAdd( aCols, {	SX6->X6_FIL,;											//Filial
								SX6->X6_VAR,;											//Parâmetro
								SX6->X6_TIPO,;										//Tipo
								SX6->X6_DESCRIC+SX6->X6_DESC1+SX6->X6_DESC2,;		//Descrição
								SX6->X6_CONTEUD,;										//Conteúdo
								SX6->(RecNo()),;										//RecNo
								.F.})													//Excluído?
		EndIf
	
		SX6->(DbSkip())
	EndDo

	//Se tiver zerada, adiciona conteúdo em branco
	If Len(aCols) == 0
		aAdd( aCols, {	"",;		//Filial
							"",;		//Parâmetro
							"",;		//Tipo
							"",;		//Descrição
							"",;		//Conteúdo
							0,;			//RecNo
							.F.})		//Excluído?
	EndIf

	//Senão for a primeira vez, atualiza grid
	If !lFirst
		oMsGet:setArray(aCols)
	EndIf

	RestArea(aAreaSX6)
Return

/*---------------------------------------------------------------------*
 | Func:  fMontaTela                                                   |
 | Autor: Daniel Atilio                                                |
 | Data:  14/11/2014                                                   |
 | Desc:  Função que atualiza o aCols com os parâmetros                |
 | Obs.:  /                                                            |
 *---------------------------------------------------------------------*/

Static Function fMontaTela(nOpcP, nRecP)
	Local nColuna := 6
	Local nEsp := 15
	Private nOpcPvt := nOpcP
	Private nRecPvt := nRecP
	Private aOpcTip := {" ", "C - Caracter", "N - Numérico", "L - Lógico", "D - Data", "M - Memo"}
	Private oFontNeg := TFont():New("Tahoma")
	Private oDlgEdit
	//Campos
	Private oGetFil, cGetFil
	Private oGetPar, cGetPar
	Private oGetTip, cGetTip
	Private oGetDes, cGetDes
	Private oGetCon, cGetCon
	Private oGetRec, nGetRec
	//Botões
	Private aBtnPar	:= {}
	aAdd(aBtnPar,{"Confirmar",   "{|| fBtnEdit(1)}", "oBtnConf"})
	aAdd(aBtnPar,{"Cancelar",    "{|| fBtnEdit(2)}", "oBtnCanc"})

	//Se não for inclusão, pega os campos conforme array
	If nOpcP != 3
		aColsAux := oMsGet:aCols
		nLinAtu  := oMsGet:nAt
		nPosFil  := aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_FILIAL" })
		nPosPar  := aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_PARAME" })
		nPosTip  := aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_TIPO" })
		nPosDes  := aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_DESCRI" })
		nPosCon  := aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_CONTEU" })
		nPosRec  := aScan(aHeader,{|x| AllTrim(x[2]) == "ZZ_RECNUM" })

		//Atualizando gets
		cGetFil := aColsAux[nLinAtu][nPosFil]
		cGetPar := aColsAux[nLinAtu][nPosPar]
		cGetTip := aColsAux[nLinAtu][nPosTip]
		cGetDes := aColsAux[nLinAtu][nPosDes]
		cGetCon := aColsAux[nLinAtu][nPosCon]
		nGetRec := aColsAux[nLinAtu][nPosRec]

		//Caracter
		If cGetTip == "C"
			cGetTip := aOpcTip[2]
		//Numérico
		ElseIf cGetTip == "N"
			cGetTip := aOpcTip[3]
		//Lógico
		ElseIf cGetTip == "L"
			cGetTip := aOpcTip[4]
		//Data
		ElseIf cGetTip == "D"
			cGetTip := aOpcTip[5]
		//Memo
		ElseIf cGetTip == "M"
			cGetTip := aOpcTip[6]
		EndIf

	//Senão, deixa os campos zerados
	Else
	
		//Atualizando gets
		cGetFil := Space(TAM_FILIAL)
		cGetPar := Space(010)
		cGetTip := aOpcTip[1]
		cGetDes := Space(150)
		cGetCon := Space(250)
		nGetRec := 0
	EndIf

	oFontNeg:Bold := .T.

	//Criando a janela
	DEFINE MSDIALOG oDlgEdit TITLE "Dados:" FROM 000, 000  TO nJanAltu, nJanLarg COLORS 0, 16777215 PIXEL
		nLinAux := 6
			//Filial
			@ nLinAux    , COL_T1						SAY				oSayFil PROMPT	"Filial:"						SIZE 040, 007 OF oDlgEdit COLORS CLR_AZUL							PIXEL
			@ nLinAux-003, COL_T1+ESP_CAMPO				MSGET			oGetFil VAR		cGetFil						SIZE 060, 010 OF oDlgEdit COLORS 0, 16777215						PIXEL
			//Parâmetro
			@ nLinAux    , COL_T2						SAY				oSayPar PROMPT	"Parâmetro:"					SIZE 040, 007 OF oDlgEdit COLORS CLR_AZUL		FONT oFontNeg		PIXEL
			If lComboPvt
				@ nLinAux-003, COL_T2+ESP_CAMPO			MSCOMBOBOX		oGetPar VAR		cGetPar ITEMS aParamsPvt		SIZE 060, 010 OF oDlgEdit COLORS 0, 16777215						PIXEL
			Else
				@ nLinAux-003, COL_T2+ESP_CAMPO			MSGET			oGetPar VAR		cGetPar						SIZE 060, 010 OF oDlgEdit COLORS 0, 16777215	VALID (cGetPar $ cParamsPvt)	PIXEL
			EndIf
			//Tipo
			@ nLinAux    , COL_T3						SAY				oSayTip PROMPT	"Tipo:"						SIZE 040, 007 OF oDlgEdit COLORS CLR_AZUL		FONT oFontNeg		PIXEL
    		@ nLinAux-003, COL_T3+ESP_CAMPO				MSCOMBOBOX		oGetTip VAR		cGetTip ITEMS aOpcTip		SIZE 060, 010 OF oDlgEdit COLORS 0, 16777215						PIXEL
			//RecNo
			@ nLinAux    , COL_T4						SAY				oSayRec PROMPT	"RecNo:"						SIZE 040, 007 OF oDlgEdit COLORS CLR_AZUL							PIXEL
			@ nLinAux-003, COL_T4+ESP_CAMPO				MSGET			oGetRec VAR		nGetRec						SIZE 060, 010 OF oDlgEdit COLORS 0, 16777215						PIXEL
		nLinAux += nEsp
			//Descrição
			@ nLinAux    , COL_T1						SAY				oSayDes PROMPT	"Descrição:"					SIZE 040, 007 OF oDlgEdit COLORS CLR_AZUL		FONT oFontNeg		PIXEL
			@ nLinAux-003, COL_T1+ESP_CAMPO				MSGET			oGetDes VAR		cGetDes						SIZE 300, 010 OF oDlgEdit COLORS 0, 16777215						PIXEL
		nLinAux += nEsp
			//Conteúdo
			@ nLinAux    , COL_T1						SAY				oSayCon PROMPT	"Conteúdo:"					SIZE 040, 007 OF oDlgEdit COLORS CLR_AZUL		FONT oFontNeg		PIXEL
			@ nLinAux-003, COL_T1+ESP_CAMPO				MSGET			oGetCon VAR		cGetCon						SIZE 300, 010 OF oDlgEdit COLORS 0, 16777215						PIXEL
	
		//Grupo Legenda
		@ (nJanAltu/2)-30, 003 	GROUP oGrpLegEdit TO (nJanAltu/2)-3, (nJanLarg/2)-3 	PROMPT "Ações (Confirmação): " 		OF oDlgEdit COLOR 0, 16777215 PIXEL
		//Adicionando botões
		For nAtual := 1 To Len(aBtnPar)
			@ (nJanAltu/2)-20, nColuna  BUTTON &(aBtnPar[nAtual][3]) PROMPT aBtnPar[nAtual][1]   SIZE 60, 014 OF oDlgEdit  PIXEL
			(&(aBtnPar[nAtual][3]+":bAction := "+aBtnPar[nAtual][2]))
			nColuna += 63
		Next
		
		//Se for visualização ou exclusão, todos os gets serão desabilitados
		If nOpcP == 2 .Or. nOpcP == 5
			oGetFil:lActive := .F.
			oGetPar:lActive := .F.
			oGetTip:lActive := .F.
			oGetDes:lActive := .F.
			oGetCon:lActive := .F.
		Else
			//Se for alteração, desabilita a Filial, Parâmetro e Tipo
			If nOpcP == 4
				oGetFil:lActive := .F.
				oGetPar:lActive := .F.
				oGetTip:lActive := .F.
			EndIf
		EndIf
		
		//Campo de RecNo sempre será desabilitado
		oGetRec:lActive := .F.
	ACTIVATE MSDIALOG oDlgEdit CENTERED
Return

/*---------------------------------------------------------------------*
 | Func:  fBtnEdit                                                     |
 | Autor: Daniel Atilio                                                |
 | Data:  16/12/2014                                                   |
 | Desc:  Função que confirma a tela                                   |
 | Obs.:  /                                                            |
 *---------------------------------------------------------------------*/

Static Function fBtnEdit(nConf)
	Local aAreaAux := GetArea()
	
	//Se for o Cancelar
	If nConf == 2
		oDlgEdit:End()
	//Se for o Confirmar
	ElseIf nConf == 1
		//Se for visualizar
		If nOpcPvt == 2
			oDlgEdit:End()
			
		//Senão for visualizar
		Else
			//Se for exclusão
			If nOpcPvT == 5
				SX6->(DbGoTo(nRecPvt))
				RecLock("SX6", .F.)
					DbDelete()
				SX6->(MsUnlock())
				oDlgEdit:End()
			Else
				//Descrição ou conteúdo em branco?
				If Empty(cGetDes) .Or. Empty(cGetCon)
					If !MsgYesNo("O campo <b>Descrição</b> e/ou <b>Conteúdo</b> estão com conteúdo em branco!<br>Deseja continuar?", "Atenção")
						Return
					EndIf
				EndIf
				
				//Se for inclusão
				If nOpcPvt == 3
					//Tipo e parâmetro em branco?
					If Empty(cGetTip) .Or. Empty(cGetPar)
						MsgAlert("O campo <b>Parâmetro</b> e/ou <b>Tipo</b> estão com conteúdo em branco!", "Atenção")
						Return
					EndIf
					
					//Já existe registro?
					SX6->(DbGoTop())
					If (SX6->(DbSeek(cGetFil+cGetPar)))
						MsgAlert("Filial e Parâmetro já existem!", "Atenção")
						Return
					EndIf
					
					//Travando tabela para inclusão
					RecLock("SX6", .T.)
					X6_FIL			:= cGetFil
					X6_VAR			:= cGetPar
					X6_TIPO		:= cGetTip
				//Se for alteração, trava tabela para alteração
				ElseIf nOpcPvt == 4
					SX6->(DbGoTo(nRecPvt))
					RecLock("SX6", .F.)
				EndIf
				
				//Gravando informações
				X6_DESCRIC		:= SubStr(cGetDes,001,50)
				X6_DESC1		:= SubStr(cGetDes,051,50)
				X6_DESC2		:= SubStr(cGetDes,101,50)
				X6_CONTEUD		:= cGetCon
				SX6->(MsUnlock())
				
				oDlgEdit:End()
			EndIf
		EndIf
		
		//Atualizando a grid
		fAtuaCols(.F.)
	EndIf
	
	RestArea(aAreaAux)
Return

Esses e outros códigos, estão disponíveis gratuitamente no nosso GitHub, acesse em github.com/dan-atilio/AdvPL.

Bom pessoal, por hoje é só.
Abraços e até a próxima.

About Dan_Atilio

Analista e desenvolvedor de sistemas. Técnico em Informática pelo CTI da Unesp. Graduado em Banco de Dados pela Fatec Bauru. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor do projeto Terminal de Informação, onde são postados tutoriais e notícias envolvendo o mundo da tecnologia.

Deixe uma resposta

%d blogueiros gostam disto: