Pular para o conteúdo principal

Postagem em destaque

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️

🚀 Oferecendo Serviços Remotos de Desenvolvedor AdvPL e Mais 🖥️ Olá pessoal, Espero que este post encontre todos vocês bem! É com grande entusiasmo que compartilho que estou expandindo meus serviços como Desenvolvedor AdvPL para novos desafios e colaborações. Com mais de duas décadas de experiência sólida, minha jornada profissional tem sido enriquecedora, com a oportunidade de participar de projetos empolgantes ao longo dos anos. Agora, estou ansioso para trazer minha experiência e habilidades para novas equipes e projetos, trabalhando de forma remota. Minha expertise abrange não apenas AdvPL, mas também outras tecnologias-chave, incluindo JS, SQL, Infraestrutura e Otimização de Processos. Acredito que essa combinação de conhecimentos me permite oferecer soluções abrangentes e eficazes para uma variedade de necessidades de desenvolvimento. Acredito que a tecnologia tem o poder de transformar negócios e impulsionar o sucesso, e estou comprometido em ajudar meus clientes a alcançar seu

Protheus :: Alternativa às Funções do Tipo FT_F*

Outro dia precisei ler um arquivo, através das funções FT_F* e, surpreso, descobri que ela possui limitações: Função: FT_FReadLn (Lê e retorna uma linha de texto do arquivo aberto pela função FT_FUse(). As linhas do texto, são delimitadas pela sequência de caracteres CRLF (chr(13)+chr(10)) ou apenas LF (chr(10)), e o tamanho máximo de cada linha é 1022 bytes.).

O arquivo que estava tentando ler superava, em muito, a quantidade de caracteres suportado pela FT_FReadLn: 2668 no total ( quase 3 vezes mais ).

Para a solução do problema, desenvolvi a classe fT com as mesmas semelhanças as funções FT_F* e sem as limitações impostas por esta.

#INCLUDE "PROTHEUS.CH"
#INCLUDE "TRYEXCEPTION.CH"
#INCLUDE "FILEIO.CH"
/*/
 CLASS:  fT
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Alternativa aas funcoes tipo FT_F* devido as limitacoes apontadas em (http://tdn.totvs.com.br/kbm#9734)
 Sintaxe: ft():New() : Objeto do Tipo fT
/*/
CLASS fT FROM LongClassName

 DATA aLines
 
 DATA cCRLF
 DATA cFile
 DATA cLine

 DATA cClassName

 DATA nRecno
 DATA nfHandle
 DATA nFileSize
 DATA nLastRecno
 DATA nBufferSize

 METHOD New()  CONSTRUCTOR
 METHOD ClassName()

 METHOD ft_fUse( cFile )
 METHOD ft_fOpen( cFile )
 METHOD ft_fClose()
 
 METHOD ft_fAlias()
 
 METHOD ft_fExists( cFile )
 
 METHOD ft_fRecno()
 METHOD ft_fSkip( nSkipper )
 METHOD ft_fGoTo( nGoTo )
 METHOD ft_fGoTop()
 METHOD ft_fGoBottom()
 METHOD ft_fLastRec()
 METHOD ft_fRecCount()

 METHOD ft_fEof()
 METHOD ft_fBof()

 METHOD ft_fReadLn()
 METHOD ft_fReadLine()
 
 METHOD ft_fError( cError )

 METHOD ft_fSetCRLF( cCRLF )
 METHOD ft_fSetBufferSize( nBufferSize )

END CLASS

User Function ft()
Return( NIL )

/*/
 METHOD:  New
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: CONSTRUCTOR
 Sintaxe: ft():New() : Object do Tipo fT    
/*/
METHOD New() CLASS fT

 Self:aLines   := Array(0) 

 Self:cFile   := ""
 Self:cLine   := ""

 Self:cClassName  := "FT"

 Self:nRecno   := 0
 Self:nLastRecno  := 0
 Self:nfHandle  := -1
 Self:nFileSize  := 0

 Self:ft_fSetCRLF()
 Self:ft_fSetBufferSize()

Return( Self )

/*/
 METHOD:  ClassName
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Retornar o Nome da Classe
 Sintaxe: ft():ClassName() : Retorna o Nome da Classe
/*/
METHOD ClassName() CLASS fT
Return( Self:cClassName )

/*/
 METHOD:  ft_fUse
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Abrir o Arquivo Passado como Parametro
 Sintaxe: ft():ft_fUse( cFile ) : nfHandle ( nfHandle > 0 True, False)
/*/
METHOD ft_fUse( cFile ) CLASS fT

 TRYEXCEPTION

  IF !( Self:ft_fExists( cFile ) )
   BREAK
  EndIF

  Self:ft_fOpen( cFile )
 
 CATCHEXCEPTION

  Self:ft_fClose()

 ENDEXCEPTION

