FWBrowse com Array e atualizar por TTimer

Senhores, tenho um FWBrowse com SetDataArray, está funcionando bem, porém preciso colocar a instrução DEFINE TIMER para atualizar o array e logo refletir no FWBrowse. Quando o TIMER aciona, o array e atualizado, passo novamente para o SetArray da classe FWBrowse, porém os dados não atualizam. Alguém pode ajudar? Segue o protótipo para uma noção do que fiz e do que preciso. Obrigado!

User Function Gerenciador() Local bSair := {|| .T. }

Local nHeight := 0 Local nWidth := 0

Local oArea Local oBtn1, oBtn2, oBtn3, oBtn4, oBtn5, oBtn6, oBtn7 Local oCenterPanel Local oDlg Local oLayout Local oPanel Local oOption Local oSide

Private aHeader := {} Private nCateg := 1 Private oBrowse Private oColumn

aHeader := {'Coluna 1','Coluna 2','Coluna 3','Coluna 4','Coluna 5','Coluna 6','Coluna 7','Coluna 8','Coluna 9','Coluna 10','Coluna 11','Coluna 12'}

bSair := {|| Iif(MsgYesNo('Deseja realmente sair do gerenciamento?','Gerenciamento'),(oDlg:End()),NIL)}

oMainWnd:ReadClientCoors() nHeight := oMainWnd:nHeight-50 nWidth := oMainWnd:nWidth-15

DEFINE MSDIALOG oDlg FROM 0,0 TO nHeight,nWidth TITLE "" PIXEL STYLE nOR(WS_VISIBLE,WS_POPUP) oPanel := TPanel():New(0,0,,oDlg,,,,,,15,0,.F.,.F.) oPanel:Align := CONTROL_ALIGN_ALLCLIENT

oArea := FWArea():New(000,000,nHeight/2,nWidth,oPanel,0) oArea:CreateBorder(2)

oArea:AddSideBar ( 12, 1, "oSide" ) oSide := oArea:GetSideBar("oSide")

oArea:AddWindow ( 100, 100, "cId1" ,"Ações", 3 , 2,oSide, CONTROL_ALIGN_TOP ) oArea:AddPanel(100,100,"oOption") oOption := oArea:GetPanel("oOption")

oBtn1 := TButton():New( 1,202,'Opção 1' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. ) oBtn1:Align := CONTROL_ALIGN_TOP

oBtn2 := TButton():New( 1,202,'Opção 2' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. ) oBtn2:Align := CONTROL_ALIGN_TOP

oBtn3 := TButton():New( 1,202,'Opção 3' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. ) oBtn3:Align := CONTROL_ALIGN_TOP

oBtn4 := TButton():New( 1,202,'Opção 4' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. ) oBtn4:Align := CONTROL_ALIGN_TOP

oBtn5 := TButton():New( 1,202,'Opção 5' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. ) oBtn5:Align := CONTROL_ALIGN_TOP

oBtn6 := TButton():New( 1,202,'Opção 6' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. ) oBtn6:Align := CONTROL_ALIGN_TOP

oBtn7 := TButton():New( 1,202,'Sair' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. ) oBtn7:Align := CONTROL_ALIGN_BOTTOM

oArea:AddLayout ( "Default" ) oLayout := oArea:GetLayout ( "Default" )

oArea:AddWindow ( 100, 100, "cId2","Posicionamento", 3 , 3,oLayout, CONTROL_ALIGN_TOP ) oArea:AddPanel(100,100,"oCenterPanel") oCenterPanel := oArea:GetPanel("oCenterPanel")

MontaBrw(@oCenterPanel)

DEFINE TIMER oTimer INTERVAL 4000 ACTION (UpdSetArray()) OF GetWndDefault() oTimer:Activate()

ACTIVATE MSDIALOG oDlg CENTERED Return

Static Function MontaBrw(oObjFather) Local aFields := {} Local i := 0

If oBrowse<>NIL oBrowse:DeActivate() Endif

Aadd( aFields, { "Coluna 1","Coluna 1","C",2,0,""} ) Aadd( aFields, { "Coluna 2","Coluna 2","C",40,0,""} )

aList := {} For i := 1 To 20 AAdd(aList,{LTrim(StrZero(i,2)),'ADULTO '+Chr(64+i),'0','1','2','0','1','2','0','1','2',''}) Next i

oBrowse := FwBrowse():New() oBrowse:SetOwner(oObjFather) oBrowse:SetDataArray() oBrowse:SetArray(aList) oBrowse:SetFieldFilter(aFields) oBrowse:SetUseFilter()

