getting value from another sub in VB - visual-studio-2010

I have this Sub which does the calculation get the information from CSV file.
Private Sub getTotalAmt(intDuration As integer, strProgrameType As String)
I've another Sub:
Private Sub getMembershipDiscount(ByRef dtDOB As Date, dblTotalAmt as Double)
which calculates the age of the customer and based on their age, gives them discount. So to do this, I've got to get the total amount from the above Sub (getTotalAmt) to this Sub procedure.
My question is, how to receive total amount from that sub procedure?

by definition, subroutines don't have output.
Instead, you want to write a function. In your case, change the code you have to something like this:
private function getTotalAmt(intDuration As integer, strProgrameType As String) as double
'do the same maths you do in the sub, and store your answer in a variable called "whatever"
getTotalAmt = whatever
end function
then to use the function:
sub IUseFunctions()
dim myDiscount as double
myDiscount = getTOtalAtm(1,"s")
end sub
In this example case, I've decided for you that the discount value is stored in a double type number. You can change that to whatever you like, at the top line of the getTotalAmt function.

Please speicify return types and convert your Sub to a Function
In that way you can always return something from your Functions,
if you specify a return type to your getTotalAmt(int Duration As Integer, StrProgrameType As String) method , That would be look like this Function getTotalAmt(int Duration As Integer, StrProgrameType As String) As double
then from another method you can call it and use retuned value of it for further calculation or whatever.
i.e
Private Sub sub1()
//You use the Sub2's value in here like
msgbox(sub2)
End Sub
Private Function sub2() As String //You can specifiy any data type you are returning, I specified String just for demnostrate
//Set the value of Sub2 in here
sub2 = "Yourvalue";
End Function

Related

HP-UFT / VBscript - Setting an array value through a function with an array index reference

I have an issue with assigning/retrieving correct values to/from an array which is within a class in VBScript. Whenever I try to set the array's value through a stand-alone function, it just does not work and I keep getting the old array values.
Here is an example code:
Class NewClass
Public TestValues
Public Sub Init()
TestValues = array("value0", "value1", "value2")
End Sub
End Class
Class NewFunctions
Public Function GetValue(xRef)
GetValue = xRef(2)
print "Value within Function: " & xRef(2)
End Function
Public Sub SetValue(xRef, xValue)
xRef(2) = xValue
print "Value within Sub: " & xRef(2)
End Sub
End Class
Dim MyClass, MyFunction
Set MyClass = New NewClass
Set MyFunction = New NewFunctions
Now, when I try to set the index 2 of the given array MyClass.TestValues with the SetValue Sub, it claims the new value has been set, but when I then call GetValue for this array or print out the content of the MyClass.TestValues(2) directly, I am still getting the old values:
MyFunction.SetValue MyClass.TestValues, "newvalue2"
It returns: Value within Sub: newvalue2
But when I retrieve the value with GetValue:
MyFunction.GetValue MyClass.TestValues
It returns: Value within Function: value2, which is the old value.
When I, however, set the array directly:
Myclass.TestValues(2) = "newvalue2"
then calling with:
MyFunction.GetValue MyClass.TestValues
gives me correct result: Value within Function: newvalue2
I am not sure whether this is a general VBScript behavior and I am making a mistake in hoping to change array values in this 'dirty' manner or whether this is strictly HP-UFT (Unified Functional Testing) related, since this is where I could observe this.
I am not a profficient VBScripter either so I appreciate any help.
This is a documented behaviour
Argument in a Class
If the parameter is specified as ByRef, the argument is passed by
value if the variable sent as an argument is in a class

"That name is not valid" for my VBA function in Excel/Mac

