Go to new record on a form without adding data to the table

G

Guest

I have a form with multiple text boxes and 3 command buttons at the bottom:
Add Record to Table, Create Report, and Enter Next Record. I want the user
to click on these buttons in that order. When the last button is clicked,
I'd like the form to be cleared of previous input so the user can enter the
data for the next record but I don't want the button to add the previous
record's data to the table because that was already accomplished when they
clicked on the Add Record to Table button.

I want the user to click on these buttons in this order because I can't get
a report to be produced with the most recently entered data until the user
has the data put into the table. Maybe I'm missing the big picture here and
there's a really simple way to do this with only 2 buttons instead of 3.
Maybe there's a way to generate a report with the most recently entered data
even though it's not added to the table yet. Any suggestions?
 
J

Jeff Boyce

Sue

I suppose one possibility would be to do away with the "Create a Report"
command button. You can add code to your <Save> command button, after the
"save" code, in which you open a report, perhaps something like:

DoCmd OpenReport "YourReportName",,,,,,,,,,,,,RecordID =
Me!YourRecordIDControlName
(note that you'll need to look up the syntax for the OpenReport command to
get the correct number of commas)

Regards

Jeff Boyce
Microsoft Office/Access MVP
 
A

Arvin Meyer [MVP]

Put this (aircode) in a button event:

Public Sub cmdClearForm_Click()
On Error Resume Next
Dim ctl As Control

For Each ctl In Me.Controls

ctl.Value = ""

Next ctl

Set ctl = Nothing

End Sub

It can only be used AFTER the data has been saved. This assumes that you are
using unbound forms. If you are using bound forms, the default, the record
is automatically saved when you go to a new record.
 
G

Guest

(note that you'll need to look up the syntax for the OpenReport command to
get the correct number of commas)

Or, better yet, use named arguments. In my opinion, this makes your code a
lot more readable. Here is an example for a numeric RecordID:

DoCmd OpenReport "YourReportName", _
WhereCondition:="[RecordID] = " & Me!YourRecordIDControlName


Tom Wickerath
Microsoft Access MVP

http://www.access.qbuilt.com/html/expert_contributors.html
http://www.access.qbuilt.com/html/search.html
__________________________________________
 
J

Jeff Boyce

oooh! Good Idea!

Then I don't have to count commas any more!

Thanks, Tom.

Jeff Boyce

Tom Wickerath said:
(note that you'll need to look up the syntax for the OpenReport command
to
get the correct number of commas)

Or, better yet, use named arguments. In my opinion, this makes your code a
lot more readable. Here is an example for a numeric RecordID:

DoCmd OpenReport "YourReportName", _
WhereCondition:="[RecordID] = " & Me!YourRecordIDControlName


Tom Wickerath
Microsoft Access MVP

http://www.access.qbuilt.com/html/expert_contributors.html
http://www.access.qbuilt.com/html/search.html
__________________________________________

Jeff Boyce said:
Sue

I suppose one possibility would be to do away with the "Create a Report"
command button. You can add code to your <Save> command button, after
the
"save" code, in which you open a report, perhaps something like:

DoCmd OpenReport "YourReportName",,,,,,,,,,,,,RecordID =
Me!YourRecordIDControlName
(note that you'll need to look up the syntax for the OpenReport command
to
get the correct number of commas)

Regards

Jeff Boyce
Microsoft Office/Access MVP
 
G

Guest

Hi, Jeff, Tom, and Arvin.

Sorry I didn't respond sooner. I was out of town for a week.

Arvin, I thought my form was bound because it populates a table with the
user's input on the form. Your code works in my form though so it must be an
unbound form. What does aircode mean? Thanks sooo much!!
 
G

Guest

Hi Sue,

An unbound form will not have anything specified for the Record Source
property. In addition, text box, combo box and list box controls will
indicate "Unbound" when you open the form in design view. If you see a field
name displayed for these controls, then the controls are bound, and so is the
form. To view the form properties, press the F4 button. Click on the small
black square in the upper left corner to select the form (as opposed to
having a control selected). You should see the word "Form" in the title bar
of the Properties dialog. Click on the Data tab of the Properties dialog. The
first entry reads Record Source. If there is no record source specified, then
you have an unbound form. Otherwise, your form is bound.