oBrowse:DisableSeek() oBrowse:DisableReport() oBrowse:DisableConfig() oBrowse:DisableLocate()

oColumn := FWBrwColumn():New() oColumn:SetData( &(" { || aList[oBrowse:At(),1]}")) oColumn:SetTitle(aHeader[1]) oColumn:SetSize(2) oBrowse:SetColumns({oColumn})

oColumn := FWBrwColumn():New() oColumn:SetData( &(" { || aList[oBrowse:At(),2]}")) oColumn:SetTitle(aHeader[2]) oColumn:SetSize(40) oBrowse:SetColumns({oColumn})

oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,3])}, {|| Legend()}) oBrowse:aColumns[3]:cTitle := aHeader[3] oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,4])}, {|| Legend()}) oBrowse:aColumns[4]:cTitle := aHeader[4] oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,5])}, {|| Legend()}) oBrowse:aColumns[5]:cTitle := aHeader[5] oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,6])}, {|| Legend()}) oBrowse:aColumns[6]:cTitle := aHeader[6] oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,7])}, {|| Legend()}) oBrowse:aColumns[7]:cTitle := aHeader[7] oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,8])}, {|| Legend()}) oBrowse:aColumns[8]:cTitle := aHeader[8] oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,9])}, {|| Legend()}) oBrowse:aColumns[9]:cTitle := aHeader[9] oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,10])}, {|| Legend()}) oBrowse:aColumns[10]:cTitle := aHeader[10] oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,11])}, {|| Legend()}) oBrowse:aColumns[11]:cTitle := aHeader[11]

oColumn := FWBrwColumn():New() oColumn:SetData( &(" { || aList[oBrowse:At(),12]}")) oColumn:SetTitle(aHeader[12]) oColumn:SetSize(2) oBrowse:SetColumns({oColumn})

oBrowse:Activate() Return

Static Function UpdSetArray() Local aCateg := {'ADULTO ','INFANTIL ', 'JUNIOR ', 'EXPERT '} Local aList := {} Local i := 0

nCateg++

If nCateg > Len(aCateg) nCateg := 1 Endif

aList := {}

For i := 1 To 20 AAdd(aList,{LTrim(StrZero(i,2)),aCateg[nCateg]+Chr(64+i),'0','1','2','0','1','2','0','1','2',''}) Next i

oBrowse:SetDataArray() oBrowse:SetArray(aList) oBrowse:Refresh() Return

Static Function Legend() Local oLegend

oLegend := FWLegend():New() oLegend:Add('','BR_VERDE' ,'Realizado' ) oLegend:Add('','BR_VERMELHO','A realizar' ) oLegend:Activate() oLegend:View() oLegend:DeActivate() Return

Static Function Status(cSit) Local cStatus := '' If cSit == '1' cStatus :='BR_BRANCO' Elseif cSit == '2' cStatus := 'BR_VERDE' EndIf Return(cStatus)

Robson, seu exemplo gerou error.log pra mim. Mas corrigindo o error.log, a atualização ocorreu perfeitamente. O que acontece pra você, gera erro? Não atualiza?

Oi Daniel, não gerou error, apenas não atualiza as linhas da FWBrowse. Estou na versão 12.1.27. Qual orientação posso seguir?

Já fiz assim e funcionou:

oBrowse:SetArray( aList ) oBrowse:Refresh()

Se não der certo, tenta algo assim:

oBrowse:SetDataArray() oBrowse:SetArray( aList ) oBrowse:Refresh() oBrowse:Data():DeActivate()oBrowse:Data():Activate() oBrowse:Refresh( .T. ) oBrowse:Activate()

Robson,

Eu tive alguns erros quando executei o POC, porém corrigindo os mesmos, o browse foi atualizado corretamente conforme a execução do TTimer.

Abaixo o seu POC com as correções que fiz para deixar de gerar error.log, remoção das variáveis private, tipagem das variáveis e criação dos cabeçalhos.


#include "protheus.ch"

