I have a Grid view control with a few columns that is populated from a form that the user fills in. In the form some values are not mandatory and if the user does not select them, then it is displayed as "select" in the Grid view. How do i go about changing that value to something for relative like "none" when i load the Grid view. In other words , if that column contains "select" then change it to "None"
This is my code behind to populate my Gridview
Private Sub LoadGridAll()
txtSearchEmployee.Text = ""
Try
Using conn As New SqlConnection(ConfigurationManager.ConnectionStrings("XXX").ConnectionString)
Using cmd As New SqlCommand("SELECT EmployeeCodes.Code, EmployeeCodes.FirstName , EmployeeCodes.LastName , EmployeeCodes.EmployeeID , CostCentre , ExaminationType.ExaminationTypeName , PhysicalExam.PhysicalExamName , ExaminationType.ExaminationTypeName , PhysicalExam.PhysicalExamName , Audiogram.AudiogramName , AudiogramRec.AudiogramRecName,LungFunction.LungFunctionName,ChestResults,ECGResult,DrugScreeningResult,BloodGlucoseResult,GGTResult,LeftEyeDayNight,RightEyeDayNight,LeftEyeCorrDayNight,RightEyeCorrDayNight,VisualFieldLeftDayNight,VisualFieldRightDayNight,ColourVisionDayNight,DeptPerceptionDayNight,OptometristYesNo,Outcome.Name , OutcomeRecommendations.OutcomeRecommendationsName,OtherProblems,Notes,DateTested,NextDueDate FROM MedicalResults,EmployeeCodes,ExaminationType,PhysicalExam,Audiogram,AudiogramRec,LungFunction,Outcome,OutcomeRecommendations WHERE MedicalResults.EmployeeID = EmployeeCodes.EmployeeID AND ExaminationType.ExaminationTypeID = MedicalResults.ExaminationTypeID AND PhysicalExam.PhysicalExamID = MedicalResults.PhysicalExamType AND Audiogram.AudiogramID = MedicalResults.AudiogramID AND MedicalResults.AudiogramRecID = AudiogramRec.AudiogramRecID AND LungFunction.LungFunctionID = MedicalResults.LungFunctionID AND OutcomeRecommendations.OutcomeRecommendationsID = MedicalResults.OutcomeRecommendationsID AND Outcome.OutcomeID = MedicalResults.OutcomeID ", conn)
conn.Open()
Dim sda As New SqlDataAdapter(cmd)
Dim dt As New DataTable()
sda.Fill(dt)
For Each row As DataRow In dt.Rows
Dim strDetail As Object
strDetail = row.Item(10)
If strDetail = "Select" Then
strDetail = "None"
End If
Next row
GridViewAll.DataSource = dt
GridViewAll.DataBind()
conn.Close()
End Using
End Using
Catch ex As Exception
End Try
End Sub
First of all, I wouldn't save "Select" to DB, it would make more sense to save a null value (DBNull.Value). Then in your select statement you could use a function IsNull(yourField,'None'). Edit: if you have Null values in grid, you could also use DataGridView's property:
Me.GridViewAll.RowsDefaultCellStyle.NullValue = "None"
However, if you want to do it like you've shown, you're very close - you just need to save the new String value to DataTable:
row.Item(10) = "None" 'strDetail
Related
I am working on a website with VB.NET and ASP.NET. I currently have recurring DropDownLists for the user to provide input.
The design is recurring. These DropDownLists get their values from a database table, Everything with the Web interface is working except for writing these recurring values to the database - that is just to give you some background.
I have set the ID's of each DropDownList like so:
FrequencyList.ID = String.Concat("FreqList", DBReader(0))
That is in a loop while reading the DatabaseReader.
This is what I'm having issues with (please note I simplified the code down to make it easier to read:
Dim i As Integer
DBCommand = New SqlCommand()
DBCommand.Connection = DBConnection
DBCommand.CommandType = Data.CommandType.StoredProcedure
DBCommand.CommandText = "StoredProcedureName"
DBConnection.Open()
For i = 1 To AspectTableLength
Dim ParamFrequencyID As SqlParameter = DBCommand.Parameters.Add("#nFrequencyID", SqlDbType.Int)
ParamFrequencyID.Value = FindControl("FreqList" & Convert.ToString(i))
ParamFrequencyID.Direction = ParameterDirection.Input
Next
The FindControl("FreqList" & Convert.ToString(i)) variable is incorrect because it does not access the value - and adding .SelectedItem.Value does not work.
I got help from a developer.
Dim MyControls As ControlCollection = Panel.Controls
Dim Number As Integer 'this is the same as "DBReader(0)"
For Each MyControl As Control In MyControls
If MyControl.ID Is Nothing Then
Else
If MyControl.ID.StartsWith("Span") Then
Number = Replace(MyControl.ID, "Span", "")
Dim Freq As DropDownList = PanelMain.FindControl(“FreqList” & Number)
Dim ParamFrequencyID As SqlParameter = DBCommand.Parameters.Add("#nFrequencyID", SqlDbType.Int)
ParamFrequencyID.Value = Freq.SelectedIndex
ParamFrequencyID.Direction = ParameterDirection.Input
DBCommand.ExecuteNonQuery()
DBCommand.Parameters.Clear()
End If
End If
Next
DBConnection.Close()
Behind code of aspx page, I have a Datatable:
Dim people As DataTable = New DataTable()
people.Columns.Add("ID", System.Type.GetType("System.Int32"))
people.Columns.Add("FirstName", System.Type.GetType("System.String"))
people.Columns.Add("LastName", System.Type.GetType("System.String"))
people.Rows.Add(10, "Merci", "Beaucoup")
and this the GridViewData: (Not asp:GridView)
Dim gvPeople As System.Windows.Forms.DataGridView = New DataGridView()
gvPeople.AutoGenerateColumns = False
'Set Columns Count
gvPeople.ColumnCount = 3
'Add Columns
gvPeople.Columns(0).Name = "ID"
gvPeople.Columns(0).HeaderText = "ID"
gvPeople.Columns(0).DataPropertyName = "ID"
gvPeople.Columns(1).Name = "FirstName"
gvPeople.Columns(1).HeaderText = "FirstName"
gvPeople.Columns(1).DataPropertyName = "FirstName"
gvPeople.Columns(2).Name = "LastName"
gvPeople.Columns(2).HeaderText = "LastName"
gvPeople.Columns(2).DataPropertyName = "LastName"
Here I set the datasource of the DataGridView to the DataTable:
gvPeople.DataSource = people
When I import the DataGridView into the Excel sheet using Gembox.Spreadsheet, it only shows me the headerText of the DataGridView without the data.
This is the Import Code:
DataGridViewConverter.ImportFromDataGridView(ws, gvPeople, New ImportFromDataGridViewOptions() With _
{
.ColumnHeaders = True,
.StartRow = 8,
.StartColumn = 0
})
I tried multiple things such as:
setting up the .DataMember to the DataTable name : gvPeople.DataMember=people.TableName
Refresh() or Update() the DataGridView after assigning the .Datasource.
Note: This is not an asp:GridView, it's a DataGridView and it does not have a DataBind() method.
if using asp:GridView, Just use the databind function
gvPeople.DataSource = people
gvPeople.Databind()
Note: It is not recommended to use a datagridView in a Web project this control is designed for winforms applications.
If using windows.Forms.DataGridView
DataGridView must be added to a form controls collection to perform its layout
Me.Controls.Add(gvPeople)
But this cannot be done when using web project (Getting Error)
so you have to do some workaround
First i created a Function that convert a datarow to an array of string
Public Function ToStringArray(ByVal dRow As DataRow) As String()
Dim lst As New List(Of Object)
lst.AddRange(dRow.ItemArray)
Return lst.Select(Function(x) x.ToString).ToArray()
End Function
Then i used the Following code
this is your code:
Dim people As DataTable = New DataTable("people")
people.Columns.Add("ID", System.Type.GetType("System.Int32"))
people.Columns.Add("FirstName", System.Type.GetType("System.String"))
people.Columns.Add("LastName", System.Type.GetType("System.String"))
people.Rows.Add(10, "Merci", "Beaucoup")
Dim gvPeople As System.Windows.Forms.DataGridView = New System.Windows.Forms.DataGridView()
gvPeople.AutoGenerateColumns = False
''Set Columns Count
gvPeople.ColumnCount = 3
''Add Columns
gvPeople.Columns(0).Name = "ID"
gvPeople.Columns(0).HeaderText = "ID"
gvPeople.Columns(0).DataPropertyName = "ID"
gvPeople.Columns(1).Name = "FirstName"
gvPeople.Columns(1).HeaderText = "FirstName"
gvPeople.Columns(1).DataPropertyName = "FirstName"
gvPeople.Columns(2).Name = "LastName"
gvPeople.Columns(2).HeaderText = "LastName"
gvPeople.Columns(2).DataPropertyName = "LastName"
And here is my Added Code
For Each drow As DataRow In people.Rows
gvPeople.Rows.Add(ToStringArray(drow))
Next
gvPeople.RowCount = people.Rows.Count
gvPeople.Refresh()
You should really reconsider that approach (using DataGridView in ASP.NET application).
If you want to insert only a data from GridView control into an Excel file, then use DataTable.
As you mentioned in the comments, you want to customize which columns to export and the order of the columns. In that case, you just need to adjust the DataTable itself, for example try the following:
' Sample DataTable.
Dim people As New DataTable()
people.Columns.Add("ID", GetType(Integer))
people.Columns.Add("FirstName", GetType(String))
people.Columns.Add("LastName", GetType(String))
people.Rows.Add(1, "John", "Doe")
people.Rows.Add(2, "Jane", "Doe")
people.Rows.Add(10, "Merci", "Beaucoup")
' Remove "ID" column.
people.Columns.Remove("ID")
' Set "LastName" column on first place.
people.Columns("LastName").SetOrdinal(0)
' Create Excel file.
Dim ef As New ExcelFile()
Dim ws As ExcelWorksheet = ef.Worksheets.Add("Sheet1")
' Insert DataTable into Excel file.
Dim op As New InsertDataTableOptions()
op.ColumnHeaders = True
ws.InsertDataTable(people, op)
' Save Excel file.
ef.Save("Sample.xlsx")
I hope this helps.
Also just in case you're interested here is how you would insert the data together with the styling and formatting from the GridView control into an Excel file with GemBox.Spreadsheet:
https://www.gemboxsoftware.com/support-center/kb/articles/export-gridview-and-or-datagrid-control-to-excel-file
Instead of using datagrid in asp.net application you can use asp gridview
which is possible according below link
https://www.gemboxsoftware.com/spreadsheet/examples/asp-net-excel-export/5101
Ok so what I'm trying to do is allow the users of my web form in asp.net to select multiple assets from a list box. When they select these assets and press the select button it fires the following code which should run through the selected indices, query the DB for the description and asset tag's, and populate the Description and Asset tag boxes with those values. Working through this I've been able to get it to read the values from the database and populate the fields but it would only populate the value from the first selected item and it would just insert the same value equal to the number of times equal to the number of items selected in the inbox. I tried my current code to run through the indices a little better but it seems to be failing the If statement and I just can't figure out why. Any help is appreciated, thanks everyone!
Dim i As Integer
For i = 0 To lstAssets.GetSelectedIndices.Count
If lstAssets.Items(i).Selected = True Then
Dim str2 As String = lstAssets.Items(i).Value.ToString
Dim cs As New OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings("CSIWebUpd").ConnectionString)
Dim ds As String = cs.DataSource
Dim cn As OracleConnection = New OracleConnection("user id=webupd;password=webupd;data source=" + ds)
Dim sql As String = "SELECT description, tag FROM assets WHERE id = :id"
Dim cmd As New OracleCommand(sql, cn)
cmd.Parameters.Add(":id", OracleDbType.Varchar2).Value = str2
cmd.CommandType = CommandType.Text
cmd.BindByName = True
cn.Open()
Dim dr As OracleDataReader = cmd.ExecuteReader()
cmd.ExecuteNonQuery()
dr.Read()
desc = dr.GetString(0).ToString
ass = dr.GetString(1).ToString
If txtDescription.Text = Nothing Then
txtDescription.Text = dr.GetString(0).ToString
Else
txtDescription.Text = txtDescription.Text + Chr(13) + Chr(10) + dr.GetString(0).ToString
End If
If txtAsset.Text = Nothing Then
txtAsset.Text = dr.GetString(1).ToString
Else
txtAsset.Text = txtAsset.Text + Chr(13) + Chr(10) + dr.GetString(1).ToString
End If
cmd.Dispose()
cn.Close()
End If
Next i
UpdatePanel1.UpdateMode = UpdatePanelUpdateMode.Conditional
UpdatePanel1.Update()
I would work with the SelectedIndices values in this way
For Each i in lstAssets.GetSelectedIndices
Now i contains the index of the items selected not the offset of the GetSelectedIndices array
The GetSelectedIndices returns an array where every element of the array is the index in the Items collection where you have an item selected.
An example could explain better:
Supposing the the items selected are 1, 5 6 (Count=3), your code set the value of i to 0,1,2 and then uses that value to lookup the ID in the items collection, but the following check on lstAssets.Items(i).Selected found just the item at index 1 as selected. Instead using the for each approach you get the values 1,5,6.
I'm having a problem populating a child gridview using a function I define. I keep getting the error "Object reference not set to an instance of an object". What am I doing wrong? Am I using the FindControl function incorrectly? It doesn't seem to find the child gridview.
Sub RecordsByZip()
Dim DBConn As New SqlConnection(Application("DBConn"))
Dim gv1 As GridView
gv1 = grdTotal
Dim gv2 As GridView
gv2 = DirectCast(gv1.FindControl("grdChild"), GridView)
Dim ZipCode = lbZip.SelectedItem
For Each ZipCode In lbZip.Items
If ZipCode.Selected = True Then
Dim cmdZip As SqlCommand = New SqlCommand("spPICAInsertTotals2", DBConn)
cmdZip.CommandType = CommandType.StoredProcedure
strZip = ZipCode.Text
strUser = Session("User")
Dim Zip As New SqlParameter("#Zip", SqlDbType.VarChar)
Zip.Value = strZip
cmdZip.Parameters.Add(Zip)
Dim UserID As New SqlParameter("#UserID", SqlDbType.Int)
UserID.Value = strUser
cmdZip.Parameters.Add(UserID)
DBConn.Open()
gv1.DataSource = cmdZip.ExecuteReader
gv1.DataBind()
gv1.Visible = True
DBConn.Close()
End If
Next
btnExport.Visible = True
lblmsg.Visible = False
' Dim DBConn = New SqlConnection(Application("DBConn"))
Dim cmdCounty As SqlCommand = New SqlCommand("spPICAInsertTotals", DBConn)
cmdCounty.CommandType = CommandType.StoredProcedure
'Dim gv As GridView = TryCast(e.Row.FindControl("grdChild"), GridView)
strUser = Session("User")
Dim UserID2 As New SqlParameter("#UserID", SqlDbType.Int)
UserID2.Value = strUser
cmdCounty.Parameters.Add(UserID2)
DBConn.Open()
gv2.DataSource = cmdCounty.ExecuteReader
gv2.DataBind()
gv2.Visible = True
DBConn.Close()
btnExport.Visible = True
lblmsg.Visible = False
lblInstructions.Visible = False
End Sub
First of all . . .
Just as a disclaimer, I normally use repeater controls instead of gridview controls.
But this may help you . . .
I can tell you that with repeater controls, if you want to find a nested repeater then you must look for them inside the item of the parent repeater to which they belong. Essentially, what you are trying to do with the code above, is find grdChild when there might actually be several grdChild (it is a nested gridview, after all). I'd be willing to bet this is where you're object reference error is occurring.
In other words, if you want to find the nested repeater with the ID nestedRepeater, and you know it is located in the first item of your main repeater (which in this case I've assigned to the myRepeater variable), you can do this:
Dim myItem as RepeaterItem = myRepeater.Items(0)
Dim Rep2 as Repeater = myItem.FindControl("nestedRepeater")
Using SqlDataAdapter and a DataSet (recommended)
Dim sa As New SqlDataAdapter(cmdCounty) 'Initialize the SqlDataAdapter and assign the SqlCommand object to it.
Dim ds As New DataSet() 'Initialize the DataSet (we will bind this to the gridview)
Try 'The Try/Catch statements help you to handle errors.
cmdCounty.Connection.Open() 'Open the connection to the database.
sa.Fill(ds) 'This statement uses the SqlDataAdapter to easily execute the SqlCommand (using the query specified in the SqlCommand object) and . . .
'. . .use that data to fill our dataset.
cmdCounty.Connection.Close() 'These statement close the connection and dispose of the SqlCommand object. Note: You may only need the dispose command.
cmdCounty.Dispose()
Catch ex As Exception
'Catch your error here.
cmdCounty.Connection.Close()
cmdCounty.Dispose()
End Try
gv2.DataSource = ds 'Set the datasource for your GridView control.
gv2.DataBind() 'Bind the data.
Using SqlDataReader and a DataTable
According to your comment, you're code is breaking when you assign the gridview to the cmd.ExecuteReader.
You will need to access your data using a method like this:
Dim rdr as SqlDataReader = cmdCounty.ExecuteReader() 'Declare the SqlDataReader and set it to handle your SqlCommand.
Dim dt as New DataTable 'Initialize a new DataTable. This is where we will place the information we read using the SqlDataReader.
'Make sure you add the columns...
dt.Columns.Add("firstColumnName") 'Create a column for each field you will be retrieving data from.
dt.Columns.Add("secondColumnName")
Dim r as DataRow 'Declare the variable r as a DataRow.
'You may want to insert the line "If rdr.HasRows Then" to check if any data was pulled before attempting to read it.
While rdr.Read() 'Loop through each row in the reader.
r = dt.NewRow() 'Set r to equal a new DataTable in the DataTable we created. Note: This does not actually add the row to the table.
r("firstColumnName") = rdr("firstColumnName") 'Set the values of each column in the current DataRow to equal their corresponding data read from SQL.
r("secondColumnName") = rdr("secondColumnName")
dt.Rows.Add(r) 'Add the DataRow r to the DataTable.
End While 'Loop back until there are no more rows.
gv2.DataSource = dt
gv2.DataBind()
Both of these examples assume you have already created your SqlCommand object and have assigned a working SQL query string and Connection object to it.
I am trying to check the value of a field before decided what to input into a drop down list in ASP.net.
I am using datareader.Read() in order to read the recordset so I can do this. However this then skips the first row of data . . The drop down box is basically a list of sizes and colours . . . So currently I am missing the first size.
Here is the code:
Using cmd As New SqlCommand("doGetAllSizesForProduct", oConn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#id", CType(Request.QueryString("id"), Integer))
oConn.Open()
Using dr As SqlDataReader = cmd.ExecuteReader()
If dr.HasRows() = True Then
dr.Read()
ddlSize.Visible = True
pnlSize.Visible = True
pnlNoStock.Visible = False
If dr("colour") = "None" Then
ddlSize.DataTextField = "size"
Else
ddlSize.DataTextField = "sizeColour"
End If
ddlSize.DataValueField = "mapperid"
ddlSize.DataSource = dr
ddlSize.DataBind()
Else
End If
dr.Close()
End Using
End Using
I guess either there must be another method other than Read or a way to stop it skipping the first record?
I've never seen a datareader being used as the datasource. What I think is happening is that your first call to dr.Read() is skipping to the first record as expected. However, when you assign the reader as the datasource, it's doing its own dr.Read() logic inside which starts at the next record. This could explain why you're not seeing the first item. Try modifying your code like this to use a DataTable instead (warning, didn't test this):
using dr as SqlDataReader = cmd.ExecuteReader()
if dr.HasRows() then
ddlSize.Visible = True
pnlSize.Visible = True
pnlNoStock.Visible = False
While dr.Read()
dim Value as string = dr("mapperid")
dim Text as string = if(dr("colour") = "None",dr("size"),dr("sizeColour"))
ddlSize.Items.Add(New ListItem(Text, Value))
End While
end if
dr.Close()
end using
How about changing the doGetAllSizesForProduct stored procedure to return two recordsets?
The first recordset can return a single row giving an indication of what type of data is contained in the second recordset, which contains the same content as previously.
you are not supposed to use the DataReader like this, executing a single Read to get the value in the first record then binding the UI control to it like this:
ddlSize.DataValueField = "mapperid"
ddlSize.DataSource = dr
ddlSize.DataBind()
I would personally use a DataTable for binding to a UI control, or try to remove the call to dr.Read() and see how it works.