Touch Screen Interface

  • Thread starter Thread starter Stephen
  • Start date Start date
S

Stephen

Hi, All

I need to make an order form where users can click
multiple menu buttons on the same form to add up
customers' order.

The form should have a sub form, which displaces order
items. My question is how can I pass item value or id to
the sub form by clicking item buttons on the main order
form?

I've tried on-click event command on to pass item id to
the sub form table, but it didn't work well.

Please help me how to build a touch screen form.


Thank you.
 
Stephen said:
Hi, All

I need to make an order form where users can click
multiple menu buttons on the same form to add up
customers' order.

The form should have a sub form, which displaces order
items. My question is how can I pass item value or id to
the sub form by clicking item buttons on the main order
form?

I've tried on-click event command on to pass item id to
the sub form table, but it didn't work well.

Please help me how to build a touch screen form.

I almost didn't read this message, because I have no experience with
actual touch-screen applications. However, your design question isn't
really about the touch-screen technology at all, but just about the form
design. Let me see if I understand what you're asking.

As I understand it, you want to create an order form with a subform of
order details. On the main form, you want the user to be able to add
items to the order by clicking on item buttons -- each button, when
clicked, adds the associate item to the order, so a new line for that
item appears in the OrderDetails subform. Correct?

I can think of several ways to make this work, some more flexible than
others. A really flexible structure would have the buttons associated
with available items when the form opens, by reading the item ID values
and button captions from a table. It would be kind of like the Access
Switchboard and Switchboard Items table, as managed by the Switchboard
Manager. For now, though, I'll stick with a design in which the buttons
are defined to represent certain items at the time the form is designed.

Suppose you have tables Orders, Items, and OrderItems, and you have form
frmOrders for entering orders, with subform sfOrderItems to show the
items that have been ordered. The form frmOrders is based on table
Orders, while the subform is based on a query that joins OrderItems and
Items, like this:

SELECT
OrderItems.OrderItemID, OrderItems.OrderID,
OrderItems.ItemID, Items.ItemDescription
FROM Items INNER JOIN OrderItems
ON Items.ItemID = OrderItems.ItemID
ORDER BY OrderItems.OrderItemID;

Suppose further that you will have three items that can be ordered:
Cheeseburger, Fries, and Soft Drink. These are items 1, 2, and 3,
respectively. So you put three buttons on frmOrders: cmdCheeseburger,
cmdFries, and cmdSoftDrink. Set appropriate captions for these buttons,
and then -- this is the important part -- set the Tag property of each
to the ItemID of the item that it is supposed to represent. So button
cmdCheeseburger has its Tag property set 1, cmdFries to 2, and
cmdSoftDrink to 3.

Now add the following function to the form's code module, in the General
section:

'----- start of code -----
Function AddToOrder()

On Error GoTo Err_AddToOrder

Dim varItem As Variant

If IsNull(Me.OrderID) Then
MsgBox "Enter basic order information first."
Exit Function
End If

If Me.Dirty Then Me.Dirty = False

varItem = Me.ActiveControl.Tag

If IsNumeric(varItem) Then

CurrentDb.Execute _
"INSERT INTO OrderItems (OrderID, ItemID) " & _
"VALUES(" & Me.OrderID & ", " & varItem & ")", _
dbFailOnError

Me.sfOrderItems.Requery

End If

Exit_AddToOrder:
Exit Function

Err_AddToOrder:
If Err.Number = 3201 Then
MsgBox "Item " & varItem & " is not defined in the Items table."
Else
MsgBox Err.Description, vbExclamation, "Error " & Err.Number
End If
Resume Exit_AddToOrder

End Function
'----- end of code -----

Finally, select all three of the command buttons and bring up their
joint property sheet. On the Event tab of that sheet, on the On Click
line, enter this:

=AddToOrder()

From this point on, clicking one of those buttons should add the
associated item to the OrderDetails for that order, and the added item
should show up on the subform.
 
Dear Dirk.

Thank you so much for your awesome help.

You really taught me where should I begin, I will follow
your guideline.

