Learn Microsoft Access Advanced Programming Techniques, Tips and Tricks.

Saturday, March 28, 2009

MS-Access and Reference Library

Introduction

When developing an Access database, we often use several object libraries in addition to the default reference libraries. These include Microsoft Data Access Objects (DAO), Microsoft ActiveX Data Objects (ADODB), and Visual Basic for Applications (VBA), among others. They are essential for creating data processing routines in VBA.

I briefly touched on this topic in my first article on this site, Command Button Animation, where I recommended linking these libraries manually before attempting to run the sample program provided there. The same article also listed the essential library files and the procedure to manually attach them to your database.

Some libraries—such as Microsoft Access 9.0 Object Library, Visual Basic for Applications, and OLE Automation—are attached by default when a new database is created. Additional libraries can be added manually as needed. We add new reference libraries to take advantage of the powerful features, which are not included in Access by default.

For example, we have used the Microsoft Office Library to create customized message boxes, option balloons, check boxes, and other controls. The Office Assistant is an interesting feature, which we used to capture user responses. We even created a wizard that allows users to select an Office Assistant character—such as Clippy, the Cat, or others—directly from Access, without the built-in Office Assistant options.

Databases and tables can be accessed in VBA only when either the Microsoft DAO or Microsoft ADODB library is referenced in your database.

If you have written your own custom functions, you can store them in a separate database on the server.  Attach that database as a Library Database, eliminating the need to copy and paste those functions into other databases.

You can use the Object Browser in the VBA editor (View → Object Browser) to explore the properties, methods, and classes provided by each referenced library.

Library Reference and Physical Files.

Most of the time, we work with a fixed set of library references in our databases. These libraries are typically attached manually through Tools → References in the VBA editor, one by one. Although this is usually a one-time setup task, it can become tedious when starting a new project—or necessary again if references are lost, such as after recovering a corrupted database.

Fortunately, this process can be automated. With a simple VBA routine, we can programmatically attach all required library files to a new project or restore missing links automatically whenever needed.

Before we look at the VBA code, let’s review the few preparatory steps required to accomplish this.

  1. Prepare a list of essential Library References and save it in a Text File, on the Server if you are developing databases to use on a Network.

  2. Write a VBA routine to read this list from the Text File and attach it to the Project.

  3. To prepare the required Object Library References List, we must know the details of these files and the Folder on the Disk where they can be located. Assume that we need to know the physical file name and location representing the Reference Library Description Microsoft DAO 3.6 Object Library in the Available References list.

To verify this, open the VBA Module Window by selecting View → Code or pressing Alt + F11. Then, from the menu, choose Tools → References. In the References dialog box that appears, scroll through the list and locate the item Microsoft DAO 3.6 Object Library among the other available Microsoft reference libraries. Refer to the image below for guidance.

When you select the file Description, the physical File path name and Language are displayed. You can write down the Pathname to prepare the list if you want to. But we will do half of the task differently. We can attach the required files manually and prepare the list with a small VBA Routine.

Display List of Library Files with VBA

Following is a list of References that I use regularly to start with my Projects, and we will use them as an example:

The first three items will be automatically selected by MS Access when you create a new Database. Others must be added manually.

  1. Attach the above list of Library References manually.

  2. Copy and paste the following lines of code into a Standard Module of your Project and save it.

    Public Sub ReferenceList()
    Dim Ref As Reference
    For Each Ref In Application.References
       Debug.Print Ref.FullPath
    Next
    End Sub
    
  3. Press Ctrl+G to display the Debug Window (Immediate Window) if it is not already visible.

  4. Click in the middle of the Code, press F5 to run it, and print the following Path Names of the selected Reference Library Files in the Debug Window.

  1. C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6.DLL

  2. C:\Program Files\Microsoft Office\OFFICE11\MSACC.OLB

  3. C:\WINDOWS\system32\stdole2.tlb

  4. C:\Program Files\Common Files\Microsoft Shared\DAO\dao360.dll

  5. C:\Program Files\Common Files\system\ado\msado15.dll

  6. C:\Program Files\Common Files\Microsoft Shared\OFFICE11\MSO.DLL

  7. C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB

  8. D:\MDBS\aprRefLib.mde