//----------------------------------------------------------------------
/*/{Protheus.doc} Gerenciador
Exemplo de browse de array que atualiza os registros com TTimer

@sample U_Gerenciador()
@author Robson Gonçalves
@since 13/11/2020
@version 1.0
/*/
//----------------------------------------------------------------------
user function Gerenciador()
    local bSair as block
    local nHeight as numeric
    local nWidth as numeric
    local oArea as object
    local oBtn1 as object
    local oBtn2 as object
    local oBtn3 as object
    local oBtn4 as object
    local oBtn5 as object
    local oBtn6 as object
    local oBtn7 as object
    local oCenterPanel as object
    local oDlg as object
    local oLayout as object
    local oPanel as object
    local oOption as object
    local oSide as object
    local aHeader as array
    local nCateg as numeric
    local aList as array
    local oBrowse as object

    nCateg := 1
    aHeader := {'Coluna 1','Coluna 2','Coluna 3','Coluna 4','Coluna 5','Coluna 6','Coluna 7','Coluna 8','Coluna 9','Coluna 10','Coluna 11','Coluna 12'}
    bSair := {|| Iif(MsgYesNo('Deseja realmente sair do gerenciamento?','Gerenciamento'),(oDlg:End()),NIL)}

    oMainWnd:ReadClientCoors()

    nHeight := oMainWnd:nHeight-50
    nWidth  := oMainWnd:nWidth-15

    DEFINE MSDIALOG oDlg FROM 0,0 TO nHeight,nWidth TITLE "" PIXEL STYLE nOR(WS_VISIBLE,WS_POPUP)

    oPanel := TPanel():New(0,0,,oDlg,,,,,,15,0,.F.,.F.)
    oPanel:Align := CONTROL_ALIGN_ALLCLIENT

    oArea := FWArea():New(000,000,nHeight/2,nWidth,oPanel,0)
    oArea:CreateBorder(2)

    oArea:AddSideBar ( 12, 1, "oSide" )
    oSide := oArea:GetSideBar("oSide")

    oArea:AddWindow ( 100, 100, "cId1" ,"Ações", 3 , 2,oSide, CONTROL_ALIGN_TOP )
    oArea:AddPanel(100,100,"oOption")
    oOption := oArea:GetPanel("oOption")

    oBtn1 := TButton():New( 1,202,'Opção 1' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. )
    oBtn1:Align := CONTROL_ALIGN_TOP

    oBtn2 := TButton():New( 1,202,'Opção 2' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. )
    oBtn2:Align := CONTROL_ALIGN_TOP

    oBtn3 := TButton():New( 1,202,'Opção 3' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. )
    oBtn3:Align := CONTROL_ALIGN_TOP

    oBtn4 := TButton():New( 1,202,'Opção 4' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. )
    oBtn4:Align := CONTROL_ALIGN_TOP

    oBtn5 := TButton():New( 1,202,'Opção 5' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. )
    oBtn5:Align := CONTROL_ALIGN_TOP

    oBtn6 := TButton():New( 1,202,'Opção 6' ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. )
    oBtn6:Align := CONTROL_ALIGN_TOP

    oBtn7 := TButton():New( 1,202,'Sair'    ,oOption, bSair,35 ,15 ,,,.F. ,.T. ,.F. ,,.F. ,,,.F. )
    oBtn7:Align := CONTROL_ALIGN_BOTTOM

    oArea:AddLayout ( "Default" )
    oLayout := oArea:GetLayout ( "Default" )

    oArea:AddWindow ( 100, 100, "cId2","Posicionamento", 3 , 3,oLayout, CONTROL_ALIGN_TOP )
    oArea:AddPanel(100,100,"oCenterPanel")
    oCenterPanel := oArea:GetPanel("oCenterPanel")

    MontaBrw(@oCenterPanel, aHeader, @oBrowse, @aList)

    DEFINE TIMER oTimer INTERVAL 4000 ACTION (UpdSetArray(oBrowse, @nCateg, @aList)) OF GetWndDefault()    
    oTimer:Activate()    

    ACTIVATE MSDIALOG oDlg CENTERED
return

