MS Access requery form after group delete - ms-access-2010

Access 2010 & Access backend.
I use a Delete query to delete a select group of items on a
continuous form.
The Delete query is in the form_delete event and
it works.
in the form_AfterDelConfirm event I have a me.requery command but the form is not requeried because in the form_delete I have Cancel = True which prevents the AfterDelConfirm event from firing. If i change the Cancel to False the AfterDelConfirm fires but the me.requery produces an error that the record is in use by another user (I am the only user).
The problem is that the continuous form displays #Deleted
in the deleted records of the deleted group items.
I also have a requery button that requeries the subform which clears the deleted items.
My goal is to have the deleted items clear without the user having to click the requery button.
How can I accomplish this?
Thanks,

Skip the delete query. Instead, delete directly from the form using its recordset in the code you call from the button click:
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
While Not rs.EOF
' Specify conditions for a delete, for example:
If rs!FieldA.Value = SomeNumber And rs!FieldB.Value = "SomeText" Then
rs.Delete
End If
rs.MoveNext
Wend
Set rs = Nothing
No requery of the form will be needed.

Related

PagedDataSource not working with previous/next pages

I'm having a hard time with this scenario and hoping someone can help me clarify where I'm missing a step/logic. I tried searching online but I couldn't find an example that addressed this issue.
We are setting up a search page that when first loads shows a bunch of options (e.g., textboxes, checkboxes, etc). The user will fill out the form and submit the form back to itself. Once posted back, the page will build and run a SQL query (e.g., SELECT ID FROM Customers WHERE Company = 'Acme' AND AmtDue = 3) against the database with the user's options and then the results will show up. This part works ok.
The part that breaks down is when I am trying to add pagination. The result set is a DataTable bound to a Repeater. I am using a PagedDataSource to add pagination. Pagination works great for the first page but for subsequent pages, it does not work. Basically, instead of returning the next page of the result requested (e.g., SELECT ID FROM Customers WHERE Company = 'Acme' AND AmtDue = 3), the results returned is the SQL query before appending the user's search options (e.g., SELECT ID FROM Customers).
I think my basic problem is that I'm not sure how to distinguish a normal Page.IsPostBack and paginating through results. The reason why this is causing problems is because I don't want to be regathering form data, rebuilding query, and requerying the DB.
The examples that I found online involved pagination of a DataTable that is rebuilt every time the page loads (e.g., Not Page.IsPostBack).
Here is a rough outline of our code:
Public dtCustomers As DataTable = New DataTable()
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load
' When the page first loads, show the search form with search options.
If Not Page.IsPostBack Then
ShowSearchForm()
' Once the form is submitted, show the search results.
Else
' ----------------------------------------
' This is the part that I'm having trouble with. How do I skip the following two steps (GatherFormData() and BuildDT()) when the user requests a subsequent page?
GatherFormData()
dtCustomers = BuildDT()
' ----------------------------------------
BindData()
End If
End Sub
Sub BindData()
Dim objPDS As PagedDataSource = New PagedDataSource()
objPDS.DataSource = dtCustomers.DefaultView
objPDS.AllowPaging = True
objPDS.PageSize = intNumPerPage
objPDS.CurrentPageIndex = Me.ViewState("_CurrentPage")
rptSearchResults.DataSource = objPDS
End Sub
' Subroutine called when the previous page button is pressed.
Sub GoToPrevPage()
' Set viewstate variable to the previous page.
Me.ViewState("_CurrentPage") -= 1
BindData()
End Sub
' Subroutine called when the next page button is pressed.
Sub GoToNextPage()
' Set viewstate variable to the next page.
Me.ViewState("_CurrentPage") += 1
BindData()
End Sub
Note: I understand that the DataTable will have to be put into cache or a session variable, but haven't decided the best method.
Please excuse the code outline but the actual code is massive so the simplification is to make it easier to get to the heart of the issue.
Let me know if any of that was unclear. Thanks in advance!
I am assuming that you are going to store your data in session/cache (I would prefer the later but there can be use case for storing it in session) - you can store the key in the view-state and presence of key could be use to determine if post-back is for pagination or not. For example,
if (ViewState["dataKey"] == null)
{
// first form submittal, do the search
GatherFormData();
dtCustomers = BuildDT();
// store it in cache
ViewState["dataKey"] = Guid.NewGuid().ToString(); // create a key
Cache.[ViewState["dataKey"].ToString()] = dtCustomers; // TODO use Add method to control expiration etc
}
Its important that you clear the view-state when the search is reset (or similar condition)
Lastly, it is also possible to do the paging from database/data-store (for example, using ranking functions in SQL Server) so that you need not have to store the search results into the session/cache but rather do a database trip at each post-back. Such approach is useful when the complete result set size can be huge.