Thank you, thank you, and more thank you.
 
Dear Dirk.

The code worked flawlessly, thank you.

However, I still have some problem of adding values like
Menu Quantity and preventing duplicated menu to the
subform (datasheet).

To add menu quantity to the subform, I changed your code
to following, but when I click number buttons with tag
property, it gives me error # 3201.

---------------------------------------------------------
Function Addquantity()

On Error GoTo Err_Addquantity

Dim varItem As Variant

If IsNull(Me.TicketId) Then
MsgBox "Select Ticket Type First."
Exit Function
End If

If Me.Dirty Then Me.Dirty = False

varItem = Me.ActiveControl.Tag

If IsNumeric(varItem) Then

CurrentDb.Execute _
"INSERT INTO tbl_ticketdetail (TicketId,
MenuQty) " & _
"VALUES(" & Me.TicketId & ", " & varItem
& ")", _
dbFailOnError

Me.sbf_frm_ticket.Requery

End If

End Function
--------------------------------------------------------

Another problem I have is that how can I prevent people
from entering duplicate menu to the subform? Moreover, is
there anyway to undo the ticket even after users entered
menu to the subform?


Thank you so much for your time.
 
Stephen said:
Dear Dirk.

The code worked flawlessly, thank you.

I'm glad to hear it.
However, I still have some problem of adding values like
Menu Quantity and preventing duplicated menu to the
subform (datasheet).

Yes, it occurred to me that you might want to extend the functionality a
bit. However, you're going to have to make up your mind -- and then
explain to me, if I am to help you -- how you want this order form to
work. That is, what buttons are going to be on it, and what you want to
have happen when you click on them. I'll also need to know the
definitions of the tables involved.
To add menu quantity to the subform, I changed your code
to following, but when I click number buttons with tag
property, it gives me error # 3201.

---------------------------------------------------------
Function Addquantity()

On Error GoTo Err_Addquantity

Dim varItem As Variant

If IsNull(Me.TicketId) Then
MsgBox "Select Ticket Type First."
Exit Function
End If

If Me.Dirty Then Me.Dirty = False

varItem = Me.ActiveControl.Tag

If IsNumeric(varItem) Then

CurrentDb.Execute _
"INSERT INTO tbl_ticketdetail (TicketId,
MenuQty) " & _
"VALUES(" & Me.TicketId & ", " & varItem
& ")", _
dbFailOnError

Me.sbf_frm_ticket.Requery

End If

End Function
--------------------------------------------------------

I don't see where you are providing the ItemID in the append query
you're executing. I gather that the "number buttons" have the quantity
for each button in its Tag property, but you still need to know which
item you're trying to add a quantity for. I believe you need to think
this through a bit more.
Another problem I have is that how can I prevent people
from entering duplicate menu to the subform? Moreover, is
there anyway to undo the ticket even after users entered
menu to the subform?

Regarding the first of these questions, it all depends on how you want
the form to work. In my quick example, I was satisfied with having the
user add the same item multiple times to represent ordering more than
one of that item. That's still a possible arrangement. An alternative
would be to have the code in the AddItem() function first check to see
if the item is already present in this order. If it isn't, a record is
added with a quantity of 1. If it is, the quantity in the existing
record is simply incremented by 1. So, instead of number buttons -- or
in addition to them -- you can just click the item button multiple
times.

Regarding the second question, "undoing the ticket", I'm not sure what
you have in mind: cancelling the entire order, removing a specific item
from the order, or removing all the items from the order. These are all
doable, but different code would be required to accomplish them. One
must also think about the user interface for all this. To remove items
from the order, I'd be inclined to have a command button on the
continuous subform, that would just delete the current subform record
when clicked. To delete an order, you can let an enforced relationship
with cascading deletes take care of removing the order items when you
delete the parent order record. To remove all items from the order
while retaining the order itself, you can execute a suitably framed
delete query against tbl_ticketdetail.
 
Dear Dirk.

I wish I could upload my mdb file to this news group, but
I hope the following gives you some idea of what I am
making.