Project Names of Library Files.

The internal names (Project Names) of the above library files differ from their file names, and it is essential to know the details about them. If you ever need to remove any of these libraries from the current project through code, you must reference them by their Project Name rather than by the file name.

When you create the MS-Access database with the name abcd.mdb, by default, the same name abcd will be inserted into the Project Name control in the database. You can check the Project Name of your database by selecting the Tools Menu in the VBA Editing Window. You will find a Menu Option like abcd Properties. You can open this option and set a different name in the Project Name control if needed.  If you create a Standard Module with the name abcd, you will run into Error: Name Conflicts with Existing Module, Project, or Object Library

Note: You may change the Project Name, but you are not allowed to use any of the Standard Modules' Names.

You can read this Property Value in programs or in the Debug Window using the statement x = Application.GetOption("Project Name").

Or modify the Project Name with a statement like Application.SetOption "Project Name", "Myabcd"

The list of library files mentioned above also includes their unique Project Names, which are the internal object library reference names that will appear in your database once linked. You can verify these names by opening the Object Browser (View → Object Browser or F2) and clicking the drop-down list. You will also notice that the Project Name of your current database (for example, abcd) appears among the list.

Let us inspect the Project Names of the first three files in the list given above.

  • VBA
  • Access
  • Stdole

    When you create a new database, MS Access attaches the above three references by default, and they are important too. So we will exclude them from our add/remove operations.

    These names are unique irrespective of which version of Access you are using, and the same goes for the other Library References as well.

    If you attempt to attach a different version of a reference library that shares the same Project Name, a conflict may occur. To prevent this, we need to pay special attention to two additional references and ensure they are not removed before attaching the items from our list.

  • abcd (current database project name)
  • aprRefLib (you can read this as your own Function Library Project Name, and I will come to that later in this article.)

Leaving aside the above five items, we are left with the following four Reference Libraries selected out of the eight items listed above to attach to our new Projects automatically:

C:\Program Files\Common Files\Microsoft Shared\DAO\dao360.dll

C:\Program Files\Common Files\Microsoft Shared\OFFICE11\MSO.DLL

C:\Program Files\Common Files\system\ado\msado15.dll

C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB
  1. Open Notepad.exe, copy and paste the above File Names, and save them on your Server's common location where all your MS-Access Projects are installed.

  2. Let us call the Server PathName (the Location and File Name) of the target text file as

\\hosfs03\InhouseSys\CommonLib\RefLib.txt

The first stage of our preparation is now complete. The next step is to create a VBA program that can read the contents of the text file above and automatically link the reference library files (as shown in the second image) to your new project.

The VBA routine is provided below, but you have two options for where to place the code. The second option—copying the code into each new project and running it from there—is not recommended, as it leads to unnecessary duplication. Instead, choose the first option and do some ground work now by following the steps below. This approach will make future development easier, allowing you to reuse common routines across all projects without duplicating code.

If you haven’t already started building a Reference Library Database of your own, now is the perfect time. It’s straightforward to create, and you’ll quickly see how useful it can be.

Attaching Missing Library Files with VBA

  1. Create a new Database with the name MyLib.mdb and save it to your Server's Common Location. Let us insert this location address, like the one we have saved in our Text File with the list.

  2. Open the VBA Editing Window (Alt+F11).

  3. Create a Standard Module (Insert -> Module) to create an empty Code Module with the name Module1. You can change the name of the Module after displaying its Property Sheet (View ->Properties Window).

  4. Copy and paste the following Code into the Module; save and close the VBA Editing Window.

Public Function AddReferences()
Dim j As Integer, i As Integer, msg As String
Dim Ref As Reference, RefObj As Object
Dim RefPath As String, LibName As String
Dim LibPath As String, libAttached() As String
Dim refcount As Integer, chk_flag As Boolean
Dim lib_Attached As String, validate As Boolean

Const LibraryList As String = "\\hosfs03\InhouseSys\CommonLib\RefLib.txt"

On Error GoTo AddReferences_Err

validate = Ref_Retain_Remove()
If validate = False Then
   msg = "Errors Encountered in Validation check, Program aborted. "
   Exit Function
End If

Set RefObj = Application.References
refcount = Application.References.Count
ReDim libAttached(1 To refcount) As String
i = 0
'Prepare list of exiting attached Library Files
For Each Ref In RefObj
    i = i + 1
    libAttached(i) = Ref.FullPath
Next'Open text file with List of required Reference Library files
Open LibraryList For Input As #1
msg = ""
Do While Not EOF(1)
    Input #1, LibPath
    chk_flag = False
    For j = 1 To i'check for missing cases
        lib_Attached = libAttached(j)
        If libAttached(j) = LibPath Then
            chk_flag = True
            Exit For
        End If
    Next
    If chk_flag = False Then 'Reference found missing, add to the Project
        Set RefObj = Application.References.AddFromFile(LibPath)
        msg = msg & LibPath & vbCr
    End If
Loop
Close #1

If Len(msg) <>  0 Then
    msg = "Following References Attached: " & vbCr & vbCr & msg
End If

MsgBox msg, , " AddReferences()"

AddReferences_Exit:
Exit Function

AddReferences_Err:
MsgBox Err.Description, , "AddReferences()"
Resume AddReferences_Exit
End Function

Public Function Ref_Retain_Remove() As Boolean
Dim Ref As Reference, Reflist(), exclusion(1 To 5) As String
Dim ref_count As Integer, strRefName As String
Dim i As Integer, j As Integer, chk_flag As Boolean

On Error GoTo Ref_Retain_Remove_Err

exclusion(1) = "VBA"
exclusion(2) = "Access"
exclusion(3) = "stdole"
exclusion(4) = Application.GetOption("Project Name")
'Replace this line with your own Reference Library Name
exclusion(5) = "aprRefLib"

ref_count = Application.References.Count

If ref_count > 4 Then
    ReDim Reflist(1 To ref_count)
    i = 0
    For Each Ref In Application.References
       strRefName = Ref.Name
       chk_flag = False
       For j = 1 To 5
          If strRefName = exclusion(j) Then
              chk_flag = True
              Exit For
           End If
        Next
        If chk_flag = False Then
            i = i + 1
       'Collect the Reference Library Project Names, if any, other than
       'the Names in the exclusion list to remove them
       'before attaching the new ones, to avoid Project Name conflict.
            Reflist(i) = Ref.Name
        End If
    Next
    ReDim Preserve Reflist(1 To i)'Remove the collected Reference Libraries
    For j = 1 To i
        Set Ref = References(Reflist(j))
        References.Remove Ref
    Next
End If

Ref_Retain_Remove = True

Ref_Retain_Remove_Exit:
Exit Function

Ref_Retain_Remove_Err:
MsgBox Err.Description, , "Ref_Retain_Remove()"
Ref_Retain_Remove = False
Resume Ref_Retain_Remove_Exit
End Function

Note: Before closing the database, you can save a compiled copy of your Library Database by selecting Tools → Database Utilities → Make MDE File and naming it, for example, MyLib.MDE. Save it in the same location as the .mdb file, and you can move the .mdb file to a private location where others cannot access it.

Whenever you add new common routines to the library, you can recompile and replace the existing .MDE file. This makes the updated programs available to all your projects without modifying them. You can attach your Library Database (MyLib.MDE) along with others to all current and future projects.

We have two programs: the second one validates existing attached references and removes unnecessary ones, leaving only the essential references mentioned earlier to avoid conflicts.

The Demo Run from a new Database