Return( Self:nfHandle )

/*/
 METHOD:  ft_fOpen
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Abrir o Arquivo Passado como Parametro
 Sintaxe: ft():ft_fOpen( cFile ) : nfHandle ( nfHandle > 0 True, False)
/*/
METHOD ft_fOpen( cFile ) CLASS fT

 TRYEXCEPTION

  IF !( Self:ft_fExists( cFile ) )
   BREAK
  EndIF

  Self:cFile  := cFile
  Self:nfHandle := fOpen( Self:cFile , FO_READ )
  
  IF ( Self:nfHandle <= 0 )
   BREAK
  EndIF
  
  Self:nFileSize := fSeek( Self:nfHandle , 0 , FS_END )

  fSeek( Self:nfHandle , 0 , FS_SET )

  Self:nFileSize := ReadFile( @Self:aLines , @Self:nfHandle , @Self:nBufferSize , @Self:nFileSize , @Self:cCRLF )

  Self:ft_fGoTop()

 CATCHEXCEPTION
 
  Self:nfHandle := -1
 
 ENDEXCEPTION

Return( Self:nfHandle )

/*/
 Funcao:  ReadFile
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Percorre o Arquivo a ser lido e alimento o Array aLines
 Sintaxe: ReadFile( aLines , nfHandle , nBufferSize , nFileSize , cCRLF ) : nLines Read
/*/
Static Function ReadFile( aLines , nfHandle , nBufferSize , nFileSize , cCRLF )
    
 Local cLine   := ""
 Local cBuffer  := ""

 Local nLines  := 0
 Local nAtPlus  := ( Len( cCRLF ) -1 )
 Local nBytesRead := 0

 While ( nBytesRead <= nFileSize )
  cBuffer   += fReadStr( @nfHandle , @nBufferSize )
  nBytesRead  += nBufferSize
  While ( cCRLF $ cBuffer )
   ++nLines
   cLine   := SubStr( cBuffer , 1 , ( AT( cCRLF , cBuffer ) + nAtPlus ) )
   cBuffer  := SubStr( cBuffer , Len( cLine ) + 1 )
   cLine  := StrTran( cLine , cCRLF , "" )
   aAdd( aLines , cLine )
   cLine  := ""
  End While
 End While

 IF !Empty( cBuffer )
  ++nLines
  aAdd( aLines , cBuffer )
  cBuffer := ""
 EndIF

Return( nLines )

/*/
 METHOD:  ft_fClose
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Fechar o Arquivo aberto pela ft_fOpen ou ft_fUse
 Sintaxe: ft():ft_fClose() : NIL
/*/
METHOD ft_fClose() CLASS fT

 IF ( Self:nfHandle > 0 )
  fClose( Self:nfHandle )
 EndIF

 aSize( Self:aLines , 0 )

 Self:cFile   := ""
 Self:cLine   := ""

 Self:nRecno   := 0
 Self:nfHandle  := -1
 Self:nFileSize  := 0
 Self:nLastRecno  := 0

Return( NIL )

/*/
 METHOD:  ft_fAlias
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Retornar o Nome do Arquivo Atualmente Aberto
 Sintaxe: ft():ft_fAlias() : cFile
/*/
METHOD ft_fAlias() CLASS fT
Return( Self:cFile )

/*/
 METHOD:  ft_fExists
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Verifica se o Arquivo Existe
 Sintaxe: ft():ft_fExists( cFile ) : lExists
/*/
METHOD ft_fExists( cFile ) CLASS fT

 Local lExists

 TRYEXCEPTION

  IF Empty( cFile )
   BREAK
  EndIF

  lExists := File( cFile )

 CATCHEXCEPTION
 
  lExists := .F.

 ENDEXCEPTION

Return( lExists )

/*/
 METHOD:  ft_fRecno
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Retorna o Recno Atual
 Sintaxe: ft():ft_fRecno() : nRecno
/*/
METHOD ft_fRecno() CLASS fT
Return( Self:nRecno )

/*/
 METHOD:  ft_fSkip
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Salta n Posicoes 
 Sintaxe: ft():ft_fSkip( nSkipper ) : nRecno
/*/
METHOD ft_fSkip( nSkipper ) CLASS fT

 DEFAULT nSkipper := 1

 Self:nRecno += nSkipper

Return( Self:nRecno )

/*/
 METHOD:  ft_fGoTo
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Salta para o Registro informando em nGoto
 Sintaxe: ft():ft_fGoTo( nGoTo ) : nRecno
/*/
METHOD ft_fGoTo( nGoTo ) CLASS fT

 Self:nRecno := nGoTo

Return( Self:nRecno )

/*/
 METHOD:  ft_fGoTop
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Salta para o Inicio do Arquivo
 Sintaxe: ft():ft_fGoTo( nGoTo ) : nRecno
/*/
METHOD ft_fGoTop() CLASS fT
Return( Self:ft_fGoTo( 1 ) )

/*/
 METHOD:  ft_fGoBottom
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Salta para o Final do Arquivo
 Sintaxe: ft():ft_fGoBottom() : nRecno
/*/
METHOD ft_fGoBottom() CLASS fT
Return( Self:ft_fGoTo( Self:nFileSize ) )

/*/
 METHOD:  ft_fLastRec
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Retorna o Numero de Registro do Arquivo
 Sintaxe: ft():ft_fLastRec() : nRecCount
/*/
METHOD ft_fLastRec() CLASS fT
Return( Self:nFileSize )

/*/
 METHOD:  ft_fRecCount
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Retorna o Numero de Registro do Arquivo
 Sintaxe: ft():ft_fRecCount() : nRecCount
/*/
METHOD ft_fRecCount() CLASS fT
Return( Self:nFileSize )

/*/
 METHOD:  ft_fEof
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Verifica se Atingiu o Final do Arquivo
 Sintaxe: ft():ft_fEof() : lEof
/*/
METHOD ft_fEof() CLASS fT
Return( Self:nRecno > Self:nFileSize )

/*/
 METHOD:  ft_fBof
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Verifica se Atingiu o Inicio do Arquivo
 Sintaxe: ft():ft_fBof() : lBof
/*/
METHOD ft_fBof() CLASS fT
Return( Self:nRecno < 1 )

/*/
 METHOD:  ft_fReadLine
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Le a Linha do Registro Atualmente Posicionado
 Sintaxe: ft():ft_fReadLine() : cLine
/*/
METHOD ft_fReadLine() CLASS fT

 TRYEXCEPTION

  Self:nLastRecno := Self:nRecno
  Self:cLine  := Self:aLines[ Self:nRecno ]

 CATCHEXCEPTION

  Self:cLine := ""

 ENDEXCEPTION

Return( Self:cLine )

/*/
 METHOD:  ft_fReadLn
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Le a Linha do Registro Atualmente Posicionado
 Sintaxe: ft():ft_fReadLn() : cLine
/*/
METHOD ft_fReadLn() CLASS fT
Return( Self:ft_fReadLine() )

/*/
 METHOD:  ft_fError
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Retorna o Ultimo erro ocorrido
 Sintaxe: ft():ft_fError( @cError ) : nDosError
/*/
METHOD ft_fError( cError ) CLASS fT
 cError := CaptureError()
Return( fError() )

/*/
 METHOD:  ft_fSetBufferSize
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Redefine nBufferSize
 Sintaxe: ft():ft_fSetBufferSize( nBufferSize ) : nLastBufferSize
/*/
METHOD ft_fSetBufferSize( nBufferSize ) CLASS fT

 Local nLastBufferSize := Self:nBufferSize

 DEFAULT nBufferSize := 1024
 
 Self:nBufferSize := nBufferSize
 Self:nBufferSize := Max( Self:nBufferSize , 1 )

Return( nLastBufferSize )

/*/
 METHOD:  ft_fSetCRLF
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Redefine cCRLF
 Sintaxe: ft():ft_fSetCRLF( cCRLF ) : nLastCRLF
/*/
METHOD ft_fSetCRLF( cCRLF ) CLASS fT

 Local cLastCRLF := Self:cCRLF
 
 DEFAULT cCRLF := CRLF
 
 Self:cCRLF  := cCRLF

Return( cLastCRLF )

Abaixo um exemplo de uso

#INCLUDE "PROTHEUS.CH"
/*/
 Funcao:  FTFSample
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Exemplo de Uso da Classe fT
/*/
User Function FTFSample()

 Local aCab
 Local aDet

 Local cFile   := "fTfSample.csv" //Deve estar em \system\

 aFile     := FileToArr( @cFile )
 aCab    := aFile[1]
 aDet     := aFile[2]

Return( NIL )

