O exemplo a seguir, é uma demonstração do uso do componente FWMBrowse com alias temporário usando a tabela SX5. Usaremos apenas os includes TOTVS.CH e FWMVCDEF.CH
#include "totvs.ch" #INCLUDE "FWMVCDEF.CH" user function AGPE001() //Declarar variaveis locais Local aSeek := {} Local aFields := {} Local aIndex := {} Local aFieFilter:= {} //Declarar variaveis privadas Private oBrowse := Nil Private cCadastro := "Cadastro de Gestores" Private aRotina := Menudef() //Cria e popula a tabela temporária AGPE001TRB() //Campos que serão exibidos no browse Aadd(aFields,{"Tabela" ,"X5_TABELA" ,TamSx3("X5_TABELA")[3] ,TamSx3("X5_TABELA")[1] ,TamSx3("X5_TABELA")[2] ,PESQPICT("SX5","X5_TABELA")}) Aadd(aFields,{"Código" ,"X5_CHAVE" ,TamSx3("X5_CHAVE")[3] ,TamSx3("X5_CHAVE")[1] ,TamSx3("X5_CHAVE")[2] ,PESQPICT("SX5","X5_CHAVE")}) Aadd(aFields,{"Nome" ,"X5_DESCRI" ,TamSx3("X5_DESCRI")[3] ,TamSx3("X5_DESCRI")[1] ,TamSx3("X5_DESCRI")[2] ,PESQPICT("SX5","X5_DESCRI")}) Aadd(aFields,{"Localidade" ,"X5_DESCSPA" ,TamSx3("X5_DESCSPA")[3],3,0,PESQPICT("SX5","X5_DESCSPA")}) Aadd(aFields,{"Desc.Local" ,"X5_DESCENG" ,TamSx3("X5_DESCENG")[3],TamSx3("X5_DESCENG")[1],TamSx3("X5_DESCENG")[2],PESQPICT("SX5","X5_DESCENG")}) //Campos que irão compor a tela de filtro Aadd(aFieFilter,{"X5_CHAVE" , "Código" , "C", TamSx3("X5_CHAVE")[1] , 0,PESQPICT("SX5","X5_CHAVE")}) Aadd(aFieFilter,{"X5_DESCRI" , "Nome" , "C", TamSx3("X5_DESCRI")[1] , 0,PESQPICT("SX5","X5_DESCRI")}) Aadd(aFieFilter,{"X5_DESCSPA" , "Localidade" , "C", TamSx3("X5_DESCSPA")[1], 0,PESQPICT("SX5","X5_DESCSPA")}) DbSelectArea("TRB") dbGoTop() //Campo da pesquisa Aadd(aSeek , {"Código" , {{"","C", TamSx3("X5_CHAVE")[1] , TamSx3("X5_CHAVE")[1] , 1, "X5_CHAVE"}} } ) Aadd(aSeek , {"Nome" , {{"","C", TamSx3("X5_DESCRI")[1] , TamSx3("X5_DESCRI")[1] , 2, "X5_DESCRI"}} } ) Aadd(aSeek , {"Localidade" , {{"","C", TamSx3("X5_DESCSPA")[1] , TamSx3("X5_DESCSPA")[1], 3, "X5_DESCSPA"}} } ) //Indice de pesquisa Aadd( aIndex, "X5_CHAVE" ) Aadd( aIndex, "X5_DESCRI" ) Aadd( aIndex, "X5_DESCSPA" ) //aStruct := TRB->(DBStruct()) //aStructCon := aClone(aStruct) oBrowse := FWMBrowse():New() oBrowse:SetDescription( cCadastro ) oBrowse:SetAlias("TRB") oBrowse:SetQueryIndex(aIndex) oBrowse:SetTemporary(.T.) oBrowse:SetSeek(,aSeek) oBrowse:SetFields(aFields) oBrowse:SetTemporary(.T.) oBrowse:DisableConfig() oBrowse:SetFieldFilter(aFieFilter) oBrowse:SetFilterDefault("") oBrowse:SetDBFFilter(.T.) oBrowse:SetUseFilter(.T.) oBrowse:SetLocate() oBrowse:ForceQuitButton() oBrowse:Activate() ReturnCriamos aqui os menus que serão apresentados
Static Function MenuDef() Local aRotina := {} ADD OPTION aRotina Title 'Pesquisar' Action 'PesqBrw' OPERATION 1 ACCESS 0 ADD OPTION aRotina Title 'Visualizar' Action 'U_AGPE001A(2)' OPERATION 2 ACCESS 0 ADD OPTION aRotina Title 'Incluir' Action 'U_AGPE001A(3)' OPERATION 3 ACCESS 0 ADD OPTION aRotina Title 'Alterar' Action 'U_AGPE001A(4)' OPERATION 4 ACCESS 0 ADD OPTION aRotina Title 'Excluir' Action 'U_AGPE001A(5)' OPERATION 5 ACCESS 0 Return( aRotina )continua página 2 Aqui desenharemos a tela que será exibida na inclusão, alteração, visualização e exclusão. Existem outras formas de criar a janela, mas optamos por essa para poder mostrar mais comandos ADVPL
User Function AGPE001A(nOpc) Local cTabela := SPACE(TAMSX3("X5_TABELA")[1]) Local cChave := SPACE(TAMSX3("X5_CHAVE")[1]) Local cDescri := SPACE(TAMSX3("X5_DESCRI")[1]) Local cLocal := SPACE(3) Local cLocalN := SPACE(TAMSX3("X5_DESCENG")[1]) Local oChave Local oDescri Local oLocal Local oLocalN Local cTitulo := iif(nOpc==3,'Incluir',iif(nOpc==4,'Alterar','Excluir')) Local bOk := {|| oDlg:End(), iif(nOpc==2,Nil,fGrava(M->cTabela,M->cChave,M->cDescri,M->cLocal,M->cLocalN,nOpc)) } Local bCancela:= {|| oDlg:End() } Local aButtons:= {} Local oPainel Local oLayer Local oTela1 Static oDlg dbSelectArea("SX5") SX5->(dbSetOrder(1)) if nOpc==3 //incluir cTabela := "ZL" cChave := Ultimo() cDescri := SPACE(TAMSX3("X5_DESCRI")[1]) cLocal := SPACE(3) cLocalN := SPACE(TAMSX3("X5_DESCENG")[1]) Else SX5->(dbGoTop()) If SX5->(dbSeek(xFilial("SX5")+TRB->(X5_TABELA+X5_CHAVE))) cTabela := TRB->X5_TABELA cChave := Alltrim(TRB->X5_CHAVE) cDescri := TRB->X5_DESCRI cLocal := Substr(TRB->X5_DESCSPA,1,3) cLocalN := TRB->X5_DESCENG Else Alert("Registro não existe mais!!!!") Return .f. EndIf Endif DEFINE MSDIALOG oDlg TITLE cTitulo FROM 000, 000 TO 330, 600 COLORS CLR_BLACK, CLR_WHITE PIXEL oPainel:= tPanel():New(0,0,,oDlg,,,,,CLR_WHITE,100,030) oPainel:Align := CONTROL_ALIGN_ALLCLIENT oLayer := FWLayer():New() oLayer:Init( oPainel, .F. ) oLayer:AddLine( "LINE01", 95, .T. ) oLayer:AddCollumn("BOX" ,100,,"LINE01" ) oLayer:AddWindow( "BOX" , "PANEL01","Informe o nome do gestor",80, .F.,.F.,,"LINE01" ) oTela1 := oLayer:GetWinPanel("BOX" ,"PANEL01","LINE01") oTabela:= tGet():New(005,005,{|u| if(PCount()>0,cTabela:=u,cTabela)}, oTela1 ,030,15,PESQPICT("SX3","X5_TABELA") ,{ || },CLR_BLACK,CLR_WHITE,,,,.T.,,, {|| .F. } ,,,,.F.,,"",'cTabela',,,,.T.,,,"Tabela: ",1 ) oChave := tGet():New(005,040,{|u| if(PCount()>0,cChave :=u,cChave )}, oTela1 ,030,15,PESQPICT("SX3","X5_CHAVE") ,{ || ExistChav("SX5", "ZL"+M->cChave ,1)},CLR_BLACK,CLR_WHITE,,,,.T.,,, {|| .F. } ,,,,.F.,,"",'cChave',,,,.T.,,,"Codigo: ",1 ) oDescri:= tGet():New(035,005,{|u| if(PCount()>0,cDescri:=u,cDescri)}, oTela1 ,285,20,PESQPICT("SX3","X5_DESCRI") ,{ || },CLR_RED,CLR_WHITE,,,,.T.,,, {||IIF(nOpc==3.OR.nOpc==4,.T.,.F.) } ,,,,.F.,,"",'cDescri',,,,.T.,,,"Nome do Gestor: *",1 ) oLocal := tGet():New(070,005,{|u| if(PCount()>0,cLocal:=u,cLocal)} , oTela1 ,060,20,PESQPICT("SX3","X5_DESCSPA"),{ || cLocalN := POSICIONE("SYA",1,XFILIAL("SYA")+cLocal,"YA_DESCR"), oLocalN:Refresh() },CLR_BLACK,CLR_WHITE,,,,.T.,,, {||IIF(nOpc==3.OR.nOpc==4,.T.,.F.) } ,,,,.F.,,"SYA",'cLocal',,,,.T.,,,"Localidade: ",1 ) oLocalN:= tGet():New(070,070,{|u| if(PCount()>0,cLocalN:=u,cLocalN)}, oTela1 ,220,20,PESQPICT("SX3","X5_DESCENG"),{ || },CLR_BLACK,CLR_WHITE,,,,.T.,,, {|| .F. } ,,,,.F.,,"",'cLocalN',,,,.T.,,,"Desc.Local: ",1 ) ACTIVATE MSDIALOG oDlg ON INIT EnchoiceBar(oDlg,bOk,bCancela,,aButtons) CENTERED ReturnA função abaixo, usamos para gravar na tabela SX5
Static Function fGrava(_cTabela,_cChave,_cDescri,_cLocal,_cLocalN,nOpc) Local lGrava := .F. Local cMsg := "" If Empty(_cChave) .OR. Empty(_cDescri) //.OR. Empty(_cLocal) MsgStop("Campos obrigatorio em branco!") Return Endif dbSelectArea("SX5") SX5->(dbSetOrder(1)) SX5->(dbGoTop()) if nOpc==3 .OR. nOpc==4 if nOpc==4 .AND. ExisteGestor(_cChave) if !MsgNoYes("O código do gesto já está em uso, tem certeza que deseja alterar o nome do Gestor?") Return() Endif Endif lGrava := !dbSeek(xFilial("SX5")+_cTabela+_cChave) RecLock("SX5",lGrava) SX5->X5_FILIAL := xFilial("SX5") SX5->X5_TABELA := _cTabela SX5->X5_CHAVE := _cChave SX5->X5_DESCRI := _cDescri SX5->X5_DESCSPA:= _cLocal SX5->X5_DESCENG:= _cLocalN SX5->(MsUnlock()) cMsg := "Registro salvo com sucesso!" Else IF ExisteGestor(_cChave) cMsg := "Problema: Não é possível excluir o gestor." + CRLF + CRLF +; "Motivo: O gesto " + _cChave + " está em uso." + CRLF + CRLF +; "Solução: Entre no cadastro de funcionários e filtre pelo campo 'Cod.Gestor' pesquisando com o código " + _cChave else If dbSeek(xFilial("SX5")+_cTabela+_cChave) Reclock("SX5",.F.) SX5->(dbDelete()) SX5->(MsUnlock()) cMsg := "Registro removido com sucesso!" ENDIF EndIf Endif MsgInfo(cMsg,"Aviso") AGPE001TRB() oBrowse:Refresh(.T.) ReturnCriamos uma função via SQL para buscar o último código
Static Function Ultimo() Local cUltimo:= "000001" Local cTmpSX5 := GetNextAlias() IF SELECT(cTmpSX5) # 0 (cTmpSX5)->(dbCloseArea()) ENDIF BeginSql Alias cTmpSX5 SELECT MAX(X5_CHAVE) ULTIMO FROM %Table:SX5% SX5 WHERE SX5.D_E_L_E_T_ = ' ' AND X5_FILIAL = %xFilial:SX5% AND X5_TABELA = %Exp:"ZL"% EndSql dbSelectArea(cTmpSX5) If !(cTmpSX5)->(Eof()) cUltimo := SOMA1((cTmpSX5)->ULTIMO) EndIf Return cUltimocontinua página 3 A função abaixo é para montar a estrutura da tabela SX5 no browse e exibir o registros caso houver.
Static Function AGPE001TRB() Local aTam := {} Local aCampos := {} Local cQuery := "" If Select('TRB') > 0 TRB->(dbCloseArea()) Endif aTam:= TamSX3("X5_TABELA") Aadd(aCampos,{"X5_TABELA","C",aTam[1],aTam[2]}) aTam:= TamSX3("X5_CHAVE") Aadd(aCampos,{"X5_CHAVE","C",aTam[1],aTam[2]}) aTam:= TamSX3("X5_DESCRI") Aadd(aCampos,{"X5_DESCRI","C",aTam[1],aTam[2]}) aTam:= TamSX3("X5_DESCSPA") Aadd(aCampos,{"X5_DESCSPA","C",aTam[1],aTam[2]}) aTam:= TamSX3("X5_DESCENG") Aadd(aCampos,{"X5_DESCENG","C",aTam[1],aTam[2]}) If (Select("TRB") <> 0) dbSelectArea("TRB") TRB->(dbCloseArea ()) Endif cArqTRB := CriaTrab(aCampos,.T.) DbUseArea(.T.,,cArqTRB,"TRB",.T.) dbSelectArea( "TRB" ) IndRegua( "TRB", cArqTRB+"1", "X5_CHAVE" ,,,"Codigo" ) IndRegua( "TRB", cArqTRB+"2", "X5_DESCRI" ,,,"Nome" ) IndRegua( "TRB", cArqTRB+"3", "X5_DESCSPA",,,"Localidade" ) dbClearIndex() dbSetIndex( cArqTRB+"1" + OrdBagExt() ) dbSetIndex( cArqTRB+"2" + OrdBagExt() ) dbSetIndex( cArqTRB+"3" + OrdBagExt() ) TRB->(DbSetOrder(1)) TRB->(DbGotop()) cQuery := " SELECT X5_TABELA, X5_CHAVE, X5_DESCRI, X5_DESCSPA, X5_DESCENG " cQuery += " FROM " + RetSQLName("SX5") + " SX5" cQuery += " WHERE SX5.D_E_L_E_T_ = ' ' " cQuery += " AND X5_FILIAL = '" + xFilial("SX5") + "' " cQuery += " AND X5_TABELA = 'ZL' " cQuery += " AND X5_CHAVE <> '' " cQuery += " ORDER BY X5_CHAVE " If (Select("TRBSX5") <> 0) dbSelectArea("TRBSX5") TRBSX5->(dbCloseArea ()) Endif cQuery := ChangeQuery(cQuery) DbUseArea(.T., "TOPCONN", TCGenQry(,,cQuery), 'TRBSX5', .F., .T.) DbSelectArea("TRBSX5") DbGotop() While TRBSX5->(!Eof()) RecLock("TRB",.T.) TRB->X5_TABELA := TRBSX5->X5_TABELA TRB->X5_CHAVE := TRBSX5->X5_CHAVE TRB->X5_DESCRI := TRBSX5->X5_DESCRI TRB->X5_DESCSPA := TRBSX5->X5_DESCSPA TRB->X5_DESCENG := TRBSX5->X5_DESCENG TRB->(MsUnLock()) TRBSX5->(DbSkip()) EndDo TRBSX5->(dbCloseArea()) Return
Static Function ExisteGestor(cCodigo) Local lRet := .F. Local cArea := GetArea() Local cTmpSRA := GetNextAlias() IF SELECT(cTmpSRA) # 0 (cTmpSRA)->(dbCloseArea()) ENDIF BeginSql Alias cTmpSRA SELECT RA_ZZGESTO FROM %Table:SRA% SRA WHERE SRA.D_E_L_E_T_ = ' ' AND RA_FILIAL = %xFilial:SRA% AND RA_ZZGESTO = %Exp:cCodigo% EndSql dbSelectArea(cTmpSRA) If (cTmpSRA)->(!Eof()) lRet := .T. EndIf RestArea(cArea) Return(lRet)Se conhece uma forma mais simples, compartilhe com a gente, Let's Share!