Criando um MarkBrowse com Mais de uma Coluna de Legenda | Ti Responde 0199

No vídeo de hoje, vamos demonstrar em como criar um MarkBrowse com mais de uma coluna de legenda.

A dúvida de hoje, nos perguntaram, se seria possível criar uma tela com marcação de dados (por exemplo usando a FWMarkBrowse), mas que houvesse a possibilidade de ter mais de uma legenda.

 

Pensando nisso, montamos um exemplo, onde vamos mostrar em como montar uma FWBrowse com AddMarkColumns e com 3 colunas de legendas distintas.

 

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 video0199
Teste de grid com marcação com mais de uma legenda
@type Function
@author Atilio
@since 03/06/2024
@example custom.terminal.youtube.u_video0199()
/*/

User Function video0199()
	Local aArea       := FWGetArea()                   As Array
	Local aParameters := {}                            As Array
	Local cInitId     := Space(TamSX3('B1_COD')[1])    As Character
	Local cLastId     := StrTran(cInitId, " ", "Z")    As Character
	
	//Adicionando os parametros do ParamBox
	aAdd(aParameters, {1, "Produto De",  cInitId,   "", ".T.", "SB1", ".T.", 80,  .F.})
	aAdd(aParameters, {1, "Produto Até", cLastId,  "", ".T.", "SB1", ".T.", 80,  .T.})
	
	//Se a pergunta for confirmada, chama o preenchimento dos dados do .dot
	If ParamBox(aParameters, 'Informe os parâmetros', /*aRet*/, /*bOk*/, /*aButtons*/, /*lCentered*/, /*nPosx*/, /*nPosy*/, /*oDlgWizard*/, /*cLoad*/, .F., .F.)
		Processa({|| createDialog()})
	EndIf
	
	FWRestArea(aArea)
Return

Static Function createDialog()
    Local aArea             := FWGetArea()                  As Array
    Local lOk               := .F.                          As Logical
    Local cMessageLog       := ""                           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 oFontSubtitle     := TFont():New(cFont,,-20,,.T.) As Object
    Local oFontButtons      := TFont():New(cFont,,-14)      As Object
    //Janela e componentes
    Private oTestDialog                                     As Object
    Private oTempTable                                      As Object
    Private oPanelBrowse                                    As Object
    Private oTempBrowse                                     As Object
    Private aGridColumns    := {}                           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, { 'FLAG_OK', 'L', 1,                       0}) //Flag para marcação
    aAdd(aFields, { 'B1_COD',  'C', TamSX3('B1_COD')[1],     0}) //Produto
    aAdd(aFields, { 'B1_TIPO', 'C', TamSX3('B1_TIPO')[1],    0}) //Tipo
    aAdd(aFields, { 'B1_UM',   'C', TamSX3('B1_UM')[1],      0}) //Unid. Med.
    aAdd(aFields, { 'B1_DESC', 'C', TamSX3('B1_DESC')[1],    0}) //Descrição
    aAdd(aFields, { 'B1_MSBLQL','C', TamSX3('B1_MSBLQL')[1], 0}) //Bloqueio
    aAdd(aFields, { 'RECNUM',  'N', 16,                      0}) //RecNo da SB1
        
    //Define as colunas usadas, adiciona indice e cria a temporaria no banco
    oTempTable:SetFields( aFields )
    oTempTable:AddIndex("1", {"B1_COD"} )
    oTempTable:Create()
    
    //Monta a estrutura das colunas
    mountColumns()
    
    //Montando os dados, eles devem ser montados antes de ser criado o FWBrowse
    FWMsgRun(, {|oSay| insertInTemporary(oSay) }, "Processando", "Buscando grupos")
    
    //Criando a janela
    oTestDialog := TDialog():New(0, 0, nDialogHeight, nDialogWidth, "Teste Tabela Temporária", , , , , , 16777215, , , .T.)

        //Títulos e SubTítulos
        oSayBigger   := TSay():New(004, 003, {|| "FAT"                 }, oTestDialog, "", oFontBigger,  , , , .T., RGB(149, 179, 215), , 200, 30, , , , , , .F., , )
        oSayTitle    := TSay():New(004, 050, {|| "Listagem Genérica de"}, oTestDialog, "", oFontTitle,  , , , .T., RGB(031, 073, 125), , 200, 30, , , , , , .F., , )
        oSaySubtitle := TSay():New(014, 050, {|| "Dados Temporários"   }, oTestDialog, "", oFontSubtitle, , , , .T., RGB(031, 073, 125), , 300, 30, , , , , , .F., , )

        //Botões
        oBtnOk     := TButton():New(006, (nDialogWidth/2-001)-(0052*02), "Confirmar",          oTestDialog, {|| lOk := .T., oTestDialog:End()}, 050, 018, , oFontButtons, , .T., , , , , , )
        oBtnCancel := TButton():New(006, (nDialogWidth/2-001)-(0052*01), "Fechar",             oTestDialog, {|| oTestDialog:End()}, 050, 018, , oFontButtons, , .T., , , , , , )
    
        //Cria o Painel e o Browse
        oPanelBrowse := tPanel():New(033, 006, "", oTestDialog, , , , RGB(000,000,000), RGB(254,254,254), (nDialogWidth/2 - 13),     (nDialogHeight/2 - 45))
            oTempBrowse := FWBrowse():New()
            oTempBrowse:DisableFilter()
            oTempBrowse:DisableConfig()
            oTempBrowse:DisableReport()
            oTempBrowse:DisableSeek()
            oTempBrowse:DisableSaveConfig()
            oTempBrowse:SetFontBrowse(oFontButtons)
            oTempBrowse:SetAlias(cTempAlias)
            oTempBrowse:SetDataTable()
            oTempBrowse:SetEditCell(.T., {|| .T.}) 
            oTempBrowse:lHeaderClick := .F.
            oTempBrowse:AddMarkColumns(;
                {|| Iif((cTempAlias)->FLAG_OK, 'LBOK', 'LBNO') },;             //ícones
                {|| (cTempAlias)->FLAG_OK := ! (cTempAlias)->FLAG_OK};   //ao dar duplo clique
            )
            
            //Adicionando as Legendas (coluna 1)
            oTempBrowse:AddLegend(cTempAlias + "->B1_MSBLQL == '1'",          'BR_CANCEL',   'Produto Bloqueado',     '1')
            oTempBrowse:AddLegend(cTempAlias + "->B1_MSBLQL != '1'",          'CHECKED',     'Produto Ativo',         '1')

            //Adicionando as Legendas (coluna 2)
            oTempBrowse:AddLegend(cTempAlias + "->B1_TIPO == 'PA'",           'GREEN',       'Produto Acabado',       '2')
            oTempBrowse:AddLegend(cTempAlias + "->B1_TIPO == 'PI'",           'RED',         'Produto Intermediário', '2')
            oTempBrowse:AddLegend("! " + cTempAlias + "->B1_TIPO $ 'PA;PI;'", 'WHITE',       'Outros Tipos',          '2')

            //Adicionando as Legendas (coluna 3)
            oTempBrowse:AddLegend(cTempAlias + "->B1_UM == 'UN'",             'YELLOW',      'Unitário (UN)',         '3')
            oTempBrowse:AddLegend(cTempAlias + "->B1_UM == 'KG'",             'BLACK',       'Quilograma (KG)',       '3')
            oTempBrowse:AddLegend("! " +cTempAlias + "->B1_UM $ 'UN;KG;'",    'PINK',        'Outras Unidades',       '3')

            //Define as colunas, vincula ao painel e exibe
            oTempBrowse:SetColumns(aGridColumns)
            oTempBrowse:SetOwner(oPanelBrowse)
            oTempBrowse:Activate()

    //Ativa e exibe a janela
    oTestDialog:Activate(, , , .T., , , {|| })
    
    //Se foi confirmado
    If lOk
        cMessageLog := "Abaixo os registros marcados da temporária: " + CRLF

        //Percorre os dados
        (cTempAlias)->(DbGoTop())
        While ! (cTempAlias)->(EoF())
            //Se tiver apagado, incrementa o log
            If (cTempAlias)->FLAG_OK
                cMessageLog += "+ Código " + (cTempAlias)->B1_COD + ";" + CRLF
            EndIf

            (cTempAlias)->(DbSkip())
        EndDo

        //Exibe a mensagem de log
        ShowLog(cMessageLog)
    EndIf

    //Deleta a temporaria
    oTempTable:Delete()
    
    FWRestArea(aArea)