Aircode refers to code that has not been tested for your specific situation.
So, the author indicates that it should be close, but may not be *exactly*
what you need.


Tom Wickerath
Microsoft Access MVP
https://mvp.support.microsoft.com/profile/Tom
http://www.access.qbuilt.com/html/expert_contributors.html
__________________________________________
 
G

Guest

Thanks for the info, Tom.

My form must be bound because I have T000_Main for the Record Source of my
form. But the code Arvin gave me worked even though he said it would only
work on an unbound form. I hope I don't have a problem with it down the road
because of the fact that it is bound.
 
G

Guest

In that case, you should not need Arvin's code. You originally stated:
I have a form with multiple text boxes and 3 command buttons at the bottom:
Add Record to Table, Create Report, and Enter Next Record. I want the user
to click on these buttons in that order.

While you may tell a user to do things in a certain order, user's can be
like children and do exactly the opposite. You really shouldn't need three
command buttons. Just have one button that includes code to perform three
tasks: 1.) Save the record, 2.)Create the report for the record and 3.) Go to
a new record. Something like this for a command button named
"cmdSavePrintNew":

Option Compare Database
Option Explicit

Private Sub cmdSavePrintNew_Click()
On Error GoTo ProcError

' Save the record first
If Me.Dirty = True Then
Me.Dirty = False
End If

' Print report for record just added
DoCmd.OpenReport "YourReportName", View:=acViewNormal, _
WhereCondition:="[RecordID] = " & Me!YourRecordIDControlName

' Go to new record
DoCmd.GoToRecord Record:=acNewRec


ExitProc:
Exit Sub
ProcError:
MsgBox "Error " & Err.Number & ": " & Err.Description, _
vbCritical, "Error in procedure cmdSavePrintNew_Click..."
Resume ExitProc
End Sub


When you land on the new record, all controls should have their default
values.

There is a potentially disasterous situation running the code Arvin
suggested with a bound form. First, the code sets all controls to a zero
length string. This will cause a run-time error on any fields that are
numeric, including dates. It also requires that your text and memo data types
allow zero lenght strings (ZLS) as a user input. Access MVP Allen Browne
shows you in this page why the default ZLS setting may not be the best choice:

Problem properties
http://allenbrowne.com/bug-09.html

If the code to set all controls was run *before* advancing to a new record,
well then, you would have just wiped out the active record. So, yes, it is
potentially disasterous. Your form is most definately bound. I would remove
that code.


Tom Wickerath
Microsoft Access MVP
https://mvp.support.microsoft.com/profile/Tom
http://www.access.qbuilt.com/html/expert_contributors.html
__________________________________________
 
G

Guest

Wow, Tom! Thanks for the heads-up!

I will remove the code that Arvin gave me but I don't want the button on the
form to automatically generate a report every time the user is done entering
data on the form. I want that to be an optional thing (the user may or may
not want a report for every record they create). So I'll try your code
without the print report part and see if it will just save the record and get
a blank form to enter a new record.
--
Sue
Programmer/Data Analyst
Minnesota
 
G

Guest

I'm having a problem with the first 2 lines of code you gave me:

Option Compare Database
Option Explicit

Everytime someone gives me code to use with this type of coding at the top,
I get a compile error because it adds these lines to the bottom of the
previous method after the End Sub. So I put your code up at the top on my
Visual Basic Editor screen but now I'm getting compile errors for a lot of
other methods that used to work. Should I put the code in a new module
instead of the class objects' code?