The preparations are in place, and we are going to do a Trial Run.

  1. Create a new Database.

  2. Open the VBA Editing Window (Alt+F11).

  3. Open the Debug Window (Immediate Window) . . . Ctrl+G.

  4. Type the following line in the Debug Window and press Enter so that we can attach your own Common Library File MyLib.mde and run the main program AddReferences() from there:

Note: Change the Server Location address to match your own.

Application.References.AddFromFile("\\hosfs03\InhouseSys\CommonLib\MyLib.mde")

If you select Tools -> Reference, you can see that your own Library File is now attached to your Project.

We can now call the AddReferences program from your Function Library from the Debug Window and attach the other Library Files List we created in the Text File.

Type the following line in the Debug Window and press the Enter key to do that:

AddReferences

You can now check the Reference Library List to confirm that all the required files are in place. In your next project, all you need to do after creating a new Database is to type the following two lines in the Debug Window and press the Enter key to add all required Reference Libraries to your Project at once:

Application.References.AddFromFile("\\hosfs03\InhouseSys\CommonLib\MyLib.mde")

AddReferences

Friday, March 20, 2009

Inputbox and Simple Menus

Introduction.

We have already learned how to create menus and toolbars through the following articles:

The InputBox() function is one of the first tools we encounter when learning VBA, but it is often discarded later in favor of more “exciting” objects like MsgBox(). This neglect is unfortunate because the InputBox() function is simple to use—just like MsgBox()—and is a useful way to gather user input directly.

While MsgBox() is the more commonly used option and offers a variety of command buttons (OK, Cancel, Retry, Yes, No, etc.), it cannot be programmed to allow selections from user-defined options—a capability that InputBox() provides.

We have also explored how to use the Office Assistant with a preferred animation character as an alternative to MsgBox(), collecting user responses through checkboxes or option balloon menus. Admittedly, the VBA routines involved in these methods are more complex and take some time to fully understand. However, once implemented, these routines are easy to use and can be freely incorporated into your code across projects—especially if stored in a library database and linked to other projects.

A Simple Example

Coming back to the InputBox() function, let’s look at a simple example used within a subroutine.

Imagine a Report Command Button on the Main Switchboard: when the user clicks this button, a small menu appears asking whether they would like to:

  1. Preview the Report,

  2. Print the Report directly to the printer, or

  3. Exit, if they change their mind.

The simplest form of the InputBox() function syntax is:

X = InputBox("Message Text", "Title", DefaultValue)
  • Message Text → Appears in the body of the dialog box.

  • Title → Appears in the title bar of the InputBox window.

  • DefaultValue → (Optional) The initial value that appears in the text box.

The Title and Default Value parameters are optional. (There are other optional parameters as well—refer to the Microsoft Access Help documentation for details.)

In our example, we’ll use 1 as the third parameter (Default Value). This means that when the InputBox appears, the value 1 will already be displayed in the text box, as shown in the example image below.

The Code that brings this Form up with a Command Button Click Event Procedure is given below.

Private Sub cmdRpt_Click()
Dim varResponse as Variant

varResponse = InputBox("(1) Print Preview (2) Print (3) Exit", "Select 1/2/3",1)

Select Case varResponse
    Case 1
        DoCmd.OpenReport "Orders", acViewPreview
    Case 2
        DoCmd.OpenReport "Orders", acViewNormal
    Case 3
        Exit Sub
End Select

End Sub

When the user makes a selection from the options provided, the chosen value is evaluated using the Select Case... End Select statement, and the corresponding action is executed.

Note:
The InputBox() function displays a small form whose Border Style property is set to Dialog. As a result, the Minimize, Maximize, and Restore buttons are removed from the title bar, leaving only the Close button.

Additionally, while the InputBox is open, you cannot click on any other form or object within the Access application window. This behavior indicates that the InputBox operates with its Modal property set to Yes—it must be closed or completed before returning control to other parts of the application.

We have already explored the usage of Pop-up, Modal, and other related form properties in our earlier discussions on Form design and behavior, particularly in the following articles:

Taking Care of Pitfalls

While using the InputBox() function this way in programs, we must take care to avoid a few undesirable side effects and also pay attention to improving the appearance of the menu.

Let us first deal with the side effects. We have provided Option 3 to close the dialog box normally if the user changes her mind after opening the menu. However, she might ignore Option 3 and instead use the Close button on the title bar or click Cancel, and that can cause problems in the code.

Since the option values in the menu are defined as integers (1, 2, and 3), it is natural to use an Integer variable to capture the user’s response. But if the user closes the window using the Cancel button or the Close control, the InputBox() function returns an empty string (""). If this value is assigned to an Integer variable, a Type Mismatch error will occur, and the program will crash.

To avoid this, we can declare the variable as a String, which can safely receive an empty string. The Select Case... End Select structure will still work correctly even though we are testing for numeric values, because VBA automatically handles the type conversion in this context. A better alternative, however, is to use a Variant variable, which can accept any data type and gives more flexibility.

With a small trick, we can also make the program ignore Cancel and Close button clicks, forcing the user to choose one of the defined menu options if she wants to exit the menu normally.

We have inserted 1 as the third optional parameter value in the InputBox() function to handle the case where the user clicks OK without entering anything in the text box. If she types one of the option values and presses Enter, as expected, that value will be returned into the varResponse variable, and the InputBox() will close normally.

We will modify the above Code:

  1. To make a real Menu with a good appearance.

  2. To ignore the Cancel Command Button and Window Close Title Bar control clicks.

  3. To prepare the Menu, we will define a string Variable and write the following expression before inserting it into the InputBox() Function:

    Dim strMenu as String
    
        strMenu = "1. Report Preview" & vbCr & vbCr
    
        strMenu = strMenu & "2. Print Report" & vbCr & vbCr
    
        strMenu = strMenu & "3. Exit"
          
  4. We will place the InputBox() function inside a Do While...Loop structure. This ensures that the menu keeps reappearing until the user makes a valid selection from the available options. In this setup, the user will not be able to exit the dialog box by clicking the Cancel button or the Close control on the title bar. The loop will continue to prompt the user until a valid response—such as 1, 2, or 3—is entered.

varResponse = ""
Do While Len(varResponse) = 0 Or varResponse < 1 Or varResponse > 3

       varResponse = InputBox(strMenu, "Select 1/2/3",1)

  Loop

After the above changes, the Menu will look like the following image:


Modified VBA Code

The modified code is given below:
Private Sub cmdRpt_Click()
'------------------------------------------------------------
'Author : a.p.r. pillai
'Date : March-2009
'URL  : www.msaccesstips.com
'All Rights Reserved by www.msaccesstips.com
'------------------------------------------------------------
Dim varResponse As Variant
Dim strMenu As String

strMenu = "1. Report Preview" & vbCr & vbCrstrMenu = strMenu & "2. Print Report" & vbCr & vbCrstrMenu = strMenu & "3. Exit"

varResponse = ""
Do While Len(varResponse) = 0 Or varResponse < 1 Or varResponse > 3
    varResponse = InputBox(strMenu, "Select 1/2/3", 1)
Loop

Select Case varResponse
    Case 1
        DoCmd.OpenReport "Orders", acViewPreview
    Case 2
        DoCmd.OpenReport "Orders", acViewNormal
    Case 3
        Exit Sub
End Select

End Sub

Probably the next question that comes into one's mind is, do we have to use the Menu Options always in the form 1,2,3, etc., can we use alphabet instead, like

  • R. Report Preview
  • P. Print Report
  • E. Exit?

Yes, we can with a few changes in the Code as given below:

strMenu = "R. Report Preview" & vbCr & vbCr
strMenu = strMenu & "P. Print Report" & vbCr & vbCr

strMenu = strMenu & "E. Exit"

varResponse= ""

Do While instr(1, "RPE",varResponse)=0 or len(varResponse)=0
    varResponse = InputBox(strMenu, "Select R/P/E", "R")

