ComboBox RowSourceType containing UDF => call back oddities

  • Thread starter Thread starter Malcolm Cook
  • Start date Start date
M

Malcolm Cook

Hi,

I've created and installed a custom UDF to populate my combobox, and have
defined it per :
http://msdn.microsoft.com/library/d...html/acproRowSourceTypeFunctionParameters.asp

I'm using ACC2002 in an ADP.

However, I'm finding that he control variable (called "code" in the above
documentation), is passed into my UDF with a value other than those listed
in the documentation.

2 gets passed in

But these are the only documented values

acLBInitialize = 0
acLBOpen = 1
acLBGetRowCount = 3
acLBGetColumnCount = 4
acLBGetColumnWidth = 5
acLBGetValue = 6
acLBGetFormat = 7
acLBClose = 8
acLBEnd = 9

Has anyone figured this out, or know where it is documented fully?

Thanks.
 
Is the callback procedure not working to fill the Combo? If it is working,
perhaps ignoring the code of 2 would be appropriate; if not, please clarify.

Have you looked in Help for previous versions, like Access 97. Have you
searched the knowledge base at http://support.microsoft.com? Have you
searched online papers and other documentation at http://msdn.microsoft.com?

Larry Linson
Microsoft Access MVP
 
Hi Larry,

Yes, I've searched around quite a bit. I only found one other person
wondering about the "2". The most informative code snippets and discussions
I've found were these:

http://www.mvps.org/access/forms/frm0049.htm

http://groups.google.com/[email protected]&rnum=2


I did not get any help from:

'http://support.microsoft.com/?kbid=304252
'http://support.microsoft.com/?kbid=281870
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnofftalk/html/office04062000.asp


The reason that this issue is not apparent to most is (I'm guessing)
1) no one puts a case else in their select statements
2) no one uses the feature of being able to use the same code to handle
multiple combo boxes.

At least, I could NOT find any examples where the ID parameter to the
callback function was being used.

The reason I discovered this is:
1) I always put a case else statments on my select cases, even if it is
to just 'debug.assert false'
2) I'm trying to make my callback routine reusable by multiple combo
boxes, and understand the use of the ID parameter.

The documention suggests to me that if the value returned from a acLBOpen
call will be passed in on subsequent calls. I am finding that this is not
true. Rather, through guesswork and experimentation, I've discovered that
the value returned from the callback when passed code 2 is what is used.

!!

So, I'm getting SOME understanding, but not enough.

I am getting the combobox to work.... Just not (yet) with sufficient
understanding to trust using my callback routine with multiple comboboxes.

In case your interested, my custom callback is used to execute a
paramaterized stored procedure on SQL Server. But, before execution, it
"injects" values from global program state into the .parameters. It also
does what the default behaviour of Access combo boxes do, namely "inject"
values from controls on the current form (and recordset.fields). Thus, my
combo boxes are sensitive to both controls on the same form as they appear,
AND global state (And they prompt the user if any parameters remain unbound
after these "injection"). I hope you can see the value of making this
generic across combo boxes.

If you're still with me... I have a concern with my approach as it relates
to instancing of forms. It appears to me that when I have multiple
instances of a form displayed, they are all using the same combo box, so,
if they are parameterized differently they will still change in lock step
with one another. This would be a problem regardless of whether I use a
callback or not. Does this make sense to you?

To summarize: None of the examples I've discovered make any use of the ID
parameter, which usage seems tte require understanding of the 2 code. This
is fine if your callback is particular to the control. Mine is not, and so
I'm trying to get this feature to work for me.

Any light you can shed would be appreciated.

Thanks,

Malcolm Cook
..
 
I have used a callback, but it has been some time, and I did not try to use
it for multiple combo boxes. I also don't do multiple instances of the same
form, on the assumption that I often find that confusing or misleading, and
do not want to confuse or mislead my users. So, I agree, most people don't
try to do a "generic callback" and they probably never have the issues you
describe.

In the more recent versions of Access, we have the AddItem method, which
allows building a value list at runtime; I am also told that if you are
using ADO in an ADP that you can specify a disconnected recordset directly
as the Row Source (though I have not had occasion to try that).

Larry Linson
Microsoft Access MVP
 
Fascinating!