Casting a control to another page

I have tried everything to no avail. I need to cast the value from a user selected dropdownlist to another dropdownlist on another page. The data in the textboxes are a series of numbers.
Also is there a way to display the value in the second dropdown list as well as other values? For example, my dropdown has the values 1-6, user selects 4, which displays first in the dropdown on page 2 but the other values also display in case they want to change there selection??
If Not Page.PreviousPage Is Nothing Then
Dim table As Control = PreviousPage.Controls(0).FindControl("table1")
Dim ddl As DropDownList = CType(table.FindControl("ddlB_Codes"),c DropDownList)
If Not ddl Is Nothing Then
ddl_OC.DataSource = ddl.SelectedValue.Substring(0, 6)
End If
End If
Quick update I FINALLY got my casting to work through a session, only now I need to know how to display the session values and the other additional values for my drop box in case the user wants to change something? Thanks for the help
ddl_OC.DataSource = CType(Session.Item("valCodes"), String)
ddl_OC.DataBind()
ddl_SO.DataSource = CType(Session.Item("valAccts"), String)
ddl_SO.DataBind()
Use event selectedvaluechanged to set datasource for another DropDownList, when first one is changed.
Don't forget to populate it vin DataBind function usage.

Reading a DataSet in JavaScript

' USED TO REFRESH THE PAGE WHIN IT IS POSTED BACK
If (IsPostBack = False) Then
' USED TO DISPLAY DEFAULT FIRST ITEM IN THE DROPDOWN
Dim Li1 As New ListItem()
Li1.Text = "ALL"
Li1.Value = ""
cboStudy.Items.Add(Li1)
' USED TO COUNT THE STUDIES IN THE DROPDOWN
If (objDS.Tables(0).Rows.Count <> 0) Then
' USED TO CIRCULATE LOOP UPTO THE RECORD COUNT
Dim i As Integer
For i = 0 To objDS.Tables(0).Rows.Count - 1
' USED TO CREATE NEW ITEM IN THE DROPDOWN
Dim Li As New ListItem
Li.Text = objDS.Tables(0).Rows(i)("Study_Desc").ToString()
Li.Value = objDS.Tables(0).Rows(i)("Study_ID").ToString()
'USED TO ADD ITEMS IN THE DROPDOWN
cboStudy.Items.Add(Li)
Next
End If
'USED TO SAVE THE CHANGES IN DATASET
objDS.AcceptChanges()
' USED TO CLOSE THE DATABASE CONNECTION
objDS.Dispose()
End If
End If
I have to read dataset in javascript. So that I have to bind Study_Desc in DropDownList.
How can I do that?
I believe you might find it useful to review how an ASP.NET page works and how it renders. In your particular case you are setting the contents of a dropdownlist to your dataset. This will then render a 'select' object to the user with the appropriate entries without the need for Javascript. This all occurs on the server-side, which is processed on the server before a HTML response to given back to the user.
With Javascript, this code runs on the client-side, i.e. the user's computer. Here it is possible to retreive your dataset (by this, the dataset will get serialised to be passed over the wire and read into a format that Javascript can read) and have it interact on the client-side. The question is, in your case, is why bother as you're rendering the dropdown on the server-side. If you are interested in pushing your dataset to Javascript, check out the links on this post for a selection of approaches you can take.
Minor notes:
In your code you're using the 'AcceptChanges' method when there is absolutely no reason to use this unless you're making a change(s) to the dataset which I'm guessing you're not in the PageLoad...

