sábado, 28 de junio de 2014

Trucos y Consejos para optimización de consultas y mejorar los tiempos (Rendimiento)

Desde hace muchos años trabajo en desarrollo de software y en el transcurso de ese tiempo he venido adquiriendo algunas costumbres a la hora de escribir las sentencias  SQL, algunas óptimas y otras no tan ortodoxas, a continuación se las pongo a disposición. Les recuerdo que esto es bajo su propia responsabilidad.

Aquí encontrarás las diferentes formas de hacer consultas con parámetros  dinámicos y la manera de optimizar y mejorar los tiempos de consulta.

1.       La primera parte es la optimización de los campos durante el diseño de la tabla. Utiliza el tipo de campo necesario para almacenar el valor. Por ejemplo si necesito almacenar una fecha “20/11/2014”, utilizo un campo Date en vez del DateTime. Si el campo va a almacenar un texto utiliza un NVarChar(n) con un “n” que corresponda a un valor ligeramente mayor al tamaño máximo esperado, procuró nunca usar el NVarChar(Max).
2.       Trato  de tener cuidado con la creación de los índices, generalmente al inicio del sistema los coloco solo en los campos necesarios, como costumbre tengo el usar identificadores únicos de registro como llave de los datos mediante el uso de “IDENTITY”, esto hace necesario la creación de un índice adicional único por la llave de los datos. Por ejemplo, si estamos hablando de cuentas de un banco la llave natural de los datos sería el tipo y el número de la cuenta, si fuesen personas la clave natural sería el tipo y el número del documento. Para mí los índices dependen más del tipo de sistema, si es para registrar información más que para consultarla, el uso de índices debe ser mínimo.
3.       La lectura (interpretación) de un código de consulta es más sencillo si uno sigue ciertos parámetros, por ejemplo: Al momento de hacer una sentencia SQL, ubico un solo campo por línea, esto facilita la lectura de la sentencia:
Así no: Select dCliente, NombreCliente, TipoIdentificacion, Identificacion ,Direccion, Correo, EsActivo, CreadoPor, FecCreacion, ModificadoPor, FecModificacion From Cliente
Es mejor así:
Select IdCliente
      ,NombreCliente
      ,TipoIdentificacion
      ,Identificacion
      ,Direccion
      ,Correo
      ,EsActivo
      ,CreadoPor
      ,FecCreacion
      ,ModificadoPor
      ,FecModificacion
From Cliente

4.       A diferencia de los ejemplos que encuentro en internet No escribo las comas al final del campo, para mi es mejor escribirlas al comienzo, esto facilita  la actualización, cuando necesito quitar un campo, basta con agregar el carácter de comentario “--”al inicio del campo.
Select IdCliente
      ,NombreCliente
      ,TipoIdentificacion
      ,Identificacion
      ,Direccion
      ,Correo
      ,EsActivo
      --,CreadoPor
      --,FecCreacion
      --,ModificadoPor
      --,FecModificacion
From Cliente

5.       Cuando inicio la elaboración de una consulta utilizo el asterisco “*”, que me trae todos los campos, posteriormente lo sustituyo por los nombres de los campos necesarios, nunca lo dejo al final, esto impactaría demasiado en el rendimiento de la BD.
Select * From Cliente --Esto no se debe hacer
Es más optimo así:
Select IdCliente
      ,NombreCliente
      ,TipoIdentificacion
      ,Identificacion
      ,Direccion
      ,Correo
      ,EsActivo
      ,CreadoPor
      ,FecCreacion
      ,ModificadoPor
      ,FecModificacion
From Cliente

6.       Utilizo  alias para los nombres de las tablas, es más rápido para escribir y si utiliza un editor de sentencias con “IntelliSense”. Es más fácil encontrar los campos.
Select CL.IdCliente
      ,CL.NombreCliente
      ,CL.TipoIdentificacion
      ,CL.Identificacion
      ,CL.Direccion
      ,CL.Correo
      ,CL.EsActivo
      ,CL.CreadoPor
      ,CL.FecCreacion
      ,CL.ModificadoPor
      ,CL.FecModificacion
From Cliente CL

