Función económica: Valor Actual Neto (VAN o VNA)

Un lugar dónde compartir funciones, procedimientos y aplicaciones
Avatar de Usuario
Neckkito
Moderador
Mensajes: 829
Registrado: Dom Oct 25, 2015 3:42 pm

Función económica: Valor Actual Neto (VAN o VNA)

Mensajepor Neckkito » Mar Dic 01, 2015 10:12 pm

Cuando se analizan proyectos de inversión uno de los sistemas que suele utilizarse es el cálculo del Valor Actual Neto, conocido como VAN o VNA.

Si queremos calcular el VAN en Access podemos hacer dos cosas: o bien utilizamos el generador de expresiones -> Funciones incorporadas -> Financieras -> NPV o bien nos montamos nuestra propia función un tanto más personalizada.

Y si elegimos la segunda opción aquí tenéis un ejemplo que nos calcula el valor actual neto de una inversión, suponiendo unos flujos de caja constantes en el tiempo. Y es personalizada porque la he preparado para poder decidir si el bien objeto de la inversión se va a vender al final por su valor residual o no.

Para aclararnos, y a modo de ejemplo, si yo sé que un proyecto que me costará 100.000 euros y que me dará, durante dos años, unos rendimientos de 55.000 euros para el primer año y 55.000 euros para el segundo, con una tasa de descuento del 5%, la pregunta es: ¿es conveniente esa inversión?

Ya sabemos que si el resultado es positivo en principio "lo ganado" supera a "lo invertido", por lo que sí es conveniente. Si no, pues "palmamos pasta" (ganamos menos de lo que invertimos).

Pues aplicarlo es tan sencillo como:

1.-Crearnos un módulo estándar y en él escribir la siguiente función:

'*------------------------------------------------------------------------------.-
'*---Neckkito @ http://neckkito.siliconproject.com.ar/- ... --------.-
'-------Fecha creación: 01/12/15------------------------------------------------.-
'-------Fecha última modificación: 01/12/15-------------------------------------.-
'*------Función que calcula el Valor Actual Neto (VAN o VNA) de una inversión---.-
'*------suponiendo unos flujos de caja constantes-------------------------------.-
'*------Permite la actualización del valor residual al final del periodo--------.-
'*------------------------------------------------------------------------------.-
Public Function fncVAN( _
valorInversion As Currency, _
tasaDescuento As Double, _
flujoDeCaja As Currency, _
anosInversion As Byte, _
Optional valorResidual As Currency = 0)
Dim i As Byte
Dim valorActualAcumulado As Currency
For i = 1 To anosInversion
valorActualAcumulado = valorActualAcumulado + flujoDeCaja / (1 + tasaDescuento) ^ i
Next i
If valorResidual <> 0 Then
valorActualAcumulado = valorActualAcumulado + valorResidual / (1 + tasaDescuento) ^ anosInversion
End If
fncVAN = Round(valorActualAcumulado - valorInversion, 2)
End Function

2.- Hacer una llamada a la función cumplimentando los argumentos. Siguiendo con el ejemplo, si queremos almacenar el VAN en una variable VanProyecto (de tipo Currency), escribiríamos:

VanProyecto = fncVAN(100000, 0.05, 55000, 2)

Si supuestamente esa inversión consistía en comprar una máquina que, al cabo de dos años, podemos vender por 7000 euros, pues la llamada sería:

VanProyecto = fncVAN(100000, 0.05, 55000, 2, 7000)

Y hasta aquí el tema. El día que me sienta inspirado, y si alguien lo solicita, ya os explicaré cómo calcular el VAN con flujos de caja no constantes... :roll:

Espero que os pueda ser de utilidad.

Saludos!
Access MVP 2017-2019
http://bit.ly/NckAccess

Avatar de Usuario
Sveinbjorn
Moderador
Mensajes: 1073
Registrado: Sab Oct 24, 2015 10:12 pm

Re: Función económica: Valor Actual Neto (VAN o VNA)

Mensajepor Sveinbjorn » Mié Dic 02, 2015 9:20 pm

El día que me sienta inspirado, y si alguien lo solicita, ya os explicaré cómo calcular el VAN con flujos de caja no constantes...


A mí ya se me ocurrió una forma de hacerlo.... :roll:
Sveinbjorn El Rojo

Avatar de Usuario
Neckkito
Moderador
Mensajes: 829
Registrado: Dom Oct 25, 2015 3:42 pm

Re: Función económica: Valor Actual Neto (VAN o VNA)

Mensajepor Neckkito » Mié Dic 02, 2015 9:26 pm

Je, je... cómo se nota a quién le tiran los temas económicos... ¿por qué será? :P

