Building expressions in VB

T

tcb

Older versions of Access allowed you to build expressions in code as
you can in controls.

For example you could build something like this to refer to a subform:

Me.sfCustomerConcern.Form.Controls

New versions don't have that build feature (though it is available
through third party).

What is the best way to build such expressions or statements in code?

I know that:

Form_sfCustomerConcern.Controls refers to the same subform named above.

Can names of objects be inserted from the object browser into VB code?

Thanks
 
A

Albert D.Kallal

tcb said:
Older versions of Access allowed you to build expressions in code as
you can in controls.

For example you could build something like this to refer to a subform:

Me.sfCustomerConcern.Form.Controls

New versions don't have that build feature (though it is available
through third party).

Hum, not sure what you mean by "build" feature. the above expression you
have should have worked find for that last 5 versions of access (that going
back to office 95, which is more then 10 years old now. So, I don't see any
problem with the above expression. And, inteli-sense (auto completion)
should work for the above.
What is the best way to build such expressions or statements in code?

Well, if you always compile your code after you make changes, then as you
type new code, then inteli-sense will work. In the above, you would type in

me.

And then you should get a popup list.

If you are not getting a popup list, then likely your code has "many" or
some compile errors in other locations. do a debug->compile, and fix all of
the existing errors. When you got all errors fixed, THEN inti-sense, and
autocompltion should work as you type new code.

So, I can't think of anything that changed in the last 5 versions in terms
of the above expression. It should be business as usual.
I know that:

Form_sfCustomerConcern.Controls refers to the same subform named above.

NO NO, you do you NOT want to use the above format to reference forms. That
syntax of

Form_YourFormName

Refers to the BASE class object. If you form is NOT loaded, and you use the
above, such as:

msgbox form_YourFormName!LastName

The above code will actually cause the form to load (if it not yet loaded).
And, this means all of the startup events (on-open, on-load etc) will run.
This is certainly NOT the behavior one would expect with the above
expression. You loose complete control of when the form loads, and the
startup events fire.

Further, by using the above syntax, then the form does NOT get added to the
forms collection (at least the key "name" as a string does not).

So, the syntax to reference a form is:

me (this must be used inside of a forms module, and "me" is the
current form instance)

forms!YourFormName
forms("YourFormName")

note how the last one is a string:

strForm = inputbox("what form to load")

docmd.OpenForm strForm

msgbox "last name is " & forms(strForm)!LastName

Note how I can use a string var to ref the form. And, if you use the
form_yourforname syntax, the above code will break, and not work.

It is important to thus realize that you do NOT want to use the forms base
class object of

form_YourFormName

In fact, if you don't have any code in the form, then the form's base class
object is NOT created. This actually means that the syntax of

form_YourFormNaem

Will NOT WORK unless the form actually has some code in it (again, that is
enough reason to NOT use the above syntax, since it will NOT work if the
form ahs no code!!!.). Further, as mentioned, if you got multiple instances
of the form open, you can't tell which one. Worse, the above format can
cause a form to load if it is NOT already loaded (this is unexpected).
Further, it does not add the form to the forms collection correctly. So, all
in all, you REALLY want to avoid using the above syntax.
Can names of objects be inserted from the object browser into VB code?

As mentioned, any form with code becomes a base class object and you can
view it in the object browser. However, if the form has no code, then a base
class object NOT created.

Anway, I not sure whats changed in the last few versions, but you do want to
compile your code frequently (I do it after EVERY single time I change
code).

Furhter, if you don't comple your code in the currnet window and save it,
then next time ms-access will "load" the code module when you go back to
code, and this can be quite annoying. So, if you compile the code, then
ms-access thinks your are done, and thus does NOT load a zillon code modules
when you go back to the code window. the add bonus of this is that you need
to do this to ensure that inti-sense (auto completion) works also.
 
B

Brendan Reynolds

Excellent explanation, Albert, I learned something from that myself.

Re what changed in recent versions I believe the original poster is
referring to the Expression Builder, which worked in the old Access 97 VBA
editor. It doesn't work in the VBA editor in Access 2000 and later, only in
the main Access window. Michael Kaplan (www.trigeminal.com) has a free
add-in to make it work in Access 2000. I haven't used the add-in myself -
I'd long stopped using the Expression Builder by the time Access 2000 was
released anyway - so I can't say whether it still works with Access 2003.
 
T

tcb

Thanks for your response.

The expression builder could be used to create such statements as:

Forms![frmDonorO]![frmDonorO_Contact_sf].Form.Enabled = True

Intellisense won't do that. It's a lot of typing when referring to a
subform. Intellisense works with the current form using Me but not like
above.

For example, I want to open one form from another and do all of the
rest below, intellisense aiding and assisting:

stDocName = "frmDonorO"
DoCmd.OpenForm stDocName, acNormal, , , acFormAdd

Form_frmDonorO.frmDonorO_Contact_sf.Enabled = True

Form_frmDonorO.D_DATE_ADDED = Date
Form_frmDonorO.D_TYPE = "O"
Form_frmDonorO.DonorID = DMax("[Donor_ID]", "tbl_Donor") + 1
Form_frmDonorO.txtD_LAST_NAME.SetFocus

What do you suggest?
 
B

Brendan Reynolds

If you're using Access 2000 or Access 2002, try Michael Kaplan's add-in at
the URL I posted earlier in this thread - it's free.

The add-in doesn't seem to work with Access 2003 (Michael does say at his
web page that he doesn't expect it to work with later versions, so that's as
expected).

In the example you give below, you are assigning the name of the form to a
variable, but you make very little use of the variable after assigning to
it. You could make your code more concise by making more use of the
variable. You could also use the With .. End With construct. And
IntelliSense will help out - within the With ... End With construct, you'll
get a list of public properties and methods of the form when you type the
"."

Dim stDocName As String
Dim frm As Form

stDocName = "frmDonorO"
DoCmd.OpenForm stDocName, acNormal, , , acFormAdd
Set frm = Forms(stDocName)
With frm
.Contact_sf.Enabled = True
.D_DATE_ADDEDD = Date
.D_TYPE = "O"
.DonorID = DMax("[Donor_ID]", "tbl_Donor") + 1
.txtD_LAST_NAME.SetFocus
End With
 
B

Brendan Reynolds

Sorry, I just realized that was potentially misleading. Within the With ...
End With construct, you will get IntelliSense lists for public members of
the generic Form object, like ActiveControl and AllowEditions, but not
'instance members' - things specific to your form, like the name of your
subform control.

The bottom line, I guess, is that yes, the loss of the ability to use the
Expression Builder in the VBA editor in recent versions is a loss of
functionality. In my experience, if you do a lot of coding, you soon learn
to write the code faster than you could have built it with the Expression
Builder. If you only write code occasionally, I guess it's a bigger loss.
But unless you know of a third-party solution that works with Access 2003, I
don't think there's any solution other than to learn to manage without it.

--
Brendan Reynolds

Brendan Reynolds said:
If you're using Access 2000 or Access 2002, try Michael Kaplan's add-in at
the URL I posted earlier in this thread - it's free.

The add-in doesn't seem to work with Access 2003 (Michael does say at his
web page that he doesn't expect it to work with later versions, so that's
as expected).

In the example you give below, you are assigning the name of the form to a
variable, but you make very little use of the variable after assigning to
it. You could make your code more concise by making more use of the
variable. You could also use the With .. End With construct. And
IntelliSense will help out - within the With ... End With construct,
you'll get a list of public properties and methods of the form when you
type the "."

Dim stDocName As String
Dim frm As Form

stDocName = "frmDonorO"
DoCmd.OpenForm stDocName, acNormal, , , acFormAdd
Set frm = Forms(stDocName)
With frm
.Contact_sf.Enabled = True
.D_DATE_ADDEDD = Date
.D_TYPE = "O"
.DonorID = DMax("[Donor_ID]", "tbl_Donor") + 1
.txtD_LAST_NAME.SetFocus
End With

--
Brendan Reynolds

tcb said:
Thanks for your response.

The expression builder could be used to create such statements as:

Forms![frmDonorO]![frmDonorO_Contact_sf].Form.Enabled = True

Intellisense won't do that. It's a lot of typing when referring to a
subform. Intellisense works with the current form using Me but not like
above.

For example, I want to open one form from another and do all of the
rest below, intellisense aiding and assisting:

stDocName = "frmDonorO"
DoCmd.OpenForm stDocName, acNormal, , , acFormAdd

Form_frmDonorO.frmDonorO_Contact_sf.Enabled = True

Form_frmDonorO.D_DATE_ADDED = Date
Form_frmDonorO.D_TYPE = "O"
Form_frmDonorO.DonorID = DMax("[Donor_ID]", "tbl_Donor") + 1
Form_frmDonorO.txtD_LAST_NAME.SetFocus

What do you suggest?
 
A

Albert D.Kallal

For example, I want to open one form from another and do all of the
rest below, intellisense aiding and assisting:

stDocName = "frmDonorO"
DoCmd.OpenForm stDocName, acNormal, , , acFormAdd

Form_frmDonorO.frmDonorO_Contact_sf.Enabled = True

Form_frmDonorO.D_DATE_ADDED = Date
Form_frmDonorO.D_TYPE = "O"
Form_frmDonorO.DonorID = DMax("[Donor_ID]", "tbl_Donor") + 1
Form_frmDonorO.txtD_LAST_NAME.SetFocus

What do you suggest?

You are absolute correct. And, it to be honest, I have "often" just typed in
the code as follows

'forms(stDocName).
Form_frmDonorO.

(I type the form_frmDonorO in the code editor, find the correct property,
and then do a shift-home to delete the stuff to the left
the Form_frmDonorO.) and then move hit backspace to move the whole line up
to

forms(stDocName).D_DATE_ADDED = Date

So, on occasion, I will type in the actual form class object, to get that
"help" you mention.

However, 90% or more of the time, your code is "in-side" the form, and thus
me. works just fine....

While it is true that you code "most" of the time will run, those "problems"
I pointed out do exist when you use the base class object.

I have some old code running were I did use the base forms object ref, and
it does work fine. So, one could argue that you continue to use the forms
base object.

You can even ref a sub form as the original base class object, and that
worked in a97, (but only for the first instance of the sub-form). I not sure
what happens now...

So, I will say that I don't recommend the practice, you *can* get away doing
this.

Come to think of it, this would be a great add in for the code editor....
 
T

tcb

Well, this has been a great discussion for me thank both of you for
your responses.

My main concern was, what is the proper syntax for referring to objects
in a form, from outside of that form (when you can't use Me.) Since
the expression builder was gone, I figured maybe there was a better
way, but apparently not.

And as you mentioned Albert (at least) 90% of the time, the code is
written in the same form. Anyhow I like your idea about deleting and
backspacing and have already used that ploy.

Regarding your comments Brendan, I have used that Michael Kaplan add-in
in the past, but haven't downloaded and tried it with 2003. Using the
With End With constuct is a good practice, but I often don't think that
far ahead. I'm more of a sword slasher than a fencer. Write a
statement, write another statement, and then suddenly there are a bunch
of them. Thanks to your influence I did go back and edit some of
those.

Tom Benson
Minneapolis
 

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