7.       Cuando comienzo a escribir las validaciones de un Where, siempre comienzo con la línea 1=1, su resultado es siembre True. Esto facilita el agregar nuevas líneas y la depuración de los comandos. Si en el momento de estar elaborando un Select complejo, necesitas quitar alguno de los parámetros es más fácil comentar la línea del parámetro a quitar.
Select CL.IdCliente
      ,CL.NombreCliente
      ,CL.TipoIdentificacion
      ,CL.Identificacion
      ,CL.Direccion
      ,CL.Correo
      ,CL.EsActivo
      ,CL.CreadoPor
      ,CL.FecCreacion
      ,CL.ModificadoPor
      ,CL.FecModificacion
From Cliente CL
Where 1=1
      --And CL.EsActivo = 1
      And CL.CreadoPor = 'Administrador'

8.       Hace algún tiempo necesitaba leer la estructura de una tabla sin la necesidad de traer datos, para esto comencé a utilizar la sentencia: Select * From DigitalTP.Cliente Where IdCliente=-1, Esto permite tener la estructura de columnas y sus tipos de datos, pero hacia un pique al índice de la llave (consulta al índice), encontré que es más eficiente usar: Select * From DigitalTP.Cliente Where 1=2

9.       Cuando empiezo la elaboración de un procedimiento almacenado, declaro los parámetros y le asigno valores predeterminados mientras elaboro la sentencia SQL. Si la consulta es a una tabla con demasiados registros, al ejecutarla las primeras veces esta puede demorarse, para evitar esto  le escribo un TOP al principio de la consulta. Una vez finalizado el procedimiento, quito los valores predeterminados y el TOP.  Para el momento de la implementación coloco al inicio del Script una validación para saber si el procedimiento ya existe, eliminarlo y volver a crearlo, esto facilita las actualizaciones a los servidores de producción.

Mientras elaboro y evaluó la consulta:

Declare @CreadoPor NVarchar(50) = 'Administrador'
Declare @EsActivo Int = 1

Select Top 1000 CL.IdCliente
      ,CL.NombreCliente
      ,CL.TipoIdentificacion
      ,CL.Identificacion
      ,CL.Direccion
      ,CL.Correo
      ,CL.EsActivo
      ,CL.CreadoPor
      ,CL.FecCreacion
      ,CL.ModificadoPor
      ,CL.FecModificacion
From Cliente CL
Where 1=1
      And CL.EsActivo = @EsActivo
   And CL.CreadoPor = @CreadoPor

Cuando ya tengo listo el procedimiento para enviar a producción.

If (select Count(*) from sysobjects where type='P' and name='[uspCliente_Consultar')>0
BEGIN
      DROP PROCEDURE dbo.[uspCliente_Consultar];
END
GO

CREATE PROCEDURE [dbo].[uspCliente_Consultar] 
                         @CreadoPor NVarchar(50)
                        ,@EsActivo Int
AS 
BEGIN 

Select CL.IdCliente
      ,CL.NombreCliente
      ,CL.TipoIdentificacion
      ,CL.Identificacion
      ,CL.Direccion
      ,CL.Correo
      ,CL.EsActivo
      ,CL.CreadoPor
      ,CL.FecCreacion
      ,CL.ModificadoPor
      ,CL.FecModificacion
From Cliente CL
Where 1=1
      And CL.EsActivo = @EsActivo
      And CL.CreadoPor = @CreadoPor
End


10.   Cuando la base de datos es muy grande, en ocasiones  elaboro procedimientos almacenados genéricos para algunas consultas, los cuales pueden responder a múltiples necesidades, estas reciben múltiples parámetros y filtran los datos por los parámetros que traen valores, lo anterior hace que el uso de los parámetros del Where  sea más delicado. Para esto hay varias maneras de configurar las consultas, aquí describiré a continuación las que conozco:

Una manera rápida, es adicionar una validación al parámetro de tal manera que si viene con un valor nulo no se tenga en cuenta para la búsqueda de registros, Esto es rápido de hacer aunque degrada el desempeño de la base de datos, su uso debiese restringir a tablas de poco tamaño Ejemplo:
Where 1=1
      And (@EsActivo Is Null Or CL.EsActivo = @EsActivo)
   And (@CreadoPor Is Null Or CL.CreadoPor = @CreadoPor)
Otra manera es mediante el uso de la instrucción  COALESCE
Where 1=1
      And CL.EsActivo=COALESCE(@EsActivo, EsActivo)
      And CL.CreadoPor=COALESCE(@CreadoPor, CL.CreadoPor)
