Calcular Días laborales en Visual Basic .Net con SQL
June 3, 2009 por admin
Categoria: Programación
Hace ya algunos meses desarrollé un Sistema Electrónico de Trámite Documentario en Visual Basic .NET 2005 usando como gestor de BD el SQL Server 2008 para un municipio de mi ciudad.
Bueno he buscado por todos lados este código, pero no lo encontré, así que yo mismo tube que hacerlo y lo comparto en este mi BLOG a Ustedes y se que les va a ser de gran ayuda. La programación que hice es Semi-Estructurada ( Utiliza Clases en algunos casos ). Uds. ya vean como acomodan el código.
1.- Deben de incluir la Funcion Días Laborales en alguna parte de su código, si la van a usar constantemente lo recomentable sería incluirlo en una clase como yo lo hice, como ven esta funcion tiene dos parámetros o datos de entrada: La fecha inicial para indicar el rango de inicio y la fecha final para indicar el rango de fin, es decir calculará los días laborales contenidos entre las dos fechas excluyendo días feriados, festivos, sabados y domingos. El parámetro que se envía luego de @FechaInicial y @Fecha final , es decir @ Dias Laborales es un parámetro OUTPUT de salida en el procedimiento almacenado, es por ello que tiene el Valor de 0. Esta función retorna la cantidad entera de días laborables que existe entre el rango de fechas.
Function DiasLaborales(ByVal fechainicial As Date, ByVal fechafinal As Date) As Integer
Dim diaslab As Integer = 0
Dim ini As Date = Format(fechainicial, “dd/MM/yyyy”)
Dim fin As Date = Format(fechafinal, “dd/MM/yyyy”)
‘Dim com As New SqlCommand(“DECLARE @DiasLaborales int EXEC DifDias @FechaInicial,@FechaFinal,@DiasLaborales output PRINT @DiasLaborales”, conexion)
Dim com As New SqlCommand(“DifDias”, conexion)
com.CommandType = CommandType.StoredProcedure
com.Parameters.Add(“@FechaInicial”, SqlDbType.DateTime).Value = ini
com.Parameters.Add(“@FechaFinal”, SqlDbType.DateTime).Value = fin
com.Parameters.Add(“@DiasLaborales”, SqlDbType.Decimal).Value = 0
conexion.Open()
diaslab = com.ExecuteScalar
conexion.Close()
Return diaslab
End Function
2.- Deberán crear mediante el Analizador de Consultas del SQL Server el siguiente Procedimiento Almacenado llamado “DifDias”, recuerden que la función anterior hace la llamada a este procedimiento mediante un Comand Execute, enviando dos parámetros de : Fecha Inicio, Fecha Fin y el resultado será devuelto mediante el parámetro de Salida: DiasLaborales.
CREATE PROCEDURE DifDias
@FechaInicial DATETIME,
@FechaFinal DATETIME,
@DiasLaborales INT OUTPUT
AS
BEGIN
DECLARE @RangoDiasNormales INT
DECLARE @Cnt INT
DECLARE @cantidad INT
DECLARE @FechaComparacion DATETIME
DECLARE @fechafiesta VARCHAR(5)
DECLARE @ini VARCHAR(10)
DECLARE @fin VARCHAR(10)
SELECT @RangoDiasNormales = 0
SELECT @DiasLaborales = 0
SELECT @Cnt=0
SELECT @cantidad=0
IF ((datepart(dw,@FechaFinal) = 6) or (datepart(dw,@FechaFinal) = 7))
BEGIN
SELECT @RangoDiasNormales = DATEDIFF(DAY,@FechaInicial,@FechaFinal)
END
ELSE
BEGIN
SELECT @RangoDiasNormales = DATEDIFF(DAY,@FechaInicial,@FechaFinal) + 1
END
SELECT @ini = (SELECT CAST((CAST(datepart(dd,@FechaInicial)AS
VARCHAR(2))+’/'+ CAST(datepart(mm,@FechaInicial)AS
VARCHAR(2))+’/'+CAST(datepart(yy,@FechaInicial)AS VARCHAR(4))) as
varchar(10)))
SELECT @fin = (SELECT CAST((CAST(datepart(dd,@FechaFinal)AS
VARCHAR(2))+’/'+ CAST(datepart(mm,@FechaFinal)AS VARCHAR(2))+’/'+
CAST(datepart(yy,@FechaFinal)AS VARCHAR(4)))as varchar(10)))
IF @ini <>@fin
BEGIN
IF @RangoDiasNormales = 2
BEGIN
SELECT @DiasLaborales = 1
END
ELSE
BEGIN
WHILE @Cnt < @RangoDiasNormales
BEGIN
SELECT @FechaComparacion = @FechaInicial + @Cnt
IF ((datepart(dw,@FechaComparacion) <> 6) and (datepart(dw,@FechaComparacion) <> 7))
BEGIN
SELECT @fechafiesta = (SELECT CAST((CAST(datepart(dd,@FechaComparacion)AS
VARCHAR(2))+’/'+ CAST(datepart(mm,@FechaComparacion)AS VARCHAR(2)))as varchar(5)))
SELECT @cantidad=(SELECT COUNT(*) FROM TDIAS_NOLABORABLES WHERE FECHA=@fechafiesta)
IF @cantidad=1
BEGIN
SELECT @DiasLaborales = @DiasLaborales
END
ELSE
BEGIN
SELECT @DiasLaborales = @DiasLaborales + 1
END
END
SELECT @Cnt = @Cnt + 1
END
END
END
ELSE
BEGIN
SELECT @DiasLaborales = 0
END
SELECT DiasLaborales = @DiasLaborales
END
Sabado se representa con el número 6 y Domingo con el 7, como ya había indicado al inicio de este Post, considera unicamente días laborables, es decir de Lunes a Viernes excluyendo los dias feriados y festivos, es decir : Lunes a Sabados excluyendo feriados y festivos , deberán quitar todas las comparaciones que se hacen con el DATEPART en 6 ( Sábados). Si la fecha inicial o final cae un día Sábado o Domingo esta no será contabilizada, Ojo! … sólo hace el calculo de dias entre Lunes a Viernes.
3.- El procedimiento almacenado anterior, hace uso de la tabla “TDIAS_NOLABORABLES”, para definir los días no laborables, festivos y feriados, deberán incluir entre sus tablas , la siguiente tabla:
CREATE TABLE TDIAS_NOLABORABLES
(
ID_DNL INT NOT NULL PRIMARY KEY IDENTITY(1,1),
FECHA CHAR(5),
DESCRIPCION VARCHAR(50)
)Algunos registros de ejemplo:
INSERT INTO TDIAS_NOLABORABLES VALUES (’1/1′,’AÑO NUEVO’)
INSERT INTO TDIAS_NOLABORABLES VALUES (’9/4′,’JUEVES SANTO’)
INSERT INTO TDIAS_NOLABORABLES VALUES (’10/4′,’JUEVES SANTO’)
INSERT INTO TDIAS_NOLABORABLES VALUES (’1/5′,’DIA DEL TRABAJO’)
INSERT INTO TDIAS_NOLABORABLES VALUES (’29/6′,’DIA DE SAN PEDRO’)
INSERT INTO TDIAS_NOLABORABLES VALUES (’28/7′,’DIA DE LA INDEPENDENCIA’)
INSERT INTO TDIAS_NOLABORABLES VALUES (’8/10′,’COMBATE DE ANGAMOS’)
INSERT INTO TDIAS_NOLABORABLES VALUES (’8/12′,’CONCEPCION DE MARIA’)
INSERT INTO TDIAS_NOLABORABLES VALUES (’25/12′,’NAVIDAD’)
4.- Ahora viene lo mas emocionante, “el funcionamiento”, como yo declaré dentro de una clase mi función hago la llamada a esa clase para heredar todos los métodos, en este caso uno de mis metodos es la función DiasLaborales. Mi Clase de llama ” Funciones” , primero declaro que la variable “funcion” es mi clase “Funciones”.
Dim funcion As New Funciones
Luego, en algún procedimiento, función, u otro tipo de estructura puedo llamar a mi función “DiasLaborales” contenida en mi clase “Funciones”, de la siguiente manera:
c= funcion.DiasLaborales(i,f)
Donde:
- i: Es la fecha inicial, variable de tipo DateTime
- f:Es la fecha final, variable de tipo DateTime
- c:Es la cantidad de dias laborales entre i – f, variable de tipo Entero
Espero que les haya servido de gran ayuda, ya que yo cuando busqué algo así no lo encontré, y bueno espero que agradezcan con un comentario.
Atte: Rafael Villafuerte

jaime dijo el Sat, 18th Jul 2009 11:36 am
te amo men graciass eres un genioo estaba buscando estooo gracias mil veces gracias men
mensajes movistar dijo el Wed, 29th Jul 2009 10:33 pm
esta bien chula la programación.
kinesiologas dijo el Sat, 1st Aug 2009 9:49 am
excelente gracias por el codigo
caperusita dijo el Thu, 13th Aug 2009 11:13 am
buena aportacion
Eduardo dijo el Tue, 16th Mar 2010 9:51 pm
Los invito a consultar la libería que desarrollé, descarguenla de megaupload.
http://www.megaupload.com/?d=2RU458VA
Juan Sejuro dijo el Mon, 7th Jun 2010 12:12 am
Muchas gracias por tu aporte, tengo un pequeño problema que es: cuando hago la diferencia de 2 fechas por ejemlo 23/06/2010 al 24/06/2010 me sale un resultado de 1 día pero cuando le saco la diferencia del 23/06/2010 al 25/06/2010 me sale de 3 días,sino es mucha molestía te agradecería me ayudes
Gracias