La parte positiva es que, si alguien lo pide, ya lo habrás pensado tú y yo no tendré que trabajar :twisted:

Ni que decir tiene que si te apetece explicarlo aquí soy todo ojos... :shock:

Un abrazo
Access MVP 2017-2019
http://bit.ly/NckAccess

Avatar de Usuario
Sveinbjorn
Moderador
Mensajes: 1073
Registrado: Sab Oct 24, 2015 10:12 pm

Re: Función económica: Valor Actual Neto (VAN o VNA)

Mensajepor Sveinbjorn » Jue Dic 03, 2015 6:41 pm

Bueno, como parece que nadie más que nosotros, de momento, tiene "inquietudes económicas", dejo mi aportación para calcular el VAN con la posibilidad de que los flujos de caja no sean constantes:


1º/ Código de la función:
'---------------------------------------------------------------------------------------
' Procedimiento: fncVANFlujosVariables
' Autor : Sveinbjorn para Dudas Access Foro (http://nksvaccessolutions.com/Foro/)
' Partiendo de la función fncVAN de Neckkito
' Fecha : 03/12/2015
' Propósito : Función que calcula el Valor Actual Neto (VAN o VNA) de una inversión
' unos flujos de caja variables
' Permite la actualización del valor residual al final del periodo
'---------------------------------------------------------------------------------------
Public Function fncVANFlujosVariables(valorInversion As Currency, _
tasaDescuento As Double, _
valorResidual As Currency, _
ParamArray flujosDeCaja())
Dim i As Byte
Dim valorActualAcumulado As Currency
Dim anosInversion As Byte

anosInversion = UBound(flujosDeCaja) + 1

For i = 1 To anosInversion
valorActualAcumulado = valorActualAcumulado + IIf(IsMissing(flujosDeCaja(i - 1)), 0, flujosDeCaja(i - 1)) / (1 + tasaDescuento) ^ i
Next i
If valorResidual <> 0 Then
valorActualAcumulado = valorActualAcumulado + valorResidual / (1 + tasaDescuento) ^ anosInversion
End If
fncVANFlujosVariables = Round(valorActualAcumulado - valorInversion, 2)
End Function


2º/ Explicación de uso:
En este caso los parámetros a pasar a la función son diferentes:
.- No se le pasa la duración de la inversión (anosInversion), pues ahora se calculan en función del número de flujos de caja que le pasemos.
.- El valor residual (valorResidual) ya no es opcional como antes, por lo que si no tenemos hay que poner obligatoriamente 0.
.- El último parámetro (flujosDeCaja) es un array que contendrá los distintos flujos de caja de los que conste la inversión. Si algún año no hay flujo de caja, se puede dejar vacío o poner como flujo un 0. La propia función se encarga de convertir los flujos "ausentes" a 0 con esta expresión: IIf(IsMissing(flujosDeCaja(i - 1)), 0, flujosDeCaja(i - 1))
¡OJO! Si el último año fuera el que no tiene flujo de caja, obligatoriamente hay que poner 0 como flujo.

Para aplicarla, igual que la función anterior, sólo hay que pasarle los parámetros:

VanProyecto = fncVAN(100000, 0.05, 0, 55000, 45000, 27000)

que calcularía el VAN de una inversión de 100000 u.m., un interés del 5%, un valor residual de 0 y tres flujos de caja de 55000, 45000 y 27000 u.m. en los años 1, 2 y 3.

Si el mismo proyecto sólo tuviera dos flujos de caja, en los años 1 y 3, por ejemplo, la sintaxis sería:

VanProyecto = fncVANFlujosVariables (100000, 0.05, 0, 55000, , 27000)

o esta otra:

VanProyecto = fncVANFlujosVariables (100000, 0.05, 0, 55000, 0, 27000)

Y, por supuesto, si los 3 flujos fuesen constantes, pondríamos:

VanProyecto = fncVANFlujosVariables (100000, 0.05, 0, 55000, 55000, 55000)

que nos dará el mismo resultado que la función de Miquel (si no mal vamos.... :roll: ) :
VanProyecto = fncVAN(100000, 0.05, 55000, 3)


Y ésta es mi aportación financiera de la semana... :lol:

Saludos!!
Sveinbjorn El Rojo

Avatar de Usuario
Neckkito
Moderador
Mensajes: 829
Registrado: Dom Oct 25, 2015 3:42 pm

Re: Función económica: Valor Actual Neto (VAN o VNA)

Mensajepor Neckkito » Jue Dic 03, 2015 8:21 pm

Y... ¡olé! :lol:
Access MVP 2017-2019
http://bit.ly/NckAccess

Avatar de Usuario
javier.mil
Colaborador
Reto01
Mensajes: 30
Registrado: Jue Mar 16, 2017 5:21 pm

Re: Función económica: Valor Actual Neto (VAN o VNA)

Mensajepor javier.mil » Mar Jun 11, 2019 1:01 pm

¿ Y por que No usar la función que lleva incorporada Access de fabrica para el calculo del VAN ?

La historia: Después de pelearme un rato con un función publicada por Microsoft y que No daba el resultado esperado Nii correcto pues decidí a investigar a ver que pasaba ,.... hasta que llegue aquí y gracias a ayuda de Sveinbjorn he llegado a la siguiente conclusión , de como usar la instrucción que lleva incorporada de fabrica Access para el calculo de VAN siendo el sistema algo mas exacto

https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/npv-function?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev11.query%3FappId%3DDev11IDEF1%26l%3Den-US%26k%3Dk(vblr6.chm1009284)%3Bk(TargetFrameworkMoniker-Office.Version%3Dv16)%26rd%3Dtrue

Código: Seleccionar todo

Public Function funNPV_Mal()
    Rem Código Original de Microsoft
    Rem AVISO: Este código da un resultado incorrecto
   
    Dim Fmt, Guess, RetRate, NetPVal, Msg
    Static Values(5) As Double    ' Set up array.
    Fmt = "###,##0.00"    ' Define money format.
    Guess = 0.1   ' Guess starts at 10 percent.
    RetRate = 0.0625   ' Set fixed internal rate.
    Values(0) = -70000    ' Business start-up costs.
    ' Positive cash flows reflecting income for four successive years.
    Values(1) = 22000: Values(2) = 25000
    Values(3) = 28000: Values(4) = 31000
    NetPVal = NPV(RetRate, Values())    ' Calculate net present value.
    Msg = "The net present value of these cash flows is "
    Msg = Msg & Format(NetPVal, Fmt) & "."
    Debug.Print Msg
    MsgBox Msg    ' Display net present value.
End Function




Código: Seleccionar todo

Private Function funTets()
    Const cFormato As String = "##,##0.00"

    Rem La Inversion Inicial debe estar en POSITIVO y la Tasa de Descuento sin dividir por 100
    MsgBox "VAN = " & Format(funNPV_2(70000, 6.25, 22000, 25000, 28000, 31000), cFormato), vbInformation, "VAN"
End Function




Código: Seleccionar todo

Public Function funNPV(ByVal PonInversionInicial As Double, ByVal PonTasaDescuento As Double, ParamArray arrPonFlujos() As Variant) As Double

Rem ---------------------------------------------------------------------------------------
Rem Procedure :  funNPV
Rem Date      :  11/Junio/2019
Rem Author    :  Javier Gomez ("Javier.Mil")
Rem Email     :  accessdemo@hotmail.com
Rem WEB       :  http://www.accessdemo.info
Rem Purpose   :  Calcula el Valor Actual Neto (VAN o VNA o NPV) de una inversión con flujos variables, utilizando la intruccion interna de Access NPV
'---------------------------------------------------------------------------------------

    Dim arrValores() As Double    ' << Matriz , Array
    Dim varValor As Variant
    Dim intX As Integer



    Rem Comprobacion del signo de la Inversion inicial
    If PonInversionInicial < 0 Then
        MsgBox "Error: La Inversion tiene que ser un valor positivo", vbExclamation, "Error"
        Exit Function
    End If


    Rem compruebo que el valor sea 6.25% en lugar de 0.0625 (dividido por 100) como suele ser habitual
    If Left(PonInversionInicial, 1) = 0 Then
        MsgBox "AVISO: Cuidado el % quizas No deberia empezar por cero", vbExclamation, "Aviso"
    End If



    Rem Pequeño truco para evitar el Error en la instrucción NPV , ya que No se puede poner directamente arrValores() como parametro
    For Each varValor In arrPonFlujos
        ReDim Preserve arrValores(intX)
        arrValores(intX) = CDbl(arrPonFlujos(intX))
        intX = intX + 1
    Next varValor


    ' funNPV = NPV(PonTasaDescuento / 100, arrPonFlujos()) - PonInversionInicial  ' << Da Error , por eso utilizo la rutina arriba expuesta
    funNPV = NPV(PonTasaDescuento / 100, arrValores()) - PonInversionInicial



End Function




Después de terminarlo me sigue quedando la duda si esta parte se puede mejorar

For Each varValor In arrPonFlujos
ReDim Preserve arrValores(intX)
arrValores(intX) = CDbl(arrPonFlujos(intX))
intX = intX + 1
Next varValor


 





 


Volver a “Almacén Accesiano”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado