segunda-feira, 31 de março de 2014

Dias uteis (WorkDays) do Excell mas mais completo

Dias e horas úteis

Mais um desafio que recentemente tive de superar, num projecto. Engraçado foi o quão simples é a solução e o quão rebuscada a mente consegue ser para a encontrar.

Neste caso uma simples classe em C# permite achar as horas uteis decorridas entre duas datas e horas, sendo estas passadas como objectos Datetime.

Outras particularidades da classe é asseitar como parametro os dias feriados (excludeDays), que com pouco código até podem vir de uma tabela de uma BD.

Achei engraçada a facilidade com que se consegue instanciar, fazer os calculos e obter o tempo decorrido com precisão ao segundo.

using System;
using System.Linq;
namespace duteis
{
    public class uteis
    {
        private TimeSpan startingTime;
        private TimeSpan endingTime;
        private DayOfWeek[] excludeDays;
        public uteis(TimeSpan? startingTime, TimeSpan? endingTime, DayOfWeek[] excludeDays)
        {
            this.startingTime = startingTime ?? new TimeSpan(8, 30, 0);
            this.endingTime = endingTime ?? new TimeSpan(17, 30, 0);
            this.excludeDays = excludeDays ?? new DayOfWeek[]   
   {   
    DayOfWeek.Saturday ,   
    DayOfWeek.Sunday   
   };
        }
        public uteis()
            : this(null, null, null)
        {
        }
        public double Calculate(DateTime startDate, DateTime endDate)
        {
            var counter = startDate;
            double hours = 0;
            while (counter <= endDate)
            {
                var dayStart = counter.Date.Add(startingTime);
                var dayEnd = counter.Date.Add(endingTime);
                var nextDayStart = startDate.Date.Add(startingTime).AddDays(1);
                if (counter < dayStart)
                    counter = dayStart;
                if (excludeDays == null ||
                  excludeDays.Contains(counter.DayOfWeek) == false)
                {
                    if (endDate < nextDayStart)
                    {
                        var ticks = Math.Min(endDate.Ticks, dayEnd.Ticks) - counter.Ticks;
                        hours = TimeSpan.FromTicks(ticks).TotalHours;
                        break;
                    }
                    else if (counter.Date == startDate.Date)
                    {
                        if (counter >= dayStart && counter <= dayEnd)
                        {
                            hours += (dayEnd - counter).TotalHours;
                        }
                    }
                    else if (counter.Date == endDate.Date &&
                         startDate.Date != endDate.Date)
                    {
                        if (counter >= dayStart && counter <= dayEnd)
                        {
                            hours += (counter - dayStart).TotalHours;
                        }
                        else if (counter > dayEnd)
                        {
                            hours += (endingTime - startingTime).TotalHours;
                        }
                    }
                    else
                    {
                        hours += (endingTime - startingTime).TotalHours;
                    }
                }
                counter = counter.AddDays(1);
                if (counter.Date == endDate.Date)
                    counter = endDate;
            }
            return hours;
        }
    }
}


Atenção a estas linhas onde se define a duração do dia ùtil, e são tratados os "excludeDays" que podem ser os feriados como escrevi anteriormente.

this.startingTime = startingTime ?? new TimeSpan(8, 30, 0);  
this.endingTime = endingTime ?? new TimeSpan(17, 30, 0);  
this.excludeDays = excludeDays ?? new DayOfWeek[]  

Eliminar duplicados numa tabela SQL

Nos ultimos tempos tenho-me deparado com desafios cada vez mais interessantes e incomuns.

Desta feita, precisei de localizar e eliminar de forma eficiente registos duplicados numa tabela, onde não existia um campo identificador unico nem um autonumber, ou outro que me permitisse isolar duplicados e eliminar apenas os duplicados, deixando um registo e não as várias duplicações do mesmo.

