ASP VB NET List(of T) find method failing in a for each loop - asp.net

Good morning stackers!
I'm designing a massive update page. Here are the general steps:
I have a class called item which has two properties: Equipment number and new due date.
I have a textbox where i paste values from Excel, the values consist of two columns divided by a vbtab character: the columns are an equipment number and a new due date
A button is clicked and the values from textbox are parsed into a list(of item) and the equipment master builds a string for an SQL criteria for a commandtext.
The command fills a dataset from a database which gets equipment number and current due date.
I add manually a column to the dataset (new due date)
I iterate over the rows of the dataset, and i use the list(of item) find method matching equipment from the list and from the database to get a new due date from the textbox parsed values.
Everything is going well, except that when using the find method for more than 1 row in the dataset, the method fails:
Here is the code from point 5 and 6:
da.Fill(ds, "Equipments")
dt = ds.Tables(0)
ds.Tables(0).Columns.Add("column_1", Type.GetType("System.DateTime"))
Dim rw As DataRow
For Each rw In ds.Tables(0).Rows
Dim strsearch As String = rw(0).ToString
Dim fequnumb As item = myItemList.Find(Function(p) p.EquipNumber = strsearch)
rw(2) = fequnumb.DueDate <- Error occurs here
Next
Again, if instead of ftechid.DueDate I put a static value like Today()the code runs fine for the loop and fills correctly the gridview, but if i leave the ftechid.DueDate then an error is thrown after the first row:
Object reference not set to an instance of an object.
Any help is very much appreciated as to how to use the find method inside a for..each loop

If the Find function cannot match the string requested it returns Nothing and then you cannot set the due date from a variable that is Nothing. If this is a condition expected from the input then you need to protect the assignment to the new column with something like this.
For Each rw In ds.Tables(0).Rows
Dim strsearch As String = rw(0).ToString
Dim fequnumb As item = myItemList.FirstOrDefault(Function(p) p.EquipNumber = strsearch)
if fequnumb IsNot Nothing Then
rw(2) = fequnumb.DueDate <- Error occurs here
End if
Next
If this is not supposed to happen then you need to check your inputs

Related

Get cell value from specified column in a Gridview upon "RowUpdating" Event ASP.NET/VB

What i want to do is te following... i have a gridview that loads the data from a SQL server, i have the e.NewValue and e.oldValue to determine which data was being modified/updated but i need to get the unique record ID which is store in "ID_ControlCharts" column
So, can you provide a code snippet/brief explanation in how to get the value from "ID_controlCharts" already filled by the gridview when i updated 1 cell (e.new/old)???
Note: The index is not what i needed since the row can be deleted and the reference to that row is now lost, so since the "ID_controlCharts" is filled automatically by SQL server key, its perfect for my situation.
codebehind
If e.Equals("Control_SeqRef_CH") = False Then
Dim oldvalue As String = e.OldValues("Control_SeqRef_CH")
Dim newvalue As String = e.NewValues("Control_SeqRef_CH")
Dim rowindex As Integer = e.RowIndex
Dim IDfromcontrol as integer = ???
MsgBox(oldvalue)
MsgBox(newvalue)
MsgBox(rowindex)
Msgbox(IDfromcontrol)
Else
MsgBox("same")
End If
You have a couple of options:
If the ID_ControlCharts column is in the record, couldn't you fetch it from e.OldValues?
Dim IDfromcontrol = e.OldValues("ID_ControlCharts")
Failing that, if you set ID_ControlCharts as a column for the DataKeyNames property, you should be able to fetch it using the ItemIndex:
Dim IDfromcontrol = GridView1.DataKeys(e.ItemIndex).Values(0)
(This is all from memory, so the syntax may be a little off.)

Error while using DataTable.Select() Method in Vb.Net

I am using DataTable.Select() method to filer based on some conditions.
dtRows = m_dtTable.Select(String.Format("IdentifierID={0}", dtRow
("QuestionID").ToString))
I used the similar way to sort the data in different places . But only one place i am getting error.
Can any help me to find why this exception is occurs? Also help me to know why there is no exception in other places ? The values of datatable is filled from a stored procedure.
Min (2) must be less than or equal to max (-1) in a Range object. is exception I am getting.
EDIT -- After the First Answer --
I am getting exception not every time, but only some time that I cannot identify the scenario. :(
ADDED -- After the First Answer --
Thanks for the solution. :)
Note : m_DependantQuestionsDataTable and m_dtTable are same by its schema.
colIdentifierID.DataType = Type.GetType("System.String")
colIdentifierID.ColumnName = "IdentifierID"
This is the type of particular column. There is also another column which is also similar type and there is no error occurs when I use it with the similar method.
colQuestionID.DataType = Type.GetType("System.String")
colQuestionID.ColumnName = "QuestionID" is the column and I am using like this. ' Dim strFilterExpression As String = "questionID={0}" m_DependantQuestionsDataTable.Select(String.Format(strFilterExpression, dRow("QuestionID")))'
Here there is no exception or error is occurring . So if I am choosing your solution I need to change the Filter Expression by adding ' in all place in my solution where I am using Filter Method.
You don't specify the data type of the column you're filtering on and if it's a string then you'll need to add single quotes around the parameter in your filter expression:
dtRows = m_dtTable.Select(String.Format("IdentifierID='{0}'", dtRow("QuestionID").ToString()))
alternatively, if you want to sort+ filter via the DGV, without need to repopulate the DT and DGV, you can use .Sort and .RowFilter of the DataView
http://msdn.microsoft.com/en-ca/library/system.data.dataview.rowfilter.aspx
Private _DS As New DataSet
Private _DT As New DataTable
Private _DV As New DataView
Private _DGV As New DataGridView
Private _isFiltering As Boolean = False
Private Sub filterView()
If _isFiltering Then Return
_isFiltering = True
Dim _SF As String = "price ASC"
'Dim _RF As String = tableStructure.Columns(0).Name & " < 20" ' just an example
Dim _RF As String = "price < 20"
_DGV.ClearSelection()
_DT.DefaultView.Sort = _SF
_DT.DefaultView.RowFilter = _RF
_isFiltering = False
End Sub

Using arrays with asp.net and VB

Sorry, I'm sure this is something that has been covered many times, but I can't find quite what I am after.
I have a single row data table which contains various settings which are used within my web system. I have been toying with turning this into an XML document instead of the single row datatable, would that make more sense?
Anyway, so, given that this is one record, there is a field called "locations," this field contains data as follows:
locationName1,IpAddress|locationName2,IpAddress|etc
The ipAddress is just the first 5 digits of the IP and allows me to ensure that logins to certain elements (admin section managed by staff) can only be accepted when connected from a company computer (ie using our ISP) - this is a largely unnecessary feature, but stops kids I employ logging in at home and stuff!
So, as the user logs in, I can check if the IP is valid by a simple SQL query.
SELECT ips FROM settings WHERE loginLocations LIKE '%" & Left(ipAddress, 5) & " %'
What I need to be able to do now, is get the name of the users location from the dataField array.
I've come up with a few long winded looping procedures, but is there a simple way to analyse
locationName1,IpAddress1|locationName2,IpAddress2|etc
as a string and simply get the locationName where LoginIp = IpAddressX
... or am I going about this in a totally ridiculous way and should turn it into an xml file? (which will then create a whole load of other questions for you about parsing XML!!)
u can split the string in Vb.net and the send it to a query or anything
'Split the string on the "," character
Dim parts As String() = s.Split(New Char() {","c})
In SQL Server, these are the functions of interest in extracting a sub-string:
CHARINDEX
SUBSTRING
LENGTH
You can google the details about them (e.g. CHARINDEX at http://msdn.microsoft.com/en-us/library/ms186323.aspx). With these, you'll need to use computed columns in your query to extract that location name.
If it's not too late, you may want to devise a new way to layout these elements. For instance, instead of:
locationName1,IpAddress1|locationName2,IpAddress2|etc
How about
{IpAddress1,locationName1}{IpAddress2,locationName2}etc
That way you can use CHARINDEX to locate "{" & Left(ipAddress, 5); from that position, locate ","; then from that position locate the closing "}". From there it should be straightforward to use SUBSTRING to get at the locationName. Be forewarned that this will likely be a messy query (probably built from a few sub-queries, one for each position).
In the end, SpectralGhost's idea to just read in the column and do the extraction in VB is probably the way with the least hassle.
I've decided to do it this way, but would appreciate comments on efficiency.
I've split ipAddress and locationName into two database columns, within the one row, and getting the required data by comparing strings as arrays, as per the code below.
For this particular application I'm only dealing with one record, so it's pretty simple. However, further down the line, I need to product a system for monitoring product sales. from an invoices table.
Each invoice record is a row in the database with items in the invoice held similarly, [item1],[item2] etc. There is another column for quantities [qty1],[qty2] etc, prices [price1],[price2], etc. I'll need to be able to search the database for invoices in which an item number occurs (easy SQL WHERE itemList LIKE %[invNO]%) and then compare arrays to get the quantities and individual prices of each item on that invoice. Extracting these rows as arrays and locating the relevant position in these as per the code below, will work fine, but when the whole operation is looping through several hundred or thousand rows, will this become really slow?
ipList, locationList = list as comma separated string from database record field
Dim ipArray As Array = Split(ipList, ",")
Dim locationArray As Array = Split(locationList, ",")
For i = 0 To UBound(ipArray)
If Left(ipArray(i), 5) = Left(ipAddress, 5) Then
arrayPosition = i
itemFound = "True"
Exit For
End If
Next
location = locationArray(arrayPosition)
'loop through ips then get the position and make the location equal to that
If itemFound <> "True" Then
inValidIP = "True"
End If
I strongly advise that you break those our into database columns and each location is a separate row; had it been done that way in the first place, you wouldn't have the problem you have now.
But since you have it in a single row/column, why not bring that back and simply get the value from .NET?
Dim Source As String = "TestLocationA,127.0|TestLocationB,128.0|TestLocationC,129.0"
Dim Test As String = Source
Dim ToFind As String = "127.0"
Test = Test.Substring(0, Test.IndexOf(ToFind & "|") - 1)
Test = Test.Substring(Test.LastIndexOf("|") + 1)
MsgBox(Test)
OR
Public Class Form1
Private IpLocationList As New List(Of IpLocation)
Private IpToFind As String = ""
Private Class IpLocation
Public Name As String
Public IP As String
Public Sub New(ByVal FullLocation As String)
Me.Name = FullLocation.Substring(0, FullLocation.IndexOf(","))
Me.IP = FullLocation.Substring(FullLocation.IndexOf(",") + 1)
End Sub
End Class
Private Function FindIP(ByVal IpLocationItem As IpLocation) As Boolean
If IpLocationItem.IP = IpToFind Then
Return True
Else
Return False
End If
End Function
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim Source As String = "TestLocationA,127.0|TestLocationB,128.0|TestLocationC,129.0"
Dim LocationList As New List(Of String)
LocationList.AddRange(Split(Source, "|"))
For Each LocationItem As String In LocationList
IpLocationList.Add(New IpLocation(LocationItem))
Next
IpToFind = "127.0"
Dim result As IpLocation = IpLocationList.Find(AddressOf FindIP)
If result IsNot Nothing Then
MsgBox(result.Name)
End If
End Sub
End Class
enter code here
This has the benefit of loading the array one time and not needing to manually loop through arrays.

Search data from dataset

I want to search record based on following fields
P_num ,P_name, P_dob,P_code
I am using more than 4 tables to retrive data,
I have created dataset called P_search and i want to fill data into dataset and thsn display it according to which field is selected for search purpose.
Suggest me to write code by creating own function in which all fields and a boolean variable will be taken as parameters
Please help me to write code using VB.net.
I am very new to VB.net. Is ther anyone who can help me giving above code.
Thank You In advance
You use DataTable.Select Method
Private Sub GetRowsByFilter()
Dim table As DataTable = DataSet1.Tables("Orders")
' Presuming the DataTable has a column named Date.
Dim expression As String
expression = "Date > #1/1/00#"
Dim foundRows() As DataRow
' Use the Select method to find all rows matching the filter.
foundRows = table.Select(expression)
Dim i As Integer
' Print column 0 of each returned row.
For i = 0 to foundRows.GetUpperBound(0)
Console.WriteLine(foundRows(i)(0))
Next i
End Sub

How can I copy object types in VB.NET?

I am building an ASP.NET application that needs dynamic tables. That's another issue that I've already posted about (and gotten a pretty good response!). Now, I'm running into another issue - I want to add new rows to my table, but given that I will have 10-12 tables on one page, each containing different objects in their rows (text boxes, check boxes, etc.) I need a way of simply generically adding a new row that has the same objects as the first row in the table. Here's my code:
Private Sub AddTableRow(ByRef originalTable As System.Web.UI.WebControls.Table)
Dim originalRow As System.Web.UI.WebControls.TableRow = originalTable.Rows(1)
Dim insertingRow As New System.Web.UI.WebControls.TableRow
Dim insertingCells(originalRow.Cells.Count) As System.Web.UI.WebControls.TableCell
Dim index As Integer = 0
For Each cell As System.Web.UI.WebControls.TableCell In originalRow.Cells
insertingCells(index) = New System.Web.UI.WebControls.TableCell
insertingCells(index).Controls.Add(cell.Controls.Item(0))
index += 1
Next
insertingRow.Cells.AddRange(insertingCells)
originalTable.Rows.Add(insertingRow)
End Sub
But I'm getting a null reference exception at the second to last line,
insertingRow.Cells.AddRange(insertingCells)
...and I can't figure out why. Is it because the contents of each cell are not being initialized with a new object? If so, how would I get around this?
Thanks!
EDIT:
The inside of my for loop now looks like this -
For Each cell As System.Web.UI.WebControls.TableCell In originalRow.Cells
Dim addedContent As New Object
Dim underlyingType As Type = cell.Controls.Item(0).GetType
addedContent = Convert.ChangeType(cell.Controls.Item(0), underlyingType)
insertingCells(index) = New System.Web.UI.WebControls.TableCell
insertingCells(index).Controls.Add(addedContent)
index += 1
Next
Stepping through with a debugger, I see that this strategy is working - but the additional table row still doesn't appear...and still does when I do this statically.
I think your culprit may be this line:
Dim insertingCells(originalRow.Cells.Count) As TableCell
Confusingly, the number you specify in an array declaration in VB.NET is the upper bound, not the number of elements. So Dim ints(10) As Integer will create an Integer() array with eleven elements, not ten (10 will be the highest index of the array).
Try this instead:
Dim insertingCells(originalRow.Cells.Count - 1) As TableCell

Resources