//----------------------------------------------------------------------
/*/{Protheus.doc} MontaBrw
Cria e ativa o browse (FWBrowse) com suas respectivas colunas

@param oObjFather Objeto owner do browse
@param aHeader Array contendo as informações das colunas do browse
@param oBrowse Objeto do browse
@param aList Array que corresponde as linhas do browse

@author Robson Gonçalves
@since 13/11/2020
@version 1.0
/*/
//----------------------------------------------------------------------
static function MontaBrw(oObjFather, aHeader, oBrowse, aList)
    local aFields as array
    local nI as numeric
    local oColumn as object

    if oBrowse != nil
        oBrowse:DeActivate()
    endif

    aFields := {}

    Aadd( aFields, { "Coluna 1","Coluna 1","C",2,0,""} )
    Aadd( aFields, { "Coluna 2","Coluna 2","C",40,0,""} )

    aList := {}

    for nI := 1 to 20
        AAdd(aList,{LTrim(StrZero(nI,2)),'ADULTO '+Chr(64+nI),'0','1','2','0','1','2','0','1','2',''})
    next

    oBrowse := FwBrowse():New()
    oBrowse:SetOwner(oObjFather)
    oBrowse:SetDataArray()
    oBrowse:SetArray(aList)
    oBrowse:SetFieldFilter(aFields)
    oBrowse:SetUseFilter()

    oBrowse:DisableSeek()
    oBrowse:DisableReport()
    oBrowse:DisableConfig()
    oBrowse:DisableLocate()

    oColumn := FWBrwColumn():New()
    oColumn:SetData( &(" { || aList[oBrowse:At(),1]}"))
    oColumn:SetTitle(aHeader[1])
    oColumn:SetSize(2)
    oBrowse:SetColumns({oColumn})

    oColumn := FWBrwColumn():New()
    oColumn:SetData( &(" { || aList[oBrowse:At(),2]}"))
    oColumn:SetTitle(aHeader[2])
    oColumn:SetSize(40)
    oBrowse:SetColumns({oColumn})

    oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,3])}, {|| Legend()})
    oBrowse:aColumns[3]:cTitle := aHeader[3]
    oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,4])}, {|| Legend()})
    oBrowse:aColumns[4]:cTitle := aHeader[4]
    oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,5])}, {|| Legend()})
    oBrowse:aColumns[5]:cTitle := aHeader[5]
    oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,6])}, {|| Legend()})
    oBrowse:aColumns[6]:cTitle := aHeader[6]
    oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,7])}, {|| Legend()})
    oBrowse:aColumns[7]:cTitle := aHeader[7]
    oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,8])}, {|| Legend()})
    oBrowse:aColumns[8]:cTitle := aHeader[8]
    oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,9])}, {|| Legend()})
    oBrowse:aColumns[9]:cTitle := aHeader[9]
    oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,10])}, {|| Legend()})
    oBrowse:aColumns[10]:cTitle := aHeader[10]
    oBrowse:AddStatusColumns({|| Status(aList[oBrowse:nAt,11])}, {|| Legend()})
    oBrowse:aColumns[11]:cTitle := aHeader[11]

    oColumn := FWBrwColumn():New()
    oColumn:SetData( &(" { || aList[oBrowse:At(),12]}"))
    oColumn:SetTitle(aHeader[12])
    oColumn:SetSize(2)
    oBrowse:SetColumns({oColumn})

    oBrowse:Activate()
return

//----------------------------------------------------------------------
/*/{Protheus.doc} UpdSetArray
Atualiza as linhas do browse conforme o TTimer é executado

@param oBrowse Objeto do browse
@param nCateg Inteiro que indica a categoria que será utilizada
@param aList Array que corresponde as linhas do browse

@author Robson Gonçalves
@since 13/11/2020
@version 1.0
/*/
//----------------------------------------------------------------------
static function UpdSetArray(oBrowse, nCateg, aList)
    local aCateg as array
    local nI as numeric
    local aNewList as array

    nCateg++
    aCateg := {'ADULTO ','INFANTIL ', 'JUNIOR ', 'EXPERT '}

    if nCateg > Len(aCateg)
        nCateg := 1
    endif

    aNewList := {}

    for nI := 1 to 20
        AAdd(aNewList,{LTrim(StrZero(nI,2)),aCateg[nCateg]+Chr(64+nI),'0','1','2','0','1','2','0','1','2',''})
    next

    aSize(aList, 0)
    aList := nil

    aList := aNewList

    oBrowse:SetDataArray()
    oBrowse:SetArray(aList)
    oBrowse:Refresh()
    oBrowse:GoTop()
return

//----------------------------------------------------------------------
/*/{Protheus.doc} Legend
Exibe as legendas do browse

@author Robson Gonçalves
@since 13/11/2020
@version 1.0
/*/
//----------------------------------------------------------------------
static function Legend()
    local oLegend as object

    oLegend := FWLegend():New()
    oLegend:Add('','BR_VERDE'    ,'Realizado' )
    oLegend:Add('','BR_VERMELHO','A realizar' )
    oLegend:Activate()
    oLegend:View()
    oLegend:DeActivate()

    FreeObj(oLegend)

    oLegend := nil
return

//----------------------------------------------------------------------
/*/{Protheus.doc} Status
Retorna a imagem do browse (resource) conforme a situação recebida

@param cSit String contendo o código da situação

@return cStatus String contendo o nome do resource

@author Robson Gonçalves
@since 13/11/2020
@version 1.0
/*/
//----------------------------------------------------------------------
static function Status(cSit)
    local cStatus as char

    cStatus := ''

    if cSit == '1'
        cStatus := 'BR_BRANCO'
    elseif cSit == '2'
        cStatus := 'BR_VERDE'
    endif

return cStatus

1 curtida

Daniel, mais um vez muito obrigado pelo apoio e dedicação, funcionou como eu esperava. Tks,