Also, I can see how just having 2 buttons instead of 3 will create a
problem. The Create Report button generates a report with the LAST record's
data the user just entered. In order for this to work, the input needs to be
added to the table before the report is generated. That's why I had the Add
Record to Table button. If I change it to 2 buttons, when the user clicks on
the "Save and Get New" button, they'll go to a blank form to enter new data
but it won't seem intuitive to click on the Get Report button at this point
since there's no data entered on this new record yet. And if the user clicks
on Get Report before they click on "Save and Get New" button, they won't get
a report with the most recently entered data because the data hasn't been
enetered into the table yet. Do you understand? Here's the query for the
report's Record Source:

SELECT TOP 1 T000_Main.Process_ID_Num, T000_Main.Process_Name,
T000_Main.Process_Owner, T000_Main.Process_Type, T000_Main.Program_Type,
T000_Main.Description, T000_Main.Program_Names, T000_Main.Last_Updated,
T000_Main.Process_Keyword, T000_Main.Directory, T000_Main.Frequency,
T000_Main.DateCreated FROM T000_Main ORDER BY T000_Main.DateCreated DESC;

Currently, everytime the user clicks on the Add Record to Table button, the
record is date and time stamped so the report "knows" which record is the
most recently entered one to create a report for. I want the report to be
generated for all records in descending order. Any other suggestions?
 
J

John W. Vinson

Option Compare Database
Option Explicit

Everytime someone gives me code to use with this type of coding at the top,
I get a compile error because it adds these lines to the bottom of the
previous method after the End Sub. So I put your code up at the top on my
Visual Basic Editor screen but now I'm getting compile errors for a lot of
other methods that used to work. Should I put the code in a new module
instead of the class objects' code?

These lines should appear only once, at the beginning (before the first Sub or
Function line) of each module.

John W. Vinson [MVP]
 
G

Guest

Hi, John.

I need to clarify what is meant by a module. On my Visual Basic Editor
screen under the db1 file directory-like structure, I have 2 folder-like
structures: Microsoft Office Access Class Objects and Module. Microsoft
Office Access Class Objects contains 3 file-like structures:
Form_frmCalendar, Form_Switchboard, and Report_R000_Main. And Modules
contains 2 file-like structures: ajbCalendar and Class1. Are you suggesting
I create a new file-like structure and put the code that Tom gave me in
db1\Microsoft Office Access Class Objects or in db1\Modules?

Thanks!
--
Sue
Programmer/Data Analyst
Minnesota
 
J

John W. Vinson

I need to clarify what is meant by a module. On my Visual Basic Editor
screen under the db1 file directory-like structure, I have 2 folder-like
structures: Microsoft Office Access Class Objects and Module.

So... you're programming in Visual Basic 6.0??

All the advice you've been getting presumed that you were writing Microsoft
Access VBA code within an Access database.

Am I misunderstanding here?

John W. Vinson [MVP]
 
G

Guest

I clicked on the Help > About Microsoft Visual Basic menu and it says I have
Visual Basic 6.3. The db1 file directory-like structure I was talking about
is in a small window on the left-hand side of the screen. The title on this
small window is Project - db1. Yes, I'm writing Microsoft Access VBA code
within an Access database. Does that clear things up?
--
Sue
Programmer/Data Analyst
Minnesota
 
J

John W. Vinson

I clicked on the Help > About Microsoft Visual Basic menu and it says I have
Visual Basic 6.3. The db1 file directory-like structure I was talking about
is in a small window on the left-hand side of the screen. The title on this
small window is Project - db1. Yes, I'm writing Microsoft Access VBA code
within an Access database. Does that clear things up?
--

Yes. My apologies - I did jump to an unwarrented conclusion. You're using
Access VBA. I'll review the thread and see if I can make a more useful
suggestion!

John W. Vinson [MVP]
 
J

John W. Vinson

Hi, John.

I need to clarify what is meant by a module. On my Visual Basic Editor
screen under the db1 file directory-like structure, I have 2 folder-like
structures: Microsoft Office Access Class Objects and Module. Microsoft
Office Access Class Objects contains 3 file-like structures:
Form_frmCalendar, Form_Switchboard, and Report_R000_Main. And Modules
contains 2 file-like structures: ajbCalendar and Class1. Are you suggesting
I create a new file-like structure and put the code that Tom gave me in
db1\Microsoft Office Access Class Objects or in db1\Modules?

I'm actually suggesting that you CLOSE the VBA editor; view the Database
window (hit F11 if necessary); select the Modules tab; and click the New
button to create a new module. You can name it whatever you want (except that
the name of the module must be different from the name of any routine in that
module).

John W. Vinson [MVP]
 
G

Guest

Hi Sue,
I'm having a problem with the first 2 lines of code you gave me:

Option Compare Database
Option Explicit

As John has mentioned earlier, these two lines of code should appear only
once, at the top of each module. If you have not already configured your VBA
editor to automatically include Option Explicit as the second line of code in
all new modules, I highly suggest that you do so now. Here's why:

Always Use Option Explicit
http://www.access.qbuilt.com/html/gem_tips.html#VBEOptions

...but now I'm getting compile errors for a lot of other methods that
used to work.

This indicates that you are using variables that have not been declared, as
explained in the "gem tip" shown above. You should always declare the
variables that you use in VBA code.
Should I put the code in a new module instead of the class objects' code?

No. The code I provide goes in the form's class module for the applicable
form. As a matter of fact, one cannot use the Me keyword in VBA code that is
in a stand-alone module (ie. a module that is not associated with a form or a
report).
Also, I can see how just having 2 buttons instead of 3 will create a
problem. The Create Report button generates a report with the LAST record's
data the user just entered.

Not really. The code for creating the report generates a report for the
current record. It really has no relation to the last record entered.
In order for this to work, the input needs to be added to the table
before the report is generated.

Correct. The record, whether new or existing, must be in a saved state (ie.
Me.Dirty = False), in order for the report to reflect a change entered by the
user. That's why there is code just prior to opening the report that saves
the record first. It does not matter whether this is a new record, or an
existing record that you were editing.
... but it won't seem intuitive to click on the Get Report button at this
point since there's no data entered on this new record yet.

That's true. So, your print report button should could include the following
modification:

Option Compare Database
Option Explicit

Private Sub cmdPrintReport_Click()
On Error GoTo ProcError

' Save the record first if it has been edited
If Me.Dirty = True Then
Me.Dirty = False
End If

' Print report for current record
DoCmd.OpenReport "YourReportName", View:=acViewNormal, _
WhereCondition:="[RecordID] = " & Me!YourRecordIDControlName


ExitProc:
Exit Sub
ProcError:
MsgBox "Error " & Err.Number & ": " & Err.Description, _
vbCritical, "Error in procedure cmdPrintReport_Click..."
Resume ExitProc
End Sub

_________________________________

Here is an example that you can insert into the Customers form in the sample
Northwind database. You likely already have a copy of Northwind on your hard
drive. My recommendation is to do a search for this file (Northwind.mdb).
Once you find it, make a copy of the original and place it in your normal
working directory. That way, you leave a pristine copy of the original sample
available.

Option Compare Database
Option Explicit

Private Sub cmdPrintReport_Click()
On Error GoTo ProcError

' Save the record first if it has been edited
If Me.Dirty = True Then
Me.Dirty = False
End If

' Print report for current record
DoCmd.OpenReport "Customer Labels", View:=acViewPreview, _
WhereCondition:="[CustomerID] = '" & Me!CustomerID & "'"


ExitProc:
Exit Sub
ProcError:
MsgBox "Error " & Err.Number & ": " & Err.Description, _
vbCritical, "Error in procedure cmdPrintReport_Click..."
Resume ExitProc
End Sub


You might notice that I added a bit more to the WhereCondition statement in
this code, versus the code I had previously given you. Notice how I am
surrounding the Me!CustomerID with a pair of single quotes, one just after
the = sign, and one at the end, enclosed in double quotes. The reason this is
necessary is because the primary key, CustomerID, is text. If the primary key
was numeric, then the WhereCondition statement would be like this:

WhereCondition:="[CustomerID] = " & Me!CustomerID