/*/
 Funcao:  FileToArr
 Autor:  Marinaldo de Jesus
 Data:  01/05/2011
 Descricao: Exemplo de Uso da Classe fT
/*/
Static Function FileToArr( cFile )

 Local aCab   := {}
 Local aDet   := {}

 Local cLine   := ""
 Local cToken  := Chr(255)

 Local oFT   := fT():New()

 BEGIN SEQUENCE

  IF ( oFT:ft_fUse( cFile ) <= 0 )
   BREAK
  EndIF

  While !( oFT:ft_fEof() )
   IncProc()
   cLine   := oFT:ft_fReadLn()
   ConOut( cLine )
   cLine  := StrTran( cLine , '""' , '" "' )    //Carrego um espaço em branco
   cLine  := StrTran( cLine , '","' , cToken ) //Defino o Separador
   cLine  := StrTran( cLine , '"' , "" )   //Retiro as Aspas 
   IF ( oFT:ft_fRecno() == 1 )
    aCab := StrTokArr( cLine , cToken )   //A primeira Linha contem o Cabeçalho dos campos
   Else
    aAdd( aDet , StrTokArr( cLine , cToken ) )  //As demais linhas sao os Detalhes
   EndIF
   cLine  := "" 
   oFT:ft_fSkip()
  End While

  oFT:ft_fUse()

 END SEQUENCE

Return( { aCab , aDet } )

Para baixar o código da classe, do exemplo e dos arquivos usados, clique aqui. []s иαldσ dj

Comentários

Postar um comentário

Postagens mais visitadas deste blog

BlackTDN :: RLeg ~ Desvendando a Função ParamBox

Para quem precisar desenvolver uma interface de entrada de dados, coisa rápida, e não quer ter aquele trabalhão danado que todos já sabemos, o Protheus tem uma função que ajuda muito, é uma interface semelhante a função Pergunte, porém com muito mais opção de objeto de entrada de dados, alias até colocar o scrollbox desta interface com todos os objetos em outra MsDialog ou Wizard é simples. Vejam o exemplo abaixo, boa sorte! Rleg. //---------------------------------------------------------- // Função exemplo utilizando a função ParamBox() //---------------------------------------------------------- User Function xParamBox() Local aRet := {} Local aParamBox := {} Local aCombo := {"Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"} Local i := 0 Private cCadastro := "xParambox" // ---------------

BlackTDN :: Customizando a interface de Login no Protheus e by You

A publicação “ BlackTDN :: By You e sua nova tela de login ”  de nosso amigo OBona deu o que falar e, em função disso, esse que a muito não vos escreve resolveu criar uma versão onde será possível personalizar, “por completo”, a tela de login no Protheus/by You. Considerando que OBona já havia “mapeado, identificado e customizado” as imagens peguei-as emprestadas para o exemplo que se segue: O primeiro passo para a customização “total” da interface de login do Protheus/by You será implementar o “Ponto de Entrada” ChgPrDir (Diretório de impressão) . Usaremos esse PE juntamente como programa U_FindMsObject.prg (apresentado pela primeira vez em: Protheus :: ADVPL : The Container : Presents Pandora's box ). Diferente do exemplo proposto por OBona, que substitui, durante o processo de compilação, as imagens padrões do sistema (excluindo-as) por imagens customizadas (com o mesmo nome) este novo exemplo mantém, no RPO, as imagens padrões adicionando novas imagens customizadas que serã

Protheus :: Chamando Funções do Menu Diretamente e sem a Necessidade de Login

Ferne$ perguntou: "...é possível abrir alguma rotina do sistema sem solicitar login ao usuário, como por exemplo a rotina MATA010..." Sim Ferne$, é possível sim. Abaixo um Exemplo para a Chamada à função MATA010 sem a necessidade de Login no sistema. #INCLUDE "PROTHEUS.CH" #INCLUDE "TBICONN.CH" /*/ Funcao: MATA010Ex Data: 30/04/2011 Autor: Marinaldo de Jesus Descricao: Executar a Funcao MATA010 diretamente sem a necessidade de LOGIN no Protheus Sintaxe: 1 ) U_MATA010Ex ( Chamada diretamente na Tela de Entrada do Sistema ) ; ou 2 ) totvsclient.exe -q -p=u_MATA010Ex -a=01;01 -c=rnp_local -e=rnp -m -l ( Chamada Via Linha de Comando ) /*/ User Function MATA010Ex( cEmpFil ) Local aEmpFil Local bWindowInit := { || __Execute( "MATA010()" , "xxxxxxxxxxxxxxxxxxxx" , "MATA010" , "SIGAFAT" , "SIGAFAT", 1 , .T. ) } Local cEmp Local cFil Local cMod Local cModName := "SIGAFAT" DEFA