Like Larry, I've never tried anything this ambitious and
have no comments about the code 2 issue.

However, I'm sure that the only way to get the multiple
instances of the same form to work is if the callback
function operates on the form instance's class object. This
means that the array the function operates on should be in
the form's module along with the query parametes. This can
probably be done relatively cleanly by using properties and
methods of the form object along with the specific combo box
object.
 
Larry!



re:


if you are
using ADO in an ADP that you can specify a disconnected recordset directly
as the Row Source (though I have not had occasion to try that).



Man-o-man-o-man-o-man-o-man-o-man, there are just sooo many ways to skin a
cat! This way is best for me and works in my hands and is MUCH faster than
the callback I had installed with fewer redisplay problems (flicker).



I'm sure I must have read it somewhere in these last months (AHA, oh yeah,
here it is, right here in ACC2002 Desktop Developers Handbook, pg 367).
Keeping track of all the possibilities has got me a bit frazzled. I'm new
to the ACC game, joined with ADPs in ACC2002 against SQL Server 2000.



Anyway, final upshot is that I'm now satisfactorily generically injecting
global program state into my comboboxes (as well as values from each
combobox.parent.form.recordset.fields (like native Access does), as well as
prompting user if any are still Empty (again, like native access)).



Thanks so much for sussing out my goals and suggesting an alternate tactic.



re:
I also don't do multiple instances of the same
form, on the assumption that I often find that confusing or misleading, and
do not want to confuse or mislead my users.



I really like the interfaces that I provide with this capability. I present
my users with a list (datasheet). They double click on the record selector,
and it opens another instance of the same form, but now in form view (of
course after getting itself registered first in an instance catalog (global
dictionary) and also wrapped in a event sinking class that extends the basic
Access UI behaviors (like putting useful info in the window title and
providing Form_Error handling)). The 2nd instance can have the same
underlying recordset as the first (so they stay synced), or not, so the user
can, for instance, go find two records and open them side by side.



Anyway, thanks again. You're the man!



Sincerely,



Malcolm Cook - (e-mail address removed) - 816-926-4449

Database Applications Manager - Bioinformatics

Stowers Institute for Medical Research - Kansas City, MO USA
 
Marshall,

I had been planning on using a static scripting.dictionary from ID to array,
under the assumption that the access engine performing the callbacks would
fill them seperately and give them seperate IDs.

Regardless, the fact remains that however I contrive to manage their values
array (or whatever datastructure) if they are on different instances of a
form, they "are the same control". So, changing the values list in one of
them will effect the other. It is similar to the conundrum that programmers
(like me) get into when we want to use the combobox in datasheet view with a
control source that depends upon a field in the current record. AFAI can
figure out, this is not a good application of comboboxes. N'est pas? This
will effect me as well when I assign an open recordset to the comboboxes
recordset.

Thanks for your thoughts on the topic. Do you see my reasoning as faulty?
Do you still think I would be better of putting the array into the form?

Cheers,
 
Malcolm said:
Marshall,

I had been planning on using a static scripting.dictionary from ID to array,
under the assumption that the access engine performing the callbacks would
fill them seperately and give them seperate IDs.

Regardless, the fact remains that however I contrive to manage their values
array (or whatever datastructure) if they are on different instances of a
form, they "are the same control". So, changing the values list in one of
them will effect the other. It is similar to the conundrum that programmers
(like me) get into when we want to use the combobox in datasheet view with a
control source that depends upon a field in the current record. AFAI can
figure out, this is not a good application of comboboxes. N'est pas? This
will effect me as well when I assign an open recordset to the comboboxes
recordset.


A combo box on different instances of the same form are
separate items. You just have to refer to them through
their respective form object (not via the Forms collection).

The only time you have a single control displayed multiple
times is on a single instance of a continuous form or a form
in datasheet view.

Thanks for your thoughts on the topic. Do you see my reasoning as faulty?
Do you still think I would be better of putting the array into the form?


Either in the form's class module or in a wrapper class for
the form instance. You definitely need it in a place that
can have multiple instances or it will be overwritten by
another instance of the same form/combo combination.

I see from your discussion with Larry that you found another
approach that seems to make most of this discussion moot.
If not, then I think I've lost track of what topic we're
talking about.
 
Back
Top