Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: Previsão de Horas para Customizações em ERP TOTVS

_Créditos da imagem: Gerada com auxílio do ChatGPT_ --- # **Previsão de Horas para Customizações em ERP TOTVS: Uma Abordagem Baseada em Fatores de Complexidade** No universo de customizações para o ERP da TOTVS, uma das etapas mais desafiadoras é a estimativa precisa do esforço necessário para o desenvolvimento. Muitas vezes, projetos aparentemente simples podem se tornar complexos devido a fatores como dificuldade de acesso ao ambiente ou falta de conhecimento da regra de negócio. Por isso, criamos uma metodologia de cálculo baseada em fatores de ajuste para tornar as estimativas mais precisas e confiáveis. ## **Por que uma boa estimativa é essencial?** Um orçamento mal calculado pode impactar diretamente o cronograma, os custos e até a qualidade da entrega. No caso de projetos relacionados ao ERP TOTVS, onde cada customização está ligada a regras de negócios específicas e a um ambiente muitas vezes complexo, subestimar ou superestimar o tempo necessário pode gerar problemas sign

BlackTDN :: DNA.TECH x TOTVS Framework (Rinha de Framework) :: FWFileReader():FullRed() x dna.tech.fileTools():FullContentBinaryFile() x dna.tech.cTools():ReadMemo()

#DNA.TECH x TOTVS Framework (Rinha de Framework)

***Nem Sempre utilizar um recurso do Framework irá garantir a melhor performance.***
Hoje iremos comparar a Classe FWFileReader():FullRed() do Framework da TOTVS com Funções/métodos criados por este que vos escreve.

A vítima da vez é:

FWFileReader:FullRed()

Vamos comparar FWFileReader():FullRead() x dna.tech.fileTools():FullContentBinaryFile() x dna.tech.cTools():ReadMemo(cFile)
O Código que usaremos para comparação está transcrito abaixo. 
```xBase

#pragma @__COMPSTR__@

cEOL:=chr(13)+chr(10)
cFile:=cGetFile("*.*|*.*","*.*",1,"C:\",.F.,16,.F.,.F.)

cTimeIni:=Time()

cHashFWFileReader:=""
lFWFileReader:=.T.

MsAguarde(;
    {||;
         if(lFWFileReader,oFWFileReader:=FWFileReader():New(cFile),nil);
        ,if(lFWFileReader,oFWFileReader:Open(),nil);
        ,cContentFWFileReader:=if(lFWFileReader,oFWFileReader:FullRead(),"DEU RUIM");
        ,if(lFWFileReader,oFWFileReader:Close(),nil);
        ,if(lFWFileReader,FreeObj(@oFWFileReader),nil);
        ,cHashFWFileReader:=if(lFWFileReader,SHA256(cContentFWFileReader,2),"DEU RUIM");
        ,cContentFWFileReader:="";
    };
    ,"Aguarde","oFWFileReader:FullRead";
)

nTimeFWFileReader:=if(lFWFileReader,dna.tech.timeCalc():TimeToSecs(ElapTime(cTimeIni,Time())),9999999999999999)
cTimeFWFileReader:=cValToChar(nTimeFWFileReader)

EEcView(;
    "cHashFWFileReader: "+;
    cHashFWFileReader+cEOL+;
    "Elapsed: "+cTimeFWFileReader+"s";
)

cTimeIni:=Time()

cHashFullContentBinaryFile:=""

MsAguarde(;
    {||;
         cFullContentBinaryFile:=dna.tech.fileTools():FullContentBinaryFile(cFile);
        ,cHashFullContentBinaryFile:=SHA256(cFullContentBinaryFile,2);
        ,cFullContentBinaryFile:="";
    };
    ,"Aguarde","dna.tech.fileTools():FullContentBinaryFile";
)

nTimeFullContentBinaryFile:=dna.tech.timeCalc():TimeToSecs(ElapTime(cTimeIni,Time()))
cTimeFullContentBinaryFile:=cValToChar(nTimeFullContentBinaryFile)

EEcView(;
    "cHashFullContentBinaryFile: "+;
    cEOL+;
    cHashFullContentBinaryFile+cEOL+;
    "Elapsed: "+cTimeFullContentBinaryFile+"s";
)

cTimeIni:=Time()

cHashReadMemo:=""

MsAguarde(;
    {||;
         cContentReadMemo:=dna.tech.cTools():ReadMemo(cFile);
        ,cHashReadMemo:=SHA256(cContentReadMemo,2);
        ,cContentReadMemo:="";
    };
    ,"Aguarde","dna.tech.cTools():ReadMemo";
)

nTimeReadMemo:=dna.tech.timeCalc():TimeToSecs(ElapTime(cTimeIni,Time()))
cTimeReadMemo:=cValToChar(nTimeReadMemo)

EEcView(;
    "cHashReadMemo: "+;
    cEOL+;
    cHashReadMemo+;
    cEOL+;
    "Elapsed: "+cTimeReadMemo+"s";
)

EEcView(;
    "cHashFWFileReader: ( Epapsed:"+cTimeFWFileReader+"s)"+;
    cEOL+;
    cHashFWFileReader+;
    cEOL+;
    cEOL+;
    "cHashFullContentBinaryFile: (Epapsed:"+cTimeFullContentBinaryFile+"s)"+;
    cEOL+;
    cHashFullContentBinaryFile+;
    cEOL+;
    cEOL+;
    "cHashFWFileReader==cHashFullContentBinaryFile: "+cValToChar(cHashFWFileReader==cHashFullContentBinaryFile)+;
    cEOL+;
    cEOL+;
    "cHashFWFileReader: (Epapsed:"+cTimeFWFileReader+"s)"+;
    cEOL+;
    cHashFWFileReader+;
    cEOL+;
    cEOL+;
    "cHashReadMemo: (Epapsed:"+cTimeReadMemo+"s)"+;
    cEOL+;
    cHashReadMemo+;
    cEOL+;
    cEOL+;
    "cHashFWFileReader==cHashFWFileReader: "+cValToChar(cHashFWFileReader==cHashReadMemo);
)


```
Vou utilizar, para isso, meu Editor Pessoal de Códigos......
***Neste caso tivemos um empate entre: oFWFileReader:FullRead(), e dna.tech.fileTools():FullContentBinaryFile dna.tech.cTools():ReadMemo()
cHashFWFileReader: ( Epapsed:1s)
a299a8b475f351109445a0414f371e6aa9f77882afb5ee14b1cbbb1be0830036
cHashFullContentBinaryFile: (Epapsed:1s)
a299a8b475f351109445a0414f371e6aa9f77882afb5ee14b1cbbb1be0830036
cHashFWFileReader==cHashFullContentBinaryFile: .T.
cHashReadMemo: (Epapsed:1s)
a299a8b475f351109445a0414f371e6aa9f77882afb5ee14b1cbbb1be0830036
cHashFWFileReader==cHashFWFileReader: .T.
Vamos complicar um pouco...





***Neste caso dna.tech.fileTools():FullContentBinaryFile ganhou em disparada, ficando dna.tech.cTools():ReadMemo() em segundo lugar e, na rabeira: oFWFileReader:FullRead()
cHashFWFileReader: ( Epapsed:132s)
593056342f2b0398bf9bd2b9ed5b48819f1ca2f560ac92a45fbbb931b3d0bf18
cHashFullContentBinaryFile: (Epapsed:8s)
593056342f2b0398bf9bd2b9ed5b48819f1ca2f560ac92a45fbbb931b3d0bf18
cHashFWFileReader==cHashFullContentBinaryFile: .T.
cHashReadMemo: (Epapsed:13s)
593056342f2b0398bf9bd2b9ed5b48819f1ca2f560ac92a45fbbb931b3d0bf18
cHashFWFileReader==cHashFWFileReader: .T.
Hum.... mas acredito que dê para complicar um pouco +. Boravê!








***Neste caso dna.tech.fileTools():FullContentBinaryFile ganhou em disparada, ficando dna.tech.cTools():ReadMemo() em segundo lugar e, na rabeira: oFWFileReader:FullRead()
cHashFWFileReader: ( Epapsed:427s)
16c809929e5e944c6d6bd051c0ed2b37fdda4eee8776dd4978de587f164b9730
cHashFullContentBinaryFile: (Epapsed:28s)
16c809929e5e944c6d6bd051c0ed2b37fdda4eee8776dd4978de587f164b9730
cHashFWFileReader==cHashFullContentBinaryFile: .T.
cHashReadMemo: (Epapsed:38s)
16c809929e5e944c6d6bd051c0ed2b37fdda4eee8776dd4978de587f164b9730
cHashFWFileReader==cHashFWFileReader: .T.
Hum.... Será que tem o mesmo comportamento com arquivos binários? Bora testar.






cHashFWFileReader: ( Epapsed:108s)
0f4bf8506a2560c568b9815124dfc43a11c561ed611829df841ec7aba8302359

cHashFullContentBinaryFile: (Epapsed:9s)
0f4bf8506a2560c568b9815124dfc43a11c561ed611829df841ec7aba8302359

cHashFWFileReader==cHashFullContentBinaryFile: .T.

cHashReadMemo: (Epapsed:10s)
0f4bf8506a2560c568b9815124dfc43a11c561ed611829df841ec7aba8302359

cHashFWFileReader==cHashFWFileReader: .T.

Conclusão:



    Usar funções do Framework é sempre uma boa prática. Mas, como pudemos ver, nem sempre elas se comportam da maneira que esperamos. Então uma boa solução caseira resolve o problema. Recursos a linguagem tem, basta saber-mos utilizá-los. Fica a Dica.

P.S.: No próxima publicação vou utilizar recursos de dna.tech.fileTools para ajudar a tornar FWFileReader():FullRed() mais performática.

Em Breve:

