can user qbasic functions return a string? - basic

FUNCTION QUAD_NAME (X, Y, Z AS INTEGER)
QUAD_NAME = string_var
returns a "illegal string-number conversion"
I checked the in IDE help on function command (currently using QB64, but their wiki is down), but no information as to whether it can return a string.
Currently I am using a global var to assign the quad_name but would prefer to use a function to return the desired var.
EDIT: QB64 Server is back up (forums, wiki). will check there too. If no answer here, I'll post what I find.

Yes it does
Need to change the function var to a "$" and the return var with a "$"
change the above to
FUNCTION QUAD_NAME$ (X, Y, Z AS INTEGER)
QUAD_NAME$ = string_var$
END FUNCTION

You should also probably declare all function parameters:
FUNCTION QUAD_NAME$ (X AS INTEGER, Y AS INTEGER, Z AS INTEGER)
QUAD_NAME$ = string_var$
END FUNCTION

Related

Using Subroutine for output instead of a function

I thought at this point that the role of functions and subroutines was very clear to me. But now I am not so sure... I see it written all the time
"Functions can return values / subroutines cannot return a value."
and
"a function can only return a single value" (I realize they can return arrays and such too).
But it seems as though I can effectively "return a value from a subroutine" if I pass the "result" variable into the subroutine... Is this considered a "poor practice?" or am I missing some other key concept here...
Method # 1 (Using a Function):
Sub test1()
Dim x As Integer
Dim y As Integer
Dim z As Integer
x = 2
y = 3
z = test2(x, y)
End Sub
Function test2(var1 As Integer, var2 As Integer) As Integer
test2 = var1 + var2
End Function
Method # 2 (Using a Subroutine):
Sub test3()
Dim x As Integer
Dim y As Integer
Dim z As Integer
Call test4(x, y, z)
End Sub
Sub test4(var1 As Integer, var2 As Integer, var3 As Integer)
var1 = 2
var2 = 3
var3 = var1 + var2
End Sub
Usually, it is bad practice to change the value of a parameter. Just look at you examples - it is obvious that your function does something with the 2 parameters and returns a value (which you write to z). In the second example, you don't see what will happen unless you look to the subroutine - and not only to the function definition, you need to read the complete code so that you can tell what parameter will manipulated and what not.
In software development, when you call a subroutine, you don't want to look at this subroutine - and often it is even not available for you. Let the subroutine do it's job, but without any side effects.
Use a function whenever possible, it keeps your code much more readable. Trust me...
There are (very few) cases when you want to receive more than one result from a subroutine. In that case, I would advice to put explicitly the keyword ByRef in front of the parameter (even if in VBA this is technically not necessary because it's the default). And put a comment that tells why it is the case. You will thank yourself when you look at your code weeks, months or years later.

Why declare function's type?

Sorry if this has been asked, but seriously can't find anything, so would also appreciate on how to search for this stuff.
So my question: what is the point of declaring the function's type in general? E.g. here 'as double'
Function myFunction(ByVal j As Integer) As Double
Return 3.87 * j
End Function
For a normal variable it has tons of benefits, like less memory, easier to see typos, but why here?
Edit: so, it's good because we can avoid errors, like it giving back a different type of values than expected.
Functions RETURN something. That type is the type of the return.
In your function:
Function myFunction(ByVal j As Integer) As Double
Return 3.87 * j
End Function
You are returning a decimal, so type Double make sense.
If you don't return anything, then you can declare it as a Sub.
And, for clarification, your function would throw a compile error. Unlike other languages, in VBA to return, we set the function name's value to the thing we want to return:
Function myFunction(ByVal j As Integer) As Double
myFunction=3.87 * j
End Function
Now we can call this function to get the Double value that it creates:
Sub testSub()
msgbox("This is the result of the function: " & myFunction(10))
End Sub
Which would launch a message box saying "This is the result of the function: 38.7"
Since I can't mark a comment the answer, let me quote:
#John Coleman
My opinion is that it a good thing to declare your return types because it increases the likelihood that the compiler will complain when you are doing something that really doesn't make sense.
Excel VBA is different from other programming languages in that it centers around a particular application: Excel.
Functions are useful in Excel VBA primarily because they can be typed directly into a cell on a sheet by an end user. User defined functions provide near infinite flexibility. The value the user defined function prints to Excel is formatted based on the function's type--and in a program which is about data visualization, formatting is a huge part.
For example, try putting these four functions into a blank worksheet module:
Function myInt(x, y) As Integer
myInt = x / y
End Function
Function myDouble(x, y) As Double
myDouble = x / y
End Function
Function myString(x, y) As String
myString = x / y
End Function
Function myVariant(x, y)
myVariant = x / y
End Function
Next, enter each of these functions into a different cell in the workbook. Use x=1 and y=2.
myInt produces "=0"
myDouble produces "=0.5"
myString produces "'0"
myVariant produces "=0.5"
If you're okay with Excel deciding how to format your result, that's your choice, but specifying the type offers an entire new level of control. For example, by simply declaring a function an integer, you can avoid having to devote a line of code to rounding. By declaring a function to be a string, you can avoid several lines of formatting code trying to get a number to be saved as text instead.

How to convert a string to non string in matlab

I have this function which takes a string as an input.
for example it takes handles.f = 'x^2'
but I want handles.f = x^2 so that later I'll be able to do f(x) = handles.f
function edit1_Callback(hObject, eventdata, handles)
handles.f = (get(hObject,'String'))
handles.f
area = rect(handles.f,handles.u,handles.l,handles.n)
guidata(hObject,handles)
Function:
function [ s ] = rect( f,u,l,n )
syms x;
f(x) = f;
h =(u-l)/n
z = l:h:u;
y = f(z)
s = 0;
for i=1:n
s = s+y(i);
end
s = h*s;
end
When i call this function from command prompt like this:
rect(x^2,5,1,4)
It works fine
But it gives error when I call this from gui.
This is the error I get:
Error using sym/subsindex (line 1558)
Indexing input must be numeric, logical or ':'.
Error in rect (line 8)
f(x) = f;
This goes against any advice I give myself, but if you want to do what you're asking, you'll need to use eval. This converts any string that you input into it and it converts it into a command in MATLAB for you to execute. If I am interpreting what you want correctly, you want to make an anonymous function that takes in x as an input.
Therefore, you would do this:
handles.f = eval(['#(x) ' get(hObject,'String')]);
This takes in the string stored in hObject, wraps it into an anonymous function, and stores it into handles.f. As such, you can now do:
out = handles.f(x);
x is an input number. This is one of the few cases where eval is required. In general, I would not recommend using it because when code gets complicated, placing a complicated command as a string inside eval reduces code readability. Also, code evaluated in eval is not JIT accelerated... and it's simply bad practice.
Edit
Luis Mendo recommends doing str2func to avoid eval... which is preferable (whew!).
So do:
handles.f = str2func(['#(x) ' get(hObject,'String')]);

Adding two numbers with a function

I am writing VBA code to add two numbers:
Option Explicit
Dim x As Integer, y As Integer
Function addtwo(x, y)
addtwo = x + y
End Function
This is not a good function since I have to manually input the values x and y to get for the result. How can I modify the codes so it can work with any two numbers, no matter integers or numbers with decimals?
You define your input variables in the FUNCTION declaration line, not above it. I would recommend the vartype DOUBLE for whole numbers and decimals.
Function ADDTWO(ByVal x As Double,ByVal y As Double) As Double
ADDTWO = x + y
End Function
Now this function can be used in a cell as:
=ADDTWO(3, 6)
or
=ADDTWO(A2, B7)
It can also be used in VBA.
Of course, the SUM() function does this same thing, so....I presume this is a learning exercise.
As far as working with any two numbers, try the Variant data type instead of Integer. Not sure what you mean by manually inputting the values - are you talking about getting them from the worksheet?

What is the great wisdom in defining your own object if I can't do this?

This is for Excel and VBA. Assume that BondClass has been properly defined in a Class Module. I get a #VALUE! when I type "=GetBondPrincipal()" into an Excel cell. Have I done something syntactically wrong or is this just not possible in Excel/VBA? I ask because what I really want to do is this:
Return a User Defined Data Type in an Excel Cell
but am unable to find a solution. So at the very least, I want to know if what I want to do below is possible.
Option Explicit
Function InitializeBond(ir As Double, p As Double) As BondClass
Dim mybond As BondClass
Set mybond = New BondClass
Call mybond.Initialize(ir, p)
InitializeBond = mybond
End Function
Function GetBondPrincipal()
Dim b As BondClass
Set b = New BondClass
b = InitializeBond(0.03, 100) //the code quits here,
//it doesn't like the BondClass return type?
GetBondPrincipal = b.GetPrincipal()
End Function
I know that in the example I have provided, I don't have to call InitializeBond and can simply type "Call b.Initialize(.03,100)". The code will work fine if I do this. But I can't seem to be able to get a UDF to return a type other than the built-in types. Any way to do any of this? Do I have to define assignment for non-built-in types?
Hint: use "SET".
(most common error made by VB programmers in VB6 and VBA).
Anyway, I don't find that very elegant.
I would rather write:
Function GetBondPrincipal()
Dim b As BondClass
Set b = New BondClass
with b
.param1 = 0.03
.param2 = 100
.InitializeBond
GetBondPrincipal = .GetPrincipal()
end with
End Function

Resources