Loop

The Select Case... End Select statements must be changed to:

Select Case varResponse
  Case "R"

      DoCmd.OpenReport "Orders", acViewPreview

  Case "P"

      DoCmd.OpenReport "Orders", acViewNormal

  Case "E"

      Exit Sub

End Select

Option Alphabet Values

The changed Code with alphabet as Options is given below:

Private Sub cmdRpt_Click()
'------------------------------------------------------------
'Author : a.p.r. pillai
'Date : March-2009
'URL  : www.msaccesstips.com
'All Rights Reserved by www.msaccesstips.com
'------------------------------------------------------------
Dim varResponse As VariantDim strMenu As String

strMenu = "R. Report Preview" & vbCr & vbCr
strMenu = strMenu & "P. Print Report" & vbCr & vbCr
strMenu = strMenu & "E. Exit"

varResponse = ""

Do While InStr(1, "RPE", varResponse) = 0 Or Len(varResponse) = 0
    varResponse = InputBox(strMenu, "Select R/P/E", "R")
Loop

Select Case varResponse
    Case "R"
        DoCmd.OpenReport "Orders", acViewPreview
    Case "P"
        DoCmd.OpenReport "Orders", acViewNormal
    Case "E"
        Exit Sub
End Select

End Sub

Friday, March 13, 2009

Change Form Modes on User Profile

Introduction

We have already learned how to define a Pop-up Form and control its on-screen position when it opens. We also saw how a Form’s behavior can be managed by setting or modifying its property values—such as Pop-up, Border Style, or Auto Center—during design time.

Now, we will try something different and try to change the Form opening Mode (Data Entry Mode or Edit/Search Mode) at runtime automatically based on the identity of the Current User of the Form. When the Database is shared on a Network, the same Form can be opened by different Users, and the Form should behave differently for each User or User Group.

For Example, a single Form can be used for Data Entry by one group of users, who are allowed only to key in new records, and others are allowed to view, edit, and search, but are not allowed to add new records. Data Entry Users can also edit data during the current data entry session.

This distinction in Form behavior can be implemented by checking the current user’s security account or group membership and adjusting the Form’s Data Entry and Allow Additions property values accordingly at runtime.

Checking the Current User's credentials

We need a small VBA program to check the Current User's Group Account information to determine whether the user belongs to the DATAENTRY Group Account or not (the User Workgroup name DATAENTRY is used only as an example). Accordingly, the program will set the Mode of the Form for the current session.

The VBA Routine is given below:

Public Function ChangeFormMode(ByVal strFormName As String, ByVal UserGroupName As String)
'----------------------------------------------
'Author : a.p.r. pillai
'Date   : Feb-2009
'All Right Reserved by www.msaccesstips.com
'----------------------------------------------
Dim wsp As Workspace, strUser As String
Dim j As Integer, frm As Form
Dim chkFlag As Boolean, GrpCount As Integer

On Error GoTo ChangeFormMode_Err

Set frm = Forms(strFormName)
strUser = CurrentUser
Set wsp = DBEngine.Workspaces(0)
GrpCount = wsp.Users(strUser).Groups.Count
'checks whether 'DATAENTRY' Group Name is present
'within the User's Group Account Names.
chkFlag = False
For j = 0 To GrpCount - 1
    If wsp.Users(strUser).Groups(j).Name = UserGroupName Then
        chkFlag = True
        Exit For
    End If
Next
If chkFlag Then
    frm.DataEntry = True
    frm.AllowAdditions = True
Else
    frm.DataEntry = False
    frm.AllowAdditions = False
End If

ChangeFormMode_Exit:
Exit Function

ChangeFormMode_Err:
MsgBox Err.Description, , "ChangeFormMode"
Resume ChangeFormMode_Exit
End Function

Copy and paste the above program into a Global Module (Standard Module) in your database and save it. The program is called from the Form_Load() Event Procedure of the Form with the Form Name and the User Group Account name as parameters, as follows:

Private Sub Form_Load()
   ChangeFormMode Me.Name, "DataEntry"
End Sub

About Security Accounts

A security User Account can belong to one or more Security Group Accounts, in addition to the default Users group to which all users automatically belong. Therefore, when determining how a Form should open, we must check the Security Groups to ensure that the current user belongs to. If the user belongs to the Data Entry Group, the Form’s open mode can be changed accordingly.

Note: For this method to work, the database must be secured by implementing Microsoft Access User-Level Security. It is assumed that users are organized into different workgroups, such as Data Entry, Team Leaders, or Managers, each with specific permission settings. For more information on setting up and managing Access Security, refer to the Security section in the main menu.

If your machine is not configured to use a common MS-Access Work Group Information file or if you have not implemented MS-Access Security using the local Work Group Information File, then you are automatically logged in using the default User Account Admin, a member of the Admins and Users Group. This is happening silently, and you are not asked to enter a User ID or Password. In that case, you can try this procedure with the Admins or Users' workgroup name as a parameter to the above Program.

Form View Mode Changing Manually

However, if all users need access to both features—Data Entry and Edit/Search—interchangeably at their discretion, this can be implemented using a Command Button on the Form. Since this method is manually controlled by the user, there is no need to check the Security User Account or Group Account details.

All we need is a Command Button placed in the Form Footer, with a specific Caption value that can be checked and toggled each time the button is clicked. This button will switch the Form mode between Data Entry and Normal.

Assume that the Form initially opens in Edit/Search Mode by setting the following Property Values at design time:

  • Data Entry = False
  • Allow Additions = False

The Caption of the Command Button will be set to Data Entry, indicating that if the user wishes to switch the Form into Data Entry Mode, she can simply click the button. Since the same Command Button is used to toggle between the two modes, we must check its Caption value each time it is clicked to determine the user’s intention. The user may click the button repeatedly to switch between modes.

With every click, the program should verify the current Caption value, change the Form’s Mode accordingly, and then update the Command Button Caption to Edit/Search or Data Entry alternately.

Form Mode change with VBA

We can implement this in a few lines of Code on the Form's Class Module itself. The Command Button's Name Property Value is cmdEdit.

Private Sub cmdEdit_Click()
If Me.cmdEdit.Caption = "Data Entry" Then
     Me.cmdEdit.Caption = "Edit/Search"
     Me.DataEntry = True
     Me.AllowAdditions = True
 Else
     Me.cmdEdit.Caption = "Data Entry"
     Me.DataEntry = False
     Me.AllowAdditions = False
End If
End Sub

The above technique is for a different function on a Form, and you can visit the article titled: Double Action Command Button.

Earlier Post Link References:

Saturday, March 7, 2009

Positioning Pop Up Forms

Introduction

We saw the Pop-up Form in action last week in the article titled Synchronized Floating Pop-up Form. I hope you had a chance to download and explore the demo database as well.

I know I don’t have to speak at length about Forms and their importance in a database — they are, after all, the most essential objects we work with when developing a new project. Microsoft Access Forms are, in many ways, far superior to those designed in Visual Basic.

There was an interesting incident in our office. A Visual Basic Application developed by our Computer Department was installed on one of my colleagues' machines. My friend got a brief introduction from the developer, and he started exploring the new Application.

I was developing in-house Access applications for the Audit Department, sitting just a few workstations away from a friend. After about half an hour, he called me over for some help. I was curious to see what he was working on, so I walked over to his desk. The moment I saw the screen, I immediately understood why he had called me. I couldn’t help but smile — and feel a quiet sense of pride in MS Access Forms, even though I knew that Visual Basic could do many things that Access couldn’t.

Screen Resolution and VB Form

A few years ago, before LCDs came into existence, Computer Monitors were used with 640 x 480 Resolution, and Users preferred to maintain this way because dBase and FoxPro 2.5/3.0-based Applications were also running on their machines. Some Monitors can be set with higher resolutions. When VB Forms are designed on high-resolution Screens and installed on computers with 640 x 480 resolution, the Form will overlap the Screen. Unlike MS-Access Forms, VB Forms don't auto-fit to the current resolution of the Screen.  

The VB Application's Main Switchboard Form overlaps all four sides of the Screen on my colleague's machine, and some controls on the Form, like the Command Buttons and Options Group controls at the left/right edges, are only partially visible on the screen. The Form was designed with a machine having a higher resolution, without knowing the target machine's screen resolution, and ended up this way.  After installation, the programmer didn't bother to do a trial run either.

As far as I know, VB Form doesn't have any Control Buttons (Min/Max, Restore, and Close) on the Title Bar; no sizing handles, no Header/Footer Sections, and it is not able to define Pages, and it looked like an oversized wooden board placed behind the screen frame.

I really felt a few inches taller when positive remarks came from the Users of my MS-Access Databases.

Access Forms have several Properties, and setting the appropriate values will change their behavior. We can create custom Form properties for specific use. We have set the Pop-up Property Value to Yes in the previous Article to position the EmployeeSub Form above all other Forms.

Popup Form extends Beyond Application Window

When the Database Window is maximized, any form you open in normal mode will automatically expand to fill the same maximized state. However, if the Pop-up property is set to Yes, the form will open in its original designed size, regardless of the database window state. The same behavior occurs if you set the Border Style property to Dialog or Thin, instead of enabling the Pop-up property. But note that doing so removes the Minimize, Maximize, and Restore buttons from the form’s title bar. Setting the Border Style property to None removes the title bar entirely.

It’s a well-known fact that all MS Access objects, such as Forms and Reports, open and remain confined within the Access application window. You can’t normally move any of them outside the boundaries of the Access window, right?

Wrong, you can try this to find out:

  1. If the Access Application Window is in the maximized state, click the Restore Down control button (the middle one between Minimize/Maximize and Close buttons) on the Title bar. There is a Window sizing control at the bottom right corner of the Application window. When you place the mouse pointer there, it will change into a double-headed arrow. Click and drag the corner up, moving the mouse towards the top-left corner of the screen, so that the MS-Access Application Window reduces to about half its size or makes it even smaller. You must be able to see one of your Popup Forms in the database window, and next, you will open it.

  2. Open one of your Popup Forms, and you will see that it overlaps the Application Window.

  3. If you didn't make the Application window small enough, then click on the Title Bar of the Pop-up Form and drag it out of the Application Window. You can place both the Pop-up Form and Application Window side by side or place the Pop-up Form over the small Application Window to hide it completely.

  4. Do not attempt to minimize the MS Access application window while a Pop-up form is open. If you do, the Pop-up form will immediately “jump in” and hide itself along with the application. Likewise, if the Access window is resized to a small area, the Pop-up form may appear over the application window, potentially hiding it completely from view.


Positioning PopUp Form

Forms have another Property Auto Center. Usually, this property is set to Yes along with the Pop-up Property settings to make the Form appear in the middle of the Application Window.

But, what if we want the Pop-up Form to appear in the top right corner, or bottom right corner, or any place other than the center of the Screen? There are no Property settings to make this happen. But there is a simple way to get this done, try the following method:

  1. Maximize the Application Window.

  2. Open a Pop-up Form in Design View.

  3. Display the Property Sheet of the Form (View -> Properties) and see that the Auto Center property is set to No.

  4. If the Form's design frame is larger than the actual design size, then reduce the design frame size by dragging the bottom right corner to the desired size.

  5. Click on the Title Bar of the Form and drag it to the right top corner (or any other position you prefer) and place it there.

  6. Click on the Save Toolbar Button or select Save from the File Menu.

  7. Close the Design view of the Form.

  8. Now, Open the Form in Normal View. The Form will appear where you have placed and saved it in the design view.

Tip: This works not only for Popup Forms, and for all other Forms.

Powered by Blogger.