Adicionar Clique no Cabeçalho de Colunas num FWBrowse | Ti Responde 0253

No vídeo de hoje, vamos demonstrar em como criar lógicas diferentes para o clique do cabeçalho das colunas num FWBrowse.

A dúvida de hoje, nos perguntaram, em como criar tratativas diferentes ao clicar no cabeçalho de uma coluna usando FWBrowse.

Pensando nisso, montamos um exemplo, onde vamos demonstrar em como criar marcação de dados, ordenar valores e mudar cor de uma coluna ao clicar no cabeçalho.

Segue abaixo o vídeo exemplificando:

Abaixo o código fonte desenvolvido:

//Bibliotecas
#Include "Totvs.ch"
#Include "FWMVCDef.ch"
  
/*/{Protheus.doc} User Function zVid0253
Tela de Produtos (baseado no zVid0060)
@author Atilio
@since 30/08/2022
@version 1.0
@type function
@obs Codigo gerado automaticamente pelo Autumn Code Maker
@see http://autumncodemaker.com
/*/
  
User Function zVid0253()
    Local aArea := FWGetArea()
    Local aPergs   := {}
    Local xPar0 := Space(TamSX3("B1_COD")[1])
    Local xPar1 := StrTran(xPar0, ' ', 'Z')
      
    //Adicionando os parametros do ParamBox
    aAdd(aPergs, {1, "Produto De", xPar0,  "", ".T.", "SB1", ".T.", 80,  .F.})
    aAdd(aPergs, {1, "Produto Até", xPar1,  "", ".T.", "SB1", ".T.", 80,  .T.})
      
    //Se a pergunta for confirma, chama a tela
    If ParamBox(aPergs, "Informe os parametros", , , , , , , , , .F., .F.)
        fMontaTela()
    EndIf
      
    FWRestArea(aArea)
Return
  
/*/{Protheus.doc} fMontaTela
Monta a tela com a marcação de dados
@author Atilio
@since 30/08/2022
@version 1.0
@type function
@obs Codigo gerado automaticamente pelo Autumn Code Maker
@see http://autumncodemaker.com
/*/
  
Static Function fMontaTela()
    Local aArea         := GetArea()
    Local aCampos := {}
    Local oTempTable := Nil
    Local aColunas := {}
    Local cFontPad    := 'Tahoma'
    Local oFontGrid   := TFont():New(cFontPad,,-14)
    Local lOk         := .F.
    Local bBlocoOk    := {|| lOk := .T., oDlgBrowse:End()}
    Local bBlocoCan   := {|| lOk := .F., oDlgBrowse:End()}
    Local aOutrasAc   := { }
    Local bBlocoIni   := {|| EnchoiceBar(oDlgBrowse, bBlocoOk, bBlocoCan, , aOutrasAc)}
    //Janela e componentes
    Private oDlgBrowse
    Private oPanGrid
    Private oBrowseTmp
    Private cAliasTmp := GetNextAlias()
    //Tamanho da janela
    Private aTamanho := MsAdvSize()
    Private nJanLarg := aTamanho[5]
    Private nJanAltu := aTamanho[6]
    //Ordenação da tela
    Private cUltOrdem := ""
    Private lDescend  := .F.
       
    //Adiciona as colunas que serão criadas na temporária
    aAdd(aCampos, { 'FLAG_OK', 'L', 1,                    0}) //Flag para marcação
    aAdd(aCampos, { 'B1_COD', 'C', 15, 0}) //Código
    aAdd(aCampos, { 'B1_DESC', 'C', 30, 0}) //Descrição
    aAdd(aCampos, { 'B1_TIPO', 'C', 2, 0}) //Tipo
    aAdd(aCampos, { 'B1_UM', 'C', 2, 0}) //Unidade Medida
  
    //Cria a tabela temporária
    oTempTable:= FWTemporaryTable():New(cAliasTmp)
    oTempTable:SetFields( aCampos )
    oTempTable:AddIndex("1", {"B1_COD"} )
    oTempTable:AddIndex("2", {"B1_DESC"} )
    oTempTable:Create()  
  
    //Popula a tabela temporária
    Processa({|| fPopula()}, 'Processando...')
  
    //Adiciona as colunas que serão exibidas no FWMarkBrowse
    aColunas := fCriaCols()
       
    //Criando a janela
    oDlgBrowse := TDialog():New(0, 0, nJanAltu, nJanLarg, 'Tela para Análise de Dados', , , , , , /*nCorFundo*/, , , .T.)
        //Dados
        oPanGrid := tPanel():New(030, 001, '', oDlgBrowse, , , , RGB(000,000,000), RGB(254,254,254), (nJanLarg/2)-1,     (nJanAltu/2 - 10))
        oBrowseTmp := FWBrowse():New()
        oBrowseTmp:SetDataTable()
        oBrowseTmp:SetInsert(.F.)
        oBrowseTmp:SetDelete(.F., { || .F. })
        oBrowseTmp:SetAlias(cAliasTmp)
        oBrowseTmp:DisableReport()
        oBrowseTmp:DisableFilter()
        oBrowseTmp:DisableConfig()
        oBrowseTmp:DisableReport()
        oBrowseTmp:DisableSeek()
        oBrowseTmp:DisableSaveConfig()
        oBrowseTmp:AddLegend(cAliasTmp + "->B1_TIPO == 'PA'",                                          "GREEN",       "Produto Acabado")
        oBrowseTmp:AddLegend(cAliasTmp + "->B1_TIPO == 'PI'",                                          "YELLOW",      "Produto Intermediário")
        oBrowseTmp:AddLegend(cAliasTmp + "->B1_TIPO != 'PA' .And. " + cAliasTmp + "->B1_TIPO != 'PI'", "RED",         "Outros Tipos")
        oBrowseTmp:SetFontBrowse(oFontGrid)
        oBrowseTmp:AddMarkColumns(;
            {|| Iif((cAliasTmp)->FLAG_OK, 'LBOK', 'LBNO') },;      //ícones
            {|| (cAliasTmp)->FLAG_OK := ! (cAliasTmp)->FLAG_OK};   //ao dar duplo clique
        )
        oBrowseTmp:SetColumns(aColunas)
        oBrowseTmp:SetOwner(oPanGrid)
        oBrowseTmp:lHeaderClick := .T.
        oBrowseTmp:SetItemHeaderClick({"B1_COD", "B1_DESC", "B1_TIPO"})
        oBrowseTmp:Activate()
        oBrowseTmp:aColumns[2]:bHeaderClick := {|| fMarcaTudo()}
    oDlgBrowse:Activate(, , , .T., , , bBlocoIni)
      
    //Deleta a temporária e desativa a tela de marcação
    oTempTable:Delete()
    oBrowseTmp:DeActivate()
      
    RestArea(aArea)