11.   Existe otra manera que consiste en la elaboración de una consulta con las sentencias del Where  dinámicas, que filtren la información de los parámetros que traen valores y ejecutar la consulta mediante el comando Exec. Hacer la consulta así, es rápido, pero evita que el motor de la BD pueda armar planes de ejecución y abre una puerta a inyecciones de SQL.

Declare @IdCliente int=Null
Declare @FK_TipoIdentificacion int=Null
Declare @Identificacion nvarchar(128)=Null
Declare @NombreCliente nvarchar(256)='Gustavo Molina'
Declare @Contacto nvarchar(128)=Null
Declare @CargoContacto nvarchar(128)=Null
Declare @Ciudad nvarchar(50)=Null
Declare @Direccion nvarchar(256)=Null
Declare @Correo nvarchar(256)=Null
Declare @Movil nvarchar(128)=Null
Declare @Telefono nvarchar(128)=Null
Declare @EsActivo int=Null
Declare @CreadoPor nvarchar(50)=Null
Declare @FecCreacion date=Null
Declare @ModificadoPor nvarchar(50)=Null
Declare @FecModificacion date=Null


Declare @Comilla NVarchar(1) = Char(39)
Declare @SqlExec as NVarchar(Max)

       Set @SqlExec = '
       Select   CL.IdCliente
                    ,CL.FK_TipoIdentificacion
                    ,CL.Identificacion
                    ,CL.NombreCliente
                    ,CL.Contacto
                    ,CL.CargoContacto
                    ,CL.Ciudad
                    ,CL.Direccion
                    ,CL.Correo
                    ,CL.Movil
                    ,CL.Telefono
                    ,CL.EsActivo
                    ,CL.CreadoPor
                    ,CL.FecCreacion
                    ,CL.ModificadoPor
                    ,CL.FecModificacion
       From DigitalTP.Cliente CL
       Where 1=1 '

       If(@IdCliente Is Not Null)
             Set @SqlExec = @SqlExec + ' And IdCliente = @IdCliente'
       If(@FK_TipoIdentificacion Is Not Null)
             Set @SqlExec = @SqlExec + ' And FK_TipoIdentificacion = @FK_TipoIdentificacion'
       If(@Identificacion Is Not Null)
             Set @SqlExec = @SqlExec + ' And Identificacion = ' + @Comilla + @Identificacion + @Comilla
       If(@NombreCliente Is Not Null)
             Set @SqlExec = @SqlExec + ' And NombreCliente = ' + @Comilla + @NombreCliente + @Comilla
       If(@Contacto Is Not Null)
             Set @SqlExec = @SqlExec + ' And Contacto = ' + @Comilla + @Contacto + @Comilla
       If(@CargoContacto Is Not Null)
             Set @SqlExec = @SqlExec + ' And CargoContacto = ' + @Comilla + @CargoContacto + @Comilla
       If(@Ciudad Is Not Null)
             Set @SqlExec = @SqlExec + ' And Ciudad = ' + @Comilla + @Ciudad + @Comilla
       If(@Direccion Is Not Null)
             Set @SqlExec = @SqlExec + ' And Direccion = ' + @Comilla + @Direccion + @Comilla
       If(@Correo Is Not Null)
             Set @SqlExec = @SqlExec + ' And Correo = ' + @Comilla + @Correo + @Comilla
       If(@Movil Is Not Null)
             Set @SqlExec = @SqlExec + ' And Movil =' + @Comilla + @Movil + @Comilla
       If(@Telefono Is Not Null)
             Set @SqlExec = @SqlExec + ' And Telefono = ' + @Comilla + @Telefono + @Comilla
       If(@EsActivo Is Not Null)
             Set @SqlExec = @SqlExec + ' And EsActivo = ' + @Comilla + @EsActivo + @Comilla
       If(@CreadoPor Is Not Null)
             Set @SqlExec = @SqlExec + ' And CreadoPor = ' + @Comilla + @CreadoPor + @Comilla
       If(@FecCreacion Is Not Null)
             Set @SqlExec = @SqlExec + ' And FecCreacion = ' + @Comilla + Cast(@FecCreacion as nVarchar) + @Comilla
       If(@ModificadoPor Is Not Null)
             Set @SqlExec = @SqlExec + ' And ModificadoPor ' + @Comilla + @ModificadoPor + @Comilla
       If(@FecModificacion Is Not Null)
             Set @SqlExec = @SqlExec + ' And FecModificacion ='+ @Comilla + Cast(@FecModificacion as NVarchar) + @Comilla

       Exec (@SqlExec)
