Access 2003, Determining which control has been clicked

J

Jerry Pine Pollen

I've been searching discussion groups (here and elsewhere) for days but can't
find anyone who has addressed my question.

In Access 2003, I've got a form with a mosaic of rectangles representing
various locations in our organization. I change the background color of the
rectangle or text within a rectangle depending on the specific data for that
location. When a user clicks on one of the location boxes, I want to bring
up a data form specific to that location. However, the only method I can
figure out so far is to have an onclick event for every single rectangle.
I've got that working for a representative rectangle and it works great
except that I've got 300 rectangles and counting. That makes for a program
construction and maintenance nightmare.

Conceptually, what I would like to do is to have the form determine which
rectangle was clicked and then pass the parameters to a common data
management routine to decide what form and data to load. I can poll through
all the rectangles but don't see a way to tell if one has been
selected/clicked, since rectangles don't have an "onGotFocus" property.

Any advice?
 
S

Stuart McCall

Jerry Pine Pollen said:
I've been searching discussion groups (here and elsewhere) for days but
can't
find anyone who has addressed my question.

In Access 2003, I've got a form with a mosaic of rectangles representing
various locations in our organization. I change the background color of
the
rectangle or text within a rectangle depending on the specific data for
that
location. When a user clicks on one of the location boxes, I want to
bring
up a data form specific to that location. However, the only method I can
figure out so far is to have an onclick event for every single rectangle.
I've got that working for a representative rectangle and it works great
except that I've got 300 rectangles and counting. That makes for a
program
construction and maintenance nightmare.

Conceptually, what I would like to do is to have the form determine which
rectangle was clicked and then pass the parameters to a common data
management routine to decide what form and data to load. I can poll
through
all the rectangles but don't see a way to tell if one has been
selected/clicked, since rectangles don't have an "onGotFocus" property.

Any advice?

Try this on for size. Create a public function in a standard module which
takes a form object as a parameter, eg:

Public Function FunctionName(frm As Access.Form)

Inside the function, use frm.ActiveControl to determine which rectangle was
clicked. Also do the color thing in here.

On your form in design view, select all the rectangles, open the property
sheet and go to the Events tab. Put this into the OnClick property:

=FunctionName([Form])

That sets the property for all selected controls.
 
R

Rick Brandt

Stuart said:
Try this on for size. Create a public function in a standard module
which takes a form object as a parameter, eg:

Public Function FunctionName(frm As Access.Form)

Inside the function, use frm.ActiveControl to determine which
rectangle was clicked. Also do the color thing in here.

On your form in design view, select all the rectangles, open the
property sheet and go to the Events tab. Put this into the OnClick
property:
=FunctionName([Form])

That sets the property for all selected controls.

Problem though is that since a rectangle cannot have focus it will never be
the active control. One could use TextBoxes instead though and then it
would work.
 
M

Marshall Barton

Jerry Pine Pollen <Jerry Pine
I've been searching discussion groups (here and elsewhere) for days but can't
find anyone who has addressed my question.

In Access 2003, I've got a form with a mosaic of rectangles representing
various locations in our organization. I change the background color of the
rectangle or text within a rectangle depending on the specific data for that
location. When a user clicks on one of the location boxes, I want to bring
up a data form specific to that location. However, the only method I can
figure out so far is to have an onclick event for every single rectangle.
I've got that working for a representative rectangle and it works great
except that I've got 300 rectangles and counting. That makes for a program
construction and maintenance nightmare.

Conceptually, what I would like to do is to have the form determine which
rectangle was clicked and then pass the parameters to a common data
management routine to decide what form and data to load. I can poll through
all the rectangles but don't see a way to tell if one has been
selected/clicked, since rectangles don't have an "onGotFocus" property.


If the rectangles are laid out in a regular pattern, then
you can place a large, transparent command button on top of
all of them. Then you can use the button's MouseUp event's
X,Y coordinates to calculate which rectangle was under the
mouse. For example, if your rectangles make up a uniform 3
by 3 grid and the rectangles are named box11, box12, box13,
box21, etc, then the clicked rectangle is:
Me("box" & (X \ box11.Width +1) & (Y \ box11.Height))

This concept gets real messy real fast if the rectangles are
not laid out in a uniform grid. In a worst case scenario,
you would have to cover the whole form section with the
button and loop through all the rectangle controls (named
box1, box2, ..., box300) comparing X and Y to the control's
Left, Width, Top and Height properties:

For k = 1 To 300
With Me("box" & k)
If X >= .Left And X <= .Left+.Width And _
Y >= .Top And Y <= .Top+.Height _
Then
'do your thing
. . .
Exit For
End If
End With
Next k
 
S

Stuart McCall

Rick Brandt said:
Stuart said:
Try this on for size. Create a public function in a standard module
which takes a form object as a parameter, eg:

Public Function FunctionName(frm As Access.Form)

Inside the function, use frm.ActiveControl to determine which
rectangle was clicked. Also do the color thing in here.

On your form in design view, select all the rectangles, open the
property sheet and go to the Events tab. Put this into the OnClick
property:
=FunctionName([Form])

That sets the property for all selected controls.

Problem though is that since a rectangle cannot have focus it will never
be the active control. One could use TextBoxes instead though and then it
would work.

Of course. Yes they would have to be textboxes. I'd forgotten the focus
problem.

Thanks for jumping in.
 
M

Michel Walsh

If the Mouse Down event is not consumed by a control, the form section can
and there, you can check something like:


Private Sub Detail_MouseDown(Button As Integer, Shift As Integer, X As
Single, Y As Single)
Dim z As Variant
For Each z In Me.Controls
Debug.Print z.Name, X >= z.Left And X < z.Left + z.Width And Y >=
z.Top And Y < z.Top + z.Height
Next z
End Sub



Vanderghast, Access MVP
 
J

Jerry Pine Pollen

Rick Brandt said:
Stuart said:
Try this on for size. Create a public function in a standard module
which takes a form object as a parameter, eg:

Public Function FunctionName(frm As Access.Form)

Inside the function, use frm.ActiveControl to determine which
rectangle was clicked. Also do the color thing in here.

On your form in design view, select all the rectangles, open the
property sheet and go to the Events tab. Put this into the OnClick
property:
=FunctionName([Form])

That sets the property for all selected controls.

Problem though is that since a rectangle cannot have focus it will never be
the active control. One could use TextBoxes instead though and then it
would work.

--

Yes, that is one option that occurred to me also. However, I liked some
other things about rectangles and wanted to try and make them work first.
I'll probably switch to text boxes if I can't get rectangles working.
 
J

Jerry Pine Pollen

Thanks for all your advice. Give me a bit to digest and try and implement
things and then I'll tell you how it all worked.
 
J

Jerry Pine Pollen

Marshall,

That has some real potential. I had thought about something similar to the
hot zones on a photo in html but couldn't see how to implement that in
Access. Your suggestion will probably do it. It may not be as messy as it
would seem, even though the rectangle arrangement is not regular. It might
take a bit of experimentation, though, to determine the position zones for
each rectangle.
 
J

Jerry Pine Pollen

Thanks, Michel,

I really like the kinds of thing your code snippet does. I'm going to
experiment with it.

Jerry
 
J

John W. Vinson

Marshall,

That has some real potential. I had thought about something similar to the
hot zones on a photo in html but couldn't see how to implement that in
Access. Your suggestion will probably do it. It may not be as messy as it
would seem, even though the rectangle arrangement is not regular. It might
take a bit of experimentation, though, to determine the position zones for
each rectangle.

You should be able to store the upper left and lower right coordinates of each
rectangle (even overlapping rectangles!) and given the coordinates of a
MouseUp event, determine which rectangle(s) was hit. More complex shapes of
course will be trickier!
 
D

David W. Fenton

=?Utf-8?B?SmVycnkgUGluZSBQb2xsZW4=?= <Jerry Pine
[email protected]> wrote in
In Access 2003, I've got a form with a mosaic of rectangles
representing various locations in our organization. I change the
background color of the rectangle or text within a rectangle
depending on the specific data for that location. When a user
clicks on one of the location boxes, I want to bring up a data
form specific to that location. However, the only method I can
figure out so far is to have an onclick event for every single
rectangle. I've got that working for a representative rectangle
and it works great except that I've got 300 rectangles and
counting. That makes for a program construction and maintenance
nightmare.

The very simplest way to do this would be to write a function (let's
call it MyFunction() that figures out the name of the location from
the name of the clicked button, then put a transparent command
button on top of each rectangle. Then mass select all your command
buttons and type =MyFunction().

If you use consistent naming conventions, the transparent command
button over boxLocation1 will be called cmdLocation1. Then all you
have to do in MyFunction() is check:

Mid(Screen.ActiveControl.Name, 3)

which will give you "Location1". You can then do with that what you
need to do.
 
Top