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.
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.
Ao clicar em Alterar, somente é possível, alterar o conteúdo e a descrição, os outros campos são bloqueados para edição.
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
Bom pessoal, por hoje é só.
Abraços e até a próxima.