0

Say I have a function that takes two Date arguments. Then I need to change one of those (say, I need to change its month). Is the only way to do it to reassign it to variables and then change or can it be changed by referencing to it by its argument name?

Function test(date1 As Date, date2 As Date, change As Boolean)
   If change=True Then
         date1 = DateSerial(year(date1), 10, day(date1))   'would it change date1's month or not?
   End If

   test=date1
End Function
6
  • 3
    Since you are using a Function don't you want to assign the result to test ? like test = DateSerial(Year(date1), 10, Day(date1)) ? Commented Nov 10, 2017 at 11:33
  • @ Shai Rado, well, it's a simplified example. In an actual function I need to first modify date1 and then go through a Do cycle incremeneting it and storing the dates in a collection that will be returned. Commented Nov 10, 2017 at 11:35
  • I would not expect the function to change my inputs. But right now your function will just do that. I would use ByRef in iorder to avoid that. You can also return a collection Function test(...) as collection Commented Nov 10, 2017 at 11:35
  • 1
    @Storax You mean ByVal - ByRef is the default and allows you to change the original variable. Commented Nov 10, 2017 at 12:02
  • If you're calling this as a UDF from a cell, you can't. Commented Nov 10, 2017 at 12:02

2 Answers 2

1

It's generally considered a best practice not to change inputs, although there is nothing preventing your from doing so - those arguments are treated just like variables inside the procedure. For short, simple functions you can get away with it. But if you have a longer, more complex function and you stick to never changing inputs, your code becomes much easier to maintain.

Say you get a date from the user, but you want to go back to the last statement date which is always the last day of the previous month. You can manipulate the argument like

Public Function LastStatementAmount(ByVal inputDate As Date) As Double

    Dim Return_ As Double

    inputDate = DateSerial(Year(inputDate), Month(inputDate), 0)

    'do calculations here

    LastStatementAmount = Return_

End Function

and that works. But the better way is to change the variable name to reflect what changes you made to the value

Public Function LastStatementAmount(ByVal inputDate As Date) As Double

    Dim Return_ As Double
    Dim stmtDate As Date

    stmtDate = DateSerial(Year(inputDate), Month(inputDate), 0)

    'do calculations here

    LastStatementAmount = Return_

End Function

If this were a larger function, it would be better to see stmtDate and know that you had already modified the input date.

Another reason not to change an input parameter, as mentioned in the comments, is that if you don't specify a passing mechanism, the parameter is, by default, ByRef and if the calling procedure is expecting that the value didn't change, you might break the code. You should always specify ByVal or ByRef so it's clear what your code intends.

Sign up to request clarification or add additional context in comments.

Comments

0

Within the code you can use Date1 and Date2 as variables, so you can alter their values. The variables Date1 and Date2 are declared within the function statement, and so their scope is purely withing the function. So worries abut changing the inputs are misguided in the contect of a UDF - Date1 and Date2 do not exist anywhere else. If you were using this in another routine however, then you could indeed risk this, and so you'd declare them By Value

Function Test(ByVal Date1 As Date, ByVal Date2 As Date, Change As Boolean)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.