








User Function ExJobXPT() Local lRetJob := .F. // Tenta obter acesso exclusivo pra gravar a variável global While !( GlbLock() ) Sleep(5) End While //Define e seta o valor nas variáveis globais PutGlbValue("lRetExec", lRetJob ) PutGlbValue("cTexto", "Teste" ) //Libera o acesso excluvivo a pilha de variáveis globais GlbUnlock() //Executa rotina em uma nova Thread StartJob("U_ExecXPTO",GetEnvServer(),.T.) // Le os valores gravado pela função onde a váriavel global foi alterada. lRetJob := GetGlbValue("lRetExec") If lRetJob Conount(GetGlbValue("cTexto")) Else Conount("Retornou Falso") EndIf Return
// Função executada em um botão do menu do protheus User Function ProcInic() Public cHoraIni := TIME() // Seu Código Return // Função executada em um outro botão do menu do protheus User Function ProcFim() Local cDifTime := ElapTime ( cHoraIni, TIME() ) If cDifTime > "00:03:00" Alert("O tempo de execução entre a função inicial e final demorou mais de 3 minutos.") EndIf Return
#Include "Protheus.ch" Static nVar := 0 User Function Pai() nVar += 10 conOut("Pai") conOut(nVar) Filho() // Muito importante limpar o valor da váriavel static ao concluir sua utilização nVar := 0 Return Static Function Filho() nVar += 10 conOut("Filho") conOut(nVar) Neto() Return Static Function Neto() nVar += 10 conOut("Neto") conOut(nVar) ReturnMuito importante lembrar a necessidade de limpar a variável ao final de sua utilização, pois se as funções foram executadas novamente sem essa limpeza pode acarretar em valores errôneos.
User Function Pai() Filho() If Type("cNome") == "C" conOut(cNome) Else conOut("Variável não definida") EndIf Return Static Function Filho() Private cNome := "Paulo" Neto() conOut("Filho") conOut(cNome) Return Static Function Neto() conOut("Neto") If Type("cNome") == "C" conOut(cNome) EndIf Return
User Function Pai() Local cVarNome := "Paulo" conOut(cVarNome) Filho() Return Static Function Filho() Local cVarNome := "Henrique" conOut(cVarNome) ReturnUm detalhe muito importante do escopo de variáveis é que elas podem ser subsistidas por uma variável de escopo menor caso a mesma seja declarada dentro do local utilizado, por exemplo. Se eu possuir uma variável Public cXPTO com o valor “A” já declarado e dentro de uma novo fonte eu declarar uma variável Static cXPTO com o valor “B” as duas variáveis existirão, mas o sistema vai priorizar o escopo mais baixo para a utilização no processamento corrente. Esta sequência hierárquica de escopo é : Public > Static > Private > Local . O escopo Global não entra nessa hierarquia pois o mesmo é definido e acessado de forma diferente dos outros. É isso pessoal, espero que ajude muito vocês e se tiveram alguma dúvida só deixar nos comentários.
Para você que tem dificuldade de concentração no momento de trabalho, assim como eu, vou dar algumas dicas que vão ajudar muito na sua capacidade de concentração, criativa e cognitiva.
Veja essas dicas:
No meu caso, sempre que preciso fazer tarefas onde preciso de foco total, eu coloco uma playlist de Rock que eu mesmo montei. Dessa forma tiro totalmente o som externo, as conversas e distrações que tiram meu foco.
Pode ser o tipo de música que você preferir, no meu caso foi o bom e velho Rock And Roll .
Vou deixar minha playlist do Spotify aqui caso alguém queira fazer as “Pedras rolarem”.
Uma dica muito importante, para você que acaba se perdendo no tempo, ou se aguem te chama a todo momento, é utilizar uma agenda para organizar suas tarefas.
Pode ser um agenda de papel (raiz) ou algo mais moderno como utilizar a agenda do Google Calendar ou qualquer agenda virtual, o importante é se organizar.
Tenha uma forma de organizar a ordem das suas tarefas, assim você não esquece de nenhuma e vai ter uma produtividade muito maior.
Existem diversas ferramentas e metodologias para isso.
Uma metodologia muito útil para isso é o Scrum que foi desenvolvido para gerenciar projetos, organizar tarefas e agilizar processos. Para mim ele é muito mais que uma ferramenta de trabalho e pode ser empregado em todas as áreas da sua vida.
Uma ferramenta bem bacana que uso para organizar minhas tarefas é o Trello. Essa ferramenta te ajuda a organizar suas tarefas em card’s e dividi-las em etapas de processo.
É muito importante fazer pausas durante o expediente. Nenhuma mente é produtiva 100% do tempo, e sem as pausas nossa mente e nosso corpo pode chegar a uma exaustão e comprometer a qualidade do seu trabalho.
Então, faça pausa para tomar um café, distrair a cabeça ou até mesmo bater um papo com algum colega de trabalho.
É isso mesmo, as vezes desviar o foco te ajuda a ter foco no momento correto !!!
Essas são as minhas dicas para que seu trabalho seja mais produtivo e com uma melhor qualidade.
Muitas vezes sentimos uma performance terrível em nosso banco de dados.
Um dos fatores que pode fazer isso acontecer é a defasagem dos índices das tabelas de nosso banco.
Isso acontece devido a grande quantidade de manipulações dos dados, principalmente com os comandos Insert e Delete.
Para isso podemos criar um script para reorganizar, e dependendo dos casos recriar os índices do nosso SQL Server…
Essas ações melhoram o desempenho do banco.
Vou explicar os passos para montar esse Script que vai te ajudar muito.
Primeiramente, vamos criar algumas variáveis de controle que serão utilizadas no momento da leitura dos índices…
DECLARE @tableName nvarchar(500) DECLARE @indexName nvarchar(500) DECLARE @percentFragment decimal(11,2) DECLARE @page_count int
Na sequência vamos definir nosso Cursor, que servirá para armazenar a lista de índices que iremos realizar a manutenção.
Dentro da criação do cursor, escrevemos um comando Select que vai cruzar dados entre a tabela de status dos índices (sys.dm_db_index_physical_stats), a tebela de tabelas(sys.tables), a tabela de Schemas(sys.schemas) e a tabela de Índices(sys.indexes).
Definimos um parâmetro de busca de fragmentação onde o % de fragmentação for maior que 5% e a quantidade de páginas do índice for maior que 10.
Com isso começamos a pegar os índices que já começam a apresentar lentidão nas consultas…
DECLARE FragmentedTableList cursor for SELECT dbtables.[name] AS 'Table', dbindexes.[name] AS 'Index', indexstats.avg_fragmentation_in_percent, indexstats.page_count FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS indexstats INNER JOIN sys.tables dbtables ON dbtables.[object_id] = indexstats.[object_id] INNER JOIN sys.schemas dbschemas ON dbtables.[schema_id] = dbschemas.[schema_id] INNER JOIN sys.indexes dbindexes ON dbindexes.[object_id] = indexstats.[object_id] AND indexstats.index_id = dbindexes.index_id AND dbindexes.[name] IS NOT NULL WHERE indexstats.database_id = DB_ID() AND indexstats.avg_fragmentation_in_percent > 05 AND indexstats.page_count > 10 ORDER BY indexstats.page_count DESC, indexstats.avg_fragmentation_in_percent DESC OPEN FragmentedTableList
Por último, vamos abri o cursor, fazer a leitura dos índices e executar as devidas manutenção:
Quando o percentual de fragmentação estiver entre 5% e 30%, vamos realizar o reorganize do índice, ou seja, vamos reorganizar este índice.
Agora, se o percentual for maior que 30% vamos realizar o rebuild do índice, ou seja, realizar a reconstrução do mesmo, pois a defasagem do mesmo já esta bem critica.
FETCH NEXT FROM FragmentedTableList INTO @tableName, @indexName, @percentFragment, @page_count WHILE @@FETCH_STATUS = 0 BEGIN PRINT 'Processando ' + @indexName + ' na tabela ' + @tableName + ' com ' + CAST(@percentFragment AS NVARCHAR(50)) + '% fragmentado' IF(@percentFragment BETWEEN 05 AND 30) BEGIN EXEC( 'ALTER INDEX ' + @indexName + ' ON ' + @tableName + ' REORGANIZE;') PRINT 'Concluindo a reorganização do índice ' + @indexName + ' da tabela ' + @tableName END ELSE IF (@percentFragment > 30) BEGIN EXEC( 'ALTER INDEX ' + @indexName + ' ON ' + @tableName + ' REBUILD; ') PRINT 'Concluindo a recriação do índice ' + @indexName + 'da tabela ' + @tableName END FETCH NEXT FROM FragmentedTableList INTO @tableName, @indexName, @percentFragment,@page_count END CLOSE FragmentedTableList DEALLOCATE FragmentedTableList
Agora vejam o exemplo completo do nosso script:
DECLARE @tableName nvarchar(500) DECLARE @indexName nvarchar(500) DECLARE @percentFragment decimal(11,2) DECLARE @page_count int DECLARE FragmentedTableList cursor for SELECT dbtables.[name] AS 'Table', dbindexes.[name] AS 'Index', indexstats.avg_fragmentation_in_percent, indexstats.page_count FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS indexstats INNER JOIN sys.tables dbtables ON dbtables.[object_id] = indexstats.[object_id] INNER JOIN sys.schemas dbschemas ON dbtables.[schema_id] = dbschemas.[schema_id] INNER JOIN sys.indexes dbindexes ON dbindexes.[object_id] = indexstats.[object_id] AND indexstats.index_id = dbindexes.index_id AND dbindexes.[name] IS NOT NULL WHERE indexstats.database_id = DB_ID() AND indexstats.avg_fragmentation_in_percent > 05 AND indexstats.page_count > 10 ORDER BY indexstats.page_count DESC, indexstats.avg_fragmentation_in_percent DESC OPEN FragmentedTableList FETCH NEXT FROM FragmentedTableList INTO @tableName, @indexName, @percentFragment, @page_count WHILE @@FETCH_STATUS = 0 BEGIN PRINT 'Processando ' + @indexName + ' na tabela ' + @tableName + ' com ' + CAST(@percentFragment AS NVARCHAR(50)) + '% fragmentado' IF(@percentFragment BETWEEN 05 AND 30) BEGIN EXEC( 'ALTER INDEX ' + @indexName + ' ON ' + @tableName + ' REORGANIZE;') PRINT 'Concluindo a reorganização do índice ' + @indexName + ' da tabela ' + @tableName END ELSE IF (@percentFragment > 30) BEGIN EXEC( 'ALTER INDEX ' + @indexName + ' ON ' + @tableName + ' REBUILD; ') PRINT 'Concluindo a recriação do índice ' + @indexName + 'da tabela ' + @tableName END FETCH NEXT FROM FragmentedTableList INTO @tableName, @indexName, @percentFragment,@page_count END CLOSE FragmentedTableList DEALLOCATE FragmentedTableList
Agora o mesmo pode ser executado periodicamente, ajudando a melhorar a performance do banco de dados.
Espero que gostem!!!