Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm new in vb6 and not good at searching stuff. what is wrong with this code? I created form1 and inserted class module.
Private sub form_load()
call Jo.Display(txtdate.text)
end sub
in may Class module ClsJo
public function Display(txtdate as string)
txtdate = "123abc"
end function
The Display function has one parameter, txtdate, that is passed "by reference", which means that the function may change it's value. You are passing a value to that function, so I'm assuming you want the txtdate.Text property to contain the value "123abc" after the call.
However, this will not work as you have written it.
txtdate.Text is a property and properties are not really variables, they are kind of functions. You have "let" operator to set a property value and "get" operator to get the value of the property, but you don't have direct access to the actual variable that stores the value.
Therefore, when passed to the function, VB6 will get the value of the property, create a temporary variable from it and pass that temporary variable as the parameter to the function. The change in this temporary variable will never find it's way back to the txtdate.Text property.
To get the functionality that I think you want, you can do either one of these:
A. Create a variable yourself, pass that to the function and set the txtDate.Text property to the returned value. This would be my recommended method, because the function will have cleaner parameters. Like this:
Private Sub Form_Load()
Dim myText As String
myText = txtDate.Text
call Jo.Display(myText)
txtDate.Text = myText
End Sub
B: Pass the txtDate as parameter to the function, instead of the property, like this:
Public Sub Display(ByRef dateControl As Object)
dateControl.Text = "123abc"
End Function
Private Sub Form_Load()
Jo.Display txtDate
End Sub
Related
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
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.
I'm creating XML documents with VBScript and MSXML DOM. In order to structure and simplify my code I'm using classes and thus methods (functions in VBS) too.
Here is a little function that troubles me:
function createAttribute(name, value)
dim doc
Set doc = CreateObject("Msxml2.DOMDocument.4.0")
dim attr
set attr= doc.createNode(2,name,"")
attr.NodeValue=value
createAttribute=attr
end function
The assignment createAttribute=attr, where I'm setting the return value of the function, causes the following error:
Object doesn't support this property or method
As the web resources on XML processing with VBS are rather sparse, I hope some of you can help me to understand whats going on here. Here are my questions:
What object does not support what property or method?
Can i pass objects of any given class as return values of VBS functions?
Can i pass an object of the class IXMLDOMAttribute as a return value to a VBS function?
I think the problem is that attr is an object, so you need to use set to apply the return value. Otherwise, you may simply be returning attr's default property value (if it has one):
set createAttribute = attr
You don't show how you use the return value, so I can't comment on that but it is possibly the source of the error.
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
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