There are four tables, tbl_menu, tbl_ticket,
tbl_ticketdetail, and tbl_tickettype.

Tbl_menu

MenuId(Autonumber)
MenuName(Text)
MenuPrice(Currency)

Tbl_ticket

TicketId(Autonumber)
TicketTime(Date/Time)
TicketType(Number)

Tbl_ticketdetail

TicketdetailId(Autonumber)
TicketId(Number) - Relation to TicketId in Tbl_ticket
MenuId(Number) - Relation to MenuId in Tbl_menu
MenuQty(Number)

Tbl_tickettype

TickettypeId(Autonumber) - Relation to TicketType in
Tbl_ticket
Tickettypename(Text)

There are two forms, frm_ticket and sbf_frm_ticket.

"Frm_ticket" is main form based on a query, qry_ticket,
with two tables, tbl_ticket and tbl_tickettype.

The subform, sbf_frm_ticket, is based on a query,
qry_ticketdetail, with two tables, tbl_ticketdetail and
tbl_menu.

The default views of the subform set to be datasheet view
with all columns are hide except MenuName, MenuQty, and
MenuPrice.

The main form, frm_ticket, has all fields from qry_ticket,
a subform, sbf_frm_ticket, and numerous command buttons
for entering menuId and menuQty.


Problems.


1. As far as entering menu, it works awesome as you
directed me with your code, but I can't enter menuQty
field value from then command buttons (Zero to nine on
main form).

2. I used following code to prevent duplicated menu to the
subform, but it lets user can enter only one menu per
ticket.

'Dim rs As DAO.Recordset
'Dim strSQL As String

'strSQL = "SELECT tbl_ticketdetail.MenuId FROM
tbl_ticketdetail WHERE ((tbl_ticketdetail.TicketId) = " &
Me.TicketId & ") "

'Set rs = CurrentDb.OpenRecordset(strSQL,
dbOpenSnapshot)

' If rs.RecordCount = 1 Then
' MsgBox "Duplicated Menu!"
' rs.Close
' Exit Function
' End If

'rs.Close

3. I need a "cancel" button to undo tickets made by
mistake while the subform is dirty with menu on the main
form.

Thank you so much for reading this and your time on this
matter.


Best Regards,


Stephen
 
(Please see my comments inline)

Stephen said:
Dear Dirk.

I wish I could upload my mdb file to this news group, but
I hope the following gives you some idea of what I am
making.

No, binary attachments are frowned on in these newsgroups, and sending
me your database is not really in order for this kind of question.
There are four tables, tbl_menu, tbl_ticket,
tbl_ticketdetail, and tbl_tickettype.

Tbl_menu

MenuId(Autonumber)
MenuName(Text)
MenuPrice(Currency)

Tbl_ticket

TicketId(Autonumber)
TicketTime(Date/Time)
TicketType(Number)

Tbl_ticketdetail

TicketdetailId(Autonumber)
TicketId(Number) - Relation to TicketId in Tbl_ticket
MenuId(Number) - Relation to MenuId in Tbl_menu
MenuQty(Number)

Tbl_tickettype

TickettypeId(Autonumber) - Relation to TicketType in
Tbl_ticket
Tickettypename(Text)

There are two forms, frm_ticket and sbf_frm_ticket.

"Frm_ticket" is main form based on a query, qry_ticket,
with two tables, tbl_ticket and tbl_tickettype.

The subform, sbf_frm_ticket, is based on a query,
qry_ticketdetail, with two tables, tbl_ticketdetail and
tbl_menu.

The default views of the subform set to be datasheet view
with all columns are hide except MenuName, MenuQty, and
MenuPrice.

The main form, frm_ticket, has all fields from qry_ticket,
a subform, sbf_frm_ticket, and numerous command buttons
for entering menuId and menuQty.

Okay, I follow all that, and the table structures look good.
Problems.

1. As far as entering menu, it works awesome as you
directed me with your code, but I can't enter menuQty
field value from then command buttons (Zero to nine on
main form).

How have you got these buttons laid out, and how do you intend for the
suer to interact with them? Do you have a set of buttons for each menu
item, and then another set of "quantity" buttons? Is the user supposed
to ...

(a) click a "menu" button, then click on one or more "quantity"
buttons, and then some final button to add the item? It seems to me
that you must be planning to allow them to enter 2-digit quantities, or
you wouldn't need a button for "zero".

or ...

(b) click on one or more "quantity" buttons, then on a menu item to
add that quantity of the item to the ticket? At least that way you'd
know when it was time to add the item (with the quantity) to the
subform.

or ...

(c) click a "menu" button to add an item, and then click a
"quantity" button to adjust the quantity for the item you just added.

or ...

(d) follow some other procedure that I haven't thought of?

Bear in mind that, unless you do a little more programming than we've
discussed so far, all any of these buttons knows is that it was clicked,
and what its properties are; e.g., its Tag property. I might point out
in passing that the "number" buttons don't need to use the Tag property
to reflect the number itself, because that's available in its Caption
property.
2. I used following code to prevent duplicated menu to the
subform, but it lets user can enter only one menu per
ticket.

'Dim rs As DAO.Recordset
'Dim strSQL As String

'strSQL = "SELECT tbl_ticketdetail.MenuId FROM
tbl_ticketdetail WHERE ((tbl_ticketdetail.TicketId) = " &
Me.TicketId & ") "

'Set rs = CurrentDb.OpenRecordset(strSQL,
dbOpenSnapshot)

' If rs.RecordCount = 1 Then
' MsgBox "Duplicated Menu!"
' rs.Close
' Exit Function
' End If

'rs.Close

You could make that code work with a minor adjustment to the SQL
statement -- you need a second criterion to filter the table for just
the MenuId the user clicked on. But I wouldn't do it that way. I'd use
the RecordsetClone of the subform itself, since that is already open and
filtered for this ticket:

With Me!sbf_frm_ticket.Form.RecordsetClone
.FindFirst "MenuId=" & varItem
If Not .NoMatch Then
MsgBox "Duplicated Menu!"
Exit Function
End if
End With
3. I need a "cancel" button to undo tickets made by
mistake while the subform is dirty with menu on the main
form.

I'm afraid I don't understand what you are saying here. You'll have to
explain a bit more.
 
Dear Dirk.

Thank god Dirk, you are my life saver.
How have you got these buttons laid out, and how do you intend for the
suer to interact with them? Do you have a set of buttons
for each menu item, and then another set of "quantity"
buttons?

Yes, I will make about 30+ buttons for each menu and a set
of "quantity" that counts from Zero to Nine next to the
subform.

Like following
____________________________________________________
| main form ______________________________ |
| ____________ |A 0-9 number button set here | |
| | subform | |______________________________| |
| | | |
| | | |
| | | 30+ menu buttons here |
| | | |
| | | |
| | | |
| |__________| |
|___________________________________________________|

(c) click a "menu" button to add an item, and then click a
"quantity" button to adjust the quantity for the item you just added.

(C) is exactly what I need.

Bear in mind that, unless you do a little more programming than we've
discussed so far, all any of these buttons knows is that it was clicked,
and what its properties are; e.g., its Tag property. I might point out
in passing that the "number" buttons don't need to use the Tag property
to reflect the number itself, because that's available in its Caption
property.

I will try caption property for the number button set.

You could make that code work with a minor adjustment to the SQL
statement -- you need a second criterion to filter the table for just
the MenuId the user clicked on. But I wouldn't do it that way. I'd use
the RecordsetClone of the subform itself, since that is already open and
filtered for this ticket:

With Me!sbf_frm_ticket.Form.RecordsetClone
.FindFirst "MenuId=" & varItem
If Not .NoMatch Then
MsgBox "Duplicated Menu!"
Exit Function
End if
End With

I bet this code will save me again like the last one did.
^^

I'm afraid I don't understand what you are saying here. You'll have to
explain a bit more.

I am sorry that I wasn't clear.
My question was that if users accidently created a ticket
with three or four items, for instance, I need a button
that wipe out all the items selected in the subform to
make the ticket empty then delete the ticket for the next
one.

