RTE 91 vs CTE Object Required: Fixing One Causes the Other? - ms-access

Function printerpart(outputtext As Collection) As Collection
Dim TotalRecords As Integer 'Original build didn't include this line; no other declaration of TotalRecords, though?
Set TotalRecords = outputtext.Count
For i = 1 To TotalRecords
outputext = outputtext(i)
outputext = Replace(outputext, "&", "and")
Print #1, outputext
Next i
Set printerpart = New Collection
End Function
When attempting to run this function, an error occurs on the line assigning a value/object to TotalRecords. Initial builds did not include the Set statement on that line, but failing to include it results in RTE 91. With Set, however, the function encounters a compile-time error: Object Required.
Each call to printerpart passes outputtext as a collection of string objects.
I am aware of how terrible the variable names are and intend to fix them.
This question seems to imply that the Set statement should only be used to assign Object variables, and that lacking it is the cause of RTE 91 in most cases. Does declaring TotalRecords as an Integer make it an object? The same errors occur if TotalRecords is not declared until its assignment statement.
What is the proper method for resolving these errors in this context, given that the commonly suggested fix for one issue causes the other?

When you remove the "set" the error you get is not according to TotalRecords, it refers to outputtext, seems like what you are passing to function does not have the .count property, check again the variable passed to the function please

Related

Understanding the difference between object.function(argument) and object:function(argument) in Lua

obj ={x=30}
function obj:printpos()
print(self.x)
end
other = {x=15}
obj.printpos(other)
The obj.printpos(other) gives expected output viz. 15. However the call obj:printpos(other) doesn't give expected output.It still prints 30. Why the call obj:printpos(other) is not taking other as its argument? Basically what is the difference between object.function(argument) and object:function(argument)? Is object:function(argument) same as object:function() i.e. whether argument is ignored?
obj:printpos(other) is equivalent to obj.printpos(obj, other).
function obj:printpos() end is equivalent to function obj.printpos(self) end.
From Lua 5.4 Reference Manual - §3.4.11 – Function Definitions (formatting mine):
The colon syntax is used to emulate methods, adding an implicit extra parameter self to the function. Thus, the statement
function t.a.b.c:f (params) body end
is syntactic sugar for
t.a.b.c.f = function (self, params) body end
From this, we can see the colon syntax implicitly adds the self parameter to the function scope.
Inversely, calling a function defined with the colon syntax using the dot syntax will cause the first argument passed to it to be assigned to the self parameter.
Thus, with
local thing = {}
function thing:func()
print(self)
end
the calls
thing:func()
-- and
thing.func(thing)
have the same result of assigning thing to self, and
thing.func(other_thing)
will assign other_thing to self.
The problem with
thing:func(other_thing)
is that, as previously seen, thing is assigned to self. other_thing is assigned to no parameter, as no other parameters were defined.

Index was outside the bounds of the array in SSRS

I have two parameters , let's say P1 and P2. The sample expression I used for P2 is
IIF(P1.Label="string", "null" ,Split(P1.Label," ").GetValue(0))
When the condition is false, the split expression is working fine. But if the condition is true, I'm getting 'Index was outside the bounds of the array' error. If the condition is true, I need to pass the value "null" as varchar type.
Can someone please advice on this?
The problem with the IIF function is that it is a function not a language construct. This means that it evaluates both parameters before passing the parameters to the function. Consequently, if you are trying to do a Split on a parameter that can't be split, you will still get the 'Index was outside the bounds of the array' error, even when it looks like that code shouldn't be executed due to boolean condition of the IIF statement.
The best way to solve this is to create a safe string splitter function in custom code where you can use real language constructs. Also, check that the string is splittable by checking it contains a space instead of checking for a special string:
Public Function SafeSplit(ByVal SplitThis As String) As String
If InStr(SplitThis, " ") Then
Return Split(SplitThis, " ")(0)
End If
Return "null"
End Function
and then use this in your report for the Value expression instead of IIF:
=Code.SafeSplit(Parameters!P1.Label)

How do I pass objects to functions in ooRexx?

I'm a long-time mainframe Rexx programmer who is trying out objects in ooRexx. The results are surprising. For example, here is a program:
#!/usr/bin/rexx
a = .number~new(3.14)
say "a =" a
say "a~val =" a~val
call say_number a
exit 0
say_number:
procedure
parse arg num
say "In say_number"
say "num =" num
say "num~val =" num~val
return
::class number public
::attribute val get public
::method init ; expose val ; use arg val
::method new ; expose val ; use arg val
::method string ; return "'"self~val"'"
The result is:
> number
a = '3.14'
a~val = 3.14
In say_number
num = '3.14'
18 *-* say "num~val =" num~val
8 *-* call say_number a
REX0097E: Error 97 running /home/tony/bin/.scripts/number line 18: Object method not found
REX0476E: Error 97.1: Object "'3.14'" does not understand message "VAL"
It appears that the object is being resolved to its string value before it's passed to the say_number function. Weird! Am I missing something obvious?
Well, that didn't take long. I changed parse to use in the function, and everything worked as expected. Per the Reference manual:
USE ARG retrieves the argument objects provided in a program, routine,
function, or method and assigns them to variables or message term
assignments.
PARSE assigns data from various sources to one or more variables
according to the rules of parsing. ... If you specify UPPER, the
strings to be parsed are translated to uppercase before parsing. If
you specify LOWER, the strings are translated to lowercase. Otherwise
no translation takes place.
Presumably PARSE converts the arguments to a string so that it can change case as requested (or defaulted).

lua not modifying function arguments

I've been learning lua and can't seem to make a simple implementation of this binary tree work...
function createTree(tree, max)
if max > 0 then
tree = {data = max, left = {}, right = {}}
createTree(tree.left, max - 1)
createTree(tree.right, max - 1)
end
end
function printTree(tree)
if tree then
print(tree.data)
printTree(tree.left)
printTree(tree.right)
end
end
tree = {}
createTree(tree, 3)
printTree(tree)
the program just returns nil after execution. I've searched around the web to understand how argument passing works in lua (if it is by reference or by value) and found out that some types are passed by reference (like tables and functions) while others by value. Still, I made the global variable "tree" a table before passing it to the "createTree" function, and I even initialized "left" and "right" to be empty tables inside of "createTree" for the same purpose. What am I doing wrong?
It is probably necessary to initialize not by a new table, but only to set its values.
function createTree(tree, max)
if max > 0 then
tree.data = max
tree.left = {}
tree.right = {}
createTree(tree.left, max - 1)
createTree(tree.right, max - 1)
end
end
in Lua, arguments are passed by value. Assigning to an argument does not change the original variable.
Try this:
function createTree(max)
if max == 0 then
return nil
else
return {data = max, left = createTree(max-1), right = createTree(max-1)}
end
end
It is safe to think that for the most of the cases lua passes arguments by value. But for any object other than a number (numbers aren't objects actually), the "value" is actually a pointer to the said object.
When you do something like a={1,2,3} or b="asda" the values on the right are allocated somewhere dynamically, and a and b only get addresses of those. Thus, when you pass a to the function fun(a), the pointer is copied to a new variable inside function, but the a itself is unaffected:
function fun(p)
--p stores address of the same object, but `p` is not `a`
p[1]=3--by using the address you can
p[4]=1--alter the contents of the object
p[2]=nil--this will be seen outside
q={}
p={}--here you assign address of another object to the pointer
p=q--(here too)
end
Functions are also represented by pointers to them, you can use debug library to tinker with function object (change upvalues for example), this may affect how function executes, but, once again, you can not change where external references are pointing.
Strings are immutable objects, you can pass them around, there is a library that does stuff to them, but all the functions in that library return new string. So once, again external variable b from b="asda" would not be affected if you tried to do something with "asda" string inside the function.

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.