code segment (3.0)

read carefully

Excel - Distribuciones, Planificaciones, Formulas Matriciales

Comments

No se si lo he comentado alguna vez, pero en el trabajo suelo usar mucho Excel para hacer una gran variedad de cosas, en general mucho de lo que tiene que ver con el área económico financiera (lo terminamos haciendo en Excel).

Muchas de nuestras hojas de cálculo, son planes financieros, estudios de viabilidad, análisis etc. Básicamente estas hojas planifican cobros y pagos ó gastos e ingresos, la cuestión es la planificación, en Excel podemos planificar todo aquello que queramos, es sencillo podemos establecer una fila para cada previsión a realizar y en cada columna podemos poner un periodo (ene, feb, mar…), por último en cada celda (previsión / periodo) el importe de dicha previsión.

image

El problema se complica un poco cuando el importe de cada previsión no tiene un periodo fijo, sino que este debe establecerse en función de otra variable. Supongamos que tenemos que realizar una previsión entre dos periodos dados (Inicio y Final) y el importe debe ser proporcional al número de periodos.

image

Como es lógico las formulas se nos van complicando, más y más en función de las condiciones que necesitamos. Con lo que terminamos creando nuestras funciones en VBA para simplificar el proceso.

1
2
3
4
5
Function csPDistB(importe As Integer, periodo As Integer, inicio As Integer, fin As Integer)
  If (periodo >= inicio) And (periodo <= fin) Then
    csPDistB = importe / ((fin  inicio) + 1)
  End If
End Function

Realizaría el mismo trabajo que las formulas vistas. Dándole una vuelta más podemos crear una función matricial para hacer la misma tarea y que automáticamente tome el periodo actual en función del rango en donde se encuentre.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Public Function csPDistB(importe As Variant, primero As Integer, ultimo As Integer) As Variant
  Dim i As Integer
  Dim nPeriodos As Integer
  Dim valor As Double

  ReDim a(0 To Application.Caller.Rows.Count, 0 To Application.Caller.Columns.Count) As Variant

  On Error GoTo Handler

  nPeriodos = ultimo  primero
  valor = CDbl(importe / (nPeriodos + 1))

  For i = 0 To Application.Caller.Columns.Count
      If i + 1 >= primero And i + 1 <= ultimo Then
         a(0, i) = valor
      End If
  Next

  csPDistB = a

  Exit Function
Handler:
  csPDistB = CVErr(2015)  xlErrNum = 2036
End Function

image

Por último con una pequeñas modificaciones sobre este código podemos crear funciones más complejas para nuestras planificaciones, por ejemplo distribuciones en función de una curva de porcentajes, 25%, 50% y 25% sería el 25% en el primer tercio, el 50% en el segundo tercio y el 25% en el tercer tercio del tiempo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Public Function csPDistCP(importe As Variant, ParamArray porcentajes()) As Variant
  Dim i As Integer
  Dim nParte As Integer
  Dim p As Integer

  ReDim a(Application.Caller.Columns.Count) As Variant

  On Error GoTo Handler

  nParte = (UBound(a) + 1) / (UBound(porcentajes) + 1)

  p = -1

  For i = 0 To UBound(a)
    If i Mod Int(nParte) = 0 Then
       If p < UBound(porcentajes) Then
          p = p + 1
       End If
    End If

    a(i) = CDbl((importe / nParte) * porcentajes(p))

  Next

  csPDistCP = a

  Exit Function

Handler:

  csPDistCP = CVErr(2015)  xlErrNum = 2036

End Function

Un último ejemplo en donde realizamos previsiones los periodos indicados, el importe proporcional al número de periodos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Public Function csPDistP(importe As Variant, ParamArray periodos()) As Variant
  Dim i As Integer
  Dim nPeriodos As Integer
  Dim valor As Double

  ReDim a(Application.Caller.Columns.Count) As Variant

  On Error GoTo Handler

  nPeriodos = UBound(periodos)

  valor = CDbl(importe / (nPeriodos + 1))

  For i = 0 To nPeriodos
      a(periodos(i)) = valor
  Next

  csPDistP = a

  Exit Function

Handler:

  csPDistP = CVErr(2015)  xlErrNum = 2036

End Function