Okay, so when you run this code in Northwind, you should see that it works
for whatever record is your current record. If you make a change to the
customer's address information, the report shows the latest change, because
the record was first saved. However, if you navigate to a new record, and
then attempt to click on the button, you will see the following:

#Error
#Error
#Error
#Error

There is one error for each line of the address info. The reason for this is
that VBA Trim function is being used in the Control Source of each text box
on the report. Trim generates an error when the underlying field is null. We
can fix that with a little bit of code added to the report. Open the report
in design view. Then click on View > Code to open a class module associated
with the report. (You should be seeing Option Explicit as your second line of
code by now). Copy the following code and paste it into this module:

Private Sub Report_NoData(Cancel As Integer)
On Error GoTo ProcError

MsgBox "There is no data for the selected criteria.", _
vbInformation, "No Data Available..."
Cancel = True

ExitProc:
Exit Sub
ProcError:
MsgBox "Error " & Err.Number & ": " & Err.Description, _
vbCritical, "Error in procedure Report_NoData..."
Resume ExitProc
End Sub


Now, when you click on the Print Report command button, you should see a
message box informing you that there is no data to print. However....were not
quite done yet. As soon as you click on the OK button of the message box, you
will see the following error:

Error 2501: The OpenReport action was canceled.

To handle this situation, we trap for error number 2501 and ignore it. We
can do this by adding a Select Case .... End Select construct into the error
handler, like this:


Option Compare Database
Option Explicit

Private Sub cmdPrintReport_Click()
On Error GoTo ProcError

' Save the record first if it has been edited
If Me.Dirty = True Then
Me.Dirty = False
End If

' Print report for current record
DoCmd.OpenReport "Customer Labels", View:=acViewPreview, _
WhereCondition:="[CustomerID] = '" & Me!CustomerID & "'"


ExitProc:
Exit Sub
ProcError:
Select Case Err.Number
Case 2501 'Report open cancelled
Case Else
MsgBox "Error " & Err.Number & ": " & Err.Description, _
vbCritical, "Error in cmdPrint_Click event procedure ..."
End Select
Resume ExitProc
End Sub
______________________________________

There is an alternate method of checking for no data without adding a code
module to each and every report. I'll let you investigate this method for
yourself:

Tip #45: Add NoData Event to Access Reports
http://www.fmsinc.com/free/NewTips/Access/accesstip45.asp

(See the downloadable demo associated with this tip).

Currently, everytime the user clicks on the Add Record to Table button, the
record is date and time stamped so the report "knows" which record is the
most recently entered one to create a report for. I want the report to be
generated for all records in descending order.

Are you saying that you want to print a report that includes *all* records,
whenever you click on your Print Report button? That's certainly possible,
but the code that I've been discussing is for printing only the current
record.


Tom Wickerath
Microsoft Access MVP
https://mvp.support.microsoft.com/profile/Tom
http://www.access.qbuilt.com/html/expert_contributors.html
__________________________________________
 
G

Guest

Thanks, Tom!! It'll take me a while to sift through all that you sent me so
I won't be able to respond right away. Plus, I need to set aside my Access
database for a while to work on something else. I want to respond now to a
few things though.
Not really. The code for creating the report generates a report for the
current record. It really has no relation to the last record entered.
Correct. The record, whether new or existing, must be in a saved state (ie.
Me.Dirty = False), in order for the report to reflect a change entered by the
user. That's why there is code just prior to opening the report that saves
the record first. It does not matter whether this is a new record, or an
existing record that you were editing.

The way that my databased was behaving in the past was that it would
generate several reports (one for each record) beginning with the first
record in the table. So the user couldn't see the most recently entered data
until they navigated to the last report. So maybe the problem was just that
I needed to have Me.Dirty = False.
Are you saying that you want to print a report that includes *all* records,
whenever you click on your Print Report button? That's certainly possible,
but the code that I've been discussing is for printing only the current
record.

No, I don't want 1 report that includes data from all records. I want
several reports (one for each record) to display in descending order of when
the record was entered into the table when I click on the Get Report button.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top