Aqui fica o script feito para resolver esta questão, na esperança que seja útil para mais alguém! Porque cooperar é mais produtivo que competir.


 USE BD  
 GO  
 -- ADICIONA UM CAMPO ID AUTONUMER  
 ALTER TABLE dbo.tabela  
   ADD ID INT IDENTITY  
 GO  
 -- SELECT  
 SELECT *  
 FROM tabela  
 GO  
 -- DETECTA DUPLICADOS  
 SELECT campo, COUNT(*) TotalCount  
 FROM tabela  
 GROUP BY campo  
 HAVING COUNT(*) > 1  
 ORDER BY COUNT(*) DESC  
 GO  
 -- ELEMINA DUPS  
 DELETE  
 FROM tabela  
 WHERE ID NOT IN  
 (  
 SELECT MAX(ID)  
 FROM tabela  
 GROUP BY campo)  
 GO  
 -- SELECT DE CONFIRMAÇÃO  
 SELECT *  
 FROM tabela  
 GO  
 -- REMOVE INDEX CRIADO PARA REMOVER DUPLICADOS  
 ALTER TABLE tabela  
 DROP COLUMN ID  
 GO  

terça-feira, 18 de dezembro de 2012

Revista PROGRAMAR Edição 38 (Dezembro 2012)


Nesta edição continuaremos também a premiar os autores dos três melhores artigos, dado o sucesso nas edições anteriores. E os leitores devem dar a sua opinião para que possamos premiar correctamente. Para isso vote em http://tiny.cc/ProgramarED38_V 
Assim nesta edição trazemos até si, como artigo de capa, um artigo de Introdução à Programação em Compute Unified Device Architecture (CUDA) de Patricio Domingues. Nesta 38ª edição pode ainda encontrar os seguintes artigos:
  • Accionamento de Led e Arduino Através de Interface Gráfica em Processing(Nuno Santos)
  • PostgreSQL como alternativa de SGBD (Ricardo Trindade)
  • Custo Efetivo de uma Solução na Nuvem em Ambiente Windows Azure (Edgar Santos)
  • Rápido e bem? A programação web tem! (Sérgio Laranjeira)
  • Introdução à Programação em CUDA (Patrício Domingues)
  • Visual (NOT) Basic - Organismos! Do zero ao mercado (2/2) (Sérgio Ribeiro)
  • Enigmas de C#: Foreach (Paulo Morgado)
  • Core Dump: Core Dump [8] - Fora de Horas (Fernando Martins)
  • Review do livro Introdução ao Design de Interfaces (Sérgio Alves)
  • Review do livro Exercícios em Java – Algoritmia e Programação Estruturada(Carlos José Dias)
  • Viagem da Informação (Rita Peres)
  • “Camaleão! De que cor?” (Sara Santos)
  • Verifica regularmente os ficheiros Javascript do seu site? (David Sopas)
  • Entrevista a Tiago Andrade e Silva
  • Projecto em Destaque na Comunidade Portugal-a-Programar: Taggeo

segunda-feira, 1 de outubro de 2012

Revista Programar 37º Edição


Nesta edição continuam também a premiar os autores dos três melhores artigos, dado o sucesso nas edições anteriores. E os leitores devem dar a sua opinião para que possamos premiar corretamente. Para isso vote em http://tiny.cc/ProgramarED37_V
Assim nesta edição pode-se encontrar, um artigo sobre Makefiles  para conhecer melhor esta poderosa ferramenta e ainda
  • Interface Gráfica - Termometro Usando Arduino e LM335A (Nuno Santos)
  • Algoritmos de Path Find : Princípios e Teorias (João Ferreira)
  • SEO: Search Engine Optimization - Introdução Parte III (Miguel Lobato)
  • Profilers Usar ou não usar… Os 5 minutos que mudam a experiência! (António Cunha Santos)
  • CodeDump -Core Dump [8] - Fora de Horas  (Fernando Martins)
  • Kernel Panic A importância da formação no ensino superior numa carreira dentro da área de segurança informática (Tiago Henriques)
  • Enigmas do C#: Async/Await e Threads (Paulo Morgado)
  • Organismos! Do zero ao mercado (1 de 2) Sérgio Ribeiro)
  • Review do livro HTML5 2ª Edição (Marco Amado)
  • Review do livro Sistemas Operativos (Fábio Domingos)
  • Review do livro Desenvolvimento em iOS iPhone, iPad, iPod Touch (Sara Santos)
  • Análise: O que faz de nós um bom programador? (Rita Peres)
  • Falácias da Computação na Nuvem (Edgar Santos)
  • As reais ameaças de segurança não são os APT (David Sopas)
  • Entrevista - João Barreto
  • Projeto em Destaque na Comunidade Portugal-a-Programar: NotíciasPT