Return
    
Static Function mountColumns()
    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, { 'B1_COD',  'Produto',    'C', TamSX3('B1_COD')[1],  0, '',     .F.})
    aAdd(aTempColumns, { 'B1_TIPO', 'Tipo',       'C', TamSX3('B1_TIPO')[1], 0, '',     .F.})
    aAdd(aTempColumns, { 'B1_UM',   'Unid. Med.', 'C', TamSX3('B1_UM')[1],   0, '',     .F.})
    aAdd(aTempColumns, { 'B1_DESC', 'Descrição',  'C', TamSX3('B1_DESC')[1], 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(aGridColumns, oColumn)
    Next
Return
    
Static Function insertInTemporary(oSay)
    Local cQuery   := '' As Character
    Local nTotal   := 0  As Numeric
    Local nCurrent := 0  As Numeric

    //Monta a consulta
    cQuery += "SELECT B1_COD, B1_TIPO, B1_UM, B1_DESC, SB1.R_E_C_N_O_ AS SB1REC, B1_MSBLQL "		+ CRLF
    cQuery += "FROM SB1990 SB1 "		+ CRLF
    cQuery += "WHERE B1_FILIAL = '' AND B1_COD >= '" + MV_PAR01 + "' AND B1_COD <= '" + MV_PAR02 + "' AND SB1.D_E_L_E_T_ = ' ' "		+ CRLF
    cQuery += "ORDER BY B1_COD"		+ CRLF
    PLSQuery(cQuery, 'QRYTMP')

    //Definindo o tamanho da régua
    DbSelectArea('QRYTMP')
    Count to nTotal
    ProcRegua(nTotal)
    QRYTMP->(DbGoTop())

    //Enquanto houver registros, adiciona na temporária
    While ! QRYTMP->(EoF())
        nCurrent++
        IncProc('Analisando registro ' + cValToChar(nCurrent) + ' de ' + cValToChar(nTotal) + '...')

        RecLock(cTempAlias, .T.)
            (cTempAlias)->FLAG_OK   := .F.
            (cTempAlias)->B1_COD    := QRYTMP->B1_COD
            (cTempAlias)->B1_TIPO   := QRYTMP->B1_TIPO
            (cTempAlias)->B1_UM     := QRYTMP->B1_UM
            (cTempAlias)->B1_DESC   := QRYTMP->B1_DESC
            (cTempAlias)->RECNUM    := QRYTMP->SB1REC
            (cTempAlias)->B1_MSBLQL := QRYTMP->B1_MSBLQL
        (cTempAlias)->(MsUnlock())

        QRYTMP->(DbSkip())
    EndDo
    QRYTMP->(DbCloseArea())
    (cTempAlias)->(DbGoTop())
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