I think this is relatively a simple question but it seems like I've been having a small issue with this...
I have a form where I try to pass a parameter to a function and get a string back in return with a value
ParmValue = "Juarez"
dim CheckValue = GetValueFromFunction(parmValue)
Private Sub GetValueFromFunction (ByVal Optional ValueFromFunc as string)
'do stuff
getValueFromFunction = "OK"
or
getValueFromFuncton="NOTOK"
return GetValueFromFunction
End sub
Basically I'm looking to get a string value back from my GetValueFromFunction so that CheckValue holds that value. What am I doing wrong?
You can't return something from a Sub; it has to be a Function:
Private Function GetValueFromFunction(Optional ValueFromFunc as String = Nothing) As String
Dim returnValue As String
'do stuff...
If someCondition Then
returnValue = "OK"
Else
returnValue = "NOTOK"
End If
Return returnValue
End Function
A Function is a method that returns something, whereas a Sub is a method that doesn't return something (it's more like an action). In C#, a Sub would return void.
Because you are returning a value, you need to use a Function. Your code is wrong because it declares a Sub (procedure).
The correct use of a Function is:
Private Function GetValueFromFunction (ByVal ValueFromFunc As String) As String
' do stuff
GetValueFromFunction = "OK"
' or
GetValueFromFunction = "NOTOK"
Return GetValueFromFunction
End Function
Note the use of As String. This is to dictate the return type of your Function.
Related
Is there any way to get the parameters of a function dynamic?
Like:
Function(text As String, If text = "yes" text2 As String)
End Function
So the second one just gets asked, when the first is filled or a certain value?
Optional is no way, cause for example the third needs to be filled when the second one is already.
No, you can't do that. But you might accomplish something similar via Currying.
Currying takes a function that needs multiple arguments, and converts into a set of functions that each need a single argument, where prior functions in the set return the next function in the set.
Where this will still be problematic for your situation is .Net likes strongly-typed delegates. If the initial function needs to return a method with one argument for any case, it must do that for all cases.
However, that doesn't mean it returns the same function. You can still vary which function is returned based on the initial input argument.
So instead of this:
Function test(text As String, a As String) As String
If text = "yes" Then
Return text & a
Else
Return a & text
End If
End Function
test("yes", "foo") ' produces "yesfoo"
test("no", "foo") ' produces "foono"
We have this:
Function test(text As String) As Func(Of String, String)
If text = "Yes" Then
Return Function(a) text & a
Else
Return Function(a) a & text
End If
End Function
test("yes")("foo") ' produces "yesfoo"
test("no")("foo") ' produces "foono"
This won't do exactly what you want; it still requires the additional argument or not in every situation. But it might give you enough new flexibility to accomplish your ultimate goal. For example, perhaps you could combine this with a closure, where you never use the additional argument, but in the case where you need it the additional value is still available. Exactly how this will look or whether it's really possible or helpful will depend on the details of what you're trying to accomplish beyond the simple test code in the question.
You could handle what to pass in the button code.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim paramValue As String
If MyTestText = "yes" Then
paramValue = TextBox2.Text
Else
paramValue = TextBox1.Text
End If
End Sub
Private Function SomeFunction(text As String) As String
Dim ReturnValue As String = ""
'your code here
Return ReturnValue
End Function
Or you could pass both values and test in your Function code
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim ReturnedValue = SomeFunction(TextBox1.Text, TextBox2.Text)
End Sub
Private Function SomeFunction(text1 As String, text2 As String) As String
Dim ReturnValue As String = ""
If MyTestText = "yes" Then
'process text2
Else
'process text1
End If
Return ReturnValue
End Function
I am sure there are other ways to handle this.
I have this little function that I found but I am having a hard time trying to call it correctly. how can I call it to update my ConcurrentDictionary
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Animals As New Concurrent.ConcurrentDictionary(Of String, String())
Dim iKey = "key123456"
Animals(iKey) = {"cat", "dog", "bird"}
Dim success As Boolean = TryUpdate(Animals, iKey, Func("cat", "frog"))
End Sub
Function TryUpdate(Of TKey, TValue)(dict As Concurrent.ConcurrentDictionary(Of TKey, TValue), key As TKey, updateFactory As Func(Of TValue, TValue)) As Boolean
Dim curValue As TValue
If Not dict.TryGetValue(key, curValue) Then
Return False
End If
dict.TryUpdate(key, updateFactory(curValue), curValue)
Return True
End Function
End Class
TryUpdate has three parameters,
the ConcurrentDictionary to be updated,
the Key to be updated in the dictionary, and
a delegate function that accepts the key's current value, and returns the desired value.
Dim success As Boolean = TryUpdate(myDictionary, myKey, Func(oldval) newval)
How you pass the third parameter is up to you, but it looks like the intention is so you can have a look at the old value to ensure it is what you expected, then passing either your new value, or the returned value accordingly.
Addition for clarity: The third parameter is expecting to be passed a delegate to a function which will accept the current value of the key you are trying to change, and return a new value (or the original value, if you don't want to change it).
Here I'm creating a function CheckValue that determines if the old value is what I expected, then if so returns the new value. The myDel is a delegate of that function which is passed into TryUpdate.
Dim whatIExpected As String = ""
Dim newVal As String = ""
Dim myDel As Func(Of String, String) = AddressOf CheckValue
Public Function CheckValue(ByVal oldVal As String) As String
If (oldVal = whatIExpected) Then
Return newVal
Else
Return oldVal
End If
End Function
'Then later inside some function or sub..
whatIExpected = "cat"
newVal = "frog"
Dim success As Boolean = TryUpdate(myDictionary, myKey, myDel)
Okay I want to add something to this macro
Sub Search()
Inputbox myInput
found = false
loop
Call getInput (myInput) '~> check multiple files
end loop
If found = false
'DO something
End if
End sub
Sub getInput(ByVal inputVar As String, ByVal Input as Boolean)
If a = inputVar Then
found = true '~> I want to pass this parameter back to search
End If
End sub
The case is like, I want my sub to pass the found parameter from
Search() to getInput() and then getInput() return the found parameter to
Search()
Should I add something like search(ByVal found as boolean) ?
if you want to return a value, then you should change the getInput Sub to a function as they can return values.
Sub Search()
Dim found As Boolean
InputBox myInput
found = checkInput(myInput)
If found = False Then
'DO something
End If
End Sub
Function checkInput(inputVar As String) As Boolean
Dim result As Boolean
'do your checking here and set result
'return the result
checkInput = result
End Function
This might seem like an insanely easy question, but I can't seem to find an answer anywhere to it. I'd like to think that I am decent at VB but while I was learning javascript the other day I found something that seemed awesome and now I can't figure out how to do it in VB.
In javascript it looks like this:
var someValue = getThatValue()
It's both calling and setting the value from the getThatValue() sub. what is the VB equivalent?
Edit
I've tried doing this:
private sub main()
dim value = getValue()
'do something with value
end sub
private sub getValue()
return 3
end sub
That doesn't seem to work, how can I get that to work?
Private Sub Main()
Dim value = getValue()
'do something with value
End Sub
Private Function getValue() As Integer
Return 3
End Function
You should be using a Property:
Private _myValue As String
Public Property MyValue As String
Get
Return _myValue
End Get
Set(value As String)
_myValue = value
End Set
End Property
Then use it like so:
MyValue = "Hello"
Console.write(MyValue)
Sub don't return values and functions don't have side effects.
Sometimes you want both side effect and return value.
This is easy to be done once you know that VBA passes arguments by default by reference so you can write your code in this way:
Sub getValue(retValue as Long)
...
retValue = 42
End SUb
Sub Main()
Dim retValue As Long
getValue retValue
...
End SUb
Can a function return a value byref instead of the default byval? That is to say, allow me to directly edit the variable that it is retrieving instead of just giving me a copy of that variable.
Right now I'm trying to write a function that will return, based on what the user has selected through a combobox, a particular setting (eg. My.Settings.somethingHere). I then want to be able to edit the setting directly through just calling the function. Is that at all possible?
private function myFunction() as byte
select case comboBox1.text
case "a"
return my.settings.a
case "b"
return my.settings.b
end select
end function
private sub something()
myFunction() -= 1
end sub
Function can't return reference of byte instead you may create property (Writable) to assign value.
Public WriteOnly Property Change As SByte
Set(value As SByte)
Select Case comboBox1.text
Case "a"
My.Settings.a = value
Case "b"
My.Settings.b = value
End Select
End Set
End Property
and assign value to Change property,
private sub something()
Change -= 1
end sub