12.   La última que conozco y tal vez la más versátil es la de utilizar el comando “Exec sp_executesql”, este comando permite la ejecución de un SELECT dinámico que acepta parámetros y adicionalmente arma planes de ejecución.   A diferencia del Exec, evita las inyecciones de SQL y es más óptimo para el motor de la BD. A continuación les dejo un ejemplo con uso de parámetros múltiples.
CREATE PROCEDURE [dbo].[uspCliente_Consultar] 
                     @IdCliente int=Null
                    ,@FK_TipoIdentificacion int=Null
                    ,@Identificacion nvarchar(128)=Null
                    ,@NombreCliente nvarchar(256)=Null
                    ,@Contacto nvarchar(128)=Null
                    ,@CargoContacto nvarchar(128)=Null
                    ,@Ciudad nvarchar(50)=Null
                    ,@Direccion nvarchar(256)=Null
                    ,@Correo nvarchar(256)=Null
                    ,@Movil nvarchar(128)=Null
                    ,@Telefono nvarchar(128)=Null
                    ,@EsActivo int=Null
                    ,@CreadoPor nvarchar(50)=Null
                    ,@FecCreacion date=Null
                    ,@ModificadoPor nvarchar(50)=Null
                    ,@FecModificacion date=Null

AS 
BEGIN 

       Declare @SqlExec as NVarchar(Max)
       Declare @SqlParametros as NVarchar(3000)=','

Set @SqlParametros = '@IdCliente int,@FK_TipoIdentificacion int,@Identificacion nvarchar(128),@NombreCliente nvarchar(256),@Contacto nvarchar(128),@CargoContacto nvarchar(128),@Ciudad nvarchar(50),@Direccion nvarchar(256),@Correo nvarchar(256),@Movil nvarchar(128),@Telefono nvarchar(128),@EsActivo int,@CreadoPor nvarchar(50),@FecCreacion date,@ModificadoPor nvarchar(50),@FecModificacion date'

       Set @SqlExec = '
       Select   CL.IdCliente
                    ,CL.FK_TipoIdentificacion
                    ,CL.Identificacion
                    ,CL.NombreCliente
                    ,CL.Contacto
                    ,CL.CargoContacto
                    ,CL.Ciudad
                    ,CL.Direccion
                    ,CL.Correo
                    ,CL.Movil
                    ,CL.Telefono
                    ,CL.EsActivo
                    ,CL.CreadoPor
                    ,CL.FecCreacion
                    ,CL.ModificadoPor
                    ,CL.FecModificacion
       From DigitalTP.Cliente CL
       Where 1=1 '
If(@IdCliente Is Not Null)
   Set @SqlExec = @SqlExec + ' And IdCliente = @IdCliente'
If(@FK_TipoIdentificacion Is Not Null)
   Set @SqlExec=@SqlExec + ' And FK_TipoIdentificacion=FK_TipoIdentificacion'
If(@Identificacion Is Not Null)
   Set @SqlExec = @SqlExec + ' And Identificacion = @Identificacion'
If(@NombreCliente Is Not Null)
   Set @SqlExec = @SqlExec + ' And NombreCliente = @NombreCliente'
If(@Contacto Is Not Null)
   Set @SqlExec = @SqlExec + ' And Contacto = @Contacto'
If(@CargoContacto Is Not Null)
   Set @SqlExec = @SqlExec + ' And CargoContacto = @CargoContacto'
If(@Ciudad Is Not Null)
   Set @SqlExec = @SqlExec + ' And Ciudad = @Ciudad'
If(@Direccion Is Not Null)
   Set @SqlExec = @SqlExec + ' And Direccion = @Direccion'
If(@Correo Is Not Null)
   Set @SqlExec = @SqlExec + ' And Correo = @Correo'
If(@Movil Is Not Null)
   Set @SqlExec = @SqlExec + ' And Movil = @Movil'
If(@Telefono Is Not Null)
   Set @SqlExec = @SqlExec + ' And Telefono = @Telefono'
If(@EsActivo Is Not Null)
   Set @SqlExec = @SqlExec + ' And EsActivo = @EsActivo'
If(@CreadoPor Is Not Null)
   Set @SqlExec = @SqlExec + ' And CreadoPor = @CreadoPor'
If(@FecCreacion Is Not Null)
   Set @SqlExec = @SqlExec + ' And FecCreacion = @FecCreacion'
If(@ModificadoPor Is Not Null)
   Set @SqlExec = @SqlExec + ' And ModificadoPor = @ModificadoPor'
If(@FecModificacion Is Not Null)
   Set @SqlExec = @SqlExec + ' And FecModificacion = @FecModificacion'

Exec sp_executesql  @SqlExec
                    ,@SqlParametros
,@IdCliente
,@FK_TipoIdentificacion
,@Identificacion
,@NombreCliente
,@Contacto
,@CargoContacto
,@Ciudad
,@Direccion
,@Correo
,@Movil
,@Telefono
,@EsActivo
,@CreadoPor
,@FecCreacion
,@ModificadoPor
,@FecModificacion
End


Si las opiniones aquí expresadas de fueron de tu interés o no te parecen adecuadas, por favor deja un comentario o dale un ( G+1 ) si no tienes mucho tiempo.

martes, 27 de mayo de 2014

Búsqueda dentro de procedimientos almacenados


Cuando tenemos que hacer un cambio en varios procedimientos almacenados en una base de datos de SQL Server que tienen que ver con una tabla o campo especifico, tenemos buscar en los procedimientos almacenados y modificarlos. Para hacer esta tarea basta con hacer un Select  del catálogo de información de SQL server de la siguiente manera:

SELECT Name FROM sys.procedures WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%IdPersona%'


La anterior consulta nos mostrará todos los nombres de los procedimientos almacenados que tienen la palabra IdPersona.

domingo, 17 de febrero de 2013

Plantilla presupuesto propiedad horizontal


El presupuesto es una de las principales herramientas de la administración para la consecución de objetivos. Mediante un presupuesto calculamos,  de manera anticipada y aproximada,  los ingresos y gastos de una determinada actividad económica durante un período de tiempo;  nos sirve para saber el costo de un servicio o determinar las necesidades o proyecciones para alcanzar una meta.

Adjunto a este artículo hay un  ejemplo de un presupuesto de propiedad horizontal,  elaborado en Excel,  y en el que se busca ingresar la menor cantidad posible de información para evitar confundir al usuario.

Comencemos con la determinación de costos y luego vamos al archivo de Excel y su aplicabilidad.
En propiedad horizontal los ingresos se dan principalmente por las cuotas de administración. Existen otros como son multas, intereses, etc.

Generalmente, los administradores solo colocan como ingreso en el presupuesto las cuotas de administración debido a que los otros representan un monto mínimo y/o  variable respecto a éstas.

En el archivo se deja un listado de rubros de gastos más comunes. Están ordenados de mayor a menor. Éstos pueden ser cambiados según las necesidades.

Para determinar las cuotas de administración del presupuesto se dividen los costos por los promedios de coeficiente y cantidad de tipos de unidad de propiedad horizontal (apartamentos y garajes, depósitos, etc.);  de esta manera,  se genera un valor equitativo por unidad residencial. Existen casos de conjuntos residenciales en los que los tamaños de los apartamentos varían significativamente, para cuando esto ocurra hay que crear la separación por tipo de apartamento.

En el archivo ejemplo de presupuesto debemos ingresar los valores de la cuota anterior para calcular el porcentaje y comparar la variación con respecto al nuevo año, hay que digitar los parámetros de valores de tamaño de copropiedad y la cantidad de las mismas, el porcentaje de imprevistos (porcentaje en que se quiere mejorar las cuotas de administración) y,  por último,  los rubros de gastos del presupuesto. Si se omite  porcentaje por pronto pago, el presupuesto queda en el punto de equilibrio.

Se dejan dos hojas en el libro de Excel, la primera con el ejemplo del presupuesto y la segunda adicionando un comparativo al año anterior.  Los valores para el año a proyectar siempre se deben ingresar en la primera hoja. Se resaltó, en color amarillo tenue, la información que es necesaria ingresar para generar el presupuesto. En verde la  fórmula del resultado por tipo de copropiedad.

Los valores ingresados para el ejemplo son supuestos y aleatorios. La hoja se entrega tal cual, sin ninguna garantía por su contenido. Cualquier opinión de mejora u observación será tenida en cuenta. El archivo se puede descargar pulsando clic aqui

