I have a form that has the 'data entry' property set to yes. It is bound to a table. When I start filling in the form it automatically saves it. I do not want this to happen. I only want the form to save to the table when I press a button. Any easy way to do this? w/o vba. If i can only do this with vba let me know how to do it that what.
The best way to do this is with an unbound form. When the user clicks save, you can run a query to update your table from the controls.
Using a recordset
Dim rs As Recordset
Set rs=CurrentDB.Openrecordset("MyTable")
rs.AddNew
rs!Field1 = Me.Field1
rs.Update
If you wanted to update a record where you already knew the primary key, you could say:
Dim rs As Recordset
Set rs=CurrentDB.Openrecordset("SELECT * FROM MyTable WHERE ID=" & Me.txtID)
rs.Edit
rs!Field1 = Me.Field1
rs.Update
Using a query that you have created in the query design window
SQL for the query
INSERT INTO MyTable (Field1)
VALUES ( Forms!MyForm!Field1 )
VBA
This will give a warning
DoCmd.OpenQuery "MyQuery"
This will not
CurrentDb.Execute "Query2", dbFailOnError
You could also use dynamic SQL or a query with parameters that you assign in code.
Related
Situation:
I have a pre-built form that uses two Form Views. One is for pickup and one for delivery. The form can't be changed due to client requirements. The entire form and Form Views use a WizardStep process.
Each side pre-fills in the clients company name and related data such as Pickup Name, address, city, state etc as well as Delivery Info all using the same fields using the same stored procedure.
The stored procedure shows the concat of Name and Address 1 as FullName and the ClientSubCtr. ClientSubCtr is an int field. This id is what populates the correct data to each dropdown.
The dropdown list is not inside the FormView and falls under the form tag.
When testing the connection via the <asp:SqlDataSource> tag everything works in the Configure Data Source and data is returned using the appropriate parameter. The connection for the matching client data uses a basic Select to the table used in the stored procedure. I've tried to use a different stored procedure for the data, but no success there either. I am using SQL Server Express right now locally.
I've tried disabling the asp:SqlDataSource and just use a database connection from page_load, which did not work. I've commented it out as I'm still trying different things. I may be missing some syntax to connect to the dropdown here.
'This did not work
'Using conn As New SqlConnection(connect)
' strSQL = "SELECT ClientSubCtr,CONCAT(Name,Address1) AS FullName 'FROM tblClientsSub"
' strSQL = strSQL & " WHERE Account ='" & sessAccount & "'"
' strSQL = strSQL & " ORDER BY FullName ASC"
' conn.Open()
' Using cmd As New SqlCommand(strSQL, conn)
' cmd.Parameters.AddWithValue("#Account", sessAccount)
' cmd.CommandText = strSQL
' cmd.ExecuteNonQuery()
' Dim dr As SqlDataReader = cmd.ExecuteReader()
' If dr.HasRows Then
' Do While (dr.Read())
' ClientSubCtr = dr.GetValue(0)
' FullName = dr.GetValue(1)
' s1_cboAcct.DataTextField = FullName
' s1_cboAcct.DataValueField = ClientSubCtr
' s1_cboAcct.DataBind()
'Corrected Databind still does not work
' Loop
' Else
' dr.Close()
' End If
' End Using
'End Using
Additional info: Prior to using this I have two Pre-Render functions. One for Pickup and Delivery which fills in what my client calls a Docket. It shows the info that was pre-filled in with the initial loading or by the Selected Change on the dropdown and or where the client manually added or changed something, thus sending the correct information to the database for eventual download.
Note: This was originally written making OLEDB ACE connections to my clients Go Daddy account. Go Daddy moved the site to a new server and will no longer support ACE 12.0. We begged for them to change this. Thus, the move to SQL Server.
When I get what I believe is the data getting load I get an error in my pre-render on this tag. I've purposely commented out all the pre-render to see what was returned in regards to errors. No errors are return and the general form returns showing the drop-down but no data and the field in the FormView can't be seen. In other words not even the labels are showing. I've checked all asp:sqldatasource settings.
' If IsNothing("txtcboAcct.Text") Then
'lblDocketPUName.Text = ""
(I've tried using Request.form here, but data isn't loaded so I get nothing.) and commented out the If Else End If
' Else
' lblDocketPUName.Text = CType(frmViewPUClient.FindControl("txtcboAcct"), TextBox).Text
(This is where I get an error where the object is not found because neither the data for the dropdown is loading or the data for the forms.)
' End If
I know this is a lot to digest, but I'm totally baffled why this works perfectly using OLEDB and Access 2007 but when switching to SQL Server and the exact tables named the same, it does not. Any insight to why the stored procedure won't fill in the dropdown or why even my code in page_load wouldn't fill in the drop-down would be helpful. I've updated all parameters to use the # symbol.
Here is the stored procedure:
'ALTER PROCEDURE [dbo].[qryFullNameAddr]
'#Account nvarchar(10) OUTPUT
'AS
' -- Add the parameters for the stored procedure here
'DECLARE #ClientSubCtr int
'DECLARE #Name nvarchar(50)
'DECLARE #Address1 nvarchar(125)
'DECLARE #FullName nvarchar(255)
'BEGIN
' -- SET NOCOUNT ON added to prevent extra result sets from
' -- interfering with SELECT statements.
' SET NOCOUNT ON;
' /*Write statements for procedure here */
'SELECT ClientSubCtr,CONCAT(Name,Address1) AS FullName
'FROM tblClientsSub
'WHERE #Account=#Account
'ORDER BY FULLNAME, ADDRESS1 ASC
'end
Well, first I would back the truck up so to speak.
I would create a blank new test web page. Put in a dropdown list, and get it working.
Next up:
You don't need to loop for a drop down list. You can feed a dropdown a TABLE. And that table can be a query, or perhaps a stored procedure.
So, for starters, lets display a Hotel List in a drop down. And like most drop downs, there are often two columns the hidden "id" or often "PK" of the row, and then the display text.
So, our blank we page, we drop in a drop down list. Say like this:
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="DropDownList1" runat="server"
DataTextField="HotelName"
DataValueField="ID" Height="22px" Width="219px">
</asp:DropDownList>
</div>
</form>
And now the code to fill - and as noted ALWAYS ALWAYS load only on first page load - that is PostBack = false - (break that rule, and you can't really even make a correctly working web page).
Ok, so our code is now this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData
End If
End Sub
Sub LoadData()
Using con As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String = "SELECT ID, HotelName from tblHotels ORDER BY HotelName"
Using cmdSQL As SqlCommand = New SqlCommand(strSQL, con)
con.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
DropDownList1.DataSource = rstData
DropDownList1.DataBind()
DropDownList1.Items.Insert(0, New ListItem("", "")) ' optional blank starting select
End Using
End Using
End Sub
That's it!!!
Also, don't know why so many code examples set the DataTextField and DataValue field in code? Why???? Just use the property sheet - little need to put such things in the code side - ESPECIALLY when the property sheet can do that for you!!!
Next up? Well, everyone always on SO piles in about how you should use parameters in such code in place of concatemer strings. This is correct, but if you code with parameters, then you can OFTEN reduce code, and CLEAN UP your sql anyway.
In place of say a messy sql string, you remove the text ('quotes'), and numbers (no quotes), and this even works better for dates.
So this benefit is near as great as the issue of sql injection issues.
(and to be fair, you noted a stored procedure, and it not working, so clearly you decided to try anything here - I get that approach).
So, your code snip? I would code it this way:
Dim strSQL As String =
"SELECT ClientSubCtr,CONCAT(Name, Address1) AS FullName FROM tblClientsSub " &
"WHERE Account = #Acc " &
"ORDER BY FullName ASC"
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(strSQL, conn)
cmdSQL.Parameters.Add("#Acc", SqlDbType.NVarChar).Value = sessAccount
conn.Open()
s1_cboAcct.DataSource = cmdSQL.ExecuteReader
s1_cboAcct.DataBind()
End Using
End Using
Now is that not MUCH more readable?
And in fact cut + paste your code?
I noticed this:
SELECT ClientSubCtr,CONCAT(Name,Address1) AS FullName 'FROM
Wait? what is the ' right before the FROM???? You have a stray ', don't you?
Maybe that was a code cut + paste error, maybe not. But the REAL POINT?
By using parmaters we go nuclear on the single, double quotes, and all that jazz.
in other words, sure, avoiding string concntatiion of values is important for reasons of sql injection, but REALLY MUCH more valuable is how we don't have to bother with all those quotes and stuff. The result is it is MUCH HARDER to miss or mess up!!!
The other issue of course is by using the parameters as per above?
Well, we get intel-sense. And if I have several more, then in VS I just hit ctrl-d to dupplie the line. I actually wind up TYPING LESS code then If I attempted to introduce those values right into the sql!!! Imagine that - eaiser to read, and even less typing of code!!! - all this amounts up to much less error prone code. I mean, one missing quote like ' or a extra one? You in trouble and will waste time!!
You ALSO note that I did not even use a reader into a DataTable, and just shoved the reader results RIGHT into the combo box - saves even more code!!!!
However, while a dropdown, listview, gridview (and many more) can ALL accept DataSource as a cmdSQL.ExecuteReader as I did?
I still STRONG recommend you use my first version for Grids/list views etc. (and a HUGE reason exists for this!!!). (data pagers don't work if you feed a gridview a reader, but a table they work fine, and also the data bind events (not often used for combo box, but VERY often used for grids often needs the data source - so for this combo? Sure you can skimp out on the two extra lines of code (to create a DataTable and load it). But for a gridview, don't use that cool short cut I used above by feeding the reader directly into grids or listviews - but for combos, perfect fine.
So, with above, and after running above code, we have this:
As noted, if you DO test or decide to load up a combo box, and NOT use say a DataSoruce control dropped into the markup (I don't like those things all that much), then MAKE SURE you put and ONLY call the loading of such controls inside the If Not IsPostBack code stub. DO NOT EVER fail to follow this rule.
Again: do NOT EVER EVER fail to follow this rule.
Why?
Becuase any other button or any other thing you EVER will place on that page may well need to do a post-back (say even a few simple buttons). So, if you say select a combo box, fill out some other things, and have some button (and a button click event with code behind)?
Wel, keep in mind that page load ALWAYS FIRES each post-back!!!!
So, if your code re-loads say the combo box, then it going to blow out any existing selecting the user has for that combo (or grid or just about anything else!!!). So, you have to write your code in a way that it will "assume" and "work" and "survive" post-backs. So your loading up of controls thus should only be ONE time, and on the first page load - hence my HUGE LONG narrative of how vast important it is to follow this simple rule.
I need a combo box that can be bound to a table and accept a new entry without inserting that new entry into the table until all of the other fields in the record is ready to be inserted. I tried using code where you use a SQL Insert statement however when I want to save the rest of the data on the form to a table the rest of the data is showing up on a new record. So I have one record with nothing but the project name and another record with everything else.
I have also tried this:
Append2Table = acDataErrContinue
vField = cbo.ControlSource
If Not (IsNull(vField) Or IsNull(NewData)) Then
sMsg = "Do you wish to add the entry " & NewData & " for " & cbo.Name & "?"
If MsgBox(sMsg, vbOKCancel + vbQuestion, "Add new value?") = vbOK Then
Set rst = CurrentDb.OpenRecordset(cbo.RowSource)
rst.AddNew
rst(vField) = NewData
rst.Update
rst.Close
Append2Table = acDataErrAdded
End If
End If
I don't want to use edit because I will have a lot of records with the same project name and when I used the insert statement to add the project name I don't know anyway to have it return the ID field so that I could search for that and edit the record with the rest of the information.
Thank you in advance for any suggestions.
What you want to do is to add the lookup item only if it is going to be used, hence the waiting for the insert.
I don't see how this is possible, because you are going to need the ID of the lookup value in order to do the insert.
I don't recommend doing the insert by hand, it is messy, let Access do it for you.
I think the best idea in this case is to let the user enter the lookup item and have some cleanup mechanism when the form closes to remove any unused items from the lookup table.
So, you have a recordset created like this:
Set rs = Server.CreateObject("ADODB.Recordset")
And you fill it like this:
rs.Open queryString, AuthConn, adOpenKeyset, adLockReadOnly
My question is, I want a second recordset that is a subset of the first (rs) recordset, can you do this in classic asp
Set rs2 = Server.CreateObject("ADODB.Recordset")
My immediate guess is that it would be something like this
rs2.Open queryString, rs, adOpenKeyset, adLockReadOnly
Why you ask? Well we have an older site that we are updating and adding new features too and rather than change a LOT of code I was wondering if I could be sneaky and use a setset of an already created (large) recordset, to save on another query to the db etc. Just wondering if it can be done.
Thanks,
You can use the Clone method to create a duplicate recordset, then use Filter to reduce the dataset to what you're interested in. For example:
Dim rs, rs2
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open queryString, AuthConn, adOpenKeyset, adLockReadOnly
Set rs2 = rs.Clone()
rs2.Filter = "Field1 = 'foo'"
The string form of Filter is basic; it's pretty much <Field> <op> <value>. You can combine multiple expressions using AND and OR, but even that has some limitations (see the documentation link for the full details).
For more complex filtering, you can pass the Filter property an array of Bookmark objects. In this case, you loop through the recordset (or a clone of the recordset), testing each record by whatever complex criteria you have. If the record passes the test, you save its Bookmark to an array or other collection. Then, you can set the Filter property to your array of Bookmarks and you have a custom-filtered recordset.
'Note that I haven't tested this code
Dim rs, rs2, bookmarks
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open queryString, AuthConn, adOpenKeyset, adLockReadOnly
Set rs2 = rs.Clone()
bookmarks = Array()
Do Until rs2.EOF
If rs2("Field1") = 2 * rs2("Field2") Then
ReDim Preserve bookmarks(UBound(bookmarks) + 1)
bookmarks(UBound(bookmarks)) = rs2.Bookmark
End If
rs2.MoveNext
Loop
rs2.Filter = bookmarks
' Now rs2 contains only records where Field1 = 2*Field2
You can use this same technique to get unique values (aka DISTINCT) by using a Dictionary object to store the unique key values. Doing a DISTINCT on multiple fields is a bit trickier. What I've done is the past is to combine the multiple fields using a separator that won't be in the data (such as a pipe |). That's not always possible, though.
The recordset object can be opened only by a "connection" object, you cannot replace the connection object with another recordset object as shown above, however if you modify the querystring object and open the desired subset through your own query you can achieve this.
Please post querystring if you have difficulty making the subset.
Obviously you can create a second query and recordset and run it over and over again inside "do while not rs.eof............loop" - I'm guessing that's what you want to avoid.
You might want to take a look at Datashaping. There's an article about it here. It's old, but then this is Classic ASP
https://web.archive.org/web/20210513001641/https://www.4guysfromrolla.com/webtech/092599-1.shtml
There also used to be a page on MSDN called "Using Data Shape to create hierarchical recordsets". You'll find loads of links to it on Google but they all take you to a 404 page on a resource for .net developers now :(
i hv a code that need me to find only a single line of recordset from the database into the variable.
dim Connect,conn_,data,sql
Set Connect = Server.CreateObject("ADODB.Connection")
Connect.Open "toServer"
sql = "SELECT * from sppro where proj_name='pname'"
set Data = Connect.Execute(sql)
response.write data("proj_id")
i just cant find to correct way to retrieve and view single record set... i found something about cursor, but i dont understand it at all...
can anyone pls explain to me?
edit:
error tht i got with this code is as below.
ADODB.Field error '80020009'
Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.
/bkpi-msn/Include/ServerSideAjax.asp, line 0
If I understand correctly you already know how to display one record from a database, but now you want to display more than one record. Is that right?
With some changes to your code, you can loop though all records:
dim Connect,conn_,data,sql
Set Connect = Server.CreateObject("ADODB.Connection")
Connect.Open "toServer"
sql = "SELECT * from sppro where proj_name='pname'"
set Data = Connect.Execute(sql)
Do Until Data.Eof
response.write data("proj_id")
Data.MoveNext
Loop
Edit: to retrieve just one row, you can use the following. It's basically the same, except there is a check to ensure there is at least one record, and no need to loop through the recordset.
dim Connect,conn_,data,sql
Set Connect = Server.CreateObject("ADODB.Connection")
Connect.Open "toServer"
sql = "SELECT * from sppro where proj_name='pname'"
set Data = Connect.Execute(sql)
If Not Data.Eof Then
response.write data("proj_id")
End If
My database tables list in dropdownlist...when i select table from dropdown table display in GridView. I want to edit,delete & insert dynamically in GridView. Please give me solution....
Check out these links:
http://geekswithblogs.net/dotNETvinz/archive/2009/02/22/gridview-insert-edit-update-and-delete--the-ado.net-way.aspx
http://msdn.microsoft.com/en-us/library/aa479339.aspx
Say you have three database tables, Customer, Orders and Products - do you mean the names of these tables appear in your dropdownlist?
If so, when a table name is selected in the dropdownlist (and perhaps an 'Edit' button is clicked), you'll need to bind your GridView to the selected table's data.
You could do this with inline SQL - build it from the DDL:
string _selectString = "SELECT * FROM " + ddlTables.SelectedValue ; //Remember to include the schema in the dropdownlist's value property
And then use this SQL to fetch back the data and bind your grid to it.
A better way would be to wrap up the SQL in a stored procedure that uses SQL Server's INFORMATION_SCHEMA schema (which holds all the database's objects)
CREATE PROCEDURE MySchema.GetTableData
#TableName VARCHAR(Max),
#SchemaName VARCHAR(MAX) --Pass in the relevant Schema
AS
BEGIN
SET NOCOUNT ON
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = #TableName
AND TABLE_SCHEMA = #SchemaName
END
and get the data out this way. The only difference to the way you're probably already doing this is to set the SQLCommand's CommandType property to CommandType.StoredProcedure and to pass in the tablename and schema name as SQLParameters.
More information about ASP.Net and Stored Procedures:
http://www.c-sharpcorner.com/UploadFile/gtomar/storedprocedure12052007003126AM/storedprocedure.aspx
Once you've got the data from the table you just use the code & process linked to by #Brian.
hth.