Página 1 de 1
Usando classe em codeblock
Enviado: 31 Dez 2012 09:55
por JoséQuintas
Estou mexendo na minha classe genérica e surgiu uma necessidade:
Tenho lá na classe um tbrowse.
Agora preciso definir o SkipBlock.
Como posso definir para o SkipBlock um método da classe?
Seria algo parecido com isto:
Código: Selecionar todos
oBrowse:SkipBlock :=&( " { | nRecords | Self:SkipBlock( nRecords ) }" )
Acontece que as classes são tratadas no hbclass.ch, e não em run-time, então não dá pra usar o Self nesse caso.
Usando classe em codeblock
Enviado: 02 Jan 2013 09:39
por sambomb
Coloque o objeto como private ou public e passe ele no bloco:
oBrowse:SkipBlock :=&( " { | nRecords | oBrowse:SkipBlock( nRecords ) }" )
Usando classe em codeblock
Enviado: 02 Jan 2013 10:01
por JoséQuintas
O problema é a classe, e não o objeto.
Tipo....
Classe genérica - tem lá o generica:SkipBlock()
Classe clientes, herdada da genérica: tem lá o clientes:SkipBlock()
No fonte do cadastro:
Local oFrm := ClasseClientes():New()
oFrm:Execute()
E na classe clientes:
::TbrowseCli()
Agora precisava definir que o skipblock() do tbrowse será o skipblock() da classe.
oBrowse:SkipBlock := { ||x| Self:SkipBlock }
Sendo que terá que funcionar nas classes herdadas com os respectivos SkipBlocks.
A função teria que fazer parte da classe de cadastro, porque vou ter lá na classe os filtros especiais, e a função teria que respeitar isso.
Por enquanto só imagino repetir o tbrowse da RTL do Harbour e embutir na classe genérica/principal, pra poder chamar diretamente os métodos - tipo... a classe cadastro passaria a ser cadastro+tbrowse, e assim os métodos serem visíveis entre si.
A não ser que eu consiga indicar o método skipblock() da classe em uso como sendo o skipblock do tbrowse.
Usando classe em codeblock
Enviado: 02 Jan 2013 11:21
por JoséQuintas
Só pra acrescentar....
Estou usando a classe que postei aqui, inicialmente feita pra cadastros, mas estou usando no sistema inteiro.
A classe é responsável por controlar toda a navegação nas telas, seja clientes, pedidos, ou outra qualquer.
Está funcionando beleza, um registro por vez na tela, opções inclui, altera, exclui, etc., incluindo chamada a tbrowse pra escolher registro ou passear nos dados.
Então o usuário escolhe o código e mexe, ou chama o tbrowse, escolhe com ENTER, e volta a tela individual pra mexer.
Então... a tela principal é uma tela do cadastro, com um único registro.
Agora quero abrir a opção do usuário trabalhar em forma de tbrowse.
A tela principal vai ser o tbrowse.
Pra isso, preciso poder usar os métodos da classe de cadastro no tbrowse, pra navegação.
Num jeito tradicional, só criar a função pro tbrowse como private e tudo bem.
Mas nessa função preciso usar os métodos da classe, e é aí que está pegando.
Já criei o método no cadastro chamado SKIP, que é usado na navegação normal.
O problema agora é acessar esse método pelo tbrowse.
Exemplo:
oBrowse:SkipBlock := { || x | Self:Skip( nSkip ) }
mas que eu saiba, Self: é um recurso para o pré-compilador.
Na prática já não lembro mais se testei dessa forma, pra ver se fica visível no tbrowse.
A intenção é que os mesmos recursos do cadastro estejam disponíveis no tbrowse, por isso ele precisa ficar dentro da classe, ondem tem toda informação. Vou fazer mais alguns testes pra ver no que dá.
Por enquanto eu estava eliminando os métodos Anterior() e Seguinte(), e substituindo por Skip( nSkip ).
Assim o método será o mesmo pra navegação por registro ou por tbrowse.
Usando classe em codeblock
Enviado: 02 Jan 2013 12:00
por sambomb
Deixa eu ver se entendi:
Você tem uma classe, e dentro dessa classe você faz chamada a um browse.
Você quer definir que o browse dessa classe utilize um método dessa mesma classe.
Se for o caso seria mais ou menos assim...
Method DefinirBrowse()
::oBrowse:SkipBlock := ::SkipBlock
Usando classe em codeblock
Enviado: 02 Jan 2013 13:20
por JoséQuintas
Acho que tinha pulado o teste....
Código: Selecionar todos
METHOD DbView(......)
...
oBrowse:SkipBlock := { |X| ::Skip( x ) }
oBrowse:GoBottomBlock := { || ::MoveLast() }
oBrowse:GoTopBlock := { || ::MoveFirst() }
Funcionou.
Agora falta resolver um problema com Up() e PgUp(). Estão multiplicando os primeiros registros no browse.
O método em teste é este:
Código: Selecionar todos
METHOD Skip( nSkip ) CLASS PCAD0020Class
LOCAL nSkipped := 0
DO CASE
CASE nSkip == 0
SKIP 0
CASE nSkip > 0
DO WHILE nSkipped < nSkip .AND. jpcadas->cdTipo == "1"
SKIP
IF Eof() .OR. jpcadas->cdTipo != "1"
SKIP -1
EXIT
ENDIF
nSkipped++
ENDDO
CASE nSkip < 0
DO WHILE nSkipped > nSkip .AND. jpcadas->cdTipo == "1"
SKIP -1
IF Bof() .OR. jpcadas->cdTipo != "1"
SKIP
EXIT
ENDIF
nSkipped--
ENDDO
ENDCASE
RETURN nSkipped
No arquivo, cdTipo pode conter de 1 a 4.
Neste em teste, deveria ficar limitado ao 1.
Apesar de limitar no arquivo, a tela está se multiplicando em up() e pgup().
Browse:PgUp() e Browse:Up() são internos do tbrowse e fazem uso do ::Skip() da classe.
À primeira vista, esse Skip() está igual a um skipblock que tenho fora da classe.
Continuo testando. Isso é só o começo da rotina ainda.
Usando classe em codeblock
Enviado: 02 Jan 2013 13:27
por JoséQuintas
Resolvido.
Era o SKIP em Bof().
Código: Selecionar todos
METHOD Skip( nSkip ) CLASS PCAD0020Class
LOCAL nSkipped := 0
DO CASE
CASE nSkip == 0
SKIP 0
CASE nSkip > 0
DO WHILE nSkipped < nSkip .AND. jpcadas->cdTipo == "1"
SKIP
IF Eof() .OR. jpcadas->cdTipo != "1"
SKIP -1
EXIT
ENDIF
nSkipped++
ENDDO
CASE nSkip < 0
DO WHILE nSkipped > nSkip .AND. jpcadas->cdTipo == "1"
SKIP -1
IF Bof() .OR. jpcadas->cdTipo != "1"
IF jpcadas->cdTipo != "1"
SKIP
ENDIF
EXIT
ENDIF
nSkipped--
ENDDO
ENDCASE
RETURN nSkipped
Usando classe em codeblock
Enviado: 02 Jan 2013 13:36
por JoséQuintas
Sambomb,
Como eu disse antes, ia testar novamente com { |x| ::Skip(x) }
Mas obrigado assim mesmo.
Apesar de ter funcionado o bloco desse jeito, vou deixar o ::dbview na classe.
Dessa forma, ao invés de usar uma função de usuário como string, uso direto a da classe.
Então precisei dos métodos:
::Skip(nSkip), ::MoveFirst(), ::MoveLast(), que já faziam parte da classe
::oCampos, com os campos para browse
::dbView() para o browse
::dbViewUserFunction() para a função de usuário do browse
Agora começar a acrescentar as opções inclui/altera/exclui/etc. usando os métodos que já existem na classe.
Se os novos recursos da QT estiverem mesmo compatíveis com o estilo console... vai ser interessante.
Mas sumiu o exemplo disso da QT.