Visual Basic: Comma, ')',or valid expression continuation expected - vb.net

I have the following function:
Public Function HasCurrencyChanged(ByVal idPriceList As Integer, ByVal data As Dictionary(Of String, String)) As Boolean
Dim param As ParamStruct() = New ParamStruct(2) {}
Try
param(0) = ProviderFactory.CreateParameter("#idPriceList", DbType.String, ParameterDirection.Input, idPriceList)
param(1) = ProviderFactory.CreateParameter("#ID", DbType.String, ParameterDirection.Input, data["uidIDCurrency"])
In my C# class i call this method as _clsPriceList.HasCurrencyChanged(Convert.ToInt32(priceListId), data);
In the last line i get a red line in data["uidIDCurrency"] telling me Comma, ')',or valid expression continuation expected
What is wrong?

It looks like you may have translated some C# but failed to do so completely. You don't use brackets, i.e. [], to index in VB but rather parentheses, i.e. (). You should have known that from any beginners VB tutorial or the like or even the rest of your own code that you posted.

Related

Implicit conversion from object to integer and other errors

I have two Layes Classes Business Layer And Data Layer And i have The Main class i called DatabaseManager contain all functions i need for stored procedures
I search on these errors I cannot find solutions
First Error in DatabaseManager class is :
implicit conversion from object to integer
Public Function ExecuteScalar(ByVal sql As String) As Object
Dim cmd As New SqlCommand(sql) With {
.CommandType = CommandType.Text,
.Connection = Connection
}
Dim retval As Integer = ExecuteScalar(cmd)
Return retval
End Function
In Data Layer Class i have this code :
Friend Function Get_Last_Visits_Type(ByRef cmd As SqlCommand)
Dim retval As Integer
cmd = New SqlCommand("Get_Last_Visits_Type")
retval = dm.ExecuteScalar(cmd)
Return retval
End Function
I got two errors here
function without an 'as' clause return type of object assumed
And
implicit conversion from object to integer
When Form Loaded i put this code on Load action :
TxtVisitTypeID.Text = Val(p.Get_Last_Visits_Type)
And i got this error :
implicit conversion from Double to String
Thanks...
Quite a few problems here as mentioned in comments:
Avoid naming a function anything that is a reserved word in the scope of your project at the very least: ExecuteScalar is a method of SqlCommand so use something like MyExecuteScalar instead.
Dim retval As Integer = ExecuteScalar(cmd) probably should be Dim retval As Integer = cmd.ExecuteScalar() unless you want a recursion (which I doubt). (Refer 1.)
Turn Option Strict on in your project settings. As mentioned, ALWAYS have this on. (And I prefer to have Option Explicit on and Option Infer off as well for similar reasons.)
With compile options set as in 3. you will have (valid) compilation errors pertaining to type conversion (at least), with a good chance of resulting in working code once you fix them. Eg Dim retval As Integer = Ctype(cmd.ExecuteScalar(), Integer) (if you're sure that the result of the query will be Integer, otherwise you will need to test and/or error trap).
Connection isn't defined anywhere: .Connection = Connection. You don't pass it nor declare it.
Since retval is declared as an Integer then the return type can also be tightened up to Integer as well, rather than Object.
Your second function has no return type.
What is dm? Not declared/defined.
Consider using Using blocks to close-and-dispose of SQL connection and command on exit.
CommandType.Text is the default so you only need to state it by way of explanation.
Here's what I'd do with your first function:
Public Function MyExecuteScalar(ByVal sql As String) As Integer
Try
Using con As New SqlConnection(sql)
Using cmd As New SqlCommand(sql, con)
Return CType(cmd.ExecuteScalar(), Integer)
End Using
End Using
Catch
Return -1 ' Or something recognizable as invalid, or simply Throw
End Try
End Function
Addressing the first function:
This code is too abstract to be useful. The name of the function is bad. It appears to be recursive but the value you pass back to the function is not a string but a command. If the line of code is Dim retval As Integer = cmd.ExecuteScalar(), then .ExecuteScalar() returns an Object. You cannot convert an Object to an Integer without a conversion method. If you are declaring retval as an Integer why would you have typed your function As Object? I won't even get into the connection problem here. I suggest you delete the function and start again.
Addressing the second function:
Why are you passing the command ByRef? This function has no connection at all! How do you expect it to execute anything? Same problem with retval As Integer and ExecuteScalar returning an Object.
Again, delete and start again.
Now to the code in Form.Load:
Val went out with VB6. I can give unanticipated results. Guess what, Val returns a Double. A .Text property expects a string. Also you appear to be calling the function you showed us above. That function asks for the calling code to provide an argument, namely an SqlCommand object.
My suggestions:
Forget about layers and try to learn the basics of data access with ADO.net. Turn on Option Strict now and forever. Ask new questions with a single problem. Tell us what line the error occurs on. You have been advised before that functions require a datatype but it doesn't seem to sink in.

Asynchronous Threading that is not coming over correctly using a code converter from C# to VB

I have some C# code that is doing a asynchronous call and pulling back a data set. I do this so the windows desktop UI does not hang/freeze while it is being retrieved. I now need to do the same thing in vb.net but after putting in through an online code converter it gives me the error.
Delegate 'Func(Of String, Boolean, DataSet)' requires an 'AddressOf' expression or lambda expression as the only argument to its constructor.
Here is the code before and after conversion.
Before:
var DataFunc = new Func<string, string, DataSet> (getData);
IAsyncResult Result = DataFunc.BeginInvoke(barCodeResult, orderType, null, null);
DataSet ds = DataFunc.EndInvoke(Result);
After:
Dim DataFunc As var = New Func(Of String, String, DataSet)(getData)
Dim Result As IAsyncResult = DataFunc.BeginInvoke(barCodeResult, orderType, Nothing, Nothing)
Dim ds As DataSet = mtrDataFunc.EndInvoke(Result)
Thank you very much in advance for your insights.
There are two fixes to be made:
There's no data type called var. In this case you can replace As var = with As New.
As the error states, the method that you pass to the Func constructor must be prepended by AddressOf to create a delegate.
Dim DataFunc As New Func(Of String, String, DataSet)(AddressOf getData)

variable is referenced from scope, but not defined LINQ expression tree

I'm trying to get this LINQ expression:
Result = Result.Where(Function(Row) _WhereExpressions(0).InElements.Contains(Convert.ToString(Row(0))))
I have this code for it:
convertMethod = GetType(System.Convert).GetMethod("ToString", New Type() {GetType(Object)})
containsMethod = GetType(System.Collections.Generic.List(Of String)).GetMethod("Contains", New Type() {GetType(String)})
Dim listParameter = Expression.Parameter(GetType(List(Of String)), "_WhereExpressions(0).InElements")
expr = Expression.Call(whereMethod, Result.AsQueryable.Expression,
Expression.Lambda(Expression.Call(listParameter, containsMethod,
Expression.Call(convertMethod, Expression.ArrayAccess(rowParameter, Expression.Constant(index)))), rowParameter))
I get the desired expression, but if I compile, I get the error:
variable '_WhereExpressions(0).InElements' of type 'System.Collections.Generic.List`1[System.String]' referenced from scope '', but it is not defined
The _WhereExpressions(0).InElements is of course declared.
How can I fix it?
Thanks.
EDIT: here are all the declarations:
Dim whereMethod = GetType(Queryable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "Where").MakeGenericMethod(GetType(Object()))
Dim convertMethod As MethodInfo = Nothing
Dim containsMethod As MethodInfo = Nothing
Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")
The _WhereExpressions(0).InElements is a simple list of string, like this here:
Dim idlist As New List(Of String)
idlist.Add("1")
idlist.Add("2")
I read the linked post, but I can't really figure out, how I should solve my problem.
Expression trees have a lot capability, but looks a bit difficult for me.
EDIT2:
This is an example, what exactly I would like to achieve. Just copy and paste in vs:
Dim dt As New DataTable
dt.Columns.Add("f1", Type.GetType("System.String"))
dt.Columns.Add("f2", Type.GetType("System.Int32"))
For i = 0 To 100
dt.Rows.Add(i.ToString, i * 2)
Next
Dim indexes As New List(Of Integer)
indexes.Add(0)
indexes.Add(1)
Dim lst As New List(Of String)
lst.Add("10")
lst.Add("11")
Dim datarows As New List(Of DataRow)
For i = 0 To dt.Rows.Count - 1
datarows.Add(dt.Rows(i))
Next
Dim result As IEnumerable(Of Object())
result = datarows.Select(Function(row) indexes.Select(Function(index) row(index)).ToArray)
'I would like this as an expression:
result = result.Where(Function(row) lst.Contains(Convert.ToString(row(0))))
EDIT3: I got it:
Dim lst As Expression = Expression.Constant(list, GetType(System.Collections.Generic.List(Of String)))
It is hard to replicate code without knowing the full variables. I think your mistake though is in your understanding of Expression.Parameter. This is mainly used as a way to pass explicit parameters into the lambda: In your example, Row is a good example for when Expression.Parameter should be used. _WhereExpressions isn't an explicit parameter, it is a variable that I assume is in scope that you want to create a closure around.
You should also note that the second variable of the Expression.Parameter method is optional, and for debug purposes only: If you changed it to say: Expression.Parameter(GetType(List(Of String)), "Nonsense.nonsense"), you would probably see the error message change accordingly.
It sounds like you're trying to introduce a closure around _WhereExpressions. Using raw expression trees, this is fairly hard to do. The closest thing to an easy way to do this is to wrap Expression.Constant around _WhereExpressions.InElements. However, you're going to run into trouble if you're executing the compiled expression when _WhereExpressions is out of scope. See Issue with closure variable capture in c# expression.

Collection initialisation using iif() throws ArgumentNullException

Can anyone tell me why this gives an error at run-time:
Dim mightBeNothing As List(Of String) = Nothing
Dim a As List(Of String) = IIf(mightBeNothing Is Nothing, New List(Of String)(), New List(Of String)(mightBeNothing))
I am getting ArgumentNullException on the second line. If I replace the last part with:
Dim a As List(Of String) = IIf(mightBeNothing Is Nothing, New List(Of String)(), New List(Of String)())
It works - but the constructor New List(Of String)(mightBeNothing) will never be called if mightBeNothing is nothing, so what is the issue?
the IIf function does not use short-circuit evaluation. So it will always evaluate everything, even if mightBeNothing is nothing.
MSDN on the subject.
First, collection initializers aren't supported prior to VB.NET 10.
Having said that, the first example is passing in a null (Nothing) value for the third argument. The IIf Function always evaluate all three arguments, regardless of the true/false state of the first argument. I believe that is why you are receiving the ArgumentNullException.
In the second case, none of the arguments are Nothing so it works, but doesn't give you the desired results.
I would recommend using an If Else:
Dim mightBeNothing As List(Of String) = Nothing
Dim a As List(Of String)
If mightBeNothing Is Nothing Then
a = New List(Of String)
Else
a = New List(Of String)
a.Add(mightBeNothing)
End If
Try using the IF operator instead of IIF. It will short-circuit. See this article on MSDN

Calling Generic function + lambda

I have this function in vb.net that I converted from C# for a project I'm working on.
Private Function GetAllFactory(Of T)(ByVal ctor As Construct(Of T)) As List(Of T)
'TODO: Data Access stuff
Dim ds As New DataSet()
Dim entities = New List(Of T)()
For Each dataRow As DataRow In ds.Tables(0).Rows
Dim entity As T = ctor(dataRow)
entities.Add(entity)
Next
Return entities
End Function
and the following delegate
Private Delegate Function Construct(Of T)(ByVal dataRow As DataRow) As T
I tried converting the code to call the function from C# to vb.net
Return GetAllFactory(Of MyType)(row >= New MyType(row))
the above line doesn't work. I'm sort of stuck. I haven't used lambda much in C# and even less in vb.net.
MyType constructor:
Public Sub New(ByVal dataRow As DataRow)
.
.
.
End Sub
Any suggestions on how to call the GetAllFactory?
You use the Function keyword in VB to write a lambda expression:
Return GetAllFactory(Of MyType)(Function(row) New MyType(row))
Note that >= is a comparison operator while => is the lamda operator in C#. VB might give you some unexpected error message for code using => as it accepts that as an undocumented alias for the >= operator.
VB.Net lambda expressions look like this:
Return GetAllFactory(Of MyType)(Function(row) New MyType(row))