Programación

Problema: En las escuelas secundarias y primarias ocurre esporádicamente que es necesario calcular la edad en años cumplidos de un alumno con respecto a una fecha dada. Por ejemplo, supóngase que hoy es 31 de septiembre de 2010. Un alumno nació el 8 de octubre de 2000 ¿Cuántos años exactos tiene? Se ve que no se puede simplemente restar los años (2010 menos 2000) pues el alumno cumplirá hasta el 8 de octubre así que su edad es de 9 años. Si en cambio, el hubiera nacido el 31 de septiembre de 2010 entonces él sí tendría 10 años.

Objetivo Principal: Implementar una función en VisualBasic que dada la fecha actual (FechaBase) y dada la fecha de nacimiento (FechaNacimiento) del sujeto devuelva los años cumplidos sin emplear números de serie.

Solución codificada:

Public Function AniosCumplidos(FechaBase As Date, FechaNacimiento As Date) As Integer
Dim AnioNacimiento As Integer
Dim AnioBase As Integer
Dim MesNacimiento As Integer
Dim MesBase As Integer
Dim DiaNacimiento As Integer
Dim DiaBase As Integer
AnioNacimiento = Year(CDate(FechaNacimiento))
AnioBase = Year(CDate(FechaBase))
MesNacimiento = Month(CDate(FechaNacimiento))
MesBase = Month(CDate(FechaBase))
DiaNacimiento = Day(CDate(FechaNacimiento))
DiaBase = Day(CDate(FechaBase))
If MesNacimiento > MesBase Then
AniosCumplidos = AnioBase – AnioNacimiento – 1
Else
If Not (MesNacimiento = MesBase) Then
AniosCumplidos = AnioBase – AnioNacimiento
Else
If DiaBase >= DiaNacimiento Then
AniosCumplidos = AnioBase – AnioNacimiento
Else
AniosCumplidos = AnioBase – AnioNacimiento – 1
End If
End If
End If
End Function

Problema: En ciertas industrias utilizan un doble calendario:

  • El civil conformado con todas sus irregularidades tales como que no todos los meses tengan la misma cantidad de días o que no todos los años tengan la misma duración; y
  • El juliano consistente en numerar de forma secuencial los días del año. Así el 1 de enero de cualquier año es el 1 del año juliano y el día 1 de febrero corresponde al día 32  juliano (31 días de enero más el primer día de febrero acumulan 32 días)

Objetivo principal: Escribir una función para Excel denominada Dia Juliano que reciba como argumento una fecha en un formato civil y devuelva el día juliano correspondiente.

Solución codificada:

Function DiaJuliano(fecha As Date) As Integer
‘Se creará un arreglo para almacenar los días que han
‘transcurrido desde el mes previo. Su sintaxis es: DiasTranscurridos(Mes)

‘Ejemplo 1:
‘DiasAcumuladoNoBisiesto(2) será igual a 31 porque enero que
‘es el mes previo tiene 31 días.
‘Ejemplo 2:
‘DiasAcumulados(3) será igual a 59 días porque enero
‘tiene 31 días y febrero tiene 28 días.

‘Recuerde que los meses del año tienen los siguientes días:
‘Enero=31 días para ambos casos
‘Febrero= 28 días (año no bisiesto)
‘Marzo = 31 días
‘Abril = 30 días
‘Mayo = 31 días
‘Junio= 30 días
‘Julio= 31 días
‘Agosto= 31 días
‘Septiembre = 30 días
‘Octubre=31 días
‘Noviembre=30 días
‘Diciembre=31 días

Dim Bisiesto As Integer, Anio As Integer, Mes As Integer, Dia As Integer
Dim DiasAcumulados(1 To 12) As Integer