Since "ticketId" is autonumber, the main form, frm_order
won't actually make a new ticket number when it's opened
from main switchboard until "tickettype" selected from
buttons ("Dine-In" and "Take-Out") that users can click in
the main form.

If I am just wiping out all items selected in the subform
and exit the main form, there will be a dummy ticket
number with 0 item in tbl_order as well as tbl_orderdetail.

To prevent that, I think I need to delete the ticket
number after wiping out all items in subform, and I need a
button which can perform the task.
 
Dear Dirk.

I am sorry I missed to point out one thing in the first
question. Yes, I do need to enter 2 digit quantity.


Best Regards,

Stephen
 
Stephen said:
Yes, I will make about 30+ buttons for each menu and a set
of "quantity" that counts from Zero to Nine next to the
subform.

Like following
____________________________________________________
| main form ______________________________ |
| ____________ |A 0-9 number button set here | |
| | subform | |______________________________| |
| | | |
| | | |
| | | 30+ menu buttons here |
| | | |
| | | |
| | | |
| |__________| |
|___________________________________________________|

(c) click a "menu" button to add an item, and then click a
"quantity" button to adjust the quantity for the item you just added.

(C) is exactly what I need. [...]
I'm afraid I don't understand what you are saying here. You'll have
to explain a bit more.

I am sorry that I wasn't clear.
My question was that if users accidently created a ticket
with three or four items, for instance, I need a button
that wipe out all the items selected in the subform to
make the ticket empty then delete the ticket for the next
one.

Since "ticketId" is autonumber, the main form, frm_order
won't actually make a new ticket number when it's opened
from main switchboard until "tickettype" selected from
buttons ("Dine-In" and "Take-Out") that users can click in
the main form.

If I am just wiping out all items selected in the subform
and exit the main form, there will be a dummy ticket
number with 0 item in tbl_order as well as tbl_orderdetail.

To prevent that, I think I need to delete the ticket
number after wiping out all items in subform, and I need a
button which can perform the task.

I'm afraid that, to make the quantity buttons work the way you want,
we're going to have to change some of the code you've already got. I've
been playing around with this, and this is what I've come up with. Note
that I haven't changed my table and field names to match yours, but you
should be able to figure out what of mine corresponds to what of yours.

On the form I have several "menu" buttons, each of which has its Tag
property set to an ItemID, and all of which have their OnClick event
properties set to "=AddToOrder()".

I also have 9 "quantity" buttons, with captions "1" through "9". I
didn't see any point of having a "0" button, since the current
arrangement doesn't support clicking two quantity buttons in a row to
make a two-digit number. Each of the "quantity" buttons has its OnClick
event property set to "=ChangeQuantity()". That has the effect of
setting the quantity for the current item (which will normally be the
one most recently added to the order) to the numeric value of the
button's caption. I also have a button named "cmdRemoveItem", which
will remove the current item from the order.

In addition, I have two more buttons named "cmdClearItems" and
"cmdDeleteOrder". cmdClearItems deletes all the items on the order but
leaves the order itself intact so you can add a different set of items
to it. cmdDeleteOrder deletes the order and, by way of cascading
deletes, all of the items that belong to it.

Here's the complete code for the form's code module, as it stands right
now:

'------- start of code for form module -------
Option Compare Database
Option Explicit

Function AddToOrder()

On Error GoTo Err_AddToOrder

Dim rs As DAO.Recordset
Dim varItem As Variant

If IsNull(Me.OrderID) Then
MsgBox "Enter basic order information first."
Exit Function
End If

If Me.Dirty Then Me.Dirty = False

varItem = Me.ActiveControl.Tag

If IsNumeric(varItem) Then

Set rs = Me!sfOrderItems.Form.RecordsetClone
With rs
.FindFirst "ItemID=" & varItem
If .NoMatch Then
.AddNew
!OrderID = Me.OrderID
!ItemID = CLng(varItem)
!Quantity = 1
Else
.Edit
!Quantity = !Quantity + 1
End If
.Update
.Bookmark = .LastModified
End With

Me!sfOrderItems.Form.Bookmark = rs.Bookmark
Set rs = Nothing

End If


Exit_AddToOrder:
Exit Function

Err_AddToOrder:
If Err.Number = 3201 Then
MsgBox "Item " & varItem & " is not defined in the Items table."
Else
MsgBox Err.Description, vbExclamation, "Error " & Err.Number
End If
Resume Exit_AddToOrder

End Function


Function ChangeQuantity()

Dim varQuantity As Variant

varQuantity = Me.ActiveControl.Caption

If Not IsNumeric(varQuantity) Then
MsgBox "Error: bad call to ChangeQuantity()"
Exit Function
End If

With Me.sfOrderItems.Form

If .NewRecord Then
DoCmd.Beep
Exit Function
End If

!Quantity = CLng(varQuantity)

End With

End Function


Private Sub cmdClearItems_Click()

If IsNull(Me.OrderID) Then
Exit Sub
End If

CurrentDb.Execute _
"DELETE FROM OrderItems WHERE OrderID=" & Me.OrderID, _
dbFailOnError

Me.sfOrderItems.Requery

End Sub


Private Sub cmdDeleteOrder_Click()

On Error GoTo Err_Handler

If Me.Dirty Then
Me.Undo
End If

If Not Me.NewRecord Then
RunCommand acCmdDeleteRecord
End If

Exit_Point:
Exit Sub

Err_Handler:
If Err.Number <> 2501 Then
MsgBox Err.Description, vbExclamation, "Error " & Err.Number
End If
Resume Exit_Point
End Sub


Private Sub cmdRemoveItem_Click()

Dim rs As DAO.Recordset

With Me.sfOrderItems.Form

If .Dirty Then
.Undo
End If

If Not .NewRecord Then
Set rs = .RecordsetClone
rs.Bookmark = .Bookmark
rs.Delete
If .NewRecord Then
If rs.RecordCount > 0 Then
rs.MovePrevious
.Bookmark = rs.Bookmark
End If
End If
Set rs = Nothing
End If

End With

End Sub
'------- end of code for form module -------

If you click the same "menu" button more than once for an order, that
has the effect of adding 1 to the quantity already ordered for that
item. You can change that behavior easily enough, if you just want to
display an error message.

All that may not be exactly how you want your form to behave, but it
should be a step in the right direction.
 
Stephen said:
Dear Dirk.

I am sorry I missed to point out one thing in the first
question. Yes, I do need to enter 2 digit quantity.

AARRGHH!! <lol> Too late, we'll have to deal with that problem
tomorrow. Or see what you can figure out.
 
Dear Dirk.

Words can't describe my appreciation, thank you.

Someday, I wish I could help someone like me in this
newsgroup like you did to me.

I tried to figure out how to make 2 digits or more digits
with the caption property, but help example in Access
didn't help me much.

I don't know how to combine two or more variants into one.

Thank you so much again for your time.

P.S. Is there anyway to show total amount in the bottom of
the subform in datasheet view? Do I need an union query
to display a sum of amount field in the subform?

-----Original Message-----
Yes, I will make about 30+ buttons for each menu and a set
of "quantity" that counts from Zero to Nine next to the
subform.

Like following
____________________________________________________
| main form ______________________________ |
| ____________ |A 0-9 number button set here | |
| | subform | |______________________________| |
| | | |
| | | |
| | | 30+ menu buttons here |
| | | |
| | | |
| | | |
| |__________| |
|___________________________________________________|

(c) click a "menu" button to add an item, and then click a
"quantity" button to adjust the quantity for the item you just added.

(C) is exactly what I need. [...]
3. I need a "cancel" button to undo tickets made by
mistake while the subform is dirty with menu on the main
form.

I'm afraid I don't understand what you are saying here. You'll have
to explain a bit more.

I am sorry that I wasn't clear.
My question was that if users accidently created a ticket
with three or four items, for instance, I need a button
that wipe out all the items selected in the subform to
make the ticket empty then delete the ticket for the next
one.

Since "ticketId" is autonumber, the main form, frm_order
won't actually make a new ticket number when it's opened
from main switchboard until "tickettype" selected from
buttons ("Dine-In" and "Take-Out") that users can click in
the main form.

If I am just wiping out all items selected in the subform
and exit the main form, there will be a dummy ticket
number with 0 item in tbl_order as well as tbl_orderdetail.

To prevent that, I think I need to delete the ticket
number after wiping out all items in subform, and I need a
button which can perform the task.

I'm afraid that, to make the quantity buttons work the way you want,
we're going to have to change some of the code you've already got. I've
been playing around with this, and this is what I've come up with. Note
that I haven't changed my table and field names to match yours, but you
should be able to figure out what of mine corresponds to what of yours.

On the form I have several "menu" buttons, each of which has its Tag
property set to an ItemID, and all of which have their OnClick event
properties set to "=AddToOrder()".

I also have 9 "quantity" buttons, with captions "1" through "9". I
didn't see any point of having a "0" button, since the current
arrangement doesn't support clicking two quantity buttons in a row to
make a two-digit number. Each of the "quantity" buttons has its OnClick
event property set to "=ChangeQuantity()". That has the effect of
setting the quantity for the current item (which will normally be the
one most recently added to the order) to the numeric value of the
button's caption. I also have a button named "cmdRemoveItem", which
will remove the current item from the order.

In addition, I have two more buttons named "cmdClearItems" and
"cmdDeleteOrder". cmdClearItems deletes all the items on the order but
leaves the order itself intact so you can add a different set of items
to it. cmdDeleteOrder deletes the order and, by way of cascading
deletes, all of the items that belong to it.

Here's the complete code for the form's code module, as it stands right
now:

'------- start of code for form module -------
Option Compare Database
Option Explicit

Function AddToOrder()

On Error GoTo Err_AddToOrder

Dim rs As DAO.Recordset
Dim varItem As Variant

If IsNull(Me.OrderID) Then
MsgBox "Enter basic order information first."
Exit Function
End If

If Me.Dirty Then Me.Dirty = False

varItem = Me.ActiveControl.Tag

If IsNumeric(varItem) Then

Set rs = Me!sfOrderItems.Form.RecordsetClone
With rs
.FindFirst "ItemID=" & varItem
If .NoMatch Then
.AddNew
!OrderID = Me.OrderID
!ItemID = CLng(varItem)
!Quantity = 1
Else
.Edit
!Quantity = !Quantity + 1
End If
.Update
.Bookmark = .LastModified
End With

Me!sfOrderItems.Form.Bookmark = rs.Bookmark
Set rs = Nothing

End If


Exit_AddToOrder:
Exit Function

Err_AddToOrder:
If Err.Number = 3201 Then
MsgBox "Item " & varItem & " is not defined in the Items table."
Else
MsgBox Err.Description, vbExclamation, "Error " & Err.Number
End If
Resume Exit_AddToOrder

End Function


Function ChangeQuantity()

Dim varQuantity As Variant

varQuantity = Me.ActiveControl.Caption

If Not IsNumeric(varQuantity) Then
MsgBox "Error: bad call to ChangeQuantity()"
Exit Function
End If

With Me.sfOrderItems.Form

If .NewRecord Then
DoCmd.Beep
Exit Function
End If

!Quantity = CLng(varQuantity)

End With

End Function


Private Sub cmdClearItems_Click()

If IsNull(Me.OrderID) Then
Exit Sub
End If

CurrentDb.Execute _
"DELETE FROM OrderItems WHERE OrderID=" & Me.OrderID, _
dbFailOnError

Me.sfOrderItems.Requery

End Sub


Private Sub cmdDeleteOrder_Click()

On Error GoTo Err_Handler

If Me.Dirty Then
Me.Undo
End If

If Not Me.NewRecord Then
RunCommand acCmdDeleteRecord
End If

Exit_Point:
Exit Sub

Err_Handler:
If Err.Number <> 2501 Then
MsgBox Err.Description, vbExclamation, "Error " & Err.Number
End If
Resume Exit_Point
End Sub


Private Sub cmdRemoveItem_Click()

Dim rs As DAO.Recordset

With Me.sfOrderItems.Form

If .Dirty Then
.Undo
End If

If Not .NewRecord Then
Set rs = .RecordsetClone
rs.Bookmark = .Bookmark
rs.Delete
If .NewRecord Then
If rs.RecordCount > 0 Then
rs.MovePrevious
.Bookmark = rs.Bookmark
End If
End If
Set rs = Nothing
End If

End With

End Sub
'------- end of code for form module -------

If you click the same "menu" button more than once for an order, that
has the effect of adding 1 to the quantity already ordered for that
item. You can change that behavior easily enough, if you just want to
display an error message.

All that may not be exactly how you want your form to behave, but it
should be a step in the right direction.

--
Dirk Goldgar, MS Access MVP
www.datagnostics.com

(please reply to the newsgroup)


.
 
Stephen said:
Someday, I wish I could help someone like me in this
newsgroup like you did to me.

Keep your eyes open, and when you see a question you know the answer to,
jump right in.
I tried to figure out how to make 2 digits or more digits
with the caption property, but help example in Access
didn't help me much.

I don't know how to combine two or more variants into one.

Now we've gotten to the point where you really have to think hard about
how you want this form to work, on the user-interface level. Only then
can we talk about how to make Access support the user interface you
want. For example, if you want the user to be able click the "1"
button, then the "0" button, to indicate that 10 of some menu item were
ordered, there's no way that code run from the Click event procedure of
the "1" button can know that you're going to click another number
button. So if your plan was to have the user click a menu button, then
1 *or* more number buttons to indicate the number of that menu item, you
can't update the quantity with each button clicked.

One way around the problem would be to have another button which would
be an "Update Quantity" button that you would click after you've entered
a quantity by clicking on one or more number buttons -- clicking the
"Update Quantity" button would update the order for the current item
with the quantity that was entered. But frankly, I don't like this
approach much because it always requires you to click an extra button.

Another approach would be to change the order of things -- click the
number buttons first, and then the menu-item button. That way, the
clicking of the menu button would be the signal that you've finished
entering the quantity, and can add that quantity of the selected item to
the order. Question: if the item is already in the order, would you
want to add the entered quantity to the quantity already ordered for the
item, or replace the current quantity with the new quantity? I don't
know; it's not my application.

Yet another approach would be to have buttons 1 through 10. Each of
them would add that many of the last menu item selected to the order,
adding to any number that have already been ordered. So the user would
always have to click the menu item and at least one of the number
buttons to add an item to the order; however, the user could click (for
example) "Cheeseburger", then 10, then 5, to add 15 cheeseburgers to the
order. This would be fairly efficient, but does require a minimum of
two clicks for every item. Also, there would have to be some mechanism
for adjusting or subtracting from the quantity ordered for an item.

Any of the above approaches could be implemented, and there are probably
other good ones I haven't thought of, but you need to decide what
approach you want to take. What would be the most efficient and
intuitive way for the user to interact with the form? Think about it.
Thank you so much again for your time.

You're welcome.
P.S. Is there anyway to show total amount in the bottom of
the subform in datasheet view? Do I need an union query
to display a sum of amount field in the subform?

I'd recommend having the subform in continuous forms view instead, even
if you format it to look very much like a datasheet. Then having a
"total" text box in the subform's form footer would be easy. You'd need
to base the subform, not on Tbl_ticketdetail alone, but on a query like
this:

SELECT
Tbl_ticketdetail.*,
Tbl_menu.MenuName,
Tbl_ticketdetail.MenuQty * TblMenu.MenuPrice
AS ExtendedPrice
FROM Tbl_ticketdetail INNER JOIN TblMenu
ON Tbl_ticketdetail.MenuId = TblMenu.MenuId;

That will allow the subform to show the name of the menu item, and also
automatically calculate the extended price of each item in the order.
And then the "total" text box in the footer could have this for its
ControlSource:

=Sum(ExtendedPrice)
 
Back
Top