Ayer me pidieron que creara una función por partes formada por varias rectas y que se pudiera modificar si fuera necesario en el futuro de manera sencilla… ahí estaba el reto, ¡de manera sencilla!. Desde mi punto de vista, una función por partes, en Excel no es sencilla nunca, acaba siendo bastante liosa. Por eso mismo me lancé a crear un función en VBA.
Tenemos dos datos de entrada:
- El valor X de la función
- Los valores de los puntos que componen la función. Estos puntos es donde la función cambia de pendiente.
Para ello creamos la siguiente tabla de datos:
Esta tabla me da los puntos x y los puntos y donde la función cambia de pendiente. Este será el segundo argumento de mi función.
El código que se ha utilizado no tiene partes complejas, simplemente es un código ordenado en el que se recorre la el rango tabla_puntos para encontrar los puntos entre los que se encuentra el valor del punto_x. Las ventajas de esta función es que se puede ampliar tanto como se quiera puesto que no está limitado el rango.
Los argumentos de esta función son:
=FUNCION_POR_PARTES( punto_x inicial; tabla de puntos)
Function FUNCION_POR_PARTES(punto_x As Range, tabla_puntos As Range) As Double
Dim MAX, i, punto1 As Integer
Dim x1, y1, x2, y2, pendiente As Double
Application.ScreenUpdating = False
MAX = tabla_puntos.Rows.Count 'máximo valor fila de la tabla
'compruebo que el valor x de mi punto se encuentra dentro de los valores
'máximo y mínimio de la tabla
If punto_x < tabla_puntos(1, 1) Or punto_x >= tabla_puntos(MAX, 1) Then
FUNCION_POR_PARTES = 0
Exit Function
End If
'busco entre que dos puntos se encuentra mi valor x para hallar la pendiente
'de la recta
For i = 1 To MAX
If punto_x >= tabla_puntos(i, 1) And punto_x < tabla_puntos(i + 1, 1) Then
punto1 = i
Exit For 'una vez encontrado salgo del bucle
End If
Next i
'hallo la pendiente de la recta en la que me encuentro
x1 = tabla_puntos(punto1, 1)
y1 = tabla_puntos(punto1, 2)
x2 = tabla_puntos(punto1 + 1, 1)
y2 = tabla_puntos(punto1 + 1, 2)
pendiente = (y2 - y1) / (x2 - x1)
FUNCION_POR_PARTES = y1 + pendiente * (punto_x - x1)
Application.ScreenUpdating = False
End Function