Sheridan SSDB Grid set value for entire column - datagrid

I'm not sure if what I'm trying to do here is possible. I've got a Sheridan SSDB Grid, which is bound to a data control. When I populate the data control, the grid gets filled.
However, I've had to manually add an additional column after populating the grid to display a value which isn't in a database table.
To do all of this, I've written this code:
Dim SQL As String
SQL = My_Query
dtaEmployees.DatabaseName = DB_Period_Name$
dtaEmployees.RecordSource = SQL
dtaEmployees.Refresh
dtaEmployees.Recordset.MoveFirst
grdEmployees.Redraw = True
grdEmployees.Columns.Add (4)
I'm not sure how I can fill this new column in, however. I've got a global variable storing the value that I need, but none of the following lines of code are working
grdEmployees.Columns(4).Value = My_Variable
grdEmployees.Columns(4).Text = My_Variable
How can I set the value for all of the rows in the grid?
EDIT
After following the suggestion in the comments, I've modified my code as follows.
Form load:
Dim dbsPeriod As Database
Dim tdfEmployees As TableDef
Dim fldLoop As Field
Set dbsPeriod = OpenDatabase(DB_Period_Name$)
Set tdfEmployees = dbsPeriod.TableDefs!Ledger
AppendDeleteField tdfEmployees, "APPEND", "Location", dbText, 8
grdEmployees.DataSource = tdfEmployees
AppendDeleteField tdfEmployees, "DELETE", "Location"
dbsPeriod.Close
AppendDeleteField sub:
Private Sub AppendDeleteField(tdfTemp As TableDef, strCommand As String, _
strName As String, _
Optional varType, Optional varSize)
With tdfTemp
If .Updatable = False Then
MsgBox "Failed to initialise grid!"
Exit Sub
End If
If strCommand = "APPEND" Then
.Fields.Append .CreateField(strName, varType, varSize)
Else
If strCommand = "DELETE" Then .Fields.Delete strName
End If
End With
End Sub
With this code, no data is loaded into the grid at all.

You're not loading the data into the RecordSet before you delete the field. You need to get the data (using your SELECT query) into a data structure which the grid can use as the .DataSource
A TableDef is not a data structure, it just allows you to make changes to the database table itself, which is why your code isn't returning any rows.

Related

How can I store the y value of a chart series in a label on my page?

