Using Linq in VB.NET to verify result set is NULL - vb.net

I'm trying to validate wether or not two matching columns exists using Linq/VB.NET
I believe that assuming a null result set is being returned the 'Count' value should also be null, correct?
Below is the code;
Dim crewNumEntered = crewNumInput.Text
Dim crewLeaderNumEntered = crewLeaderNumInput.Text
Dim crewNumUnique As Boolean = False
Using db As New DbClassDataContext
Dim Count = (From a In db.WarrantyPercents Where a.CrewLeaderNum = crewLeaderNumEntered And a.CrewNum = crewNumEntered Select a.WarrantyPercentsId).ToList
If Count Is Nothing Then
crewNumUnique = True
Else
'throw error
End If
End Using
The end result is I only want to perform an action (code not shown) if crewNumUnique == true.
But even when the result set should be null, this code is continuing to fill 'something' with Count.
What can I do to fix this?
EDIT: I just realized the value of count isn't null but instead returning the string 'System.Collections.Generic.List`1[System.Int32]'. Now I have no clue what is going on.

You are calling ToList .. it can never be null.
You should check its length.
If Count.Count = 0 Then
crewNumUnique = True
Else
End If

The query will return a result set even when no matching rows are found.
The below sets crewNumUnique to True if there is exactly 1 result. If instead you want to set crewNumUnique to True when there are no results, use 0 in place of 1.
Dim result = From a In db.WarrantyPercents Where a.CrewLeaderNum = crewLeaderNumEntered And a.CrewNum = crewNumEntered
Dim count As Integer = result.Count
If count = 1 Then
crewNumUnique = True
Else
'throw Error
End If

Related

Checking value of multiple variables (dynamic names)

I have 160 variables named resq1, resq2, ..., resq160. Values for these are assigned manually. I would like to check if values are assigned to all of them. Is it possible to loop through values of multiple variables.
There are examples of how to create multiple variables with dynamic names, but I was unable to find solution for this problem.
This doesn't work
Dim cond As Boolean = True
Dim resq(160) As String
Dim i As Integer
For i = 1 To 160
If resq(i) = "" Then
cond = False
End If
Next
Thanks
Edit2: For the example code you are creating the values incorrectly, You would proceed as this:
Dim resq(10) As String 'Set the array
Dim cond As Boolean = True
resq(0) = 12
resq(1) = 10
resq(2) = 7
For Each item As String In resq
If item <> Nothing Then
'Do something with your data here
Else
cond = False
End If
Next
If cond = True Then
'Do something when all variables have values
Else
'Do something when not all variables have values
End If
Remeber that resq1 is NOT the same as resq(1), The first is a seperate variable and the 2nd is the first instance of the array called resq.
Edit: To check that all the variables have an initial value you can use this code (also slightly improved since the previous code would not go through all the variables you have set):
Dim cond As Boolean = True
Dim resq(160) As String
For Each item As String In resq
If item = Nothing And item <> "" Then
cond = False
End If
Next
If you want it to also check if the value is "" you can remove the 2nd part of the if statement and just use:
Dim cond As Boolean = True
Dim resq(160) As String
For Each item As String In resq
If item = Nothing Then
cond = False
End If
Next

Testing if a string is null

I am pretty new in VBA and I have not yet got used to the syntax completely, so I'm sorry if my question sounds stupid.
I am working with RequisitePro40 and VBA 7.0 in Word 2010. In one of my modules I have the following loop and If conditions:
Dim rqRequirements As ReqPro40.Requirements
Dim rqRequirement As ReqPro40.Requirement
Const eAttrValueLookup_Label = 4
Dim a As Integer
...
For Each vReqKey In rqRequirements
Set rqRequirement = rqRequirements(vReqKey)
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text <> Null Then
a = 1
End If
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = Null Then
a = 2
End If
Next
In each iteration of the loop, both a = 1 and a = 2 are executed!!
Based on This, the equality and inequality operators are "=" and "<>". Therefore I would expect that either a = 1 or a = 2 execute for a string.
Is there something wrong with my syntax? Or is it a ReqPro related Problem?
I also tried using "Is" and "IsNot" operators but they result in Compiler error: Type mismatch
Can Someone help me with this?
Update: The actual goal is to see if the
rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text
is Null or not. I added the second if to show the problem that the statement is somehow not working the way I expect it to work.
Replacing "Null" to "vbNullString" did not make any changes.
I also tried the IsNull function as #Slai suggested. the result is pretty much the same:
If IsNull(rqRequirement.AttrValue(att, eAttrValueLookup_Label).text) Then
a = 3
End If
If Not IsNull(rqRequirement.AttrValue(att, eAttrValueLookup_Label).text) Then
a = 4
End If
Both statements a = 3 and a = 4 are true and executed.
VBA doesn't support testing whether a string is "Null". VBA isn't like a .NET language or JavaScript (for example). The basic variable types all have a default value, a String is of zero length ("") from the moment the variable is declared - it has no uninstantiated state. You can also test for vbNullString.
If you test
Dim s as String
Debug.Print s = Null, s <> Null, s = "", s = "a", IsNull(s), s = vbNullString
The return is
Null Null True False False True
So if you're trying to test whether anything has been assigned to a String variable the only things you can do are:
Debug.Print Len(s), s = "", Len(s) = 0, s = vbNullString
Which returns
0 True True True
Note that the slowest of these possibilities is s = "", even though it seems the simplest to remember.
As others have noted, you want to test against the null version of a string, vbNullString, and not against Null specifically. In addition to this, you also need to make sure your object isn't null itself. For example:
Dim rqRequirements As ReqPro40.Requirements
Dim rqRequirement As ReqPro40.Requirement
Const eAttrValueLookup_Label = 4
Dim a As Long ' Avoid Integer since it has a strong habit of causing overflow errors.
...
For Each vReqKey In rqRequirements
Set rqRequirement = rqRequirements(vReqKey)
If Not rqRequirement Is Nothing Then
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text <> vbNullString Then
a = 1
End If
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = vbNullString Then
a = 2
End If
End If
Next
Now, I haven't worked with this specific object type before, but I am fairly certain that AttrValue("MyAttreName", eAttrValueLookup_Label) is returning some kind of object. If this is the case, then the below pattern would be preferred:
Dim rqRequirements As ReqPro40.Requirements
Dim rqRequirement As ReqPro40.Requirement
Const eAttrValueLookup_Label = 4
Dim a As Long ' Avoid Integer since it has a strong habit of causing overflow errors.
...
For Each vReqKey In rqRequirements
Set rqRequirement = rqRequirements(vReqKey)
If Not rqRequirement Is Nothing Then
Dim Attribute as Object ' Or whatever type it should be
Set Attribute = rq.Requirement.AttrValue("MyAttreName", eAttrValueLookup)
If Not Attribute is Nothing Then
If Attribute.text <> Null Then
a = 1
End If
If Attribute.text = Null Then
a = 2
End If
End If
End If
Next
In this way, we are only ever calling upon the text property of the Attribute if we have actually set the Attribute. This avoids 424 errors down the line.
Finally, if you want to figure out what is happening in the code that is causing both if's to run, do something like this:
Debug.Print "Attribute Text: ", Attribute.Text
This will allow you to see what your code is seeing. You can consider using breakpoints as well.
1) I think you can use vbNullString to test for empty string. Otherwise use "Null" if actual string value.
2) Ensure a is declared as long
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text <> vbNullString Then
a = 1
End If
If rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = vbNullString Then
a = 2
Else
a = 3
End If
I landed here looking for an answer to "VBA: How to test if a string is Null"
while this answer may not apply to this particular users situation, it does apply to the subject question.
Dim s As String, s2 As String
s = ""
s2 = vbNullString
Debug.Print StrPtr(s) = 0, StrPtr(s2) = 0
which returns
False True
because vbNullString is a C style NULL pointer for working with COM objects, and so its memory address when returned by the undocumented StrPtr function will always be 0
To ensure mutual exclusivity, ask the question only once.
a = IIf(rqRequirement.AttrValue("MyAttreName", eAttrValueLookup_Label).text = vbNullString , 2, 1)
You can also use an If-Then-Else construct, particularly if you have other actions you want to perform at the same time.
The above code example assumes the ~.text call is correct.

When loading from string to checked listview, the foreach skips characters

I have a string, My.settings.prohibitions, full of 1's and 0's; they correspond to which items of a checked listview should be checked and which should not. I tried using the following code to check items on the listview according to the values in the string, but it didn't work; the even numbered items were always unchecked, but the odd numbered items did get checked correctly.
For Each setting As Char In My.Settings.Prohibitions
If setting = "0" Then
ListView1.Items(My.Settings.Prohibitions.IndexOf(setting)).Checked = False
Else
ListView1.Items(My.Settings.Prohibitions.IndexOf(setting)).Checked = True
End If
Next
Edit: This does not work either:
Dim x As String = My.Settings.Prohibitions
For y As Integer = 0 To 7
If x(y).ToString = "1" Then
ListView1.Items(y).Checked = True
Else
ListView1.Items(y).Checked = False
End If
y += 1
Next
You need something like this:
For index As Integer = 0 To My.Settings.Prohibitions.Length - 1
ListView1.Items(index).Checked = My.Settings.Prohibitions(index) = "1"
Next

Excel VBA - count number of different parameters in table

I have some problems with my excel VBA code, it does not work and yes, I do not know why...
I want to add each Record number once in a collection. My code looks like this:
For i = 1 To lo.ListRows.Count
Count = 1
Do While recordList.Count >= Count
recordFound = False
If lo.ListColumns("Record").DataBodyRange.Rows(i) = recordList(Count) Then
recordFound = True
End If
If recordFound = False Then
recordList.Add (lo.ListColumns("Record").DataBodyRange.Rows(i))
End If
Count = Count + 1
Loop
Next
What it does now, it returns empty collection...
Whould be great if you could help me guys!
There is no real need to test the Collection to see if the item exists if you give it a key.
You can code something like:
On Error Resume Next
For I = 1 To lo.ListRows.Count
With lo.ListColumns("Record").DataBodyRange.Rows(I)
RecordList.Add Item:=.Value, Key:=CStr(.Value)
End With
Next I
On Error GoTo 0
Adding an item with the same key will cause the operation to be rejected. If you are concerned about other errors than the duplicate key error, you can always check the error number in the inline code and branch depending on the results.
I haven't been able to test this with the reference to lo but it works with a reference to a range
Dim objDictionary As Object
Dim dictionaryKey As Variant
Dim i As Long
Set objDictionary = CreateObject("Scripting.Dictionary")
For i = 1 To lo.ListRows
objDictionary.Item(CStr(lo.ListColumns("Record").DataBodyRange.Rows(i))) = objDictionary.Item(CStr(lo.ListColumns("Record").DataBodyRange.Rows(i))) + 1
Next i
For Each dictionaryKey In objDictionary.keys
' Do something
Next dictionaryKey
I have used a dictionary object instead of a normal collection object as it should do what you are trying to do. Because the item is incremented each time, you can also return the count of each item by using
objDictionary.item(dictionaryKey)

Using a Case statement with an Int entry from a table

What is the best way to compare an Int entry from a table in a case statement?
Using SQL server 2008 R2, Visual Basic Express with LINQ to SQL.
The code I tried doesnt work:
Private Sub UpdateSetOpt()
Dim db = New ACEDataContext
Dim SRM = From q In db.Settings
Where q.SettingID = frmMain.CurrentSID
Select q.RollMethod
Select Case SRM
Case 1
rbStandard.Checked = True
Case 2
rbProfession.Checked = True
Case 3
rbSpecies.Checked = True
Case 4
rbRandom.Checked = True
Case Else
rbStandard.Checked = False
rbProfession.Checked = False
rbSpecies.Checked = False
rbRandom.Checked = False
End Select
End Sub
SRM isn’t an Integer since your From query returns a collection of items. To get just the first, use Single():
Dim SRM = (From q In db.Settings
Where q.SettingID = frmMain.CurrentSID
Select q.RollMethod).Single()
If the query actually returns more than a single value the above code will fail; you need to use First instead of Single then. Both will fail if no value is returned by the query. In that case, FirstOrDefault may be used instead (but probably isn’t appropriate in your situation).
Adding to that, your Select Case is a sign of code smell. You should rather create an array of all the check boxes and use the integer to map into it:
Dim checks As CheckBox() = New CheckBox() { _
rbStandard, rbProfession, rbSpecies, rbRandom }
' Unset all checkboxes:
For Each check In checks
check.Checked = False
End For
If SRM > 0 AndAlso SRM <= checks.Length Then
checks(SRM - 1).Checked = True
End If
SRM in your case is not an int but IEnumerabe<int>.
You want the first element:
SELECT CASE SRM.FirstOrDefault():