Como alterar a cor da linha de um FWBrowse

No artigo de hoje vamos demonstrar em como mudar a cor de uma linha usando a classe FWBrowse.

Alguns alunos, vira e mexe, acabam me perguntando em como mudar a cor de uma linha, usando a classe FWBrowse.

Então decidi montar dois exemplos, um usando o método SetBlkBackColor direto na FWBrowse e a segunda usando a herança com a TGrid.

Abaixo um print de exemplo:

Linhas coloridas na FWBrowse

Forma 1 – Usando os métodos SetBlkBackColor / SetBlkColor

Dessa forma aqui pessoal, basicamente vamos informar um bloco de códigos, antes do nosso Activate, e nesse bloco, o nosso Return, tem que ser o número da cor.

Então notem que antes do Activate, existem dois métodos o SetBlkBackColor (para definir a cor de fundo da linha) e o SetBlkColor (para definir a cor do texto da linha).

Abaixo segue um código fonte desse exemplo:

#Include "Totvs.ch"
     
/*/{Protheus.doc} User Function zBrwCor2
Função que demonstra como mudar a cor de uma linha
@type  Function
@author Atilio
@since  31/10/2023
@version version
/*/
     
User Function zBrwCor2()
    Local aArea := GetArea()
    //Fontes
    Local cFontUti    := "Tahoma"
    Local oFontAno    := TFont():New(cFontUti,,-38)
    Local oFontSub    := TFont():New(cFontUti,,-20)
    Local oFontSubN   := TFont():New(cFontUti,,-20,,.T.)
    Local oFontBtn    := TFont():New(cFontUti,,-14)
    //Janela e componentes
    Private oDlgGrp
    Private oPanGrid
    Private oGetGrid
    Private aColunas := {}
    Private cAliasTab := "TMPSBM"
    //Tamanho da janela
    Private    aTamanho := MsAdvSize()
    Private    nJanLarg := aTamanho[5]
    Private    nJanAltu := aTamanho[6]
     
    //Cria a temporária
    oTempTable := FWTemporaryTable():New(cAliasTab)
         
    //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})
         
    //Define as colunas usadas, adiciona indice e cria a temporaria no banco
    oTempTable:SetFields( aFields )
    oTempTable:AddIndex("1", {"XXCODIGO"} )
    oTempTable:Create()
     
    //Monta o cabecalho
    fMontaHead()
     
    //Montando os dados, eles devem ser montados antes de ser criado o FWBrowse
    FWMsgRun(, {|oSay| fMontDados(oSay) }, "Processando", "Buscando grupos")
     
    //Criando a janela
    DEFINE MSDIALOG oDlgGrp TITLE "Dados" FROM 000, 000  TO nJanAltu, nJanLarg COLORS 0, 16777215 PIXEL
        //Labels gerais
        @ 004, 003 SAY "FAT"                     SIZE 200, 030 FONT oFontAno  OF oDlgGrp COLORS RGB(149,179,215) PIXEL
        @ 004, 050 SAY "Listagem Genérica de"    SIZE 200, 030 FONT oFontSub  OF oDlgGrp COLORS RGB(031,073,125) PIXEL
        @ 014, 050 SAY "Dados Temporários"       SIZE 200, 030 FONT oFontSubN OF oDlgGrp COLORS RGB(031,073,125) PIXEL
     
        //Botões
        @ 006, (nJanLarg/2-001)-(0052*01) BUTTON oBtnFech  PROMPT "Fechar"        SIZE 050, 018 OF oDlgGrp ACTION (oDlgGrp:End())   FONT oFontBtn PIXEL
     
        //Dados
        @ 024, 003 GROUP oGrpDad TO (nJanAltu/2-003), (nJanLarg/2-003) PROMPT "Browse" OF oDlgGrp COLOR 0, 16777215 PIXEL
        oGrpDad:oFont := oFontBtn
            oPanGrid := tPanel():New(033, 006, "", oDlgGrp, , , , RGB(000,000,000), RGB(254,254,254), (nJanLarg/2 - 13),     (nJanAltu/2 - 45))
            oGetGrid := FWBrowse():New()
            oGetGrid:DisableFilter()
            oGetGrid:DisableConfig()
            oGetGrid:DisableReport()
            oGetGrid:DisableSeek()
            oGetGrid:DisableSaveConfig()
            oGetGrid:SetFontBrowse(oFontBtn)
            oGetGrid:SetAlias(cAliasTab)
            oGetGrid:SetDataTable()
            oGetGrid:SetEditCell(.T., {|| .T.}) 
            oGetGrid:lHeaderClick := .F.
            oGetGrid:AddLegend(cAliasTab + "->XXQUANTI == 0", "YELLOW", "Quantidade zerada")
            oGetGrid:AddLegend(cAliasTab + "->XXQUANTI <  0", "RED",    "Quantidade menor que zero")
            oGetGrid:AddLegend(cAliasTab + "->XXQUANTI >  0", "GREEN",  "Quantidade maior que zero")
            oGetGrid:SetColumns(aColunas)
            oGetGrid:SetOwner(oPanGrid)
            oGetGrid:SetBlkBackColor({|| fCorLinha() })
            oGetGrid:SetBlkColor({|| fCorTexto() })
            oGetGrid:Activate()
    ACTIVATE MsDialog oDlgGrp CENTERED
     
    //Deleta a temporaria
    oTempTable:Delete()
     
    RestArea(aArea)
Return
     
Static Function fMontaHead()
    Local nAtual
    Local aHeadAux := {}
     
    //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(aHeadAux, {"XXCODIGO", "Código",     "C",   6,  0, "",              .F.})
    aAdd(aHeadAux, {"XXDESCRI", "Descricao",  "C",  30,  0, "",              .F.})
    aAdd(aHeadAux, {"XXQUANTI", "Quantidade", "N",   9,  2, "@E 999,999.99", .T.})
    aAdd(aHeadAux, {"XXEMISSA", "Emissão",    "D",   8,  0, "",              .T.})
    aAdd(aHeadAux, {"XXOBSERV", "Observação", "C", 100,  0, "",              .T.})
     
    //Percorrendo e criando as colunas
    For nAtual := 1 To Len(aHeadAux)
        oColumn := FWBrwColumn():New()
        oColumn:SetData(&("{|| " + cAliasTab + "->" + aHeadAux[nAtual][1] +"}"))
        oColumn:SetTitle(aHeadAux[nAtual][2])
        oColumn:SetType(aHeadAux[nAtual][3])
        oColumn:SetSize(aHeadAux[nAtual][4])
        oColumn:SetDecimal(aHeadAux[nAtual][5])
        oColumn:SetPicture(aHeadAux[nAtual][6])
   
        //Se for ser possível ter o duplo clique
        If aHeadAux[nAtual][7]
            oColumn:SetEdit(.T.)
            oColumn:SetReadVar(aHeadAux[nAtual][1])
            //oColumn:SetValid({|| fSuaValid()})
        EndIf
   
        aAdd(aColunas, oColumn)
    Next
Return
     
Static Function fMontDados(oSay)
    Local aArea   := GetArea()
    Local nAtual  := 0
    Local nTotal  := 50
    Local dDtRef  := Date()
    Local cCodAtu := "000000"
    Local cDescri := ""
    Local nQuanti := 0
    Local dEmissa := sToD("")
     
    //Faz um laço de repetição
    For nAtual := 1 To nTotal
        //Muda a mensagem na regua
        nAtual++
        oSay:SetText("Adicionando registro " + cValToChar(nAtual) + " de " + cValToChar(nTotal) + "...")
   
        //Pega as variáveis que vão ser gravadas
        cCodAtu := Soma1(cCodAtu)
        cDescri := "[" + Time() + "] Teste - " + cCodAtu
        nQuanti := Randomize(-5, 5)
        dEmissa := DaySub(dDtRef, nAtual)
   
        //Insere os dados na temporária
        RecLock(cAliasTab, .T.)
            (cAliasTab)->XXCODIGO := cCodAtu
            (cAliasTab)->XXDESCRI := cDescri
            (cAliasTab)->XXQUANTI := nQuanti
            (cAliasTab)->XXEMISSA := dEmissa
            (cAliasTab)->XXOBSERV := ""
        (cAliasTab)->(MsUnlock())
     
    Next
     
    RestArea(aArea)
Return
 
Static Function fCorLinha()
    Local nCorFundo := 0
    Local nLinha := (cAliasTab)->(Recno())
 
    //Se for a linha 0 a 5, será na cor amarela e o texto na cor cinza meio escuro
    If nLinha <= 5
        nCorFundo := RGB(232, 216, 000)

    //Se for a linha 6 a 10, fundo será vermelho e o texto será branco
    ElseIf nLinha >= 6 .And. nLinha <= 10
        nCorFundo := RGB(255, 000, 000)

    //Senão, fundo será verde o texto será preto
    Else
        nCorFundo := RGB(000, 255, 000)
    EndIf
 
Return nCorFundo

Static Function fCorTexto()
    Local nCorTexto := 0
    Local nLinha := (cAliasTab)->(Recno())
 
    //Se for a linha 0 a 5, será na cor amarela e o texto na cor cinza meio escuro
    If nLinha <= 5
        nCorTexto := RGB(108, 108, 108)

    //Se for a linha 6 a 10, fundo será vermelho e o texto será branco
    ElseIf nLinha >= 6 .And. nLinha <= 10
        nCorTexto := RGB(255, 255, 255)

    //Senão, fundo será verde o texto será preto
    Else
        nCorTexto := RGB(000, 000, 000)
    EndIf
 
Return nCorTexto

Forma 2 – Usando a herança da TGrid

O que acontece pessoal, é que a FWBrowse, logo após o Activate, ela tem um atributo chamado “oBrowse”, que esse cara herda os métodos e atributos da TGrid.

Pensando nisso, um dos métodos disponíveis é o SetRowColor, onde você passa o número da linha, a cor de fundo e a cor da linha.

Então a lógica do nosso exemplo é:

  1. Criar normalmente nossa dialog e nossa grid com FWBrowse
  2. Logo após acionar o método Activate, vamos chamar uma função que aqui demos o nome de fDefinCor
  3. Nessa função, iremos percorrer os dados da temporária, e da linha 0 a 5 vamos pintar de uma cor, da 6 a 10 de outra, e a partir da 11 de outra
 

Abaixo segue um código fonte desse exemplo:

#Include "Totvs.ch"
     
/*/{Protheus.doc} User Function zBrwCor
Função que demonstra como mudar a cor de uma linha
@type  Function
@author Atilio
@since  31/10/2023
@version version
/*/
     
User Function zBrwCor()
    Local aArea := GetArea()
    //Fontes
    Local cFontUti    := "Tahoma"
    Local oFontAno    := TFont():New(cFontUti,,-38)
    Local oFontSub    := TFont():New(cFontUti,,-20)
    Local oFontSubN   := TFont():New(cFontUti,,-20,,.T.)
    Local oFontBtn    := TFont():New(cFontUti,,-14)
    //Janela e componentes
    Private oDlgGrp
    Private oPanGrid
    Private oGetGrid
    Private aColunas := {}
    Private cAliasTab := "TMPSBM"
    //Tamanho da janela
    Private    aTamanho := MsAdvSize()
    Private    nJanLarg := aTamanho[5]
    Private    nJanAltu := aTamanho[6]
     
    //Cria a temporária
    oTempTable := FWTemporaryTable():New(cAliasTab)
         
    //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})
         
    //Define as colunas usadas, adiciona indice e cria a temporaria no banco
    oTempTable:SetFields( aFields )
    oTempTable:AddIndex("1", {"XXCODIGO"} )
    oTempTable:Create()
     
    //Monta o cabecalho
    fMontaHead()
     
    //Montando os dados, eles devem ser montados antes de ser criado o FWBrowse
    FWMsgRun(, {|oSay| fMontDados(oSay) }, "Processando", "Buscando grupos")
     
    //Criando a janela
    DEFINE MSDIALOG oDlgGrp TITLE "Dados" FROM 000, 000  TO nJanAltu, nJanLarg COLORS 0, 16777215 PIXEL
        //Labels gerais
        @ 004, 003 SAY "FAT"                     SIZE 200, 030 FONT oFontAno  OF oDlgGrp COLORS RGB(149,179,215) PIXEL
        @ 004, 050 SAY "Listagem Genérica de"    SIZE 200, 030 FONT oFontSub  OF oDlgGrp COLORS RGB(031,073,125) PIXEL
        @ 014, 050 SAY "Dados Temporários"       SIZE 200, 030 FONT oFontSubN OF oDlgGrp COLORS RGB(031,073,125) PIXEL
     
        //Botões
        @ 006, (nJanLarg/2-001)-(0052*01) BUTTON oBtnFech  PROMPT "Fechar"        SIZE 050, 018 OF oDlgGrp ACTION (oDlgGrp:End())   FONT oFontBtn PIXEL
     
        //Dados
        @ 024, 003 GROUP oGrpDad TO (nJanAltu/2-003), (nJanLarg/2-003) PROMPT "Browse" OF oDlgGrp COLOR 0, 16777215 PIXEL
        oGrpDad:oFont := oFontBtn
            oPanGrid := tPanel():New(033, 006, "", oDlgGrp, , , , RGB(000,000,000), RGB(254,254,254), (nJanLarg/2 - 13),     (nJanAltu/2 - 45))
            oGetGrid := FWBrowse():New()
            oGetGrid:DisableFilter()
            oGetGrid:DisableConfig()
            oGetGrid:DisableReport()
            oGetGrid:DisableSeek()
            oGetGrid:DisableSaveConfig()
            oGetGrid:SetFontBrowse(oFontBtn)
            oGetGrid:SetAlias(cAliasTab)
            oGetGrid:SetDataTable()
            oGetGrid:SetEditCell(.T., {|| .T.}) 
            oGetGrid:lHeaderClick := .F.
            oGetGrid:AddLegend(cAliasTab + "->XXQUANTI == 0", "YELLOW", "Quantidade zerada")
            oGetGrid:AddLegend(cAliasTab + "->XXQUANTI <  0", "RED",    "Quantidade menor que zero")
            oGetGrid:AddLegend(cAliasTab + "->XXQUANTI >  0", "GREEN",  "Quantidade maior que zero")
            oGetGrid:SetColumns(aColunas)
            oGetGrid:SetOwner(oPanGrid)
            oGetGrid:Activate()
 
            //Após o activate para carregar o "oBrowse" instanciado da TGrid
            fDefinCor()
    ACTIVATE MsDialog oDlgGrp CENTERED
     
    //Deleta a temporaria
    oTempTable:Delete()
     
    RestArea(aArea)
Return
     
Static Function fMontaHead()
    Local nAtual
    Local aHeadAux := {}
     
    //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(aHeadAux, {"XXCODIGO", "Código",     "C",   6,  0, "",              .F.})
    aAdd(aHeadAux, {"XXDESCRI", "Descricao",  "C",  30,  0, "",              .F.})
    aAdd(aHeadAux, {"XXQUANTI", "Quantidade", "N",   9,  2, "@E 999,999.99", .T.})
    aAdd(aHeadAux, {"XXEMISSA", "Emissão",    "D",   8,  0, "",              .T.})
    aAdd(aHeadAux, {"XXOBSERV", "Observação", "C", 100,  0, "",              .T.})
     
    //Percorrendo e criando as colunas
    For nAtual := 1 To Len(aHeadAux)
        oColumn := FWBrwColumn():New()
        oColumn:SetData(&("{|| " + cAliasTab + "->" + aHeadAux[nAtual][1] +"}"))
        oColumn:SetTitle(aHeadAux[nAtual][2])
        oColumn:SetType(aHeadAux[nAtual][3])
        oColumn:SetSize(aHeadAux[nAtual][4])
        oColumn:SetDecimal(aHeadAux[nAtual][5])
        oColumn:SetPicture(aHeadAux[nAtual][6])
   
        //Se for ser possível ter o duplo clique
        If aHeadAux[nAtual][7]
            oColumn:SetEdit(.T.)
            oColumn:SetReadVar(aHeadAux[nAtual][1])
            //oColumn:SetValid({|| fSuaValid()})
        EndIf
   
        aAdd(aColunas, oColumn)
    Next
Return
     
Static Function fMontDados(oSay)
    Local aArea   := GetArea()
    Local nAtual  := 0
    Local nTotal  := 50
    Local dDtRef  := Date()
    Local cCodAtu := "000000"
    Local cDescri := ""
    Local nQuanti := 0
    Local dEmissa := sToD("")
     
    //Faz um laço de repetição
    For nAtual := 1 To nTotal
        //Muda a mensagem na regua
        nAtual++
        oSay:SetText("Adicionando registro " + cValToChar(nAtual) + " de " + cValToChar(nTotal) + "...")
   
        //Pega as variáveis que vão ser gravadas
        cCodAtu := Soma1(cCodAtu)
        cDescri := "[" + Time() + "] Teste - " + cCodAtu
        nQuanti := Randomize(-5, 5)
        dEmissa := DaySub(dDtRef, nAtual)
   
        //Insere os dados na temporária
        RecLock(cAliasTab, .T.)
            (cAliasTab)->XXCODIGO := cCodAtu
            (cAliasTab)->XXDESCRI := cDescri
            (cAliasTab)->XXQUANTI := nQuanti
            (cAliasTab)->XXEMISSA := dEmissa
            (cAliasTab)->XXOBSERV := ""
        (cAliasTab)->(MsUnlock())
     
    Next
     
    RestArea(aArea)
Return
 
Static Function fDefinCor()
    Local nCor := 0
    Local nLinha := -1
 
    //Percorre a temporária
    While ! (cAliasTab)->(EoF())
        nLinha++
 
        //Se for a linha 0 a 5, será na cor amarela e o texto na cor cinza meio escuro
        If nLinha <= 5
            nCorFundo := RGB(232, 216, 000)
            nCorTexto := RGB(108, 108, 108)
 
        //Se for a linha 6 a 10, fundo será vermelho e o texto será branco
        ElseIf nLinha >= 6 .And. nLinha <= 10
            nCorFundo := RGB(255, 000, 000)
            nCorTexto := RGB(255, 255, 255)
 
        //Senão, fundo será verde o texto será preto
        Else
            nCorFundo := RGB(000, 255, 000)
            nCorTexto := RGB(000, 000, 000)
        EndIf
 
        //Caso queira ver a documentação do método - https://tdn.totvs.com/display/tec/TGrid%3ASetRowColor
        oGetGrid:oBrowse:SetRowColor(nLinha, nCorFundo, nCorTexto )
 
        (cAliasTab)->(DbSkip())
    EndDo
    (cAliasTab)->(DbGoTop())
 
Return nCor

Bom pessoal, por hoje é só.

Abraços e até a próxima.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

Deixe uma resposta

Terminal de Informação