A simple VBA function. When I try to use it in my worksheet, all I get, no matter what I do, is "That name is not valid". I'm out of ideas.
Sub FindABV(temperature)
With Worksheets("Sheet1")
.Range("C28").GoalSeek _
Goal:=temperature, _
ChangingCell:=.Range("B28")
End With
FindABV = .Range("B28").Value
End Sub
I've tried creating a new Module to put it in. No change.
And no error indications from the code editor.
The Sub procedure performs a task and then returns control to the calling code, but it does not return a value to the calling code.
See more here.
This said, you cannot set a procedure equal to something:
FindABV = .Range("B28").Value
because that name is not valid (you cannot say that a procedure is equal to a certain value, it doesn't make sense). You probably wanted to use a Function to return the value of that cell calculated by the Goal Seeker depending on the input temperature that you pass by the function:
Function FindABV(temperature)
With Worksheets("Sheet1")
.Range("C28").GoalSeek _
Goal:=temperature, _
ChangingCell:=.Range("B28")
End With
FindABV = .Range("B28").Value '<-- return the value
End Function
However, be careful: if =FindABV(temperature) lies on Sheet1.Range("B28"), you will have a circular reference because your function will try to have the value of itself.
Your code will not deliver the results you want. If you want to have the Function work for different values than the ones stored in B28 and C28 you'll have to write it more like this:
Public Function FindABV(goalCell As Range, changeCell As Range, temperature As Double)
goalCell.GoalSeek Goal:=temperature, ChangingCell:=changeCell
FindABV = changeCell
End Function
But this doesn't matter in any case because GoalSeek actually changes the value in the ChangingCell which Excel will not do if it is called from within a Function.

Attempting to learn polymorphism, etc. in VB6, but my code doesn't do what I want it to

Here's what I've got on a command button; it's just creating variables and attempting to output their ID (which should be an instance variable inherited from the base class.)
Private Sub Command1_Click()
Dim ball1 As Ball, ball2 As Ball
Dim cube1 As Cube, cube2 As Cube
Set ball1 = New Ball
Set cube1 = New Cube
Set cube2 = New Cube
Set ball2 = New Ball
MsgBoxTheID (ball1) 'errors; should be 0
MsgBoxTheID (ball2) 'errors; should be 3
MsgBoxTheID (cube1) 'errors; should be 1
MsgBoxTheID (cube2) 'errors; should be 2
Call ball1.MsgBoxID ' works; displays 0
Call ball2.MsgBoxID ' works; displays 3
Call cube1.MsgBoxID ' works; displays 1
Call cube2.MsgBoxID ' works; displays 2
End Sub
Modeul1.bas:
Global globalID As Integer
Public Sub MsgBoxTheID(theObj As BaseObj)
' this function is meant to accept objects of type Ball, Cube, and BaseObj
MsgBox theObj.ID
End Sub
BaseObj Class Module:
Public ID As Integer
Public isVisible As Boolean
Public Sub setVisiblity(newVis As Boolean)
isVisible = newVis
End Sub
Public Sub MsgBoxID()
MsgBox ID
End Sub
Private Sub Class_Initialize()
ID = globalID
globalID = globalID + 1
End Sub
Ball Class Module:
Implements BaseObj
Private theObj As BaseObj
Public radius As Double
Private Property Let BaseObj_ID(ByVal RHS As Integer)
End Property
Private Property Get BaseObj_ID() As Integer
End Property
Private Property Let BaseObj_isVisible(ByVal RHS As Boolean)
End Property
Private Property Get BaseObj_isVisible() As Boolean
End Property
Public Sub MsgBoxID()
Call theObj.MsgBoxID
End Sub
Private Sub BaseObj_MsgBoxID()
Call theObj.MsgBoxID
End Sub
Public Sub BaseObj_setVisiblity(newVis As Boolean)
End Sub
Private Sub Class_Initialize()
Set theObj = New BaseObj
End Sub
Cube Class Module:
Implements BaseObj
Private theObj As BaseObj
Public sideLength As Double
Private Property Let BaseObj_ID(ByVal RHS As Integer)
End Property
Private Property Get BaseObj_ID() As Integer
End Property
Private Property Let BaseObj_isVisible(ByVal RHS As Boolean)
End Property
Private Property Get BaseObj_isVisible() As Boolean
End Property
Public Sub MsgBoxID()
Call theObj.MsgBoxID
End Sub
Private Sub BaseObj_MsgBoxID()
Call theObj.MsgBoxID
End Sub
Public Sub BaseObj_setVisiblity(newVis As Boolean)
End Sub
Private Sub Class_Initialize()
Set theObj = New BaseObj
End Sub
There are several things I don't like about this, two of which I am of the impression are unavoidable: (1) the fact that it's a mess compared to C++, and (2) the fact that the Ball and Cube classes merely contain an object of BaseObj type. They are not actually inheriting anything from BaseObj; they are only being forced to implement the same interface (whoopty doo.)
To make matters worse, and this is the one that I am truly hoping is rectifiable, they do not seem to be able to fill in for an object of the base class when it comes to parameter passing.
Am I doing something wrong?
Visual Basic 6 is not the ideal language with which to learn the "purer" form of OOP. VB6 was designed to implement a very much hybridized version of object-based programming that orbited the Microsoft Component Object Model (COM) world, with its interface inheritance orientation. VB6 does not support implementation inheritance, which tends to make the kind of polymorphism you're looking for hard to do.
There are a few tricks I recall from the VB6 era to "get around" (sort of) the implementation inheritance problem, particularly when it comes to substituting an object of a base class for a subclass. One trick I remember is to declare a property procedure of the type of the base interface that returns a reference to "Me" as the return type. That "tricks" the runtime into providing the conversion into the desired interface. There's another magic trick to make a property the "defaut" property by setting its "procedure number" to -4 in one of VB6's design dialogs.
The point? If you're really wanting to get into conventional OO programming, don't try to learn it with VB6 if you don't have to. Move up to (at least) VB.NET, C#, or Java. I don't say that as a VB6 hater - heck, knowing these stupid details paid the bills for a long time - but its a tough nut to crack to translate its own little idiosyncrasies into a good, fundamental understanding of OOP.
Good luck!
You've figured out how to fix the error, but I'll contribute the "why".
In VB6 (and VB5, etc), there are two syntaxes for invoking a method/function/subroutine/statement. The first is this:
MySubName arg1, arg2, arg3, arg4
Blech, I know it is my bias from C and Java, but I like to see parenthesis around my argument list. That sytax is this:
Call MySubName(arg1, arg2, arg3, arg4)
So those two are equivilent.
What you ran into is not the effect of the Call. What you ran into is the effect of the unneeded parenthesis in the non-Call version. The parenthesis force the statement/arg inside them to be evaluated before the rest of the statement (think math order of operation).
So this:
SomeSub (arg1)
Is like this:
temp = (arg1)
SomeSub temp
Further, objects in VB6 can have a "default property". This lets you write code like this:
Dim name as String
name = txtName
Instead of assigne the textbox object reference to name, the default property of .Text is used, and the result is like this:
Dim name as String
name = txtName.Text
So when you tried to evaluate SomeSub (arg1) I think it would attempt to locate and execute the default property of your object and pass that value to SomeSub.
Well, I figured it out, sort of.
MsgBoxTheID (ball1) 'errors; should be 0
MsgBoxTheID (ball2) 'errors; should be 3
MsgBoxTheID (cube1) 'errors; should be 1
MsgBoxTheID (cube2) 'errors; should be 2
...needs to be changed to...
Call MsgBoxTheID (ball1) 'errors; should be 0
Call MsgBoxTheID (ball2) 'errors; should be 3
Call MsgBoxTheID (cube1) 'errors; should be 1
Call MsgBoxTheID (cube2) 'errors; should be 2
... even though MsgBoxTheID has no return type, which is weird because I always thought Call was simply something that you could use to discard the return value without having to declare a variable, like so:
dim unneededVar as Integer
unneededVar = FunctionNameThatReturnsAnInteger()
But I guess not. So... I'll have to go read up on exactly what the Call statement is doing to make this example program work, but it's definitely working now. (I also had to add BaseObj_ID = theObj.ID to the Property Get BaseObj_ID() As Integer methods in the classes that were implementing BaseObj.)

What is the difference between Sub and Function in VB6?

I am going through some old VB code and I run into function definitions like these -
Private Function ExistingCustomer(Index As Integer, Customer As String) As Integer
Private Sub cmdCustomerList_Click()
What's the difference?
Function returns value, Sub doesn't. It's that simple.
A function can also be used in an expression. A Subroutine cannot.
Functions can lend to the readability of your code better than a subroutine.
Here's an example of how a function can increase readability:
If AccountIsLocked("JJones") then Msgbox("This account is locked")
this function would be defined somewhere
public function AccountIsLocked(UserId as string) as boolean
dim usr = uow.AccountRepository.UserInfo(UserId)
return usr.locked
end function
Here's the same example but coded with a subroutine:
CheckIfAccountLocked("JJones")
and elsewhere this sub is defined:
public sub CheckIfAccountLocked(UserId)
if uow.AccountRepository.UserInfo(UserId).locked then
msgbox("Account is locked")
end if
end sub
Also note that checking the value is separated from the action -- this contributes to separation of duties. The function would lend toward re-usability.
With VB6 there are some odd rules governing parenthesis. If there are no parameters to a sub then the parenthesis are not needed (I think Visual Studio might remove the parenthesis). One way around this is to add the keyword "Call" before your sub.
Call CheckIfAccountLocked()
vs
CheckIfAccountLocked
In function we can return values as boolean, string and other data data types.
but sub does not return any thing.
it just executes code and instruction that we give. These are also regarded as methods
Sub is also used in control's events and these events also not return any value.
for example the click event of a command button:
Private sub cmd_click()
end sub
They are both sections to write code however a function must return a value. For example if you had a program in which a complicated mathematical procedure needs to be executed a number of times you would simply make a function and have the complicated maths code in there and any time you need to do the calculation you can just call the function. Hope this helped not sure if I explained it well.
What is the difference between Sub and Function in VB6?
"sub" can perform some action.
"sub" returns no value.
Example:
Form_Load()
"function" can also perform some action but it also returns some value to point from which it was called.
that is, "Functions return a value, often based on a variable"
Example:
Val(), FormatPercentage().
function in vb
a function must return some value/s
Syntax :
private function fun_name(argument/s(optional)) as return_type(integer,string..)
return value
end function
fun_name(arguments(optional) ) is enough for function call
sub in vb
a sub need not to be return any value/s
Syntax :
private sub sub_name(argument/s(optional))
end sub
sub_name(arguments(optional) ) is enough for function call
A function holds data and code. But a subroutine contains only code, but not data.
Syntax of functions will be Function...End function and for Sub will be Sub...End Sub.
Functions may or may not have objects but sub doesn't have objects
Functions are re-usable where Sub doesn't
Functions can return values but sub doesn't
Functions may have object repository but sub doesn't
Extension of functions is .qfl where for sub it's .vba

How to call a function with function name reference to a string value in VB

I have this algorithm that I want to implement on VB6.
Sub Main()
dim stringVal1 as string, stringVal2 as string
dim getOne as boolean
stringVal1 = "FunctOne"
stringVal2 = "FunctTwo"
if getOne then
'Call Function with function name assigned to stringVal1 ... how to call the function here?**
else
'Call Function with function name assigned to stringVal1 ... how to call the function here?**
end if
End Sub
Function FunctOne()
Msgbox "I'm function one"
End Function
Function FunctTwo()
Msgbox "I'm function two"
End Function
Can this be done in VB6?
Generally, such code patterns point to errors in your software design.
In the rare cases where this is really needed, CallByName accomplishes this.
Example:
Call CallByName(Me, "NameOfFunction", vbMethod, arguments)
It would help if you give more information about why you're needing to call functions by the string representation of their name. Could you not simply re-write your code like this:
If getOne Then
Call FuncOne()
Else
Call FuncTwo()
End If
Generally, you don't want to actually dispatch based on Strings. This is error-prone (as you have to be really sure at run time that your String has the function name you want), and really unnecessary. The way to do this sort of thing where you want to be able to "pass in" the method that you want to use would be to use the polymorphism that VB has, and use a separate Class for each implementation.
In the Class Module that you use for your interface, say named MyInterface:
Public Sub DoStuff()
End Sub
Then, create two Class Modules, one for each possible implementation of the Interface:
In MyClassOne:
Implements MyInterface
Public Sub MyInterface_DoStuff()
Msgbox "I'm function one"
End Sub
Then, in MyClassTwo, the same thing but with your other implementation:
Implements MyInterface
Public Sub MyInterface_DoStuff()
Msgbox "I'm function two"
End Sub
To use it, you just need to pass in which implementation you want to use:
Private Sub UseInterface(WhichThingToUse as MyInterface)
WhichThingToUse.DoStuff
End Sub
Rather than using a String variable to store which method to use, you need to instead store a New MyClassOne or a New MyClassTwo. You don't show how your getOne variable gets set, but whatever the logic is for it, you just need to change to store an instance of MyInterface instead, and just use that directly.
For further reading in the MSDN library:
How Visual Basic Provides Polymorphism
Creating and Implementing an Interface
Creating Interfaces for Use With the Implements Statement
Implements Statement reference

Resources