Return
  
/*/{Protheus.doc} fPopula
Executa a query SQL e popula essa informação na tabela temporária usada no browse
@author Atilio
@since 30/08/2022
@version 1.0
@type function
@obs Codigo gerado automaticamente pelo Autumn Code Maker
@see http://autumncodemaker.com
/*/
  
Static Function fPopula()
    Local cQryDados := ''
    Local nTotal := 0
    Local nAtual := 0
  
    //Monta a consulta
    cQryDados += "SELECT "        + CRLF
    cQryDados += " B1_COD, "        + CRLF
    cQryDados += " B1_DESC, "        + CRLF
    cQryDados += " B1_TIPO, "        + CRLF
    cQryDados += " B1_UM "        + CRLF
    cQryDados += "FROM "        + CRLF
    cQryDados += " SB1990 SB1 "        + CRLF
    cQryDados += "WHERE "        + CRLF
    cQryDados += " B1_FILIAL = '" + FWxfilial('SB1') + "' "        + CRLF
    cQryDados += " AND B1_COD >= '" + MV_PAR01 + "' "        + CRLF
    cQryDados += " AND B1_COD <= '" + MV_PAR02 + "' "        + CRLF
    cQryDados += " AND SB1.D_E_L_E_T_ = ' ' "        + CRLF
    cQryDados += "ORDER BY "        + CRLF
    cQryDados += " B1_COD"        + CRLF
    PLSQuery(cQryDados, 'QRYDADTMP')
  
    //Definindo o tamanho da régua
    DbSelectArea('QRYDADTMP')
    Count to nTotal
    ProcRegua(nTotal)
    QRYDADTMP->(DbGoTop())
  
    //Enquanto houver registros, adiciona na temporária
    While ! QRYDADTMP->(EoF())
        nAtual++
        IncProc('Analisando registro ' + cValToChar(nAtual) + ' de ' + cValToChar(nTotal) + '...')
  
        RecLock(cAliasTmp, .T.)
            (cAliasTmp)->B1_COD := QRYDADTMP->B1_COD
            (cAliasTmp)->B1_DESC := QRYDADTMP->B1_DESC
            (cAliasTmp)->B1_TIPO := QRYDADTMP->B1_TIPO
            (cAliasTmp)->B1_UM := QRYDADTMP->B1_UM
        (cAliasTmp)->(MsUnlock())
  
        QRYDADTMP->(DbSkip())
    EndDo
    QRYDADTMP->(DbCloseArea())
    (cAliasTmp)->(DbGoTop())
Return
  