‘Se obtiene los datos del año, mes y dia
Anio = Year(fecha)
Mes = Month(fecha)
Dia = Day(fecha)
DiasAcumulados(1) = 0: DiasAcumulados(2) = 31: DiasAcumulados(3) = 59
DiasAcumulados(4) = 90: DiasAcumulados(5) = 120: DiasAcumulados(6) = 151
DiasAcumulados(7) = 181: DiasAcumulados(8) = 212: DiasAcumulados(9) = 243
DiasAcumulados(10) = 273: DiasAcumulados(11) = 304: DiasAcumulados(12) = 334

‘Los años que no sean divisibles por 4 no serán bisiestos o
‘no serán bisiestos si son divisibles entre 100

‘y al mismo tiempo no sean divisibles por 400 (como los años 1700, 1800, 1900 y 2100)

If (Anio Mod 4) <> 0 Or _
((Anio Mod 100) = 0 And (Anio Mod 400) <> 0) Then
Bisiesto = 0
Else
Bisiesto = 1
End If

‘Finalmente determinamos el día juliano
‘Observe que Enero y Febrero son inmunes a la acumulación de un dia más en
‘el caso de que el año sea bisiesto
‘<— Use este código si no entiende el que esta en funcionamiento
‘If Mes <= 2 Then
‘    DiaJuliano = DiasAcumulados(Mes) + Dia
‘Else
‘    DiaJuliano = DiasAcumulados(Mes) + Bisiesto + Dia
‘End If
‘——————>

DiaJuliano = DiasAcumulados(Mes) + Dia + Bisiesto * Sgn(Int(Mes / 3))
End Function



Problema:

Ibid (Por si no reuerdas que significa este cultismo latino consulta la página http://es.wikipedia.org/wiki/Ib%C3%ADdem)

Objetivo principal: Escribir la función inversa al anterior problema, esto es, escribir una función para Excel denominada DiaCivil que reciba como argumentos:

  • Una fecha en un formato juliano (Número entero comprendido entre 1 y 365 para años no bisiestos y entre 1 y 366 para años bisiestos) como
  • El año

y devuelva el día civil correspondiente.

Solución codificada:

Function DiaCivil(DiaJuliano As Integer, anio As Integer) As Date
Dim Bisiesto As Byte, Dia As Byte, Mes As Byte

‘Los años que no sean divisibles por 4 no serán bisiestos o
‘no serán bisiestos si son divisibles entre 100
‘y al mismo tiempo no sean divisibles por 400 (como los años 1700, 1800, 1900 y 2100)

If (anio Mod 4) <> 0 Or _
((anio Mod 100) = 0 And (anio Mod 400) <> 0) Then
Bisiesto = 0
Else
Bisiesto = 1
End If

Select Case DiaJuliano
Case 1 To 31 ‘El mes es enero
Mes = 1: Dia = DiaJuliano
Case 32 To 59 + Bisiesto ‘El mes es febrero
Mes = 2: Dia = DiaJuliano – 31
Case 60 + Bisiesto To 90 + Bisiesto ‘El mes es marzo
Mes = 3: Dia = DiaJuliano – 59
– Bisiesto
Case 91 + Bisiesto To 120 + Bisiesto ‘El mes es abril
Mes = 4: Dia = DiaJuliano – 90
– Bisiesto
Case 121 + Bisiesto To 151 + Bisiesto ‘El mes es mayo
Mes = 5: Dia = DiaJuliano – 120
– Bisiesto
Case 152 + Bisiesto To 181 + Bisiesto ‘El mes es junio
Mes = 6: Dia = DiaJuliano – 151
-Bisiesto
Case 182 + Bisiesto To 212 + Bisiesto ‘El mes es julio
Mes = 7:: Dia = DiaJuliano – 181
– Bisiesto
Case 213 + Bisiesto To 243 + Bisiesto ‘El mes es agosto
Mes = 8: Dia = DiaJuliano – 212
– Bisiesto
Case 244 + Bisiesto To 273 + Bisiesto ‘El mes es septiembre
Mes = 9: Dia = DiaJuliano – 243
– Bisiesto
Case 274 + Bisiesto To 304 + Bisiesto ‘El mes es octubre
Mes = 10: Dia = DiaJuliano – 273
– Bisiesto
Case 305 + Bisiesto To 334 + Bisiesto ‘El mes es noviembre
Mes = 11: Dia = DiaJuliano – 304
– Bisiesto
Case 335 + Bisiesto To 365 + Bisiesto ‘El mes es diciembre
Mes = 12: Dia = DiaJuliano – 334
– Bisiesto

Case Else
DiaCivil = “#N/A”
Exit Function
End Select

DiaCivil = Format(Dia & “/” & Mes & “/” & anio, “Medium Date”)

End Function


Problema:

En ciertas ocasiones se tiene una matriz rectangular (a manera de base de datos) donde se van almacenando registros (un registro es un renglón de la matriz) ordenados de manera cronológica. El registro más reciente tiene que ir en la parte superior de la matriz y el mas antiguo en la parte inferior de la base de datos. En consecuencia, cada vez que necesitas ingresar un registro es necesario insertar de forma manual una fila en la parte superior de la base de datos y luego capturar los datos en ella. Si vas a capturar al día 400 registros necesitarás realizar la inserción en igual cantidad. Lo ideal sería que mejor escribieras en la siguiente fila a la inferior de la matriz y luego excel suba tal fila a la parte superior de la matriz.

Objetivo principal: Escribir una macro denominada SubirUltimaFila() que una vez que el usuario haya ingresado una fila inferior, aquella ubique el registro en la parte superior de la base de datos. La macro debe ser independiente del tamaño de la base de datos y de su ubicación dentro de la hoja de cálculo. La macro debe ser capaz de seleccionar la base de datos aún cuando la celda activa este enla fila inmediata inferior de la matriz y en consecuencia este en una fila vacía.

Solución codificada:

Public Sub Subir_Ultima_Fila()
Dim CantidadRenglones As Integer
‘Seleccionamos la región actual
ActiveCell.CurrentRegion.Select
Verifiquemos que la región posee al menos dos celdas
If Selection.Rows.Count = 1 And Selection.Columns.Count = 1 Then End
ActiveCell.CurrentRegion.Select
‘Determinamos y asignamos los valores de los renglones de la selección actual
CantidadRenglones = Selection.Rows.Count
‘Procedemos a cortar la selección actual
Selection.Cut
‘Nos desplazamos un renglón hacia abajo y pegamos la selección
ActiveCell.Offset(RowOffset:=1, ColumnOffset:=0).Select
ActiveSheet.Paste
‘Desplacemos la celda activa al último renglón del área actual
ActiveCell.Offset(RowOffset:=CantidadRenglones – 1, ColumnOffset:=0).Select
‘Seleccionemos el último renglón y cortémoslo
Range(Selection, Selection.End(xlToRight)).Select
Selection.Cut
Desplacemos arriba de la selección y peguemos
ActiveCell.Offset(RowOffset:=-CantidadRenglones, ColumnOffset:=0).Select
ActiveSheet.Paste
‘Finalmente desplacemos la celda activa a hasta abajo del área
Selection.End(xlDown).Select
ActiveCell.Offset(RowOffset:=1, ColumnOffset:=0).Select
End Sub

Buenos Enlaces para aprender a programar VBA Macros

Estuve husmeando en la red para verificar si podíamos encontrar algo bueno para aprender VBA Macros para Excel y hasta el momento he encontrado lo siguiente:

  • En http://www.excel-vba.com/ puedes encontrar un tutorial escrito en inglés que contiene lo suficiente para empezar a programar macros en Excel. Es bueno pero solamente tiene la limitante de que no muestra todo su contenido porque es un promocional para adquirir el tutorial.
  • En http://www.xltoday.net/vba_macros_ejemplosmacros.asp encuentras ejemplos sobre distintas macros. Lo interesante es analizarlas para entender el funcionamiento de cada palabra reservada que desconozcas.
  • Finalmente, conseguí en mi lectura dos archivos en pdf interesantes:
Objetivo principal: Escribir la función inversa
Anuncios
Comments
6 Responses to “Programación”
  1. angelepg dice:

    Me interesaron las funciones para Excel que aparecen en esta página pero no se como aplicarlos o como introducirlos a Excel, si pudieras tomarte un tiempo para indicarme como aplicarlas te lo agradecerá mucho atte Angel Padilla
    http://angelepg.wordpress.com

  2. angelepg dice:

    Intenté compilar en Visual Basic de Office 2007, pero me marca error de sintaxis

    • jrgsm70 dice:

      Mira
      Estas funciones están diseñada para que sean usadas exclusivamente en Excel. Use la palabra reservada function para que puedas invocarla directa y exclusivamente de la barra de fórmulas de ese programa.

      Para que pueda indicarte cómo puedes emplear tales funciones necesito que me digas qué versión de Excel usas. En cuanto tenga tu respuesta con gusto te guiaré para que puedas añadirlas a tu biblioteca de funciones.

      Finalmente, a mí me encanta programar. Si tienes algún problema que creas que puede ser programado, mucho te agradecería que lo pusieras en este espacio.

      Saludos

      • Dispongo de office 2003 y 2007, respecto a los problemas, me llama mucho la atención el de las fechas por que es algo que usamos cada ciclo escolar, y quiero aplicarlo en la escuela donde trabajo, Saludos y Bendiciones.

  3. Traté de insertar toda la formula en Excel e hice clic en aceptar, pero no sucedió nada solo me marcó error de dicción

  4. jrgsm70 dice:

    Hola Efraín:

    Con respecto a tu duda te comento que las líneas de código en color azul que viste renglones arriba deberán ser copiadas en la sección módulo de una macro. Para que puedas tener una mejor idea a continuación te sugiero que leas la página http://www.aulaclic.es/excel2007/t_18_3.htm donde hay instrucciones pormenorizadas para realizar la macro anterior.

    Para el caso que te ocupa y posterior a la lectura de la página Web anterior te aclaro lo siguiente:

    1. Abre la hoja de cálculo donde radica la base de datos con las fechas de nacimiento de tus alumnos.
    2. Abre el editor Visual Basic presionando la combinación de teclas Alt + F11. Verifica que estes en la pantalla de un módulo
    cuya imagen es similar a:
    Modulo de Visual Basic para Aplicaciones (propiamente de Excel)
    De lo contrario deberás insertar el módulo haciendo clic en el menú insertar -> Módulo
    3. Copia el código azul que te interesó en la región blanca del módulo. En caso de que te marque algún error deberás cambiar los guiones que aparecen en el código (por ejemplo AniosCumplidos = AnioBase – AnioNacimiento) por los guiones de tu teclado. El módulo debe verse así:
    Módulo con código de Visual Basic
    4. Cierra el editor de Visual Basic para regresar a la hoja de cálculo.
    5. En la barra de fórmulas, escribe el siguiente texto:
    =AniosCumplidos(“19/04/2010″,”08/10/1970”)
    Deberás obtener 39.
    Recuerda que esta función tiene dos argumentos: El primero contiene la fecha actual en tanto que el segundo contiene la fecha de nacimiento del alumno. Adicionalmente es importante que observes que las fechas cuando no están referenciadas a alguna celda deben ir encerradas entre comillas. Por el contrario, si tienes en la celda A2 la fecha actual (19/04/2010) y en la celda B2 la fecha de nacimiento (08/10/2010) entonces no deberás usar comillas ni en A2 ni en B2. Finalmente supon que quieres obtener en la celda C2 la edad actual, entonces en tal celda deberás anotar la fórmula:
    =AniosCumplidos(A2,A3)
    Y deberás obtener 39
    Funcion AniosCumplidos
    Si tienes alguna otra duda avísame
    Josué

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: