How can I dynamically select a Form Control in Design Mode? - ms-access

I'm writing a code in MS Access/VBA to change another Form from Normal Mode to Design Mode, then trying to pick a TextBox control and change it into Combobox.
The problem I'm facing now, is that I can't find a way to SetFocus to this control. In Normal Mode I can just write:
Form_Name.Control.SetFocus
But that code doesn't work when this form is in Design Mode. Is another way to Setfocus (via VBA) to this control , in another Form in Design Mode, like clicking manually in that control when editing in Design Mode?
**Edit: ** The correct would be Select the specific form control in Design Mode and not setting it focus

You can include/exclude controls from the current selection in Design View by setting the InSelection property on each control.
The following VBA code deselects all controls and then selects the specified control:
Function SetSelection(frm as Form, CtlToSelect as Control)
Dim ctl as Control
'Deselect All Controls
For Each ctl in frm.Controls
ctl.InSelection = False
Next
'Select Specified Control
CtlToSelect.InSelection = True
End Function
For more information, see the InSelection Property documentation on MSDN (even though this is for Access 2003, it also applies to later versions).

Related

MS Access - Change appearance of form when using "Filter by Form"

I have created a front and back-end database MS Access solution (I am limited to MS Access 2013) for my team, utilizing forms for data entry, lookup, and editing. It is working well, but every now and then a user will forget they are in "Filter by form", and enter data into the filter instead of the actual form. When they realize their mistake, they have to re-enter all of the data.
Is it possible to change the appearance of the form when you are in "Filter by Form"? For instance, change the background color, or add a text box notification so that it is very obvious to the user that they are in "Filter by Form"?
You could use the Me.FilterOn property to help determine whether the form filter (ie., Home→Advanced→Filter By Form ) is on.
You might need to play with it a bit but from my experiment, you could have something in the OnOpen event that checks the property and acts appropriately.
I believe the catch is that code won't execute when it's in Filter mode, so therefore, you'd have to make the default appearance the "Filter appearance" (perhaps add a Graphic or Textbox that says "Filter Mode"), and then if Me.FilterOn = False you can hide that label in the OnOpen event.
Also:
The Apply Filter button indicates the state of the Filter and FilterOn properties. The button remains disabled until there is a filter to apply. If an existing filter is currently applied, the Apply Filter button appears pressed in.
To apply a filter automatically when a form or report is opened, specify in the OnOpen event property setting of the form either a macro that uses the ApplyFilter action or an event procedure that uses the ApplyFilter method of the DoCmd object.
(Source)
More Information:
Office.com : Apply a filter to view select records (Form Filter)
expertsexchange : Determine if filter is applied
MSDN : Form.FilterOn Property (Access)

Prevent 'save design changes' for an open form when closing Access

I have a split form as my main interface in an Access 2010 application. As normal, users are able to resize the datasheet portion, reorder columns, etc.
However, I don't want them to save such changes when leaving the form. Each time the form is opened the default format should be loaded.
I've taken care of all but one closing method. To avoid them closing using the default close button I've set Border Style = None. Instead I have a Close Form button that uses DoCmd.CLOSE acForm, "Main_form", acSaveNo
But if the user clicks the close button for the Access application, it pops the 'Do you want to save changes to the design of form` dialog like always.
I looked into disabling the application's Close button, but messing with Windows API is beyond my skill (and there should be a way to accomplish this without going to extreme measures).
I found a way to do this. A combination of database options, form format options, and vba can do it.
Go to the 'Current Database' options screen in the main Access
options and uncheck 'Enable design changes in Datasheet view'. This will prevent all datasheet view design changes in the database, so you will have to go into design mode for any table changes. Users can still reorder and resize columns within a form, but Access no longer considers that a valid design change and will not prompt to save it no matter how you close the form
Set the form format property 'Save Splitter Bar Position' = No. The form will now clear any change to the bar location when the form is closed. Access got really weird on me about this setting, however. Once I had ever set the option to no, I could no longer use design view or layout view to set a new default bar position; it always reverted to the location where it was when I first tried this setting. Even resetting the option to Yes, saving the design change, and fully exiting the database did not fix this.
So I added an On Load event to reset the split form size when the form opens: Me.SplitFormSize = 9000. The numbers involved are surprisingly high; in the form properties list this is set in inches. Mine was 6.5", which apparently translates to 9000.
With these three changes (along with the steps I detailed in the question) Access no longer prompts to save design changes when the form is closed, even if the user is closing the Access application entirely. The form also snaps the split form bar back to where it should be on load.
Since the API is beyond my skill too, here is a left-field workaround.
Duplicate Main_Form and rename it "Main_Form_Template". Create an Autoexec module or edit an existing one and add:
DoCmd.DeleteObject acForm, "Main_Form"
DoCmd.CopyObject , "Main_Form", acForm, "Main_Form_Template"
That should reinstate the standard template for the user each time they open the database even if they were to save the form when closing Access.
Turn your close button off on the form.
On the form's property sheet, format tab, about 2/3 of way down. Set Close Button = No
This forces the user to close it via the button you created.

