How to return a range object from a user defined function in vba - function

I have this piece of code in excel:
Private Function RelCell(NmdRng as String) as Range
Set RelCell = Range(NmdRng).Cells(1,1)
End Function
it gives the runtime error "91': object variable or with block variable not set.
I really don't know what is the problem with my function.. someone does?

I don't know if this is the problem but your are only setting the range and aren't returning anything from the function.
Try declaring a range variable with a different name as the function and return that.

Actually, you should be able to return a range from a UDF as described in this MSDN Thread.
Here is the code given by the MVP:
Function GetMeRange(rStartCell As Range, lRows As Long, iColumns As Integer) As Range
Set GetMe = rStartCell.Resize(lRows, iColumns) ' note the use of Set here since we are setting an object variable
End Function
(and it works)
Tiago's comment points out a very right thing, as you want to access a named range, it should be defined first.
You can try to set a breakpoint in your UDF and see if the Range(NmdRng) is defined.

Your named range already has a cell reference attached to it, so you shouldn't need to have the .Cells(1,1) at the end of it.
Using the .Range(nmdRng) property alone will return the range object you are looking for.
Try:
Private Function RelCell(NmdRng as String) as Range
Set RelCell = Range("NmdRng")
End Function

Please rewrite your code and test it as follows :
Private Function RelCell(NmdRng as String) as Range
Dim TestRange As Range
Set TestRange=Range(NmdRng)
TestRange.Activate 'I think that error will occur here because, NmdRng is somehow invalid
Set RelCell = TestRange.Cells(1,1)
End Function

Related

Why am I getting error 3078 on my SELECT query?

I've started to try and write some VBA to execute some queries and I've got stuck at the first hurdle. This is giving an error 3078 which apparently means it can't find the table or query. The table definitely exists and is spelt properly. Indeed the SQL runs fine - I tested it. What am I doing wrong?
Public Function Tester()
str_tbl = "tblGames_atp"
str_mkvrec = "SELECT * FROM " & str_tbl
dbl_fs_pct = DSum("FS", str_mkvrec)
End Function
Cannot reference SQL statement in domain aggregate function, not even a variable set to that statement. Must reference table or query object name. Could reference variable with name string but variable not really needed in this code. If you want function to return a value to calling source, then need to set function value.
Public Function Tester()
Tester = DSum("FS", "tblGames_atp")
End Function

SSRS reference report variable from report function

In SSRS, is it possible to reference a report variable from a report function?
Below is my report function. Instead of declaring and setting the MaxRFWIDRange in the function, I'd rather reference a report variable with the same name.
Function ValidateRFWIDRange(FromRFW As Integer, ToRFW As Integer) As Boolean
Dim DiffRFW As Integer
Dim MaxRFWIDRange As Integer
MaxRFWIDRange = 10000
DiffRFW = ToRFW - FromRFW
If DiffRFW > MaxRFWIDRange Then
Return False
Else
Return True
End if
End Function
It looks like you can do this.
I tested this by adding a variable TestVariable to a report, then adding the following custom code:
Function TestVariableFunctionality(var as Microsoft.ReportingServices.ReportProcessing.OnDemandReportObjectModel.Variable) As String
Return var.Value
End Function
I called the function from a textbox like so:
=Code.TestVariableFunctionality(Variables!TestVariable)
This outputs the variable's value in the textbox as a string.
You must declare the full namespace as Microsoft.ReportingServices.ReportProcessing.OnDemandReportObjectModel.Variable, because Variable alone is not defined. See below for more info.
Accessing variable in SSRS function
From an MSDN blog:
Assume that you've created a report variable named "Reportvariable1".
All you need is a piece of custom code.
Public Function SetVariableValue(val as Microsoft.ReportingServices.ReportProcessing.OnDemandReportObjectModel.Variable)
val.Value = val.Value + 2
End Function
As simple as that. All i'm doing in the function is, take the report variable reference, add 2 to the existing value. That's it.
How you can call this function from your report item?
=Code.SetVariableValue(Variables!Reportvariable1)
This will do the magic. Also note that in the above expression i'm just passing the variable reference and not its value.