sábado, 18 de agosto de 2012

Calcular el ahorro de energía con lamparas de LED


Ahorrar electricidad nos conduce a dos grandes beneficios, el primero es el contribuir a disminuir el calentamiento global y el segundo es el de ahorro de costos.

Al consumir menos energía, colaboramos a disminuir el efecto de calentamiento global, esto conlleva a la disminución de cambios climáticos (lluvias acidas, mareas, huracanes, etc.), adicionalmente evitamos que los gobiernos tengan que estar construyendo nuevas centrales eléctricas para sostener el consumo (ruptura ciclo de consumo). El impacto al medio ambiente que logremos hoy nos permitirá dejarles a nuestros hijos y la humanidad un mundo habitable.

La mayoría de personas aunque comprende el concepto de protección del medio ambiente, considera que hacer cambios para disminuir el consumo energético es costoso, esta apreciación esta errada, los elementos para ahorro de energía ya son una inversión que nos brinda un ahorro. un ejemplo de esto es el cambio de las lámparas de halógeno que generalmente se usan en bibliotecas o pasillos, el costo de las actuales de halógeno es muy inferior a las de LED, cerca a un 20%, sin embargo las de LED duran hasta 500 veces más, esto diluye su costo inicial en el tiempo.

En este articulo adjunto un archivo en Excel que contiene las formulas para cálculos de ahorro que compara dos elementos de consumo energético, en el ejemplo calculamos el ahorro al cambiar tres lámparas de halógeno de 50W por Tres lámparas de LED de alta intensidad 5W.

Este ahorro nos genera mejor calidad de vida, para que gastamos el dinero que conseguimos con el esfuerzo del trabajo innecesariamente?, a veces no es lo que ganamos sino lo que ahorramos.

Para poder calcular el ahorro, simplemente tomamos los costos de consumo, vatios y el costo de las lámparas y los llevamos a la misma unidad de medida para poder comparar y determinar que consume menos.

El costo del consumo de energía lo tomamos del recibo de electricidad, el costo de las lámparas cotizamos en cualquier almacén.

Hay que tener en cuenta que las lámparas tienen anotado el consumo en vatios, pero el costo de electricidad se presenta en miles de vatios (kilo vatio), el costo de las lámparas lo dividimos entre el promedio de vida útil de la lámpara, esto nos permite llevar el costo de compra a la misma unidad del consumo, así podemos hacer más fácil un comparativo.

Para este ejemplo comparamos el cambio de tres lámparas de halógeno por tres lámparas de LEDS de alta intensidad, con un promedio de tres horas de uso diario en un estrato tres se logra un promedio anual de ahorro de unos 45,000 pesos aproximadamente al año, aunque el costo de las lámparas de LEDS es dos veces superior al ahorro anual, su promedio de vida permite la recuperación de la inversión en el segundo año.

En el cuadro se coloreo en verde las partes que se deben modificar para calcular los ahorros.
En el siguiente enlace podrás encontrar el cuadro para efectuar los cálculos de ahorro de electricidad.


Sugerencias para ahorrar energía

Apagar todos los equipos que no se usen: todos los electrodomésticos que tienen LEDS para indicar algún estado, hora, etc. consumen un poco de energía que contabilizada de manera global y tienen un impacto en los costos a largo plazo.

No dejes encendido el PC sin hacer nada, este consume mucho, es preferible apagarlo o ponerlo a hibernar.
No dejes luces encendidas en cuartos que no uses.

Apaga el monitor de tu computador cuando no lo uses.

Plancha toda la ropa de una vez, nunca planches solamente lo que te vas a poner. Si vas a planchar muchas camisas, colócala unas sobre otra, esto permitirá que el calor de la que vayas planchando primero te ayude a planchar las otras.

Cada vez que uses la aspiradora, limpia el filtro, esto permitirá una mejor eficiencia en el uso.

Limpia de vez en cuando los bombillos, esto mejora la iluminación.

Si te bañas con agua caliente, usa un balde en la ducha para recolectar el agua que sale fría antes del agua caliente, te sirve para descargar la cisterna.

Utiliza sistemas de descarga doble en los sanitarios

Limpiar las rendijas del disipador y mejorar la ventilación de los sistemas de aires acondicionados,  neveras o refrigeradores hace que consuman menos energía y trabajen más eficientemente.