I am curious how I can access the value of a YValueMember in a chart that I am populating through a database and display that value in a label. Basically I want to set a labels text equal to the y value of my chart.
I am populating my chart through a db query and setting the YValueMembers to the alias I use within my query
SELECT ( SELECT SUM(DealerNet) FROM Agreement WHERE VoidDate IS NULL
AND IssueDate BETWEEN #PFOM AND #date) AS Actual,
(SELECT SUM(Amount) FROM Sales
WHERE [Year] BETWEEN YEAR(#PFOM) AND YEAR(#date)
AND [Month] BETWEEN MONTH(#PFOM) AND MONTH(#date)) AS Projected
I then pass this query to a function I have to populate a DataTable called GetData() as seen in the call below.
GetData() Function:
Private Shared Function GetData(cmdSQL As SqlCommand, ByVal Optional strCon As String = "") As DataTable
If strCon = "" Then
strCon = ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ToString
End If
Dim rstData As New DataTable
Using conn As New SqlConnection(strCon)
Using (cmdSQL)
cmdSQL.Connection = conn
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
Chart Code:
Dim cmdSQL As New SqlCommand(query)
cmdSQL.Parameters.Add("#date", SqlDbType.Date).Value = previousMonthDateToday
cmdSQL.Parameters.Add("#PFOM", SqlDbType.Date).Value = previousFirstOfMonth
pmtdChart.Series(0).ChartType = SeriesChartType.Column
pmtdChart.Series(1).ChartType = SeriesChartType.Column
pmtdChart.Legends(0).Enabled = True
pmtdChart.Series(0).XValueMember = xMember1
pmtdChart.Series(1).XValueMember = xMember2
pmtdChart.Series(0).YValueMembers = "Actual"
pmtdChart.Series(1).YValueMembers = "Projected"
lblPMTDprojected.Text = pmtdChart.Series(1).ToString()
lblPMTDbilled.Text = pmtdChart.Series(0).ToString()
pmtdChart.DataSource = GetData(cmdSQL)
pmtdChart.DataBind()
The GetData Function takes the query above and populates a DataTable, I don't know if I can pull directly from the Datatable within my function and I'm not terribly sure how I would do that, or If I need to pull the value from the chart that I am using.
I have tried the following in the Chart Code:
label.Text = Chart.Series(0).ToString
label.Text = Chart.Series(0).Points(0).ToString()
label.Text = Chart.Series(0).YValueMembers("Actual").ToString
label.Text = Chart.Series(0).YValueMembers(0).ToString
The first quite simply pulls the text value I have assigned to
pmtdChart.Series(0).YValueMembers = "Actual"
The second returns an exception error stating "Index was out of range. Must be non-negative and less than the size of the collection."
The Third returns an exception stating "Conversion From String "Text" to Type "Integer" is not valid.
And the fourth simply returns the first character of "Actual"
Technically I can simply pull this value from my database and assign it to the label, but I am wondering if there is a way to just snag it from my chart so I don't have to query the db again, considering I am using a similar query to populate the chart in the first place.
Any help or tips regarding this issue would be greatly appreciated and I feel like there should be a way to do what I am trying to do. If more information is needed I would be happy to supply it.
I was able to solve the problem I was having above by creating a second data table outside of the GetData() function and then using the GetData() function to populate the second data table. This allowed me to access the specific row/column that held the value I needed
actual = dt.Rows(0)("Actual").ToString()
projected = dt.Rows(0)("Projected").ToString()
I was then able to use these specific values where I needed them outside of the GetData() function.

How can I compare a text box entry against a list of database values in the Text_Changed event

as the title states I am trying to compare or validate a text box entry against a list of acceptable values stored in my database. As of now I have taken the values from my database and store them in a List(of String) and I have a for loop that loops through that list and returns true if the values match, if the values do not match it will return false. Below I have attached the code I am currently working with.
Protected Sub txtSearchOC_TextChanged(sender As Object, e As EventArgs) Handles txtSearchOC.TextChanged
Dim listEType As List(Of String) = New List(Of String)
Dim eType As String = txtSearchOC.Text
Dim strResult As String = ""
lblPrefix.Text = ""
lblList.Text = ""
Dim TypeIDQuery As String = "
SELECT a.OrderCode
FROM SKU AS a
INNER JOIN EnrollmentType AS e ON a.EnrollmentTypeID = e.TypeID
INNER JOIN Enrollment AS f ON e.RecID = f.EnrollmentTypeID
WHERE f.AccountNumber = '12345';
"
Using connEType As New SqlConnection(ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ToString)
Using cmdEType As New SqlCommand(TypeIDQuery, connEType)
cmdEType.Parameters.Add("#AccountNumber", SqlDbType.VarChar, 15).Value = "12345"
connEType.Open()
Using sdrEType As SqlDataReader = cmdEType.ExecuteReader
While sdrEType.Read
listEType.Add(sdrEType("OrderCode").ToString)
End While
End Using
End Using
End Using
For Each Item As String In listEType
strResult &= Item & ", "
Next
For i = 0 To listEType.Count - 1
If eType = listEType(i) Then
lblPrefix.Text = "True"
End If
If eType <> listEType(i) Then
lblList.Text = "Error"
End If
Next
'lblList.Text = strResult
End Sub
In the code I declare my list and a variable to store the text value of the text box. To verify that it pulled the appropriate values from the database I have the strResult variable and can confirm that the appropriate values are being stored.
The problem I am having has to do with the For loop I have at the bottom, when I enter in a valid value that is contained in the listEType, I get the confirmation message of "True" indicating it has matched with one of the values, but I also get the "Error" message indicating that it does not match. If I enter in a value that is not contained in the list I only get the "Error" message which is supposed to happen.
My question is, based on the code I have supplied, why would that For loop be returning both "True" and "Error" at the same time for a valid entry? Also, if there is a better way to accomplish what I am trying to do, I am all ears so to speak as I am relatively new to programming.
Well, as others suggested, a drop down (combo box) would be better.
However, lets assume for some reason you don't want a combo box.
I would not loop the data. You have this amazing database engine, and it can do all the work - and no need to loop the data for such a operation. Why not query the database, and check for the value?
Say like this:
Protected Sub txtSearchOC_TextChanged(sender As Object, e As EventArgs) Handles txtSearchOC.TextChanged
If txtSearchOC.Text <> "" Then
Dim TypeIDQuery As String = "
SELECT a.OrderCode FROM SKU AS a
INNER JOIN EnrollmentType AS e ON a.EnrollmentTypeID = e.TypeID
INNER JOIN Enrollment AS f ON e.RecID = f.EnrollmentTypeID
WHERE f.AccountNumber = #AccoutNumber;"
Using connEType As New SqlConnection(ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ToString)
Using cmdEType As New SqlCommand(TypeIDQuery, connEType)
cmdEType.Parameters.Add("#AccountNumber", SqlDbType.NVarChar).Value = txtSearchOC.Text
connEType.Open()
Dim rstData As New DataTable
rstData.Load(cmdEType.ExecuteReader)
If rstData.Rows.Count > 0 Then
' we have a valid match
lblPrefix.Text = "True"
Else
' we do not have a valid match
lblPrefix.Text = "False"
End If
End Using
End Using
End If
End Sub
So, pull the data into a data table. You can then check the row count, or even pull other values out of that one row. But, I don't see any need for some loop here.

ms_access Run time error 3078 in VBA although query runs as saved query [duplicate]

I have a query called qryAlloc_Source that has two paramaters under one criteria:
>=[forms]![frmReportingMain]![txtAllocStart] And <=[forms]![frmReportingMain]![txtAllocEnd])
A have a separate query that ultimately references qryAlloc_Source (there are a couple queries in between), and that query runs fine when I double click it in the UI, but if I try to open it in VBA, I get an error. My code is:
Dim rst As Recordset
Set rst = CurrentDb.OpenRecordset("qryAlloc_Debits")
I am getting run-time error 3061, Too few parameters. Expected 2. I've read that I may need to build out the SQL in VBA using the form parameters, but it would be pretty complex SQL given that there are a few queries in the chain.
Any suggestions as to a workaround? I considered using VBA to create a table from the query and then just referencing that table--I hate to make extra steps though.
The reason you get the error when you just try to open the recordset is that your form is not open and when you try to access [forms]![frmReportingMain] it's null then you try to get a property on that null reference and things blow up. The OpenRecordset function has no way of poping up a dialog box to prompt for user inputs like the UI does if it gets this error.
You can change your query to use parameters that are not bound to a form
yourTableAllocStart >= pAllocStart
and yourTableAllocEnd <= pAllocEnd
Then you can use this function to get the recordset of that query.
Function GetQryAllocDebits(pAllocStart As String, pAllocEnd As String) As DAO.Recordset
Dim db As DAO.Database
Dim qdef As DAO.QueryDef
Set db = CurrentDb
Set qdef = db.QueryDefs("qryAlloc_Debits")
qdef.Parameters.Refresh
qdef.Parameters("pAllocStart").Value = pAllocStart
qdef.Parameters("pAllocEnd").Value = pAllocEnd
Set GetQryAllocDebits = qdef.OpenRecordset
End Function
The disadvantage to this is that when you call this now on a form that is bound to it it doesn't dynamically 'fill in the blanks' for you.
In that case you can bind forms qryAlloc_debts and have no where clause on the saved query, then use the forms Filter to make your where clause. In that instance you can use your where clause exactly how you have it written.
Then if you want to still open a recordset you can do it like this
Function GetQryAllocDebits(pAllocStart As String, pAllocEnd As String) As DAO.Recordset
Dim qdef As DAO.QueryDef
Set qdef = New DAO.QueryDef
qdef.SQL = "Select * from qryAlloc_Debits where AllocStart >= pAllocStart and pAllocEnd <= pAllocEnd"
qdef.Parameters.Refresh
qdef.Parameters("pAllocStart").Value = pAllocStart
qdef.Parameters("pAllocEnd").Value = pAllocEnd
Set GetQryAllocDebits = qdef.OpenRecordset
End Function
While a [Forms]!... reference does default to a form reference when a QueryDef is run from the GUI, it is actually just another Parameter in the query in VBA. The upshot is you don't have to recode your query/create a new one at all. Also, as #Brad mentioned, whether a parameter is in the final query of a chain of queries or not, you are able to refer to the parameter as if it is in the collection of the final query. That being the case, you should be able to use code similar to this:
Sub GetQryAllocDebits(dteAllocStart As Date, dteAllocEnd as Date)
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
Set db = CurrentDb()
Set qdf = db.QueryDefs("qryAlloc_Debit")
If CurrentProject.AllForms("frmReportingMain").IsLoaded Then
qdf.Parameters("[forms]![frmReportingMain]![txtAllocStart]") = [forms]![frmReportingMain]![txtAllocStart]
qdf.Parameters("[forms]![frmReportingMain]![txtAllocEnd]") = [forms]![frmReportingMain]![txtAllocEnd]
Else
qdf.Parameters("[forms]![frmReportingMain]![txtAllocStart]") = CStr(dteAllocStart)
qdf.Parameters("[forms]![frmReportingMain]![txtAllocEnd]") = CStr(dteAllocEnd)
End If
Set rst = qdf.OpenRecordset
Do Until rst.EOF
'...do stuff here.
Loop
Set rst = Nothing
Set qdf = Nothing
Set db = Nothing
End Function
If the referenced form is open, the code is smart enough to use the referenced controls on the form. If not, it will use the dates supplied to the subroutine as parameters. A gotcha here is that the parameters did not like when I set them as date types (#xx/xx/xx#), even if the field were dates. It only seemed to work properly if I set the params as strings. It didn't seem to be an issue when pulling the values straight out of the controls on the forms, though.
I know it's been a while since this was posted, but I'd like to throw in my tuppence worth as I'm always searching this problem:
A stored query can be resolved:
Set db = CurrentDb
Set qdf = db.QueryDefs(sQueryName)
For Each prm In qdf.Parameters
prm.Value = Eval(prm.Name)
Next prm
Set rst = qdf.OpenRecordset
For SQL:
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", "SELECT * FROM MyTable " & _
"WHERE ID = " & Me.lstID & _
" AND dWeekCommencing = " & CDbl(Me.frm_SomeForm.Controls("txtWkCommencing")) & _
" AND DB_Status = 'Used'")
For Each prm In qdf.Parameters
prm.Value = Eval(prm.Name)
Next prm
Set rst = qdf.OpenRecordset
This assumes that all parameter values are accessible - i.e. forms are open and controls have values.
'I have two parameters in my recordset and I was getting the "Too few parameters. Expected 2" 'error when using an OpenRecordset in MS Access vba, and this is how I got around it and IT WORKS! see the below sub routine:
'Private Sub DisplayID_Click()
'1. I created variables for my two parameter fields xEventID and xExID as seen below:
Dim db As Database
Dim rst As Recordset
Dim xEventID As Integer
Dim xExId As Integer
'2. Sets the variables to the parameter fields as seen below:
Set db = CurrentDb
xEventID = Forms!frmExhibitorEntry!txtEventID
xExId = Forms!frmExhibitorEntry!subExhibitors!ExID
'3. Set the rst to OpenRecordSet and assign the Set the variables to the WHERE clause. Be sure to include all quotations, ampersand, and spaces exactly the way it is displayed. Otherwise the code will break!exactly as it is seen below:
Set rst = db.OpenRecordset("SELECT tblInfo_Exhibitor.EventID,tblInfo_Display.ExID, tblMstr_DisplayItems.Display " _
& "FROM tblInfo_Exhibitor INNER JOIN (tblMstr_DisplayItems INNER JOIN tblInfo_Display ON tblMstr_DisplayItems.DisplayID = tblInfo_Display.DisplayID) ON tblInfo_Exhibitor.ExID = tblInfo_Display.ExID " _
& "WHERE (((tblInfo_Exhibitor.EventID) =" & xEventID & " ) and ((tblInfo_Exhibitor.ExID) =" & xExId & " ));")
rst.Close
Set rst = Nothing
db.Close
'End Sub

Sorting a datatable

I have an asp.net listbox on my page, that I want to sort.
E.g: listbox(lstChooseFields)
MY VB code:
Private Sub LoadColumns()
If drpScreen.SelectedIndex > -1 Then
Dim daLookup As New LookupTableAdapters.LookupTableAdapter
Dim dtLookup As New System.Data.DataTable
dtLookup = daLookup.GetNestedControlValues("EM", "ExcelExport.aspx", "drpScreen", "drpScreen", drpScreen.SelectedValue)
lstChooseFields.DataSource = dtLookup
lstChooseFields.DataValueField = "LKP_ControlValue"
lstChooseFields.DataTextField = "LKP_ControlText"
lstChooseFields.DataBind()
'Dispose
daLookup.Dispose()
End If
End Sub
I have done some searching and found something like 'dtLookup.DefaultView.Sort = "LKP_ControlText" that I can use but it does not work. I don't want to sort in my database only on this page, this listbox (lstChooseFields).
So if you want to sort for the datatable then you have tried dtLookup.DefaultView.Sort = "LKP_ControlText" but you have missed out one piece of word there dtLookup.DefaultView.Sort = "LKP_ControlText asc". This generally works if LKP_ControlText is a column name in the datatable
You must use the word ascthere. which i couldnt find in your question.
After getting the dataTable sorted you can copy the same structure to another datatable if u want by using
Dim dtDuplicateLookup As New DataTable()
dtDuplicateLookup = dtLookup.DefaultView.ToTable(True)
and then access dtDuplicateLookup for further use if you want to retain the previous datatable as it is.
Use the .sorted property for the list box as shown here.
lstChooseFields.Sorted = True
UPDATE: your method was right but just tune it this way. I think you missed the DESC part. The second expression tells it how to sort the dataview.
Dim dataView As New DataView(table)
dataView.Sort = " column_name DESC" //DESC or ASC as per requirement
Dim dataTable AS DataTable = dataView.ToTable()
Else try this. After sorting a defaultview, generally you have to loopback through it
foreach(DataRowView r in table.DefaultView)
{
//... here you get the rows in sorted order
//insert the listbox items one by one here using listbox.add or listbox.insert commands
}

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.)

Resources