FWFileReader():FullRed()  irá receber uma ajudazinha de dna.tech.fileTools():Splitfile() e dna.tech.fileTools():SplitTXTfile() para se tornar mais performática.
Quer saber os recursos disponíveis em dna.tech.fileTools. Veja...
```xBase /* __ _ _ _ _ / _|(_)| | ___ | |_ ___ ___ | | ___ | |_ | || | / _ \| __| / _ \ / _ \ | |/ __| | _|| || || __/| |_ | (_) || (_) || |\__ \ |_| |_||_| \___| \__| \___/ \___/ |_||___/ */ #include "totvs.ch" #include "fileio.ch" #include "parmtype.ch" #include "tlpp-core.th" namespace dna.tech using namespace dna.tech class fileTools static method FileReader(cRDDName as character) as object /** * Retrieves the full content of a text file by concatenating the contents of all split files. * * @param cSourceFile The path of the source text file to retrieve the content from. * @return A character string containing the full content of the text file. * @class fileTools * @method FullContentTextFile */ static method FullContentTextFile(cSourceFile) as character static method FullContentBinaryFile(cSourceFile) as character /** * Splits a file into smaller chunks based on the specified target size. * * @param cSourceFile The path of the source file to be split. * @param cTargetPath The destination path where the split files will be saved. * @param nTargetSize The target size of each split file. * @param nTargetSizeType The type of target size: * 1 - bytes, * 2 - kilobytes, * 3 - megabytes. * @param bProgress A code block to evaluate progress. Receives two parameters: * - nSplit: Current split file number. * - nUnits: Total number of split files. * @param lUseUUID A logical value indicating whether to use UUID for naming split files. * @return An array containing the paths of the split files. */ static method Splitfile(cSourceFile as character,cTargetPath as character,nTargetSize as numeric,nTargetSizeType as numeric,bProgress as codeblock,lUseUUID as logical) as array /** * Splits a text file into smaller chunks based on the specified target size. * * @param cSourceFile The path of the source text file to be split. * @param cTargetPath The destination path where the split text files will be saved. * @param nTargetSize The target size of each split file. * @param nTargetSizeType The type of target size: * 1 - bytes, * 2 - kilobytes, * 3 - megabytes. * @param cCRLF The line ending characters used in the text file (e.g., "\r\n"). * @param bProgress A code block to evaluate progress. Receives two parameters: * - nSplit: Current split file number. * - nUnits: Total number of split files. * @param bGetLine A code block to extract lines from the source file. Receives five parameters: * - cBufferWrite: The buffer containing the current chunk of text. * - nLine: The current line number. * - nFilesize: Total size of the source file. * - nBufferSize: Size of the buffer. * - nBytesRead: Total bytes read so far. * @param bSetFilter A code block to filter lines from being written to the split file. Receives the same parameters as bGetLine. * @param lSetFilter A logical value indicating whether to apply the filter defined in bSetFilter. * @param lUseUUID A logical value indicating whether to use UUID for naming split files. * @return An array containing the paths of the split text files. */ static method SplitTXTfile(cSourceFile as character,cTargetPath as character,nTargetSize as numeric,nTargetSizeType as numeric,cCRLF as character,bProgress as codeblock,bGetLine as codeblock,bSetFilter as codeblock,lUseUUID as logical) as array /** * Transfers zipped data from a source directory to a target directory. * * @param cSourceDirectory The path of the source directory containing the data to be transferred. * @param cTargetDirectory The path of the target directory where the zipped data will be transferred. * @param bNotSendData A code block to determine whether to skip sending specific directories. Receives one parameter: * - cLowerDirectory: The lowercased path of the directory being evaluated. * @param cErrorMsg A character variable to store error messages if any. * @param cPassWord The password used for zipping and unzipping files. * @return A logical value indicating the success of the data transfer operation. */ static method SendDataToServerWithZip(cDirectoryClient as character,cDirectoryServer as character,bNotSendData as codeblock,cErrorMsg as character,cPassWord as character) as logical /** * Transfers zipped data from a source directory to a target directory. * * @param cSourceDirectory The path of the source directory containing the data to be transferred. * @param cTargetDirectory The path of the target directory where the zipped data will be transferred. * @param bNotSendData A code block to determine whether to skip sending specific directories. Receives one parameter: * - cLowerDirectory: The lowercased path of the directory being evaluated. * @param cErrorMsg A character variable to store error messages if any. * @param cPassWord The password used for zipping and unzipping files. * @return A logical value indicating the success of the data transfer operation. */ static method GetDataFromServerWithZip(cDirectoryServer as character,cDirectoryClient as character,bNotSendData as codeblock,cErrorMsg as character,cPassWord as character) as logical static method BrowseFiles(cTitle as character,cDirectory as character,cMask as character,nTypeOrder as numeric,bLDblClick as codeblock,bCustomHeaderClick as codeblock) as variant end class ```








Comentários

Postar um comentário

Postagens mais visitadas