No vídeo de hoje, vamos demonstrar em como apagar linhas em um FWBrowse inclusive pintando o fundo de cinza.
A dúvida de hoje, nos perguntaram, se seria possível em um FWBrowse ter o recurso de deletar linhas, similar a antiga MsNewGetDados, onde ao pressionar a tecla -Delete- do teclado, a linha ficar com um fundo cinza.
Pensando nisso, montamos um exemplo, onde vamos demonstrar em como usar os métodos SetDelete, SetBlkBackColor e SetBlkColor da FWBrowse.
Segue abaixo o vídeo exemplificando:
E abaixo o código fonte desenvolvido:
//Bibliotecas #Include "tlpp-core.th" #Include "TOTVS.ch" //Declaração da namespace Namespace custom.terminal.youtube /*/{Protheus.doc} User Function video0157 Exemplo de exclusão de registro em uma FWBrowse @type Function @author Atilio @since 03/06/2024 @example custom.terminal.youtube.u_video0157() /*/ User Function video0157() Local aArea := GetArea() As Array Local lOK := .F. As Logical Local cMessage := "" As Character //Fontes Local cFont := "Tahoma" As Character Local oFontBigger := TFont():New(cFont,,-38) As Object Local oFontTitle := TFont():New(cFont,,-20) As Object Local oFontTitleBold := TFont():New(cFont,,-20,,.T.) As Object Local oFontDefault := TFont():New(cFont,,-14) As Object //Janela e componentes Private oDialogTest As Object Private oTempTable As Object Private oPanelGrid As Object Private oBrowseTemp As Object Private aBrowseColumns := {} As Array Private cTempAlias := GetNextAlias() As Character //Tamanho da janela Private aDialogSize := MsAdvSize() As Array Private nDialogWidth := aDialogSize[5] As Numeric Private nDialogHeight := aDialogSize[6] As Numeric //Cria a temporária oTempTable := FWTemporaryTable():New(cTempAlias) //Adiciona no array das colunas as que serão incluidas (Nome do Campo, Tipo do Campo, Tamanho, Decimais) aFields := {} aAdd(aFields, {"XXCODIGO", "C", 6, 0}) aAdd(aFields, {"XXDESCRI", "C", 30, 0}) aAdd(aFields, {"XXQUANTI", "N", 9, 2}) aAdd(aFields, {"XXEMISSA", "D", 8, 0}) aAdd(aFields, {"XXOBSERV", "C", 100, 0}) aAdd(aFields, {"XXREGDEL", "L", 1, 0}) //Define as colunas usadas, adiciona indice e cria a temporaria no banco oTempTable:SetFields( aFields ) oTempTable:AddIndex("1", {"XXCODIGO"} ) oTempTable:Create() //Monta a estrutura das colunas makeColumns() //Montando os dados, eles devem ser montados antes de ser criado o FWBrowse FWMsgRun(, {|oSay| makeData(oSay) }, "Processando", "Buscando grupos") //Criando a janela oDialogTest := TDialog():New(0, 0, nDialogHeight, nDialogWidth, "Teste Tabela Temporária", , , , , , 16777215, , , .T.) //Títulos e SubTítulos oSayModule := TSay():New(004, 003, {|| "FAT" }, oDialogTest, "", oFontBigger, , , , .T., RGB(149, 179, 215), , 200, 30, , , , , , .F., , ) oSayTitle := TSay():New(004, 050, {|| "Listagem Genérica de"}, oDialogTest, "", oFontTitle, , , , .T., RGB(031, 073, 125), , 200, 30, , , , , , .F., , ) oSaySubTitle := TSay():New(014, 050, {|| "Dados Temporários" }, oDialogTest, "", oFontTitleBold, , , , .T., RGB(031, 073, 125), , 300, 30, , , , , , .F., , ) //Botões oButtonConfirm := TButton():New(006, (nDialogWidth/2-001)-(0052*02), "Confirmar", oDialogTest, {|| lOK := .T., oDialogTest:End()}, 050, 018, , oFontDefault, , .T., , , , , , ) oButtonCancel := TButton():New(006, (nDialogWidth/2-001)-(0052*01), "Fechar", oDialogTest, {|| oDialogTest:End()}, 050, 018, , oFontDefault, , .T., , , , , , ) //Cria o Painel e o Browse oPanelGrid := tPanel():New(033, 006, "", oDialogTest, , , , RGB(000,000,000), RGB(254,254,254), (nDialogWidth/2 - 13), (nDialogHeight/2 - 45)) oBrowseTemp := FWBrowse():New() oBrowseTemp:DisableFilter() oBrowseTemp:DisableConfig() oBrowseTemp:DisableReport() oBrowseTemp:DisableSeek() oBrowseTemp:DisableSaveConfig() oBrowseTemp:SetFontBrowse(oFontDefault) oBrowseTemp:SetAlias(cTempAlias) oBrowseTemp:SetDataTable() oBrowseTemp:SetEditCell(.T., {|| .T.}) oBrowseTemp:lHeaderClick := .F. oBrowseTemp:AddLegend(cTempAlias + "->XXQUANTI == 0", "YELLOW", "Quantidade zerada") oBrowseTemp:AddLegend(cTempAlias + "->XXQUANTI < 0", "RED", "Quantidade menor que zero") oBrowseTemp:AddLegend(cTempAlias + "->XXQUANTI > 0", "GREEN", "Quantidade maior que zero") oBrowseTemp:SetColumns(aBrowseColumns) oBrowseTemp:SetOwner(oPanelGrid) oBrowseTemp:SetDelete(.T., {|| deleteLine()}) //Define que pode apagar as linhas oBrowseTemp:SetBlkBackColor({|| changeLineColor() }) //Define as cores de fundo das linhas que vão ser exibidas no browse oBrowseTemp:SetBlkColor({|| changeTextColor() }) //Define as cores de texto das linhas oBrowseTemp:Activate() //Ativa e exibe a janela oDialogTest:Activate(, , , .T., , , {|| }) //Se foi confirmado If lOK cMessage := "Abaixo os registros apagados da temporária (campo XXREGDEL): " + CRLF //Percorre os dados (cTempAlias)->(DbGoTop()) While ! (cTempAlias)->(EoF()) //Se tiver apagado, incrementa o log If (cTempAlias)->XXREGDEL cMessage += "+ Código " + (cTempAlias)->XXCODIGO + ";" + CRLF EndIf (cTempAlias)->(DbSkip()) EndDo //Exibe a mensagem de log ShowLog(cMessage) EndIf //Deleta a temporaria oTempTable:Delete() RestArea(aArea) Return Static Function makeColumns() Local nCurrent As Numeric Local aTempColumns := {} As Array //Adicionando colunas //[1] - Campo da Temporaria //[2] - Titulo //[3] - Tipo //[4] - Tamanho //[5] - Decimais //[6] - Máscara //[7] - Editável? .T. = sim, .F. = não aAdd(aTempColumns, {"XXCODIGO", "Código", "C", 6, 0, "", .F.}) aAdd(aTempColumns, {"XXDESCRI", "Descricao", "C", 30, 0, "", .F.}) aAdd(aTempColumns, {"XXQUANTI", "Quantidade", "N", 9, 2, "@E 999,999.99", .T.}) aAdd(aTempColumns, {"XXEMISSA", "Emissão", "D", 8, 0, "", .T.}) aAdd(aTempColumns, {"XXOBSERV", "Observação", "C", 100, 0, "", .T.}) //Percorrendo e criando as colunas For nCurrent := 1 To Len(aTempColumns) oColumn := FWBrwColumn():New() oColumn:SetData(&("{|| " + cTempAlias + "->" + aTempColumns[nCurrent][1] +"}")) oColumn:SetTitle(aTempColumns[nCurrent][2]) oColumn:SetType(aTempColumns[nCurrent][3]) oColumn:SetSize(aTempColumns[nCurrent][4]) oColumn:SetDecimal(aTempColumns[nCurrent][5]) oColumn:SetPicture(aTempColumns[nCurrent][6]) //Se for ser possível ter o duplo clique If aTempColumns[nCurrent][7] oColumn:SetEdit(.T.) oColumn:SetReadVar(aTempColumns[nCurrent][1]) //oColumn:SetValid({|| fSuaValid()}) EndIf aAdd(aBrowseColumns, oColumn) Next Return Static Function makeData(oSay) Local aArea := GetArea() As Array Local nCurrent := 0 As Numeric Local nTotal := 100 As Numeric Local dRefDate := Date() As Date Local cCurrentID := "000000" As Character Local cDescription := "" As Character Local nQuantity := 0 As Numeric Local dDate := sToD("") As Date //Faz um laço de repetição For nCurrent := 1 To nTotal //Muda a mensagem na regua oSay:SetText("Adicionando registro " + cValToChar(nCurrent) + " de " + cValToChar(nTotal) + "...") //Pega as variáveis que vão ser gravadas cCurrentID := Soma1(cCurrentID) cDescription := "[" + Time() + "] Teste - " + cCurrentID nQuantity := Randomize(-5, 5) dDate := DaySub(dRefDate, nCurrent) //Insere os dados na temporária RecLock(cTempAlias, .T.) (cTempAlias)->XXCODIGO := cCurrentID (cTempAlias)->XXDESCRI := cDescription (cTempAlias)->XXQUANTI := nQuantity (cTempAlias)->XXEMISSA := dDate (cTempAlias)->XXOBSERV := "" (cTempAlias)->XXREGDEL := .F. (cTempAlias)->(MsUnlock()) Next RestArea(aArea) Return Static Function deleteLine() //Marca a flag de registro apagado RecLock(cTempAlias, .F.) (cTempAlias)->XXREGDEL := ! (cTempAlias)->XXREGDEL (cTempAlias)->(MsUnlock()) //Atualiza a linha do Browse oBrowseTemp:LineRefresh() Return .T. Static Function changeLineColor() Local nLineColor := 0 As Numeric //Se a linha estiver apagada, a cor será cinza If (cTempAlias)->XXREGDEL nLineColor := RGB(192, 192, 192) Else //Se a linha for Par, vai ser Azul Claro If (cTempAlias)->(Recno()) % 2 == 0 nLineColor := RGB(178, 203, 231) //Senão, se ela for Ímpar, vai ser Branco Else nLineColor := RGB(255, 255, 255) EndIf EndIf Return nLineColor Static Function changeTextColor() Local nTextColor := 0 As Numeric //Se a linha estiver apagada, vai ser Branco If (cTempAlias)->XXREGDEL nTextColor := RGB(255, 255, 255) //Senão, vai ser Preto Else nTextColor := RGB(000, 000, 000) EndIf Return nTextColor
Bom pessoal, por hoje é só.
Abraços e até a próxima.