Form Open is hiding and disabling the Navigation Pane

I am debugging an access application built by another developer. As I debug, I want to be able to see the results of specific queries and tables as I go. On one particular form, the navigation pane (which includes the list of tables, queries, forms...etc) is minimized and disabled any time the form is open. The navigation then maximizes and is fully restored when the form is closed or in design mode.
I've searched throughout the VBA and there doesn't seem to be anything that's controlling this behavior. I know there is some VBA that can do this like
DoCmd.NavigateTo "acNavigationCategoryObjectType"
DoCmd.RunCommand acCmdWindowHide
but none of these can be found in the code behind. Any idea what else might be causing this?
The Modal property of the Form will cause such behavior when set to true.
You can set that property on the property sheet for that form in the "Other" tab. It can be set by VBA-Code with code like this:
Forms("yourForm").Modal = True '(or False to disable)

View Form Creation Code in Access VBA?

Is it possible to view the form creation code in Access VBA? I don't mean the event listener code that is viewable in the VBE from View>Code in the form's Design View. I mean the code that is used to create the components, and add them to the form. I would like to programatically set Form properties; doing this from the Properties dialog is quite slow (and annoying).
Yes, it's possible to create a form to design.
Vba include CreateControl Method (see MSDN Office-11 Control )
And you can add to this controls any event procedure like OnClick, OnFocus, etc. (see MSDN Office-11 Event
You can manipulate the width, height, etc.. properties as simple as me.control.width
I developed some time ago a form that could customized OnResize event to create different views depend of screen resolution and use all of this.
In theory you could get the form definition from the system table where it is stored (MSysObjects), but it isn't in a format that is practical to work against.
In theory you could avoid using the graphical designer to layout your form and create all the controls/set their properties dynamically in the form_load event. However, this wouldn't be much of a time-saver.
Assuming the gist of the question is whether there is an XML like declarative way to define a form layout similar to WPF. The answer is no.
All (?) the properties can be set through VBA for both the form and the controls.
Sub FormInDesignView()
Dim frm As Form
Dim ctl As Control
Set frm = Screen.ActiveForm
frm.Caption = "New"
For Each ctl In frm.Controls
ctl.Name = "txt" & ctl.Name
ctl.ForeColor = vbRed
Next
End Sub
No, it is not directly possible to do what you want. But if you insisted, you could use the undocumented Application.SaveAsText/LoadFromText commands and process the resulting text file.
Why you think this is a useful way to work in Access, I haven't a clue -- it's completely antithetical to the purpose and design of Access. Give up on your habits from other development tools and learn the Access way of doing things. You'll be a lot happier and productive in the long run.

Hide a column programmatically in MS-Access

I want to hide or show a column based on variable data from a users selection. How do you set a column to hidden in MS-Access 2003?
For Example,
After user change event...
For Each ctl In Me.FormNameHere.Form.Controls
If (TypeName(ctl) = "Textbox") Then
If InStr(GetTextList(), ctl.Name) > 0 Then
ctl.hidden = True
Else
ctl.hidden = False
End If
End If
Next ctl
What is the best approach to this type of challenge?
Is there a more obvious solution?
Controls do not have a "hidden" property (no objects in Access have a hidden property). They do have a .Visible property.
For future reference, I suggest you familiarize yourself with the Object Browser in the VBE -- open the VBE and hit F2. You can then restrict your search to the individual libraries used in your project. It does take a while to get to the point where you understand the object model, though.
Also, you can rely on Intellisense to learn the properties/methods of an object, so in the code of the form you're working with, you can type "Me.MyTextBox." and the Intellisense dropdown will show you all the properties and methods of that particular control. It doesn't work for a generic control variable (as in your code) because different control types have different properties.
And, of course, the properties sheet gives the names of the properties, even though in code they don't always use the same orthography (usually they are the same with spaces removed).
Also, there are differences in how you might want to do this depending on whether it's a regular form or a datasheet form. In a datasheet, your controls also have .ColumnHidden and .ColumnWidth properties (setting those in any view other than datasheet view has no effect, and neither of those properties are available in the standard property sheet, but changes to them are retained when you save the form).
I answered a similar question to this not long ago to do with hiding columns on a datasheet. However you seem to want to hide textboxes arranged in a column on a form, is that correct?
Iterating over all the controls in the form could be slow if you have many controls. If you really need to use textboxes like that, then you could try group the 'columns' together then hide the groups. Another approach would be to use a listbox or datasheet to represent the data, where you can alter the layout of the columns directly.
I found the ColumnHidden property does the trick.
For Each ctl In Me.FormNameHere.Form.Controls
If (TypeName(ctl) = "Textbox") Then
If InStr(GetTextList(), ctl.Name) > 0 Then
ctl.Columnhidden = True
Else
ctl.Columnhidden = False
End If
End If
Next ctl
I got a hint from this related question.
A one-liner approach is using:
forms(fname).Controls(ctrlname).columnhidden = false
where
fname is name of your form
ctrlname is name of your control