E em parceira com as comunidades  PtCoreSec e Comunidade netPonto:
  • Introducao-Auditoria-Passwords (PtCoreSec)
BizTalk360 uma ferramenta de suporte e monitorização para a plataforma BizTalk Server (NetPonto)

Mais uma excelente edição, com o excelente trabalho a que me habituou enquanto leitor. Aproveito para agradecer ao pessoal da PtCoreSec, por toda a sua ajuda na revista (vocês sabem quem são). À Ana Barbosa, que mostrou ser a "eficiência em pessoa" (Muito Obrigado), ao Filipe Reis, que tanto tem feito pela nova plataforma. Ao Dr. António Pedro Cunha, que não só escreveu um excelente artigo, como tem sido sempre um apoio presente. Ao Silva (É pá tu és o verdadeiro homem dos 7 oficios). e a toda a restante equipa da Revista PROGRAMAR, que a torna cada vez mais uma leitura mais presente e aprazível. 

Não deixem de ler!

sábado, 26 de maio de 2012

Nunca se sabe quando pode fazer jeito!

 include<stdio.h>  
 main()  
  {  
  int i = 0;  
  char array[33][4] = {"NUL\0", "SOH\0","ETX\0", "EOT\0", "ENQ\0","ACK\0","BEL\0","BS\0","TAB\0","TAB\0","LF\0","VT\0","FF\0","CR\0","SO\0","SI\0", "DLE\0","DC1\0","DC2\0","DC3\0","DC4\0","NAK\0","SYN\0","ETB\0","CAN\0","EM\0","SUB\0","ESC\0","FS\0","GS\0","RS\0","US\0","Spc\0"};  
   for (i = 0; i < 33; i++)  
   {  
   printf("%d %s\n", i, array[i]);  
   }  
   for (i=33;i<256;i++)  
   {  
   printf("%d %c\n", i, i);  
   }    
  }  

sexta-feira, 8 de julho de 2011

Snippet de Codigo VB.NET pra criar directorios

Aqui fica um exemplo de codigo de como criar directorios numerados sequencialmente em vb.net.

Fiz isto porque precisei de criar 140 directorios numerados de uma só vez, e não estava com pachorra de criar um a um.

 Imports System.IO  
 Public Class Form1  
 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click  
 Dim contador As Integer  
 Dim max As Integer  
 Dim dir As String  
 Dim dir2 As String dir = "c:\meudirectorio\" max = TextBox1.Text  
 Try  
 For contador = 1 To max dir2 = dir & contador Directory.CreateDirectory(dir2)  
 Next contador  
  Catch End  
 Try MsgBox("Pronto")  
 End Sub End Class   


Na textbox1 é definido o numero do ultimo directório a ser criado.

Até uma proxima

domingo, 5 de junho de 2011

Portugal a Progamar


Em dia de calma, escrevo estas breves linhas! :)

Quem não se recorda dos tempos do Spectrum, dos primeiros PC's dos "tempos em que se programava por prazer, porque era útil, porque era "porreiro", porque se "amava" o que se fazia"?

Eu faz já alguns anos que me registei numa comunidade de Programadores Portugeses, onde muito li, algo partilhei, muito foi partilhado, na qual me orgulho de participar! Entre outras coisas porque se escreve e lê Português!

Quem acompanha ou lê este blog, e os meus caros formandos e colegas, que o lêem estão habituados a que publique sobre a revista Programar, tão agradada de todos nós. Quem não está habituado aqui fica o link, para a comunidade.

Visite, participe, questione! ;)

Portugal a Programar

Vá vai ver que não custa nada! ;)