// Salvar como : Teste.Prg
// Compilar : hbmk2 teste -w3 -es2 -run
// Código fonte original publicado em "xHarbour Language Reference Guide (Version 1.1)
// Copyright © 2006-2007 xHarbour.com Inc
//
// Adaptado por :Alexandre Santos - 11/09/2024
//
#include "tbrowse.ch"
#include "setcurs.ch"
#include "inkey.ch"
#xtrans :data => :cargo\[1]
#xtrans :recno => :cargo\[2]
PROCEDURE Main
LOCAL i, nKey, bBlock, oTBrowse, oTBColumn
LOCAL aHeading := { "Código", "Nome", "CPF / CNPJ" }
LOCAL aWidth := { 9, 40, 20 }, nRet
// Create TBrowse object
oTBrowse := TBrowse():new( 2, 2, MaxRow()-2, MaxCol()-2 )
oTBrowse:cargo := { SetDataSource(), 1 }
oTBrowse:headSep := Chr(196) + Chr(194) + Chr(196)
oTBrowse:colSep := " " + Chr(179) + " "
oTBrowse:footSep := Chr(196) + Chr(193) + Chr(196)
oTBrowse:colorSpec := "N/BG,W+/R"
// Navigation code blocks for array
oTBrowse:goTopBlock := { || oTBrowse:recno := 1 }
oTBrowse:goBottomBlock := { || oTBrowse:recno := Len( oTBrowse:data ) }
// Adicionei este parâmetro opcional: { |o| SetPict( o ) }.
// Caso contenha um codeblock, executa o mesmo a cada registro çido na fonte de dados
oTBrowse:skipBlock := { |nSkip| ArraySkipper( nSkip, oTBrowse, { |o| SetPict( o ) } ) }
// create TBColumn objects and add them to TBrowse object
FOR i:=1 TO Len( aHeading )
// code block for individual columns of the array
//
// As configurações de coluna feitas aqui são estáticas. Ou seja:
// as colunas são criadas e adicionadas ao objeto TBrowse enquanto ele ainda não
// está "vivo". Ele só será ativado no loop DO WHILE ( ! oTBrowse:stabilize() ) ... ENDDO
//
// A necessidade do caso presente, é uma picture dinâmica, conforme o Len() da coluna 3.
// Assim, não adianta setar a picture aqui. Se fizer isto, todas as linhas do TBrowse serão
// exibidas no mesmo formato...
//
bBlock := ArrayBlock( oTBrowse, i )
oTBColumn := TBColumn():new( aHeading[i], bBlock )
oTBColumn:width := aWidth[i]
oTBrowse:addColumn( oTBColumn )
NEXT
oTBrowse:goTop()
// display browser and process user input
DO WHILE .T.
DO WHILE ( ! oTBrowse:stabilize() )
// Executa ArraySkipper() repetidamente, lendo os registros da fonte de dados
// e pintando o conteúdo dos mesmos na tela...
ENDDO
nKey := Inkey(0)
IF ( nRet := oTBrowse:applyKey( nKey ) ) == TBR_EXIT // -1 --> User request for the browse to lose input focus
EXIT
ELSEIF nRet == TBR_CONTINUE // 0 --> Code block associated with was evaluated
//
ELSEIF nRet == TBR_EXCEPTION // 1 --> is unknown, key was not processed
IF nKey == K_ENTER
IF hb_Alert( PadC( " == Registro selecionado == ", 45 ) + ;
PadR( ";;Código : " + LTrim( Str( Eval( oTbrowse:getColumn(1):block ) ) ), 45 ) + ;
PadR( ";Nome : " + Eval( oTbrowse:getColumn(2):block ), 45 ) + ;
PadR( ";CPF/CNPJ: " + Transform( Eval( oTbrowse:getColumn(3):block ), oTbrowse:getColumn(3):picture ), 45 ), { " Ok ", " Fechar "}, "W+/B*" ) == 2
EXIT
ENDIF
ENDIF
ENDIF
ENDDO
CLS
RETURN
//--------------------------------------------------------------------------------
// This code block uses detached LOCAL variables to
// access single elements of a two-dimensional array.
//
FUNCTION ArrayBlock( oTBrowse, nSubScript )
RETURN {|| oTBrowse:data[ oTBrowse:recno, nSubScript ] }
//--------------------------------------------------------------------------------
// This function navigates the row pointer of the the data source (array)
// Adicionei o parâmetro opcional bCargo
FUNCTION ArraySkipper( nSkipRequest, oTBrowse, bCargo )
LOCAL nSkipped
LOCAL nLastRec := Len( oTBrowse:data ) // Length of array
// Esta função é executada repetidamente durante a estabilização, até que
// toda a área de dados do TBrowse (linhas) esteja preenchida ( oTBrowse:stable() == .T. ).
// Cada execução recupera um registro, quando existem registros na fonte de dados, que
// é pintado em uma linha da tela.
IF oTBrowse:recno + nSkipRequest < 1
// skip requested that navigates past first array element
nSkipped := 1 - oTBrowse:recno
ELSEIF oTBrowse:recno + nSkipRequest > nLastRec
// skip requested that navigates past last array element
nSkipped := nLastRec - oTBrowse:recno
ELSE
// skip requested that navigates within array
nSkipped := nSkipRequest
ENDIF
// adjust row pointer
oTBrowse:recno += nSkipped
// Neste ponto, já recuperou um registro mas ainda não pintou na tela...
// Se bCargo é um codeblock, executa
// o codeblock passado, e que será executado, vai analisar o conteúdo da
// coluna 3 (CPF ou CNPJ) e definir a picture de exibição, visto que o
// conteúdo tem tamanho variável.
//
// Para que funcione corretamente, o conteúdo de CPF/CNPJ tem que ser do tipo
// caracter. Testei com numérico mas a picture não formata corretamente.
// Parece que ele usa internamente a função Transform(), que não formata
// corretamente valores numéricos com a picture "@R...":
// ? Transform( 93985196238, "@R 999.999.999-99" ) --> "***.***.***-* " Numeric
// ? Transform( "93985196238", "@R 999.999.999-99" ) --> "939.851.962-38" Character
//
If hb_IsBlock( bCargo )
Eval( bCargo, oTBrowse )
Endif
// tell TBrowse how many rows are actually skipped.
RETURN nSkipped
//--------------------------------------------------------------------------------
FUNCTION SetDataSource()
// Coluna 3 do tio Character...
RETURN { ;
{ 1054 , "PAULO ROBERTO DE MATOS" , "35343000159" }, ;
{ 23453 , "ROCHA LAVANDERIA LTDA" , "21435343000159" }, ;
{ 1066 , "VALDIR SOUZA" , "04675000160" }, ;
{ 1067 , "SAMAR SOUZA" , "45357000185" }, ;
{ 118 , "ROMILDA STAUDT JAHNKE" , "21078246068809" }, ;
{ 23312 , "ODONTOPEDIATRIA MILANO" , "01297750000130" }, ;
{ 23413 , "CLINICA DENTARIA PAULISTA LTDA" , "12404246000108" }, ;
{ 265 , "SERGIO SEVERINO SILVA" , "89390319400" }, ;
{ 458 , "AMAZONAS DENTAL" , "08010000102" }, ;
{ 463 , "ANTONIO CARLOS PEREIRA" , "25331000122" }, ;
{ 481 , "SULINA VIVADENT LTDA" , "04004675000160" }, ;
{ 486 , "MORUMBI PRODUTOS DENTARIOS LTDA" , "73345357000185" }, ;
{ 55 , "DENTAL SOUTH AMERICA LTDA" , "48708010000102" }, ;
{ 745 , "DAIANA LIMA VENTURINI" , "78246068809" }, ;
{ 806 , "LUIZ ANTONIO MARTINS" , "12974808302" }, ;
{ 807 , "EDUARDO SILVEIRA" , "04246000108" }, ;
{ 832 , "CAROLINA VIIRA" , "97750000130" }, ;
{ 88 , "DENTAL SA IND.COM." , "33425331000122" } ;
}
//--------------------------------------------------------------------------------
STATIC FUNCTION SetPict( oTBrowse )
LOCAL cPict
// No momento desta execução, um registro foi lido na fonte de dados mas ainda
// não foi exibido na tela. Define a picture conforme o tamanho do conteúdo.
//
// Poderia escrever este código dentro da função ArraySkipper() mas preferi
// escrever separado e em ArraySkipper() adicionar apenas um parâmetro de entrada,
// que pode ser usado para executar qualquer coisa, inclusive esta função...
//
If Len( Eval( oTBrowse:getColumn(3):block ) ) <= 11
cPict := "@R 999.999.999-99"
Else
cPict := "@R 99.999.999/9999-99"
Endif
//Ajusta a picture na coluna 3 do TBrowse ...
// No próximo ciclo de estabilização, o registro será pintado na tela, com a picture correta....
oTBrowse: getColumn(3):picture := cPict
RETURN NIL
//--------------------------------------------------------------------------------