Calculo días Laborables y Festivos

 Una de las actividades comunes del quehacer de una oficina es calcular cuántos días laborables existen entre dos fechas, este cálculo nos sirve para programar una tarea, hacer o liquidar un contrato, etc., algunas veces incluyendo los sábados como no laborales. Sin embargo esta actividad aunque en principio sencilla, en Colombia puede registrar cierto grado de complejidad ya que los días festivos no necesariamente se calculan de la misma manera. En Colombia existen días que se celebran en una fecha fija, festivos que se trasladan al siguiente lunes, festivos que comienzan a partir de domingo de resurrección, este domingo se calcula mediante el "Computus" que es el cálculo de la fecha de Pascua, la mejor manera de calcular el domingo de resurrección es mediante el algoritmo de Butcher, y para finalizar existen festivos que se cuentan en el siguiente lunes a partir de una fecha calculada. 

 Debido a la complejidad de hacer los cálculos de festivos, simplemente lo que se hace cada vez que se necesita contar días laborables disponibles es buscar un calendario y comenzar a contar, algunas veces debido a la ley de Murphy, los calendarios no están disponibles o no tienen los festivos marcados o cuando se está terminando de contar alguien interrumpe y se tiene que volver a empezar, es por lo anterior que elaboré un programa para calcular los días laborables, 

 En el programa solo hay que seleccionar la fecha inicial, la fecha final y como contar el sábado, si se quiere laboral o no laboral, después pulsar clic en el botón calcular. 

 El programa de manera automática indica los días laborales y no laborables entre las dos fechas dadas. El aplicativo de días laborales se descargar en el siguiente link: Descargar


Les recuerdo que el aplicativo se entrega como esta, no me hago responsable por errores o mal uso. Si le encuentra algún error, si se le ocurre alguna idea de mejora o solo le fue de utilidad, por favor escribe un comentario. 

Enlace de interés: Wikipedia

sábado, 11 de agosto de 2012

Calcular Dígito de verificación de un NIT


Hace poco en mi trabajo tuve un pequeño problema con una aplicación y el digito de verificación del NIT de unos terceros, aunque la formula de calcular el digito de verificación es más vieja que la invención de la rueda, me toco buscar nuevamente  la fórmula para aplicarla el trabajo. La encontré en varios sitios de internet, sin embargo me pareció algo complicado el uso de los archivos encontrados, así que tratando de simplificar su manejo dejo a su disposición la clase con el cálculo del NIT en VB.NET para poder ser usada dentro de un proyecto y un modulo para ser usado dentro de archivos de Excel.

Las funciones aceptan el NIT como una cadena de texto y limpia los caracteres de separación más comunes como son el espacio, la coma , el punto y la raya.


Tiene tres maneras básicas para ser invocada, la primera si se ingresa el NIT sin el digito, la formula calcula el dígito de verificación "CalcularNit", las otras dos maneras de invocarla lo que hacen es validar si el NIT es correcto. La primera validación acepta el NIT con el digito incluido y la segunda lo acepta de manera separada como un segundo parámetro, ambas VERDADERO (True) en caso de coincidir el digito de verificación y FALSO (False) en caso de estar errado.

Para usar la formula dentro de una hoja de Excel se debe insertar el modulo o usar el libro del enlace, para usar la formula en una hoja de Excel se tiene que recurrir al asistente de insertar formula, después en la  lista de seleccionar categoría se escoge "Definidas por el usuario", entonces en la parte inferior se podrá escoger la formula a usar.

Una vez que se escoge la formula a usar se debe colocar en los parámetros las direcciones de las celdas a usar como entrada de datos.

El archivo de Excel está hecho con la finalidad de poder hacer validación de una lista grande de NIT's, si se desea solamente validar uno solo se puede usar el aplicativo ejemplo disponible para descarga, este mini programa tiene las tres maneras básicas de llamar la formula y usa la clase de .NET,  básicamente esta realizado como un ejemplo de llamado de la clase de .NET  y por si no se desea abrir el Excel para calcular un NIT.

En los siguientes enlaces podrán encontrar tanto el código fuente para Excel y .NET como mini aplicativo de ejemplo para su uso y una hoja de Excel con el ejemplo.



Entrada destacada

Arquitectura de N-Capas con Visual Studio .NET y AngularJS

Este artículo es el primero de una serie de artículos en que quiero explicar mi visión de la programación por capas. La Arquitectura ...