How to get the variable a function is assigned to?

I need to get the variable a function's return value is assigned to.
function example()
end
variable = 3 --just for example
variable = example() --I need the value of variable(in this case 3) passed as an argument to example()
Please read the Lua reference on how to call and define functions.
https://www.lua.org/manual/5.3/manual.html#3.4.10
https://www.lua.org/manual/5.3/manual.html#3.4.11
You can simply do this:
function fancyFunction(val)
return val
end
local val = 3
val = fancyFunction(val)
of course this minimum example does not make much sense. You should of course have another return value than your argument. Otherwise you don't have to call the function in the first place.
(Quite hard to understand what you're trying to do.) Could you possibly be referring to object oriented programming? If so, then you need something like this:
--setup
t = {}
function t:set(v) self.value = v end --assign value to 'variable'
function t:get() return self.value end
--use
t:set(3)
print(t:get())

SSIS Convert Blank or other values to Zeros

After applying the unpivot procedure, I have an Amount column that has blanks and other characters ( like "-"). I would like to convert those non-numberic values to zero. I use replace procedure but it only converts one at the time.
Also, I tried to use the following script
/**
Public Overrides Sub Input()_ProcessInputRows(ByVal Row As Input()Buffer)
If Row.ColumnName_IsNull = False Or Row.ColumnName = "" Then
Dim pattern As String = String.Empty
Dim r As Regex = Nothing
pattern = "[^0-9]"
r = New Regex(pattern, RegexOptions.Compiled)
Row.ColumnName = Regex.Replace(Row.ColumnName, pattern, "")
End If
End Sub
**/
but i'm getting error.I don't much about script so maybe I placed in the wrong place. The bottom line is that I need to convert those non-numberic values.
Thank you in advance for your help.
I generally look at regular expressions as a great way to introduce another problem into an existing one.
What I did to simulate your problem was to write a select statement that added 5 rows. 2 with valid numbers, the rest were an empty string, string with spaces and one with a hyphen.
I then wired it up to a Script Component and set the column as read/write
The script I used is as follows. I verified there was a value there and if so, I attempted to convert the value to an integer. If that failed, then I assigned it zero. VB is not my strong suit so if this could have been done more elegantly, please edit my script.
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
' Ensure we have data to work with
If Not Row.ColumnName_IsNull Then
' Test whether it's a number or not
' TryCast doesn't work with value types so I'm going the lazy route
Try
' Cast to an integer and then back to string because
' my vb is weak
Row.ColumnName = CStr(CType(Row.ColumnName, Integer))
Catch ex As Exception
Row.ColumnName = 0
End Try
End If
End Sub

Is there a way to determine which optional arguments were given in a VBA function call?

Say I have a VBA function with an optional argument. Is there a way to tell, from within that function, whether the calling code has supplied the optional argument or not?
Public Function SomeFunction(optional argument as Integer = 0) As Integer
End Function
i.e. Is there a way to tell the difference between the following calls?
x = SomeFunction()
x = SomeFunction(0)
As far as I am aware it is not possible. If no argument is passed then the argument is initiliazed to its default value (0 in this case).
One way around this is to change the variable type to Variant and use the IsMissing function to check whether an argument is passed or not. Example:
Public Function SomeFunction(Optional argument As Variant) As Integer
If IsMissing(argument) Then
argument = 0
Else
// Code if argument not = 0....
End If
End Function
The IsMissing function works only with the Variant data type as any other data type will always have a default initialization value.
No, there is not.
The same problem exists in other language, such as C#, as expressed clearly in "C# In Depth", Chapter 13.1.1 (I read this part 15mins ago, it's normal I remember this!)
What I suggest you is not to set the default value in the function declaration. In the function, if argument is null, you set it to 0 and you know it wasn't supplied in the function call.
Edit : Just like #Remnant said in his answer, to be able to do this, the parameter type needs to be a variant.