when using datasource and databind to set items in a dropdownlist - index is always the value of first item

I am trying to use datasource and bind in my application to set a dropdown list to the results of a query. The dropdownlist populates correctly (shows each different type_name in the set) but later when I use ddltype.selectedvalue - I am always getting the value from the first item in the dataset. Here is the code.
if ds.hasRows = true
ddlType.DataValueField = "type_id"
ddlType.DataTextField = "type_name"
ddlType.DataSource = ds
ddlType.DataBind()
end if
Then later on I use the following code to try to get teh selected value
Dim typeID = ddlType.SelectedValue
I have ran the query to get the dataset on my SQL server and get the below results - but every time I use the above dim statement, the value is set to 812 even when type 2 is selected. Below is the results from the query that fills the sqldatareader named ds.
type_id : type_name
___________________
812 : type one
813 : type two
Thanks in advance.
Based on the information in your question, I don't see anything wrong.
But based on common mistakes people make with this pattern, I am guessing you are probably running ddlType.DataBind() on every postback. So the user clicks a button or something similar to fire the postback, and the DDL is re-bound before your click handler checks the value. Re-binding sets the selectedvalue back to default.
Edit: Your databinding code in Page_Load should only run once. One way to do this is to wrap the databinding code...
If Not IsPostBack Then
If ds.hasRows = True Then
ddlType.DataValueField = "type_id"
ddlType.DataTextField = "type_name"
ddlType.DataSource = ds
ddlType.DataBind()
End If
End If
This will cause the databinding to occur only the first time the page is requested, but not after a button click or other postback action.

Insert record with EmptyDataTemplate in asp:ListView

I have an EmptyDataTemplate in my asp:ListView which I want to use to insert a new record.
I have Inserting working in the InsertItemTemplate... I thought I could copy the InsertItemTemplate into the EmptyDataTemplate, on clicking Insert this gives the error
Insert can only be called on an insert item. Ensure only the InsertTemplate has a button with CommandName=Insert.
How can I use the EmptyDataTemplate to Insert a row? Do I need to use the OnClick of the button to access the values within the EmptyDataTemplate and do an Insert by myself?
I'm using LinqDataSource
You might have figured it by now
but if you set the InsertItemPosition to anything other than None the EmptyData Template will not be rendered i.e it will always show the insert template
you can read more here
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.emptydatatemplate.aspx
No way if want to insert data in empty data template.
It is possible to do an insert from the EmptyDataTemplate by handcrafting the insert. I am using a listview to display a static number of rows based on a unique filtered item. I am basically listing all the static attributes of an object. In the case where a new object is filtered on that does not have any attributes associated with it, i use the EmptyDataTemplate of the listview to display a HTMLTable that contains asp.net controls to capture data. I have a command button within the table that i evaluate using the ListView_ItemCommand. If the CommandName matches that of the "Insert" button within the EmptyDataItem, I use the ListView.Controls(0).FindControl method to locate my table. I then loop through my table and do inserts on the data found within each row. I included the how to find a control within the htmltable. In my code I am actually grabbing a bunch of controls then crafting the sql and using a SQLConnection to perform the insert.
Protected Sub ListView_ItemCommand(sender As Object, e As System.Web.UI.WebControls.ListViewCommandEventArgs) Handles ListView.ItemCommand
Select Case e.CommandName
Case "Submit"
Dim edt As HtmlTable = ListView.Controls(0).FindControl("myhtmltable")
Dim ddl As DropDownList = CType(edt.FindControl("mydropdownlist"), DropDownList)
'Perform Insert
Case "Some other commandname"
End Select
End Sub
You will need to still do error checking and databind() and refresh your listview.
Is this the best way. Maybe not... But it is possible.
~Ian

Resources