/*/{Protheus.doc} fCriaCols
Função que gera as colunas usadas no browse (similar ao antigo aHeader)
@author Atilio
@since 30/08/2022
@version 1.0
@type function
@obs Codigo gerado automaticamente pelo Autumn Code Maker
@see http://autumncodemaker.com
/*/
  
Static Function fCriaCols()
    Local nAtual       := 0 
    Local aColunas := {}
    Local aEstrut  := {}
    Local oColumn
      
    //Adicionando campos que serão mostrados na tela
    //[1] - Campo da Temporaria
    //[2] - Titulo
    //[3] - Tipo
    //[4] - Tamanho
    //[5] - Decimais
    //[6] - Máscara
    aAdd(aEstrut, { 'B1_COD',  'Código', 'C', 15, 0, ''})
    aAdd(aEstrut, { 'B1_DESC', 'Descrição', 'C', 30, 0, ''})
    aAdd(aEstrut, { 'B1_TIPO', 'Tipo', 'C', 2, 0, ''})
    aAdd(aEstrut, { 'B1_UM',   'Unidade Medida', 'C', 2, 0, ''})
  
    //Percorrendo todos os campos da estrutura
    For nAtual := 1 To Len(aEstrut)
        //Cria a coluna
        oColumn := FWBrwColumn():New()
        oColumn:SetData(&('{|| ' + cAliasTmp + '->' + aEstrut[nAtual][1] +'}'))
        oColumn:SetTitle(aEstrut[nAtual][2])
        oColumn:SetType(aEstrut[nAtual][3])
        oColumn:SetSize(aEstrut[nAtual][4])
        oColumn:SetDecimal(aEstrut[nAtual][5])
        oColumn:SetPicture(aEstrut[nAtual][6])
  
        //Se for o código ou descrição, adiciona a opção de clique no cabeçalho
        If Alltrim(aEstrut[nAtual][1]) $ "B1_COD;B1_DESC;"
            oColumn:bHeaderClick := &("{|| fOrdena('" + aEstrut[nAtual][1] + "') }")
        ElseIf Alltrim(aEstrut[nAtual][1]) $ "B1_TIPO;"
            oColumn:bHeaderClick := {|| fMudaCor()}
        EndIf
  
        //Adiciona a coluna
        aAdd(aColunas, oColumn)
    Next
Return aColunas
  
Static Function fOrdena(cCampo)
    Default cCampo := ""
  
    //Pegando o Índice conforme o campo
    cCampo := Alltrim(cCampo)
    If cCampo == "B1_COD"
        nOrder := 1
    ElseIf cCampo == "B1_DESC"
        nOrder := 2
    EndIf
  
    //Ordena pelo Índice
    (cAliasTmp)->(DbSetOrder(nOrder))
  
    //Se o último campo clicado é o mesmo, irá mudar entre crescente / decrescente
    If cUltOrdem == cCampo
        //Se esta como decrescente, ordena crescente
        If lDescend
            OrdDescend(nOrder, cValToChar(nOrder), .F.)
            lDescend := .F.
  
        //Se esta como crescente, ordena como decrescente
        Else
            OrdDescend(nOrder, cValToChar(nOrder), .T.)
            lDescend := .T.
        EndIf
    Else
        lDescend := .F.
    EndIf
    cUltOrdem := cCampo
  
    fRefresh()
Return
  
Static Function fRefresh()
    (cAliasTmp)->(DbGoTop())
    oBrowseTmp:GoBottom(.T.)
    oBrowseTmp:Refresh(.T.)
    oBrowseTmp:GoTop(.T.)
    oBrowseTmp:Refresh(.T.)
Return

Static Function fMudaCor()
    Local nAzul     := Random(200, 255)
    Local nVerde    := Random(200, 255)
    Local nVermelho := Random(200, 255)

    //Muda a cor da coluna
    oBrowseTmp:oBrowse:SetColumnColor(;
        4,;                              //Número da Coluna
        RGB(nVermelho, nVerde, nAzul),;  //Cor de Fundo
        RGB(100,       100,    100); //Cor do Texto
    )
    oBrowseTmp:Refresh()
Return

Static Function fMarcaTudo()

    //Percorre os dados da temporária
    (cAliasTmp)->(DbGoTop())
    While ! (cAliasTmp)->(EoF())

        //Marca ou desmarca o registro
        RecLock(cAliasTmp, .F.)
            (cAliasTmp)->FLAG_OK := Iif((cAliasTmp)->FLAG_OK, .F., .T.)
        (cAliasTmp)->(MsUnlock())

        (cAliasTmp)->(DbSkip())
    EndDo
    (cAliasTmp)->(DbGoTop())
    oBrowseTmp:Refresh(.T.)
Return

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