Página 1 de 1

THREAD STATIC como reiniciar ?

Enviado: 14 Jul 2017 10:02
por asimoes
Pessoal,

Deve ser coisa boba, mas como resolvo isso ?

Tenho uma rotina que utilizei um contador de página com a instrução abaixo:

THREAD STATIC nPag := 1
...
nPag ++

Acontece que se a rotina for executado novamente o contador de página não inicia com 1, como faço para reiniciar o contador da thread static?

THREAD STATIC como reiniciar ?

Enviado: 14 Jul 2017 10:46
por janio
Variável STATIC somente eh criada se ainda não existir?

Se já existir ele assume o último valor nenao? Por isso q quando executado novamente ele não inicia em 1

Pq ao final vc não 'zera' a variável novamente?

THREAD STATIC nPag := 1
...
nPag ++
...
...
...
nPag := 1

THREAD STATIC como reiniciar ?

Enviado: 14 Jul 2017 11:01
por asimoes
Janio,

Fiz uma solução meia boca até achar algo mais funcional

ContadorPagina( .T. ) // Força inicio do contador
...
F_CABEC()

Código: Selecionar todos

STATIC FUNCTION F_CABEC()

   nPag := ContadorPagina() // Recebe contador

   @ 1,2 SAY "SECRETARIA MUNICIPAL DE FAZENDA"
   @ 2,2 SAY "DIRETORIA DE ADMINISTRAۂO / DEPARTAMENTO DE RECURSOS HUMANOS"
   @ 3,0 SAY PADL( "Data   : " + Hb_DtoC( Date(), "DD/MM/YYYY"), 204 )
   @ 4,0 SAY PADL( "P gina : " + StrZero( nPag, 4 ) + Space(6), 204 )
   @ 5,0 SAY PADL( "Rotina : " + StrZero( GROTINA, 4 ) + Space(6), 204 )
   @ 6,1 SAY PADC( "*** RELATàRIO DE FUNCIONµRIOS POR LOTA€ÇO, FORMA€ÇO E NOME  ***", 204 )
   @ 7,0 SAY Replicate( "-", 204 )
 RETURN Nil

Código: Selecionar todos

FUNCTION ContadorPagina( lStart )
THREAD STATIC nPag := 0

   hb_Default(@lStart, .F. )
   
   IF lStart
      nPag := 0
   ELSE
      nPag ++
   ENDIF

RETURN nPag

THREAD STATIC como reiniciar ?

Enviado: 14 Jul 2017 15:01
por JoséQuintas
Se complicou... algo está errado.
Pra mim, parece um mau uso de recursos.

À primeira vista é um único relatório, criar variável por thread pra um único relatório... desperdício e complicação.
O aplicativo vai reservar uma parte da memória pra que essa variável esteja sempre disponível, e lembrar do valor anterior.
Se cada vez que emite o relatório começa na página 1, precisa lembrar pra que?

Se for mais de um relatório... piorou... cada relatório vai ter sua própria numeração, e um vai atrapalhar o outro.

Vamos lá:
Se isso é rotina de cabeçalho, provavelmente também tem controle de linhas no outro fonte que vai chamar esse cabeçalho.

Ou cria uma classe (se forem vários relatórios), ou usa variável local e controla página no outro fonte.
Exemplo:

Código: Selecionar todos

nPag := 0
nLin := 66
DO WHILE ! Eof()
   IF nLin > 64
     Cabecalho( @Pag )
   ENDIF
ENDDO
...

FUNCTION Cabecalho( nPag )
  @ 0, 0 SAY ++nPag
   RETURN NIL
Sua inicialização de STATIC corresponde a npag := 0
À primeira vista, o mesmo trabalho com variáveis locais, que serão destruídas assim que não forem mais necessárias.

Nota: Também poderia ser Cabecalho( ++nPag ), mas por referência ainda economiza o espaço de uma variável na rotina, e uma tecla na digitação... rs

THREAD STATIC como reiniciar ?

Enviado: 14 Jul 2017 17:21
por asimoes
Não Quintas,

Não é um único relatório, enfim.... diz ai a solução !

Dessa forma que você postou eu já faço desde o clipper summer, enfim não sou especialista em recursos do harbour mas sabendo que existe thread static, eu só queria saber como reiniciar o contador, só isso !

THREAD STATIC como reiniciar ?

Enviado: 14 Jul 2017 18:22
por JoséQuintas
Não é um único relatório, enfim.... diz ai a solução
Não reparei antes, provavelmente deve ser uma opção com vários relatórios.
Se é STATIC, só é visível nesse fonte.

Código: Selecionar todos

STATIC FUNCTION F_CABEC()
Não existe uma solução que sirva pra todas as situações.
Vai depender do conjunto.
Classe vai ter o mesmo inconveniente de variável PRIVATE, só compensa usar classe se isso agrupar solução pra vários relatórios.
No geral, variável local seria a mais interessante, passando a variável por referência entre as sub-rotinas.

A variável PRIVATE, quando está relacionada a um único módulo, não causa efeitos colaterais, porque fica presa àquele fonte.
Acaba sendo o mesmo de usar uma classe, talvez até mais seguro do que classe.
Só declarar MEMVAR variável no topo do arquivo PRG, e PRIVATE variável no início do relatório.
Vai passar pela compilação -w3 -es2 sem problemas.
E se rodar em threads diferentes ou em janelas diferentes, um relatório não interfere no outro.

Mas tudo depende do conjunto, e do gosto pessoal.
No final o importante é que o relatório funcione.