<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7457417942281874810</id><updated>2026-07-16T23:28:30.422+05:30</updated><category term="Forms"/><category term="Functions"/><category term="How Tos"/><category term="MS-Access Security"/><category term="Reports"/><category term="msaccess forms"/><category term="Animations"/><category term="msaccess animation"/><category term="Utilities"/><category term="msaccess controls"/><category term="Access and Internet"/><category term="MS-Access Scurity"/><category term="MS-Access and Internet"/><category term="Class Module"/><category term="External Links"/><category term="Queries"/><category term="Array"/><category term="msaccess reports"/><category term="Accesstips"/><category term="WithEvents"/><category term="msaccess tips"/><category term="Downloads"/><category term="Objects"/><category term="Menus and Toolbars"/><category term="Collection Object"/><category term="MsaccessLinks"/><category term="Process Controls"/><category term="Art Work"/><category term="Property"/><category term="msaccess How Tos"/><category term="Combo Boxes"/><category term="Dictionary Object"/><category term="ListView Control"/><category term="Query"/><category term="VBA"/><category term="msaccessQuery"/><category term="Calculation"/><category term="Event"/><category term="Graph Charts"/><category term="ImageList Control"/><category term="List Boxes"/><category term="TreeView Control"/><category term="Command Buttons"/><category term="Controls"/><category term="Data"/><category term="Emails and Alerts"/><category term="Form"/><category term="Custom Functions"/><category term="Custom Wizards"/><category term="DOS Commands"/><category term="Data Type"/><category term="Key"/><category term="Object Reference"/><category term="ms-access functions"/><category term="msaccess functions"/><category term="msaccess graphs"/><category term="msaccess reporttricks"/><category term="Command Button"/><category term="Report"/><category term="msaccess menus"/><category term="msaccessprocess"/><category term="security advanced"/><category term="Access Security"/><category term="Add"/><category term="Auto-Number"/><category term="Field Type"/><category term="Form Instances"/><category term="ImageList"/><category term="Item"/><category term="Macros"/><category term="Menus"/><category term="Nodes"/><category term="RaiseEvent"/><category term="Recordset"/><category term="Top Values"/><category term="Variables"/><category term="Wrapper Classes"/><category term="msaccess email"/><category term="progressmeter"/><category term="Access2007"/><category term="Copy"/><category term="Excel"/><category term="Export"/><category term="Expression"/><category term="Fields"/><category term="Join"/><category term="Methods"/><category term="Microsoft"/><category term="Numbering System"/><category term="Records"/><category term="Security"/><category term="Split"/><category term="SubForm"/><category term="Table"/><category term="Tables"/><category term="Time Difference"/><category term="Utility"/><category term="WScript"/><category term="Workgroup"/><category term="database"/><category term="function"/><category term="msaccess wizards"/><category term="tutorial"/><category term="Access Emails and Alerts"/><category term="Access Fields"/><category term="Access How Tos"/><category term="Access Mail Merge"/><category term="Access2003"/><category term="Accounting Year"/><category term="Action"/><category term="Animation"/><category term="Attachment"/><category term="Binary Numbers"/><category term="Bookmarks"/><category term="Budgeting"/><category term="ChDir"/><category term="Color Palette"/><category term="Common Controls"/><category term="Conditional Formatting"/><category term="Data Filtering"/><category term="Database Records"/><category term="Defining Pages"/><category term="Desktop Shortcuts"/><category term="Diagram"/><category term="Disk"/><category term="Dynamic Lookup"/><category term="Error Handler"/><category term="External"/><category term="Filter"/><category term="Formatting"/><category term="Groups"/><category term="Hexadecimal Numbers"/><category term="Import"/><category term="Labels"/><category term="List"/><category term="Logo"/><category term="Macro"/><category term="Mail Merge"/><category term="Main Form"/><category term="Memo"/><category term="Message Box"/><category term="Monitoring"/><category term="Octal Numbers"/><category term="Operating System"/><category term="Paste"/><category term="Primary-Key"/><category term="Product"/><category term="Rank"/><category term="Reading"/><category term="Remove"/><category term="Rich Text"/><category term="Sequence"/><category term="SetFocus"/><category term="Summary"/><category term="Tab-Page"/><category term="Union Query"/><category term="User"/><category term="Users"/><category term="Water-Mark"/><category term="Word"/><category term="automatically"/><category term="commands"/><category term="hyperlinks"/><category term="iSeries Date"/><category term="iif"/><category term="ms-access"/><category term="msaccess"/><category term="msaccess alerts"/><category term="pdf files"/><category term="reference"/><category term="restore"/><category term="switch"/><category term="text"/><category term="toolbar"/><category term="updating"/><category term="upload"/><category term="vba code"/><title type='text'>LEARN MS-ACCESS TIPS AND TRICKS</title><subtitle type='html'>Microsoft Access VBA Tutorials for self-paced learning, Class Modules, SQL Techniques, and AI Integration Guides.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default?alt=atom&amp;redirect=false'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default?alt=atom&amp;start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>420</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-5837604671319470085</id><published>2026-07-04T20:01:38.140+05:30</published><updated>2026-07-09T10:31:51.957+05:30</updated><title type='text'>Streamlining Form Module Code in Standalone Class Module Tutorials</title><content type='html'>&lt;h3&gt;Write Reusable, Structured Form Module VBA Code with Standalone Class Modules.&lt;/h3&gt;
&lt;h4&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Eliminate repetitive and unorganized Form Module code,&amp;nbsp; accelerate Microsoft Access Application development, and simplify code management with a streamlined, reusable coding technique.&lt;/span&gt;&lt;/h4&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; &lt;i&gt;&lt;span style=&quot;font-size: medium;&quot;&gt;Each article includes a downloadable demo database for self-paced learning and hands-on experiments of the concepts explained.&lt;/span&gt;&amp;nbsp;&lt;/i&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Reusing Form Module VBA Code for New Projects.&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt;
&lt;h4 data-end=&quot;229&quot; data-start=&quot;182&quot;&gt;The Existing Form Module Coding Approach.&lt;/h4&gt;&lt;p data-end=&quot;460&quot; data-start=&quot;231&quot;&gt;Access forms include a wide range of controls—such as text boxes, command buttons, and combo boxes—each designed for specific tasks. Typically, we write &lt;span data-end=&quot;404&quot; data-start=&quot;384&quot;&gt;event procedures&lt;/span&gt; within the Form’s Class Module to handle these tasks.&lt;/p&gt;&lt;p data-end=&quot;716&quot; data-start=&quot;462&quot;&gt;However, challenges often arise when a single control, such as a text box, requires multiple event subroutines. The related code becomes scattered across different event procedures, intermingled with code for other controls within the same form module.&lt;/p&gt;&lt;p&gt;

&lt;/p&gt;&lt;p data-end=&quot;1067&quot; data-start=&quot;718&quot;&gt;This lack of structure can make the development process cumbersome. Developers frequently switch between &lt;span data-end=&quot;843&quot; data-start=&quot;823&quot;&gt;form design view&lt;/span&gt; (to adjust the user interface or event properties) and the &lt;span data-end=&quot;926&quot; data-start=&quot;903&quot;&gt;form’s class module&lt;/span&gt; (to locate or refine event code). Over time, this repeated navigation slows down workflow and makes maintaining event code more difficult. &lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt;...&lt;/p&gt;
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access - Part Two&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt;
&lt;p&gt;When designing a Microsoft Access form, we typically add controls such as Text Boxes, &lt;a href=&quot;https://www.msaccesstips.com/2006/09/command-button-animation.html&quot; target=&quot;_blank&quot;&gt;Command Buttons&lt;/a&gt;, and Combo Boxes. Each control provides a set of built-in events that are triggered in response to specific user actions or system-generated operations. These events are handled by their associated event procedures, where we write VBA code to perform the required tasks.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;p&gt;Traditionally, we have built forms by adding controls, relying on their built-in events, and writing VBA code to respond to them—often without considering how the underlying event mechanism works. &lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt;...&lt;/p&gt;
  
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events - Part 3&lt;/a&gt;.&lt;/h3&gt;&lt;/li&gt;
  &lt;p&gt;The primary objective is to move VBA code from the Form Module to a standalone Class Module, reserving the Form exclusively for user interface design. Is this feasible? Absolutely. The following pages will demonstrate how this can be achieved. Once this coding approach is implemented, significant portions of the code can be reused across new projects, simplifying development and reducing coding effort.&lt;/p&gt;

&lt;p&gt;With this coding methodology, Code Modules can be opened and edited independently, eliminating the need to repeatedly switch to Form Design View simply to access the code. This saves considerable manual effort and improves development efficiency, resulting in faster project completion. The proposed solution will continue to work seamlessly with the controls on the Form, preserving the standard behavior from the end user&#39;s perspective. In addition, the underlying framework of this approach can be exported and incorporated into other projects, making code reuse and maintenance significantly easier. &lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;
  
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt;
&lt;p&gt;The Quantity TextBox object&#39;s events are enabled by selecting the [Event Procedure] option in the control&#39;s Event Property settings. When an event is raised (fired) by the TextBox object instance, it is captured by the Form&#39;s Class Module, where the corresponding event procedure is executed. This process is illustrated in the graphical image below.&lt;/p&gt;

&lt;p&gt;The events raised (fired) by the Quantity TextBox on the Form can also be captured in the standalone `Class1` Class Module. To achieve this, an instance of the TextBox object must be declared in `Class1` and qualified with the `WithEvents` keyword. A reference to the Quantity TextBox control on the Form is then assigned to this object variable in the `Class1` Class Module.&amp;nbsp;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;
  
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing - Part Five&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt;
&lt;p&gt;Next, let us examine how to handle events for multiple TextBox controls on a Form. For this exercise, we will place three TextBox controls on the Form and use them to explore event handling through a standalone Class Module.&lt;/p&gt;

&lt;p&gt;In practical applications, a Form may contain 10, 20, or even more TextBox controls. While it is unlikely that every control will require event procedures, this approach can be extended to handle as many controls as necessary when the application design demands it. &lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;
  
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt;
&lt;p&gt;After experimenting with the previous examples, you should now have a clear understanding of how the Events Subroutines of TextBox objects work on a Form and how they can be relocated into a standalone Class Module to run the Event Procedures for specific tasks on the Form.&amp;nbsp;&lt;/p&gt;&lt;p data-end=&quot;553&quot; data-start=&quot;112&quot;&gt;In our earlier experiments, we worked mostly with a &lt;span data-end=&quot;182&quot; data-start=&quot;164&quot;&gt;single TextBox&lt;/span&gt; to understand the fundamentals. The only exception was in &lt;span data-end=&quot;254&quot; data-start=&quot;241&quot;&gt;Part Five&lt;/span&gt;, where we extended the idea to &lt;span data-end=&quot;305&quot; data-start=&quot;286&quot;&gt;three TextBoxes&lt;/span&gt; to demonstrate how to enable events and capture the fired events within a standalone Class Module. It is important to note that all of these actions were carried out &lt;span data-end=&quot;512&quot; data-start=&quot;469&quot;&gt;entirely in the standalone Class Module&lt;/span&gt;, rather than in the Form module. &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;

  
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt;
&lt;p data-end=&quot;567&quot; data-is-last-node=&quot;&quot; data-is-only-node=&quot;&quot; data-start=&quot;429&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p data-end=&quot;427&quot; data-start=&quot;74&quot;&gt;Some readers may still be in doubt about the effectiveness of these new Event-Procedure coding methods. This page demonstrates the traditional Form Module coding alongside the streamlined standalone Class Module Coding advantage. The demo is divided into three parts, ranging from standard coding to advanced automation, which helps determine which approach works best.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;p&gt;The Normal Coding method.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;The Stand-alone Class Module supported method.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Two Stand-alone Class Modules supported the option.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;On January 3, 2024, I presented a concise overview of the intricate topic: &lt;i&gt;Streamlining Form Module Code in Standalone Class Module&lt;/i&gt;&amp;nbsp;for the &lt;a href=&quot;https://www.accessusergroups.org/europe/&quot; target=&quot;_blank&quot;&gt;Access User Groups (Europe) Chapter&lt;/a&gt;&amp;nbsp;Live,&amp;nbsp;moderated by Mr. Colin Riddington &amp;amp; Mr. Alessandro Grimaldi, with the Demo Database attached to this Article.&amp;nbsp;&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://youtu.be/AjvjN3h1ipY&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;768&quot; data-original-width=&quot;1358&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiCiMJMHkFvrA1SYMmENzL2-tXLy5HcUotXZYzirfF2KxiYi19NO73DkFYQLOzxTcYc0s-4ck66fT6nyxN2OL2lIDiuGE6ZOeP0dt15CfaDpJO5PIwAjPikmGETyA8fwYZfmVBqZtnwDSJR5PBHov1kUNNb5nCwXUD7ZmNGMn4fORCqMruTQG-zYgYUNtS/s320/AEUMeeting.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;center&gt;&lt;a href=&quot;https://youtu.be/AjvjN3h1ipY&quot;&gt;https://youtu.be/AjvjN3h1ipY&lt;/a&gt;&lt;/center&gt;
&lt;p&gt;You can view the Live Presentation supported by PowerPoint Slides in a YouTube Video by clicking the above Link.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The YouTube subtitles are available in eleven languages.&amp;nbsp;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt;...&lt;/p&gt;

&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt; 

  &lt;p&gt;In the past, we used the TextBox Wrapper Class &lt;a href=&quot;https://www.msaccesstips.com/2019/05/access-form-control-arrays-and-event-3.html&quot; target=&quot;_blank&quot;&gt;Array&lt;/a&gt; to store TextBox instances with Events enabled, allowing us to capture them in memory and execute their associated Event Subroutines. While this Array-based method worked, it required frequent re-dimensioning and the maintenance of separate indices for different object types, such as Command Buttons, ComboBoxes, and List Boxes. Fortunately, there is a more efficient solution—the Collection Object. &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;


  
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The OnDirty Event Subroutine.&lt;/h3&gt;
&lt;pre&gt;Private Sub txt_Dirty(Cancel As Integer)
    &lt;b&gt;If&lt;/b&gt; MsgBox(&quot;Editing the &quot; &amp;amp; UCase(Txt.Name) _
    &amp;amp; &quot;: Value? &quot; &amp;amp; Txt.Value, vbYesNo + vbQuestion, _
    Txt.Name &amp;amp; &quot; DIRTY()&quot;) = vbNo &lt;b&gt;Then&lt;/b&gt;
    
        Cancel = True
    &lt;b&gt;End If&lt;/b&gt;
End Sub
&lt;/pre&gt;
&lt;p data-end=&quot;561&quot; data-start=&quot;104&quot;&gt;The code snippet above monitors all TextBoxes on the Main Form&amp;nbsp;&lt;em data-end=&quot;179&quot; data-start=&quot;168&quot;&gt;Employees&lt;/em&gt;&amp;nbsp;and &lt;i&gt;Orders&lt;/i&gt; subform&amp;nbsp;to prevent unintended changes. When the user attempts to modify any data field, a warning message appears, requiring confirmation before the edit can proceed. If the user recognizes the action as a mistake, he/she can cancel the event and restore the field to its original value.&amp;nbsp;&lt;/p&gt;&lt;p data-end=&quot;561&quot; data-start=&quot;104&quot;&gt;This approach helps prevent accidental modifications and maintains data integrity.&lt;/p&gt;&lt;p data-end=&quot;561&quot; data-start=&quot;104&quot;&gt;If you have 15 TextBoxes in the Form, the traditional coding needs to repeat the above 5 lines of code in fifteen different Subroutines in the Form&#39;s Class Module, instead of one time in the Standalone Class Module.&amp;nbsp;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt;...&lt;/p&gt;


&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt; 

&lt;h4&gt;Wrapper Class Templates&lt;/h4&gt;

&lt;p&gt;Create a standard set of wrapper class templates for all frequently used controls, such as &lt;a href=&quot;https://www.msaccesstips.com/2019/07/withevents-textbox-commandbutton.html&quot; target=&quot;_blank&quot;&gt;TextBoxes&lt;/a&gt;, CommandButtons, ComboBoxes, and others. When implementing these templates for a specific form, create copies of the required classes and rename them using a short, meaningful prefix that identifies the form. For example, for the Employees form, the prefix `Emp` can be used, resulting in class names such as `EmpTextBox`, `EmpCmdButton`, and `EmpComboBox`.&lt;/p&gt;

&lt;p&gt;This naming convention clearly associates each wrapper class with its corresponding form, making the code easier to identify, maintain, and manage while promoting consistency throughout the project.&lt;/p&gt;&lt;p&gt;&lt;!--Google In-Article Ads start--&gt;&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;&lt;!--Google In-Article Ads END--&gt;&lt;/p&gt;&lt;p data-end=&quot;397&quot; data-start=&quot;102&quot;&gt;After reviewing the previous nine articles on&amp;nbsp;&lt;span data-end=&quot;185&quot; data-start=&quot;148&quot;&gt;streamlining form &lt;a href=&quot;https://www.msaccesstips.com/2019/05/withevents-in-class-module-and-data.html&quot; target=&quot;_blank&quot;&gt;module&lt;/a&gt; VBA code&lt;/span&gt;, you should now be familiar with this new coding approach and understand how to create a new wrapper class whenever a required template is not already available—such as when a new control Type is added to the form. &lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;

  
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt; 
&lt;h3&gt;Wrapper Class Design.&lt;/h3&gt;
&lt;p&gt;In this episode of the &lt;i&gt;Streamlining Form Module VBA Code&lt;/i&gt; series, we will create Wrapper classes for ComboBox and OptionGroup controls. Having worked through the previous episodes, you are now familiar with the process of creating Wrapper Class Modules for other controls, including TextBox, ListBox, CommandButton, and TabControl. You have also learned how to implement event procedures within these Wrapper Class Modules instead of placing them directly in the Form Module.&amp;nbsp;&lt;/p&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;ComboBox and OptionGroup Control.&lt;/h3&gt;&lt;p data-end=&quot;238&quot; data-start=&quot;101&quot;&gt;In this session, we will focus on the usage of &lt;strong data-end=&quot;160&quot; data-start=&quot;148&quot;&gt;ComboBox&lt;/strong&gt; and &lt;strong data-end=&quot;180&quot; data-start=&quot;165&quot;&gt;OptionGroup&lt;/strong&gt; controls, as illustrated in the form image below.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtYp-Yn6oP2vkjFJsMrKe3D-K7aIfnMFm19RqIbewH2r2yuWI9678Up46CiTeTx8DLNrYD4QuV5oBusrX1-ExpFQRyr16L35bcHnqnni5pgOv_2jzUfBrWis2IWAPGBStiadjkEmZWwuJJAeGnBMagliITzxBXmJLtn5fBKhV5EWDcvrirsEaOpYlpSdSG/s1015/Streamline11.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;709&quot; data-original-width=&quot;1015&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtYp-Yn6oP2vkjFJsMrKe3D-K7aIfnMFm19RqIbewH2r2yuWI9678Up46CiTeTx8DLNrYD4QuV5oBusrX1-ExpFQRyr16L35bcHnqnni5pgOv_2jzUfBrWis2IWAPGBStiadjkEmZWwuJJAeGnBMagliITzxBXmJLtn5fBKhV5EWDcvrirsEaOpYlpSdSG/s320/Streamline11.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p data-end=&quot;344&quot; data-start=&quot;82&quot;&gt;The Order Detail data displayed in the ListBox is filtered through the query &lt;strong data-end=&quot;176&quot; data-start=&quot;159&quot;&gt;OrderDetailQ1&lt;/strong&gt;, which is based on the &lt;strong data-end=&quot;215&quot; data-start=&quot;200&quot;&gt;Employee ID&lt;/strong&gt; selected in the ComboBox control named &lt;strong data-end=&quot;265&quot; data-start=&quot;255&quot;&gt;cboEmp&lt;/strong&gt;, located above the &lt;a href=&quot;https://www.msaccesstips.com/2009/09/filter-function-output-in-listbox-2.html&quot; target=&quot;_blank&quot;&gt;ListBox&lt;/a&gt;. The SQL statement for this query is shown below: &lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;
   
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/h3&gt;&lt;/li&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Report Module VBA Code in Standalone Class Module.&lt;/h3&gt;&lt;p data-end=&quot;468&quot; data-start=&quot;105&quot;&gt;In the earlier episodes of this series, &lt;em data-end=&quot;207&quot; data-start=&quot;145&quot;&gt;Streamlining Form Module Code in the Standalone Class Module&lt;/em&gt;, we explored how to handle Event Subroutines for frequently used Access controls within a standalone Class Module. This approach allows for managing event handling in Standalone Class Module(s),&amp;nbsp; without interfering with the Form design task, resulting in cleaner, more maintainable code.&lt;/p&gt;
&lt;p data-end=&quot;524&quot; data-start=&quot;328&quot;&gt;If you’re new to handling Form/Report Module Event Procedures in standalone Class Modules, I suggest starting with the earlier episodes in this series. These articles provide the necessary background and step-by-step explanations to help you understand and apply this approach effectively. Links to all previous articles in the series are provided at the end of this page. &lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;  

  
  
&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/h3&gt;&lt;/li&gt;
&lt;p&gt;To visually emphasize specific Report line records that do not meet the required marks criteria, a &lt;span data-end=&quot;427&quot; data-start=&quot;412&quot;&gt;red ellipse&lt;/span&gt; is drawn around the corresponding TextBox. Traditionally, this procedure is implemented directly in the &lt;span data-end=&quot;550&quot; data-start=&quot;532&quot;&gt;&lt;code data-end=&quot;548&quot; data-start=&quot;534&quot;&gt;Detail_Print&lt;/code&gt;&lt;/span&gt; Event Subroutine within the Report’s Class Module. The Report Detail Format, Report_Page Events.&lt;/p&gt;&lt;p data-end=&quot;280&quot; data-start=&quot;83&quot;&gt;The &lt;span data-end=&quot;125&quot; data-start=&quot;87&quot;&gt;Report Detail Section Format Event&lt;/span&gt; runs &lt;span data-end=&quot;141&quot; data-start=&quot;131&quot;&gt;before&lt;/span&gt; the Print Event. During this phase, the Report Detail Format Event arranges the data records &lt;span data-end=&quot;251&quot; data-start=&quot;235&quot;&gt;line by line&lt;/span&gt;&amp;nbsp;within the Detail section.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;391&quot; data-start=&quot;87&quot;&gt;Other events, such as the &lt;span data-end=&quot;130&quot; data-start=&quot;113&quot;&gt;Report Header&lt;/span&gt;, &lt;span data-end=&quot;149&quot; data-start=&quot;132&quot;&gt;Report Footer&lt;/span&gt;, &lt;span data-end=&quot;166&quot; data-start=&quot;151&quot;&gt;Page Header&lt;/span&gt;, &lt;span data-end=&quot;183&quot; data-start=&quot;168&quot;&gt;Page Footer&lt;/span&gt;, and &lt;span data-end=&quot;211&quot; data-start=&quot;189&quot;&gt;Report Page Events&lt;/span&gt;, also occur during the formatting phase. When these Section events are enabled, code can be written within them to control or manipulate the layout and the report&#39;s preview or print. &lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;
  

&lt;li&gt;&lt;h3&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/h3&gt;&lt;/li&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;All other Frequently Used Controls on a Form.&lt;/h3&gt;&lt;p&gt;We have learned how to capture events fired by Form or Report controls and handle them through Event Subroutines in their respective Wrapper Classes. The TextBox and other objects&#39; Wrapper Classes are enabled with the actual references of the controls on the Form, allowing us to interact with them seamlessly. Beyond event handling, any other control on the Form can also be accessed from any Wrapper Class to read or update its values. This flexibility opens the door to creative features such as running &lt;i&gt;animations&lt;/i&gt;, &lt;i&gt;simulating a digital clock&lt;/i&gt; on the Form, implementing a &lt;i&gt;countdown timer&lt;/i&gt; before the Form is closed, and much more.&amp;nbsp;&lt;/p&gt;&lt;p data-end=&quot;772&quot; data-start=&quot;117&quot;&gt;For such activities, every Wrapper Class includes a Form object instance, to which the active Form’s reference is assigned. This allows the Wrapper Classes to interact directly with the Form. When you need to handle events such as the &lt;span data-end=&quot;366&quot; data-start=&quot;350&quot;&gt;&lt;i&gt;Form_Timer()&lt;/i&gt;&lt;/span&gt; Event or the &lt;span data-end=&quot;393&quot; data-start=&quot;380&quot;&gt;&lt;i&gt;MouseMove&lt;/i&gt;&lt;/span&gt; Event on the Form’s Detail Section, the Form instance must be declared with the &lt;span data-end=&quot;488&quot; data-start=&quot;474&quot;&gt;WithEvents&lt;/span&gt; keyword (&lt;i&gt;Private WithEvents frm as Form&lt;/i&gt;) inside the Wrapper Class. Since the Form instance is always included in a Wrapper Class, any of the above-mentioned features can be coded within the &lt;i&gt;Intermediary Class Module&lt;/i&gt; or in any control’s Wrapper Class. However, if the Form-level events are not used, the form object declaration can be like:&amp;nbsp;&lt;i&gt;Private frm as Form.&lt;/i&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Form Detail Section declaration,&lt;/h3&gt;

&lt;pre style=&quot;text-align: left;&quot;&gt;Private frm as Access.Form
Private WithEvents SecDetail As Access.Section

Set SecDetail = frm.Section(acDetail)
	SecDetail.OnMouseMove = &quot;[Event Procedure]&quot;

&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Report Detail Section Declaration.&lt;/h3&gt;
&lt;pre&gt;Private WithEvents Rpt as Access.Report
Private WithEvents RptSec as Access.[_SectionInReport]

Set RptSec = Rpt.Section(acDetail)

&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_blank&quot;&gt;Continue&lt;/a&gt; ...&lt;/p&gt;
&lt;br /&gt;
  &lt;h2&gt;Advanced Event Handling Examples in the following Articles.&lt;/h2&gt;

&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/5837604671319470085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2026/07/streamlining-form-module-code-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5837604671319470085'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5837604671319470085'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2026/07/streamlining-form-module-code-in.html' title='Streamlining Form Module Code in Standalone Class Module Tutorials'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiCiMJMHkFvrA1SYMmENzL2-tXLy5HcUotXZYzirfF2KxiYi19NO73DkFYQLOzxTcYc0s-4ck66fT6nyxN2OL2lIDiuGE6ZOeP0dt15CfaDpJO5PIwAjPikmGETyA8fwYZfmVBqZtnwDSJR5PBHov1kUNNb5nCwXUD7ZmNGMn4fORCqMruTQG-zYgYUNtS/s72-c/AEUMeeting.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-5118153074359473501</id><published>2026-06-21T22:31:42.425+05:30</published><updated>2026-07-05T14:40:13.812+05:30</updated><title type='text'>Complete Guide to Microsoft Access AI Integration</title><content type='html'>&lt;h3&gt;Complete Guide to Microsoft Access AI Integration.&lt;/h3&gt;
&lt;p&gt;Complete Guide to Microsoft Access AI Integration. Contents: Installing Ollama, Installing Qwen model, Connecting VBA to AI, Building JSON Request, Prompt Engineering, SQL Generation, VBA Generation, Debugging AI Output, Explain SQL, Explain VBA Code.&lt;/p&gt;&lt;h3&gt;Contents:&amp;nbsp;&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-microsoft-access-for.html#Ollama&quot; target=&quot;_Blank&quot;&gt;Installing Ollama&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-microsoft-access-for.html#Qwen&quot; target=&quot;_Blank&quot;&gt;Installing Qwen model&lt;/a&gt;&lt;/li&gt;
  
     &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-access-vba-and-sql.html#VBA&quot; target=&quot;_Blank&quot;&gt;Connecting VBA to AI&lt;/a&gt;&lt;/li&gt;  
      &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/05/access-and-ai-integration-part-3.html#JSON&quot; target=&quot;_Blank&quot;&gt;Building JSON Request&lt;/a&gt;&lt;/li&gt;
  
      &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/05/access-and-ai-integration-part-3.html#Prompt&quot; target=&quot;_Blank&quot;&gt;Prompt Engineering&lt;/a&gt;&lt;/li&gt;
     &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/05/access-and-ai-integration-part-3.html#SQL&quot; target=&quot;_Blank&quot;&gt;SQL Generation&lt;/a&gt;&lt;/li&gt; 
      &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/05/access-and-ai-integration-part-3.html#VBAGen&quot; target=&quot;_Blank&quot;&gt;VBA Generation&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/05/access-and-ai-integration-part-3.html#Debug&quot; target=&quot;_Blank&quot;&gt;Debugging AI Output&lt;/a&gt;&lt;/li&gt;
  
       &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/05/access-and-ai-integration-part-3.html#ExpSQL&quot; target=&quot;_Blank&quot;&gt;Explain SQL&lt;/a&gt;&lt;/li&gt;
       &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/05/access-and-ai-integration-part-3.html#ExpVBA&quot; target=&quot;_Blank&quot;&gt;Explain VBA Code&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/5118153074359473501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2026/06/complete-guide-to-microsoft-access-ai.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5118153074359473501'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5118153074359473501'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2026/06/complete-guide-to-microsoft-access-ai.html' title='Complete Guide to Microsoft Access AI Integration'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-4959130053872510427</id><published>2026-05-17T23:30:25.951+05:30</published><updated>2026-06-29T21:48:15.715+05:30</updated><title type='text'>Understanding JSON, Temperature and Max Tokens in AI Integration (Part 3)</title><content type='html'>
&lt;h2 style=&quot;text-align: left;&quot;&gt;Understanding JSON, Temperature, and Max Tokens in Microsoft Access AI Integration (Part 3)&lt;/h2&gt;

&lt;p&gt;This tutorial explains how Microsoft Access developers can use JSON requests, temperature settings, max_tokens, and prompt engineering techniques when integrating local AI models such as Ollama and qwen2.5-Coder with VBA applications.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;How JSON Works in Microsoft Access AI Integration.&lt;/h3&gt;&lt;p&gt;When working with AI models through APIs—such as those provided by Ollama—data is exchanged using a structured format known as JSON. JSON (JavaScript Object Notation) is a lightweight, text-based format used to represent data as key-value pairs. It is widely adopted because it is both human-readable and easy for machines to parse efficiently. In the context of Microsoft Access and VBA, JSON serves as the communication bridge between your application and the AI engine, transmitting prompts to the model and returning generated responses in a consistent and predictable structure.&lt;/p&gt;
&lt;h4&gt;Earlier Post Links:&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-microsoft-access-for.html&quot; target=&quot;_Blank&quot;&gt;How to Integrate AI into Microsoft Access VBA Using Ollama (Part 1)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-access-vba-and-sql.html&quot; target=&quot;_Blank&quot;&gt;Generate Microsoft Access SQL and VBA with Local AI Models (Part 2)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJm9ZPPr1BvatMcWztXM35rVj0H07mwrCR8rB75Zo_3GFnkIDtc-O2soYkEtFikrP9bSKbzzkdubb3iNPjrfAEAPk_jFvFa5oIyoMIKrHtHYvT9DEgbCYllstlc_neJE4YOhXXok8dHLr5H3qpyNrvfcPdvBmrWavxPLM7rf79iYQGUOMXLlC2L9T_1Iu6/s1425/AI3Form_DesignNew1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;AI Prompt running and Response viewing Interface design&quot; border=&quot;0&quot; data-original-height=&quot;759&quot; data-original-width=&quot;1425&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJm9ZPPr1BvatMcWztXM35rVj0H07mwrCR8rB75Zo_3GFnkIDtc-O2soYkEtFikrP9bSKbzzkdubb3iNPjrfAEAPk_jFvFa5oIyoMIKrHtHYvT9DEgbCYllstlc_neJE4YOhXXok8dHLr5H3qpyNrvfcPdvBmrWavxPLM7rf79iYQGUOMXLlC2L9T_1Iu6/s320/AI3Form_DesignNew1.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click the image to open Large-Image in a new Tab &lt;/p&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Understanding JSON structure is essential for successfully integrating AI into your Microsoft Access applications. A typical JSON request includes elements such as the model name, prompt text, and optional parameters, all enclosed within curly braces and properly formatted using quotation marks. Similarly, the AI model returns its response in JSON format, which requires careful parsing to extract the relevant output. Even minor formatting issues—such as improperly escaped double quotation marks—can result in errors. Therefore, developing a solid understanding of JSON syntax and structure is a fundamental step toward building reliable AI-assisted VBA solutions.&lt;/p&gt;


&lt;h3&gt;A visual JSON structure diagram&lt;/h3&gt;


&lt;p&gt;Understanding JSON Structure (VBA - AI Request &amp;amp; Response)&lt;/p&gt;

&lt;p&gt;When your Microsoft Access application communicates with a local AI model (via Ollama), it sends and receives data in JSON format.&lt;/p&gt;

&lt;p id=&quot;JSON&quot;&gt;This section shows exactly what goes out and what comes back.&lt;/p&gt;



&lt;h3 style=&quot;text-align: left;&quot;&gt;1. JSON Request (Sent from VBA to AI)&lt;/h3&gt;

&lt;pre&gt;{
  &quot;model&quot;: &quot;qwen2.5-coder:3b&quot;,
  &quot;prompt&quot;: &quot;Write a SQL query to list the top 5 customers&quot;,
  &quot;stream&quot;: false
}

&lt;/pre&gt;

&lt;h4&gt;Explanation.&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;model   - AI model name installed locally&lt;/li&gt;
  &lt;li&gt;prompt  - Your instruction (SQL / VBA / etc.)&lt;/li&gt;
  &lt;li&gt;stream  - false = return full response at once&lt;/li&gt;
&lt;/ul&gt;


&lt;h3 style=&quot;text-align: left;&quot;&gt;2. Same JSON Built in VBA&lt;/h3&gt;
&lt;pre&gt;JSON = &quot;{&quot;&quot;model&quot;&quot;:&quot;&quot;qwen2.5-coder:3b&quot;&quot;,&quot;&quot;prompt&quot;&quot;:&quot;&quot;&quot; &amp;amp; safePrompt &amp;amp; &quot;&quot;&quot;,&quot;&quot;stream&quot;&quot;: false}&quot;

&lt;/pre&gt;

&lt;h4&gt;Visual Mapping&lt;/h4&gt;
&lt;pre&gt;VBA String                     - JSON Output
---------------------------------------------------------
&quot;&quot;model&quot;&quot;                      - &quot;model&quot;
&quot;&quot;prompt&quot;&quot;                     - &quot;prompt&quot;
&quot;&quot;stream&quot;&quot;                     - &quot;stream&quot;
&quot;&quot;&quot;&quot;                           - &quot;

&lt;/pre&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;3. JSON Response (Returned by AI)&lt;/h3&gt;


&lt;pre&gt;{

  &quot;model&quot;: &quot;qwen2.5-coder:3b&quot;,

  &quot;created_at&quot;: &quot;2026-04-19T10:00:00Z&quot;,

  &quot;response&quot;: &quot;SELECT TOP 5 CustomerID, Name FROM Customers ORDER BY Sales DESC;&quot;,

  &quot;done&quot;: true

}

&lt;/pre&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;4. What You Actually Need&lt;/h3&gt;

&lt;p&gt;&lt;b&gt;&quot;response&quot;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;This contains the generated SQL or VBA code.&lt;/p&gt;

&lt;h4&gt;5. Visual Flow Diagram &lt;/h4&gt;
&lt;pre&gt;[Microsoft Access VBA]
        |
   Build JSON String
        |
Send via HTTP (POST)
        |
[Ollama Local API]
        |
   AI Model Processes Prompt
        |
 Returns JSON Response
        |
Extract &quot;response&quot; Field
        |
 Use in Access (SQL / VBA)
 &lt;br /&gt;&lt;/pre&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;Common JSON Issue (Very Important)&lt;/h3&gt;

&lt;pre&gt;&quot;prompt&quot;: &quot;He said &quot;Hello&quot;&quot;

&lt;/pre&gt;

&lt;p&gt;&#39;Invalid JSON (quotes not escaped)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Correct Version&lt;/b&gt;&lt;/p&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;&quot;prompt&quot;: &quot;He said \&quot;Hello\&quot;&quot;&lt;br /&gt;

&lt;/pre&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Practical Tip for Developers&lt;/h3&gt;
&lt;p&gt;Always ensure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Double quotes inside prompts are escaped (\&quot;)&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The JSON structure is properly formed&lt;/li&gt;
&lt;li&gt;VBA strings are correctly constructed&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Important Points&lt;/h4&gt;
&lt;p&gt;JSON is the communication bridge between VBA and AI.&lt;/p&gt;
&lt;p&gt;If the JSON is incorrect, the AI request will fail—no matter how good your prompt is.&lt;/p&gt;
&lt;h3&gt;VBA JSON Builder Module (Ready to Use)&lt;/h3&gt;
&lt;li&gt;Handles escaping (&quot;, \, line breaks)&lt;/li&gt;
&lt;li&gt;Clean and reusable&lt;/li&gt;
&lt;li&gt;Designed for AI prompt calls&lt;/li&gt;


&lt;h4&gt;1. JSON Escape Function (Core)&lt;/h4&gt;
&lt;pre&gt;Public Function JsonEscape(ByVal text As String) As String

    &#39; Escapes special characters for JSON

    text = Replace(text, &quot;\&quot;, &quot;\\&quot;)        &#39; Backslash

    text = Replace(text, &quot;&quot;&quot;&quot;, &quot;\&quot;&quot;&quot;)     &#39; Double quote

    text = Replace(text, vbCrLf, &quot;\n&quot;)     &#39; Line break (Windows)

    text = Replace(text, vbCr, &quot;\r&quot;)

    text = Replace(text, vbLf, &quot;\n&quot;)


    JsonEscape = text

End Function

&lt;/pre&gt;


&lt;h4&gt;2. Build AI Request JSON&lt;/h4&gt;
&lt;pre&gt;Public Function BuildAIJson(ByVal prompt As String, _

                           Optional ByVal model As String = &quot;qwen2.5-coder:3b&quot;, _

                           Optional ByVal stream As Boolean = False) As String

    

    Dim json As String
    

    json = &quot;{&quot;

    json = json &amp;amp; &quot;&quot;&quot;model&quot;&quot;:&quot;&quot;&quot; &amp;amp; model &amp;amp; &quot;&quot;&quot;,&quot;

    json = json &amp;amp; &quot;&quot;&quot;prompt&quot;&quot;:&quot;&quot;&quot; &amp;amp; JsonEscape(prompt) &amp;amp; &quot;&quot;&quot;,&quot;

    json = json &amp;amp; &quot;&quot;&quot;stream&quot;&quot;:&quot; &amp;amp; LCase(stream)

    json = json &amp;amp; &quot;}&quot;
    

    BuildAIJson = json


End Function

&lt;/pre&gt;

&lt;h4&gt;3. HTTP Call Function (Using the Builder)&lt;/h4&gt;
&lt;pre&gt;Public Function AskLocalAI(prompt As String) As String

    Dim http As Object

    Dim json As String&lt;br /&gt;

    Set http = CreateObject(&quot;MSXML2.XMLHTTP&quot;)

    json = BuildAIJson(prompt)

    http.Open &quot;POST&quot;, &quot;http://localhost:11434/api/generate&quot;, False

    http.setRequestHeader &quot;Content-Type&quot;, &quot;application/json&quot;

    http.Send json

    AskLocalAI = http.responseText

End Function

&lt;/pre&gt;


&lt;h4&gt;4. Extract Only AI Response (Clean Output)&lt;/h4&gt;
&lt;pre&gt;Public Function ExtractAIResponse(ByVal json As String) As String    

    Dim startPos As Long

    Dim endPos As Long 
    

    startPos = InStr(json, &quot;&quot;&quot;response&quot;&quot;:&quot;&quot;&quot;)

    If startPos = 0 Then Exit Function

    startPos = startPos + 12

    endPos = InStr(startPos, json, &quot;&quot;&quot;,&quot;&quot;done&quot;&quot;&quot;)&lt;br /&gt;
    ExtractAIResponse = Mid(json, startPos, endPos - startPos)


End Function

&lt;/pre&gt;

&lt;h4&gt; 5. Example Usage&lt;/h4&gt;
&lt;pre&gt;Sub TestAI()

    Dim raw As String

    Dim result As String

    raw = AskLocalAI(&quot;Write a Microsoft Access SQL query to list top 5 customers&quot;)

    result = ExtractAIResponse(raw)

    MsgBox result

End Sub

&lt;/pre&gt;

&lt;h3&gt;Important Notes&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Always use JsonEscape() for dynamic text&lt;/li&gt;
&lt;li&gt;Avoid manually concatenating quotes
&lt;/li&gt;&lt;li&gt;&lt;p&gt;This works reliably for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SQL generation&lt;/li&gt;
&lt;li&gt;VBA code generation&lt;/li&gt;
&lt;li&gt;Structured prompts&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;


&lt;h3&gt;Optional Enhancement&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;temperature&lt;/li&gt;
&lt;li&gt;max_tokens&lt;/li&gt;
&lt;li&gt;&lt;p&gt;system prompt&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&quot;temperature&quot;: 0.2

&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;1. Temperature Option&lt;/h4&gt;

&lt;p&gt;Think of Temperature as a randomness dial:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;i&gt;Low temperature (e.g., 0.1 – 0.3)&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More deterministic, consistent, and precise&lt;/li&gt;
&lt;li&gt;Best for SQL, VBA, structured output&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;&lt;i&gt;Medium (0.4 – 0.7)&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Balanced between accuracy and variation&lt;/li&gt;
&lt;li&gt;Good for explanations or mixed tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;&lt;i&gt;High (0.8 – 1.0+)&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;More creative, but less predictable&lt;/li&gt;
  &lt;li&gt;May introduce errors in code&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Simple Analogy&lt;/h4&gt;

&lt;p&gt;Low temperature  - Like a careful accountant&lt;/p&gt;
&lt;p&gt;High temperature - Like a creative writer&lt;/p&gt;

&lt;p&gt;Temperature: 0.2 is Ideal for Microsoft Access development tasks such as:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Writing SQL queries&lt;/li&gt;
  &lt;li&gt;Generating VBA procedures&lt;/li&gt;
  &lt;li&gt;Producing structured outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You want accuracy, not creativity, so:
&lt;/p&gt;&lt;pre&gt;&#39;JSON

&quot;temperature&quot;: 0.2

&lt;/pre&gt;
&lt;p&gt;Produces: Cleaner syntax, Less unnecessary text, More repeatable results&lt;/p&gt;


&lt;h4&gt;Example Comparison&lt;/h4&gt;

&lt;p&gt;&lt;b&gt;Prompt:&lt;/b&gt;&lt;/p&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;&#39;Plain Text

&quot;Write a SQL query to get top 5 customers by sales&quot;

&lt;/pre&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;Understanding Temperature Parameter&lt;/h3&gt;&lt;p&gt;Option: &lt;b&gt;Temperature: 0.2&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;&#39;SQL

SELECT TOP 5 CustomerID, SUM(SalesAmount) AS TotalSales
FROM Orders
GROUP BY CustomerID
ORDER BY TotalSales DESC;

&lt;/pre&gt;

&lt;p&gt;Clean and Precise&lt;/p&gt;

&lt;p&gt;Option: &lt;b&gt;Temperature: 0.9&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;&#39;SQL

Here is one possible query you could try:

SELECT CustomerID, SUM(SalesAmount) AS TotalSales
FROM Orders
GROUP BY CustomerID
ORDER BY TotalSales DESC
LIMIT 5;

&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Issues:&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Uses &lt;b&gt;LIMIT&lt;/b&gt; (not valid in Access), adds extra text&lt;/p&gt;

&lt;h3&gt;How to Add It in Your VBA JSON&lt;/h3&gt;

&lt;p&gt;Just include it in your builder:&lt;/p&gt;

&lt;pre&gt;&#39;vba

json = json &amp;amp; &quot;&quot;&quot;temperature&quot;&quot;:0.2,&quot;

&#39;Full Example:

&#39;JSON
{
  &quot;model&quot;: &quot;qwen2.5-coder:3b&quot;,
  &quot;prompt&quot;: &quot;...&quot;,
  &quot;temperature&quot;: 0.2,
  &quot;stream&quot;: false
}

&lt;/pre&gt;


&lt;center&gt;&lt;table bgcolor=&quot;#faf2f2&quot; border=&quot;1&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; style=&quot;width: 400px;&quot;&gt;&lt;caption&gt;&lt;font&gt;Temperature Settings&lt;/font&gt;&lt;/caption&gt;
&lt;tbody&gt;
  &lt;tr&gt;&lt;th valign=&quot;top&quot; width=&quot;50%&quot;&gt;Task Type&lt;/th&gt;        &lt;th valign=&quot;top&quot; width=&quot;50%&quot;&gt;Recommended Temperature&lt;/th&gt;&lt;/tr&gt;&lt;/tbody&gt;
  &lt;tbody&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;SQL Queries&lt;/td&gt;        &lt;td align=&quot;center&quot; valign=&quot;top&quot; width=&quot;50%&quot;&gt;0.1 - 0.3&lt;/td&gt; &lt;/tr&gt;
  
 
  &lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;VBA Code&lt;/td&gt;        &lt;td align=&quot;center&quot; valign=&quot;top&quot; width=&quot;50%&quot;&gt;0.2 - 0.4&lt;/td&gt;  &lt;/tr&gt;
  &lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;Explanation&lt;/td&gt;        &lt;td align=&quot;center&quot; valign=&quot;top&quot; width=&quot;50%&quot;&gt;0.5 - 0.7&lt;/td&gt;  &lt;/tr&gt;
  &lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;Creative Writing&lt;/td&gt;        &lt;td align=&quot;center&quot; valign=&quot;top&quot; width=&quot;50%&quot;&gt;0.8+&lt;/td&gt;  &lt;/tr&gt;
   
  &lt;/tbody&gt;
  
  &lt;/table&gt;&lt;/center&gt;

&lt;p&gt;In Short:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Lower temperature = more reliable code&lt;/li&gt;
  &lt;li&gt;Higher temperature = more creative but risky output&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Understanding Max Tokens.&lt;/h3&gt;&lt;h3&gt;2. The &lt;i&gt;max_tokens&lt;/i&gt; Parameter&lt;/h3&gt;

&lt;p&gt;— Controlling Response Length.&lt;/p&gt;

&lt;h4&gt;What does it?&lt;/h4&gt;

&lt;p&gt;&lt;i&gt;max_tokens&lt;/i&gt; limits the length of the AI’s response.&lt;/p&gt;

&lt;p&gt;A token is roughly:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;1 word = 1–1.5 tokens&lt;/li&gt;
  &lt;li&gt;1 line of code = a few tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Why it matters in Access/VBA work&lt;/h4&gt;

&lt;p&gt;Without a limit, the AI may:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Add explanations&lt;/li&gt;
  &lt;li&gt;Generate overly long code&lt;/li&gt;
  &lt;li&gt;Include unnecessary comments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With &lt;i&gt;max_tokens&lt;/i&gt;, you keep output concise and predictable&lt;/p&gt;

&lt;h4&gt;Example&lt;/h4&gt;

&lt;p&gt;Prompt:&lt;/p&gt;
&lt;pre&gt;&quot;Write a VBA function to open a recordset&quot;

&lt;/pre&gt;

&lt;h4&gt;With &lt;i&gt;max_tokens: 120&lt;/i&gt;&lt;/h4&gt;

&lt;pre&gt;&#39;Output:

Function OpenRS()

    Dim rs As DAO.Recordset

    Set rs = CurrentDb.OpenRecordset(&quot;Customers&quot;)

End Function

&lt;/pre&gt;


&lt;h4&gt;With &lt;i&gt;max_tokens: 300&lt;/i&gt;&lt;/h4&gt;

&lt;p&gt;Output may include:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Explanation&lt;/li&gt;
&lt;li&gt;Comments&lt;/li&gt;
&lt;li&gt;Extra variations&lt;/li&gt;
&lt;/ul&gt;

&lt;center&gt;&lt;table bgcolor=&quot;#faf2f2&quot; border=&quot;1&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; style=&quot;width: 400px;&quot;&gt;&lt;caption&gt;&lt;font&gt;max_tokens&lt;/font&gt;&lt;/caption&gt;
&lt;tbody&gt;
  &lt;tr&gt;&lt;th valign=&quot;top&quot; width=&quot;50%&quot;&gt;Task Type&lt;/th&gt;        &lt;th valign=&quot;top&quot; width=&quot;50%&quot;&gt;Recommended Values&lt;/th&gt;&lt;/tr&gt;&lt;/tbody&gt;
  &lt;tbody&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;SQL Queries&lt;/td&gt;        &lt;td align=&quot;center&quot; valign=&quot;top&quot; width=&quot;50%&quot;&gt;50 - 120&lt;/td&gt; &lt;/tr&gt;
  
 
  &lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;Small VBA Function&lt;/td&gt;        &lt;td align=&quot;center&quot; valign=&quot;top&quot; width=&quot;50%&quot;&gt;100 - 250&lt;/td&gt;  &lt;/tr&gt;
  &lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;Complex Procedure&lt;/td&gt;        &lt;td align=&quot;center&quot; valign=&quot;top&quot; width=&quot;50%&quot;&gt;300 - 600&lt;/td&gt;  &lt;/tr&gt;
   
  &lt;/tbody&gt;
  
  &lt;/table&gt;&lt;/center&gt;


&lt;h4&gt;Rule of Thumb&lt;/h4&gt;

&lt;p&gt;Use the smallest value that still completes the task.&lt;/p&gt;

&lt;h3&gt;&lt;i&gt;3. System&lt;/i&gt;&amp;nbsp;Prompt Parameter&lt;/h3&gt;

&lt;p&gt;Prompt — Controlling Behavior&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The “&lt;i&gt;&lt;b&gt;system&lt;/b&gt;&lt;/i&gt;” parameter plays a decisive role in shaping how the AI interprets and responds to a prompt. When you include an instruction such as “You are a Microsoft Access VBA Expert”, you are not merely adding context—you are establishing a behavioral framework for the model. This system-level instruction influences the tone, depth, and technical accuracy of the response by biasing the model toward domain-specific knowledge, coding conventions, and best practices relevant to Access and VBA. As a result, when the actual user prompt follows (e.g., “Create a function to loop through a DAO Recordset”), the AI is far more likely to produce structured, idiomatic, and efficient VBA code rather than a generic or loosely adapted solution.&lt;/p&gt;

&lt;p&gt;In practical terms, the system prompt acts as a persistent guiding instruction that remains in effect throughout the interaction, ensuring consistency across responses. It can also enforce output constraints such as:&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;“return only VBA code”,&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;“avoid explanations”,&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;“include error handling”,&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;which is particularly valuable when integrating AI into automated workflows within Access.&lt;/p&gt;

&lt;p&gt;Without a well-defined &lt;b&gt;system prompt&lt;/b&gt;, responses may vary in format, include unnecessary explanations, or drift away from the intended technical focus. Therefore, carefully designing the System parameter is essential for achieving reliable, predictable, and production-quality outputs when using AI for tasks like VBA function generation.&lt;/p&gt;

&lt;h4&gt;What does it do?&lt;/h4&gt;

&lt;p&gt;The system prompt defines the AI’s &lt;b&gt;role&lt;/b&gt; and &lt;b&gt;behavior&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Think of it as:&lt;/p&gt;

&lt;p&gt;&lt;i&gt;“Instructions that guide how the AI should respond—every time.”&lt;/i&gt;&lt;/p&gt;


&lt;h4&gt;Why is it powerful?&lt;/h4&gt;

&lt;p&gt;Instead of repeating instructions in every prompt, you define:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Tone (professional, concise)&lt;/li&gt;
  &lt;li&gt;Output format (code only, no explanation)&lt;/li&gt;
  &lt;li&gt;Context (Microsoft Access expert)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt; Example&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Without system prompt:&lt;/p&gt;
&lt;pre&gt;Write a SQL query for the top 5 customers

&lt;/pre&gt;

&lt;p&gt;Output may include explanations&lt;/p&gt;

&lt;h4&gt;With system prompt:&lt;/h4&gt;
&lt;pre&gt;You are a Microsoft Access expert.

Return only valid Access SQL.

Do not include explanations.

&lt;/pre&gt;

&lt;p&gt;Output becomes:&lt;/p&gt;
&lt;pre&gt;SELECT TOP 5 CustomerID, SUM(Amount) AS Total

FROM Orders

GROUP BY CustomerID

ORDER BY Total DESC;

&lt;/pre&gt;

&lt;h4&gt;How to Use it in JSON&lt;/h4&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;{

  &quot;model&quot;: &quot;qwen2.5-coder:3b&quot;,

  &quot;system&quot;: &quot;You are a Microsoft Access expert. Return only SQL or VBA code without explanation.&quot;,

  &quot;prompt&quot;: &quot;Write a SQL query to get the top 5 customers&quot;,

  &quot;temperature&quot;: 0.2,

  &quot;max_tokens&quot;: 150,

  &quot;stream&quot;: false

}
&lt;/pre&gt;&lt;h4&gt;Adding to Your VBA JSON Builder&lt;/h4&gt;
&lt;pre&gt;json = &quot;{&quot;

json = json &amp;amp; &quot;&quot;&quot;model&quot;&quot;:&quot;&quot;qwen2.5-coder:3b&quot;&quot;,&quot;

json = json &amp;amp; &quot;&quot;&quot;system&quot;&quot;:&quot;&quot;You are a Microsoft Access expert. Return only code.&quot;&quot;,&quot;

json = json &amp;amp; &quot;&quot;&quot;prompt&quot;&quot;:&quot;&quot;&quot; &amp;amp; JsonEscape(prompt) &amp;amp; &quot;&quot;&quot;,&quot;

json = json &amp;amp; &quot;&quot;&quot;temperature&quot;&quot;:0.2,&quot;

json = json &amp;amp; &quot;&quot;&quot;max_tokens&quot;&quot;:150,&quot;

json = json &amp;amp; &quot;&quot;&quot;stream&quot;&quot;:false&quot;

json = json &amp;amp; &quot;}&quot;

&lt;/pre&gt;

&lt;p&gt;Practical Strategy - Combine all three.&lt;/p&gt;

&lt;ul style=&quot;text-align: left;&quot;&gt;

  &lt;li&gt;temperature - accuracy&lt;/li&gt;
  &lt;li&gt;max_tokens - length control&lt;/li&gt;
  &lt;li&gt;system - behavior control&lt;/li&gt;


&lt;h4&gt;Recommended Default Setup for Access development:&lt;/h4&gt;
&lt;pre&gt;{

  &quot;temperature&quot;: 0.2,

  &quot;max_tokens&quot;: 150,

  &quot;system&quot;: &quot;You are a Microsoft Access expert. Return only valid SQL or VBA code without explanation.&quot;

}

&lt;/pre&gt;

  &lt;h4&gt;Advantages&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;temperature - controls randomness&lt;/li&gt;
  &lt;li&gt;max_tokens - controls size&lt;/li&gt;
  &lt;li&gt;system prompt - controls behavior&lt;/li&gt;
  &lt;/ul&gt;
 
  &lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; Together, they turn AI from “chatty assistant” into a precise development tool.&lt;/p&gt;


&lt;p&gt;Constructing JSON string expressions and formatting Name: Value pairs in VBA requires careful practice and attention to syntax. You can experiment with each line of VBA code by assigning the expression to a variable, examining it in the Debug window, and printing the output to verify how the expression is interpreted and stored within the variable.&lt;/p&gt;
  &lt;h4&gt;For Example:&lt;/h4&gt;
&lt;pre&gt;  
  
model=&quot;qwen2.5-coder:3b&quot;

x=&quot;&quot;&quot;model&quot;&quot;:&quot;&quot;&quot; &amp;amp; model &amp;amp; &quot;&quot;&quot;

&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;? x
&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&quot;model&quot;:&quot;qwen2.5-coder:3b&quot;


y = chr(34) &amp;amp; &quot;model&quot; &amp;amp; chr(34) &amp;amp; &quot;:&quot; &amp;amp; chr(34) &amp;amp; model &amp;amp; chr(34)

&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;? y
&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&quot;model&quot;:&quot;qwen2.5-coder:3b&quot;&lt;br /&gt;

z=&quot;&quot;&quot;stream&quot;&quot;:false&quot;

&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;? z
&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&quot;stream&quot;:false

&lt;/pre&gt;
  
  &lt;h3&gt;Access Class Module Architecture.&lt;/h3&gt;&lt;p&gt; A well-structured VBA Class Module architecture is the cornerstone of integrating AI into Microsoft Access in a maintainable and scalable way. Instead of embedding AI-related logic directly within forms or standard modules, the application should adopt a layered class-based design that encapsulates responsibilities such as prompt construction, API communication, response parsing, and conversation management. A central engine class (for example, clsLocalLLM) acts as the orchestrator, coordinating with supporting classes such as a &lt;b&gt;prompt manager&lt;/b&gt;, &lt;b&gt;JSON builder&lt;/b&gt;, and &lt;b&gt;response parser&lt;/b&gt;. This separation of concerns not only keeps the user interface clean but also allows developers to extend or replace individual components—such as switching between local and cloud-based models—without impacting the rest of the application.&lt;/p&gt;&lt;p&gt; This architectural approach enables Access applications to evolve into intelligent systems while preserving the strengths of VBA and the native Access environment. By treating AI as a reusable service layer implemented through class modules, developers can introduce features, such as natural language querying, automated VBA code generation, and intelligent reporting across multiple forms and databases with minimal duplication. Moreover, this design aligns well with the principles of modular development and code reusability, making it easier to package the entire AI capability as an add-in for broader deployment. In essence, a disciplined class module architecture transforms AI integration from an experimental feature into a robust, production-ready enhancement for modernizing Access applications.&lt;/p&gt;
  &lt;h3&gt;Access AI Interface and VBA Programs&lt;/h3&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhudsO7gkcclS0z6-86dX8UWsJbxRy9-DOvNjoozXcohlgEt1CG8X5Q9XvSRxxFR34kZBWG0PafKSM8cdG5YlV6-f1djnA52v6KXcGhUQHwP2EjWtXzYvbV1RCu4q_oxvGpbV2kh1VJ-imDRrItVt9qp1hGFZhm0AQnLF6VVsJAPb7PqX7mwcipx8izuuhr/s1427/AI3FormNew1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Microsoft Access AI Integration form using Ollama and Qwen coder&quot; border=&quot;0&quot; data-original-height=&quot;757&quot; data-original-width=&quot;1427&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhudsO7gkcclS0z6-86dX8UWsJbxRy9-DOvNjoozXcohlgEt1CG8X5Q9XvSRxxFR34kZBWG0PafKSM8cdG5YlV6-f1djnA52v6KXcGhUQHwP2EjWtXzYvbV1RCu4q_oxvGpbV2kh1VJ-imDRrItVt9qp1hGFZhm0AQnLF6VVsJAPb7PqX7mwcipx8izuuhr/s320/AI3FormNew1.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click the image to open Large-Image in a new Tab &lt;/p&gt;&lt;/a&gt;&lt;/div&gt;  
  
  &lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;A few enhancements have been made to the Main Form. On the top-right, the list of installed AI models is displayed in an Option Group Control. You may select the appropriate model based on your specific requirements. Choose the first option (qwen2.5-coder) for VBA and SQL-related solutions, and the second option for general-purpose queries.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;A Spin Button Control has been added for selecting the AI “Temperature” parameter. The value ranges from 0.1 to 1.0, with the default setting being 0.2, which is ideal for VBA code generation. At this setting, implementation guidance and supplementary information will remain minimal and focused.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;A Spin Button Control is also provided for selecting the optional “max_tokens” parameter. The available range is from 1 to 2000, with the default value set to 80.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Two Command Buttons have been added below the &lt;i&gt;Prompt&lt;/i&gt; and &lt;i&gt;Response&lt;/i&gt; fields to allow quick copying of the TextBox contents to the Clipboard.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;The Form’s record navigation buttons have been enabled. You may use a new record for each new AI session, saving the earlier activity.&lt;/p&gt;&lt;/li&gt;
  
&lt;h3&gt;frmAIMain Module VBA Code.&lt;/h3&gt;
  &lt;pre&gt; 
Option Compare Database
Option Explicit

Const dot As String = &quot; +&quot;
Dim msg As String

Private ai As New clsLocalLLM

Private Sub cboSys_Click()
    Me!isysprompt = cboSys.Column(0)
End Sub

Private Sub cmdAskAI_Click()
Dim resultJSON As String
Dim m_prompt As String
Dim sPrompt As String
Dim sModelID As Integer
Dim sTemperature As Double
Dim smax_tokens As Long
Dim txt_SysPrompt As String

&#39;Models
Const q_wen = &quot;qwen2.5-coder:3b&quot;
Const m_ist = &quot;mistral&quot;
Const d_seek = &quot;deepseek-coder:1.3b&quot;

On Error GoTo cmdAskAI_Err

&#39;Get prompt Parameters
sTemperature = IIf(Me!ITemperature = 0, 0.2, Me!ITemperature)
smax_tokens = IIf(Me!ITokens = 0, 120, Me!ITokens)
txt_SysPrompt = Me!cboSys.Column(1) &#39;column-1 System Prompt text

m_prompt = Trim(Me!Prompt)

&#39;Assign prompt Parameters
If Len(Trim(txt_SysPrompt)) &amp;gt; 0 Then
    ai.AI_System = txt_SysPrompt
End If

    ai.Temperature = sTemperature
    ai.Tokens = smax_tokens
   
    ai.AI_System = txt_SysPrompt

    Set ai.mForm = Me
    
sModelID = Me!iModels

Select Case sModelID
    Case 1
        ai.Model = q_wen
    Case 2
        ai.Model = m_ist
    Case 3
        ai.Model = d_seek
End Select


&#39;Display Working... Please wait message
With Me
    .lblMsg.visible = True
    .Repaint
End With


&#39;Convert VBA ctrl codes like vbNewLine
&#39;to JSON code: &#39;\n&#39;
sPrompt = ai.RefineRawPrompt(m_prompt)

&#39;send to AI
resultJSON = ai.GenerateResponse(sPrompt)

&#39;Write the AI returned result in the Response Field.
With Me
    !Response = &quot;&quot; &#39;erase existing contents
    !Response = resultJSON &#39;write result to field

    .lblMsg.visible = False &#39;Hide progress label
    .Repaint
End With

cmdAskAI_Exit:
Exit Sub

cmdAskAI_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;cmdAskAI()&quot;
Resume cmdAskAI_Exit
End Sub

Private Sub cmdClose_Click()
If MsgBox(&quot;Close the Form?&quot;, vbYesNo + vbQuestion, &quot;cmdClose_Click()&quot;) = vbYes Then
    DoCmd.Close acForm, Me.Name
End If
End Sub

Private Sub cmdPrompt_Click()
    Me.Prompt.SetFocus
    DoCmd.RunCommand acCmdCopy
End Sub

Private Sub cmdResponse_Click()
    Me.Response.SetFocus
    DoCmd.RunCommand acCmdCopy
End Sub

Private Sub Form_Current()
On Error GoTo Form_current_Err

With Me
    !isysprompt = IIf(Nz(!isysprompt, 0) = 0, 1, !isysprompt)
    !ITemperature = IIf(Nz(!ITemperature, 0) = 0, 0.2, !ITemperature)
    !ITokens = IIf(Nz(!ITokens, 0) = 0, 120, !ITokens)
    !iModels = IIf(Nz(!iModels, 0) = 0, 1, !iModels)
End With

Form_current_Exit:
Exit Sub

Form_current_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;Form_current()&quot;
Resume Form_current_Exit
End Sub

Private Sub Form_load()

With Me
    !Temperature = !ITemperature * 10
    If Nz(Me!ITokens, 0) = 0 Then
      Me!Tokens = 120
    Else
      Me!Tokens = !ITokens
    End If
    
    .TimerInterval = 0
    .Recalc

End With

msg = &quot;Working, please wait &quot;

End Sub

Private Sub Form_Timer()
msg = msg &amp;amp; dot
lblMsg.Caption = msg
DoEvents

End Sub

Private Sub Temperature_Updated(Code As Integer)
&#39;Convert to proper value range
Me!ITemperature = (Me!Temperature / 10)
Me.Refresh
End Sub

Private Sub Tokens_Updated(Code As Integer)
Me!ITokens = Me!Tokens
Me.Refresh
End Sub
  
&lt;/pre&gt;
  
    &lt;h2 id=&quot;JSON&quot;&gt;Building JSON Request in VBA.&lt;/h2&gt;&lt;h3&gt;The &lt;i&gt;clsLocalLLM&lt;/i&gt; Class Object Properties and Methods.&lt;/h3&gt;
    &lt;p&gt;The above Class Module has all the AI running Methods and properties. The project Diagram is given below for quick reference.&lt;/p&gt;
    &lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaT-Va6zblNRKb9L70QoHejtoOcb4s7GO_WOb_mFFsQN_zDKjDSck8w6BMtHmUsg2QeXai2p9H7_BzKUhiajkJGr8xvf6XbANs6vJopuSlnosmdd31DjoJVFF8MqyfKm_TX4PSFYW0OCDrh_DIeiiTSoC1R2_EV8h6MKJhRkW4UcLW6BpqOzO59CIlstYL/s598/clsLocalLLM.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;534&quot; data-original-width=&quot;598&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaT-Va6zblNRKb9L70QoHejtoOcb4s7GO_WOb_mFFsQN_zDKjDSck8w6BMtHmUsg2QeXai2p9H7_BzKUhiajkJGr8xvf6XbANs6vJopuSlnosmdd31DjoJVFF8MqyfKm_TX4PSFYW0OCDrh_DIeiiTSoC1R2_EV8h6MKJhRkW4UcLW6BpqOzO59CIlstYL/s400/clsLocalLLM.png&quot; width=&quot;400&quot; /&gt;&lt;p&gt;Right-click the image to open Large-Image in a new Tab &lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
    
    &lt;p&gt;The &lt;b&gt;clsLocalLLM&lt;/b&gt; Class Module VBA Code is given below.&lt;/p&gt; 
  &lt;pre&gt;Option Compare Database
Option Explicit

&#39;=============================
&#39; Private Members
&#39;=============================
Private m_Model As String
Private m_System As String
Private m_EndPoint As String
Private m_Temperature As Double
Private m_Timeout As Long
Private m_Tokens As Long
Private m_Form As Access.Form


&#39;=============================
&#39; Class Initialize
&#39;=============================
Private Sub Class_Initialize()
    m_Model = &quot;qwen2.5-coder:3b&quot;
    m_System = &quot;You are a Microsoft Access expert. Return only code.&quot;
    m_EndPoint = &quot;http://localhost:11434/api/generate&quot;
    m_Temperature = 0.2
    m_Tokens = 120
    m_Timeout = 60
End Sub

&#39;=============================
&#39; Public Properties
&#39;=============================


Public Property Set mForm(ByRef value As Access.Form)
   Set m_Form = value
End Property

Public Property Get Model() As String
    Model = m_Model
End Property

Public Property Let Model(ByVal value As String)
    m_Model = value
End Property

Public Property Get Endpoint() As String
    Endpoint = m_EndPoint
End Property

Public Property Let Endpoint(ByVal value As String)
    m_EndPoint = value
End Property

Public Property Get AI_System() As String
    AI_System = m_System
End Property

Public Property Let AI_System(ByVal value As String)
    m_System = value
End Property

Public Property Get Temperature() As Double
    Temperature = m_Temperature
End Property

Public Property Let Temperature(ByVal value As Double)
    m_Temperature = value
End Property

Public Property Get Tokens() As Long
    Tokens = m_Tokens
End Property

Public Property Let Tokens(ByVal value As Long)
    m_Tokens = value
End Property

Public Property Get TimeoutSeconds() As Long
    TimeoutSeconds = m_Timeout
End Property

Public Property Let TimeoutSeconds(ByVal value As Long)
    m_Timeout = value
End Property

&#39;=============================
&#39; Public Methods
&#39;=============================

Public Function GenerateResponse(ByVal Prompt As String) As String
On Error GoTo ErrorHandler

    Dim http As Object
    Dim jsonBody As String
    Dim rawResponse As String
    Dim extResp As String
    
Set http = CreateObject(&quot;MSXML2.XMLHTTP&quot;)
    &#39;Set http = CreateObject(&quot;MSXML2.ServerXMLHTTP.6.0&quot;)
    &#39;http.setTimeouts 5000, 5000, 5000, 60000

    jsonBody = BuildjsonBody(Prompt)
    
    http.Open &quot;POST&quot;, m_EndPoint, True &#39;False
    http.setRequestHeader &quot;Content-Type&quot;, &quot;application/json&quot;
    
    
    http.send jsonBody
    
m_Form.TimerInterval = 10000
Do While http.ReadyState &amp;lt;&amp;gt; 4
    DoEvents
Loop
m_Form.TimerInterval = 0

    rawResponse = http.responseText
    
    extResp = ExtractResponse(rawResponse)
    
&#39;Replace JSON escape Codes, if found, with VBA codes
    extResp = Replace(extResp, &quot;\n&quot;, vbNewLine)
    extResp = Replace(extResp, &quot;\u0026&quot;, &quot;&amp;amp;&quot;)
    extResp = Replace(extResp, &quot;\u003c&quot;, &quot;&amp;lt;&quot;)
    extResp = Replace(extResp, &quot;\u003e&quot;, &quot;&amp;gt;&quot;)
    extResp = Replace(extResp, &quot;\&quot;, vbNull)
    
    GenerateResponse = extResp
    
    Set http = Nothing
    
ErrorHandler_Exit:
Exit Function

ErrorHandler:
    MsgBox &quot;Error: &quot; &amp;amp; Err.Description
    Set http = Nothing

Resume ErrorHandler_Exit

End Function

Public Function RefineRawPrompt(ByVal rawPrompt As String) As String
Dim rPrompt As String

On Error GoTo ErrorHandler
&#39;Find VBA invalid CTRL characters of JSON
&#39;and replace valid control codes.

rPrompt = rawPrompt
rPrompt = Replace(rPrompt, &quot;&quot;&quot;&quot;, &quot;\&quot;&quot;&quot;)
rPrompt = Replace(rPrompt, vbCrLf, &quot;\n&quot;)
rPrompt = Replace(rPrompt, vbCr, &quot;\r&quot;)
rPrompt = Replace(rPrompt, vbLf, &quot;\n&quot;)
rPrompt = Replace(rPrompt, &quot;&#39;&quot;, &quot;\u0027&quot;)
rPrompt = Replace(rPrompt, &quot;\&quot;, &quot;\\&quot;)
rPrompt = Replace(rPrompt, &quot;/&quot;, &quot;\/&quot;)

RefineRawPrompt = rPrompt

ErrorHandler_Exit:
Exit Function

ErrorHandler:
    MsgBox &quot;Error: &quot; &amp;amp; Err.Description
Resume ErrorHandler_Exit

End Function

&#39;=============================
&#39; Private Helpers
&#39;=============================

Private Function BuildjsonBody(ByVal Prompt As String) As String
    Dim safePrompt As String
    
On Error GoTo ErrorHandler

    safePrompt = Replace(Prompt, &quot;&quot;&quot;&quot;, &quot;\&quot;&quot;&quot;)
        
    BuildjsonBody = &quot;{&quot;&quot;model&quot;&quot;:&quot;&quot;&quot; &amp;amp; m_Model &amp;amp; &quot;&quot;&quot;,&quot; &amp;amp; _
    &quot;&quot;&quot;system&quot;&quot;:&quot;&quot;&quot; &amp;amp; m_System &amp;amp; &quot;&quot;&quot;,&quot; &amp;amp; _
    &quot;&quot;&quot;prompt&quot;&quot;:&quot;&quot;&quot; &amp;amp; safePrompt &amp;amp; &quot;&quot;&quot;,&quot; &amp;amp; _
    &quot;&quot;&quot;stream&quot;&quot;:false,&quot; &amp;amp; _
    &quot;&quot;&quot;options&quot;&quot;:{&quot; &amp;amp; _
    &quot;&quot;&quot;temperature&quot;&quot;:&quot; &amp;amp; m_Temperature &amp;amp; &quot;,&quot; &amp;amp; _
    &quot;&quot;&quot;max_tokens&quot;&quot;:&quot; &amp;amp; m_Tokens &amp;amp; &quot;}}&quot;
  
ErrorHandler_Exit:
Exit Function

ErrorHandler:
    MsgBox &quot;Error: &quot; &amp;amp; Err.Description
Resume ErrorHandler_Exit
End Function

Private Function ExtractResponse(ByVal jsonText As String) As String
    Dim startPos As Long
    Dim endPos As Long
    
On Error GoTo ErrorHandler

    startPos = InStr(jsonText, &quot;&quot;&quot;response&quot;&quot;:&quot;&quot;&quot;)
    If startPos = 0 Then
        ExtractResponse = jsonText
        Exit Function
    End If
    
    startPos = startPos + 12
    endPos = InStr(startPos, jsonText, &quot;&quot;&quot;,&quot;&quot;done&quot;&quot;&quot;)
    
    If endPos &amp;gt; startPos Then
        ExtractResponse = Mid(jsonText, startPos, endPos - startPos)
    Else
        ExtractResponse = jsonText
    End If
    
ErrorHandler_Exit:
Exit Function

ErrorHandler:
    MsgBox &quot;Error: &quot; &amp;amp; Err.Description
Resume ErrorHandler_Exit
End Function

 
  &lt;/pre&gt;

&lt;p&gt;The above Program procedures were explained in detail in the second episode of this topic, viz. &lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-access-vba-and-sql.html&quot; target=&quot;_blank&quot;&gt;Access and AI Integration Part 2.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The primary VBA functions used in this application are &lt;b&gt;GenerateResponse()&lt;/b&gt; and &lt;b&gt;ExtractResponse()&lt;/b&gt;. The GenerateResponse() function sends the user’s prompt to the selected AI model via the Local API using &lt;i&gt;&lt;b&gt;HTTP.send jsonBody&lt;/b&gt;&lt;/i&gt;. The AI model processes the JSON request and returns the generated output through &lt;b&gt;&lt;i&gt;http.responseText&lt;/i&gt;&lt;/b&gt;, which is stored in the &lt;i&gt;rawResponse&lt;/i&gt; variable. The ExtractResponse() function retrieves the actual result generated for the user’s prompt and stores it in the &lt;i&gt;extResp&lt;/i&gt; variable.&lt;/p&gt;

&lt;p&gt;Within the extResp response text, certain VBA control characters or special characters, such as &amp;lt;, &amp;gt;, &amp;amp;, and similar symbols, may appear as JSON escape codes. Therefore, it is advisable to validate and replace these special characters with their corresponding VBA-compatible characters.&lt;/p&gt;

&lt;p&gt;This conversion process is performed in the final steps of the GenerateResponse() function, as shown in the following lines of code.&lt;/p&gt;

    &lt;pre&gt; extResp = ExtractResponse(rawResponse)
    
&#39;Replace JSON escape Codes, if found, with VBA codes
    extResp = Replace(extResp, &quot;\n&quot;, vbNewLine)
    extResp = Replace(extResp, &quot;\u0026&quot;, &quot;&amp;amp;&quot;)
    extResp = Replace(extResp, &quot;\u003c&quot;, &quot;&amp;lt;&quot;)
    extResp = Replace(extResp, &quot;\u003e&quot;, &quot;&amp;gt;&quot;)
    extResp = Replace(extResp, &quot;\&quot;, vbNull)
    
    GenerateResponse = extResp&lt;/pre&gt;
    
    &lt;h2 id=&quot;Prompt&quot;&gt;Best Prompt Templates for Microsoft Access Developers.&lt;/h2&gt;


&lt;h4&gt;Prompt Engineering Toolkit for Access Developers&lt;/h4&gt;
&lt;h4&gt;Reusable AI Prompts for SQL and VBA&lt;/h4&gt;


&lt;p&gt;Below is a Standard Prompt Template Library designed specifically for Microsoft Access (SQL + VBA) with local AI models (e.g., Ollama using qwen2.5-coder:3b).&lt;/p&gt;

    &lt;ol&gt;&lt;li&gt;&lt;h3&gt;Universal System Prompt (Use Everywhere)&lt;/h3&gt;
&lt;pre&gt;You are a Microsoft Access expert.

Generate only valid Microsoft Access SQL or VBA code.

Do not include explanations, comments, or alternative options.

Follow proper syntax and best practices.
&lt;/pre&gt;&lt;/li&gt;


&lt;li&gt;&lt;h3 id=&quot;SQL&quot;&gt;SQL Query Templates&lt;/h3&gt;



 &lt;h4&gt;Basic SELECT Query&lt;/h4&gt;
  &lt;pre&gt;Task: Create a Microsoft Access SQL SELECT query


Table: [TableName]

Fields: [Field1], [Field2], [Field3]

Filter: [Condition]

Sort: [Field ASC/DESC]



Return only SQL.
&lt;/pre&gt;


    &lt;h4&gt;JOIN Query&lt;/h4&gt;
        
        &lt;pre&gt;Task: Create a Microsoft Access SQL query with JOIN


Tables:

- Customers (CustomerID, Name)

- Orders (OrderID, CustomerID, Amount)


Requirement:

Join Customers and Orders

Show Customer Name and Total Order Amount


Return only SQL.

 &lt;/pre&gt;

        &lt;h4&gt;TOP N Query&lt;/h4&gt;

&lt;pre&gt;Task: Create a Microsoft Access SQL query



Table: Orders

Fields: CustomerID, Amount

Requirement:

Return top 5 customers by total Amount



Return only SQL.

&lt;/pre&gt;

        &lt;h4&gt;PARAMETER Query&lt;/h4&gt;

&lt;pre&gt;Task: Create a parameter query in Microsoft Access


Table: Orders

Fields: OrderID, OrderDate, Amount


Requirement:

Prompt user for Start Date and End Date


Return only SQL.

&lt;/pre&gt;&lt;/li&gt;

      &lt;li&gt;&lt;h3 id=&quot;VBAGen&quot;&gt;VBA Code Templates&lt;/h3&gt;

       &lt;h4&gt;Simple Function&lt;/h4&gt;
        
&lt;pre&gt;Task: Write a VBA function in Microsoft Access



Requirement:

Open a DAO Recordset for table Customers

Loop through records

Print Customer Name to Immediate Window



Return only VBA code.

&lt;/pre&gt;

      &lt;h4&gt;Form Event Procedure&lt;/h4&gt;
        
 &lt;pre&gt; 
 Task: Write VBA code for a Form Button Click event


Requirement:

On click:

- Open query &quot;qrySalesReport&quot;

- Display results


Return only VBA code.

&lt;/pre&gt;

      &lt;h4&gt; Error Handling Template&lt;/h4&gt;

        &lt;pre&gt;        
Task: Write a VBA procedure with error handling


Requirement:

Open a recordset

Handle runtime errors properly

Show error message


Return only VBA code.

&lt;/pre&gt;

      &lt;h4&gt; Reusable Class Module&lt;/h4&gt;
        
&lt;pre&gt;Task: Create a VBA class module


Requirement:

Class Name: clsCustomer

Properties:

- CustomerID

- CustomerName


Include Property Let/Get procedures


Return only VBA code.

&lt;/pre&gt;&lt;/li&gt;

      &lt;li&gt;&lt;h3 id=&quot;Debug&quot;&gt;Debugging Templates&lt;/h3&gt;

        &lt;h4&gt; Fix SQL Query&lt;/h4&gt;
        
&lt;pre&gt;Task: Correct the following Microsoft Access SQL query


SQL:

[Paste SQL here]



Return corrected SQL only.

&lt;/pre&gt;

        &lt;h4&gt;Fix VBA Code&lt;/h4&gt;
        
 &lt;pre&gt; 
 Task: Debug the following VBA code


Code:

[Paste Code here]


Fix errors and return corrected code only.

&lt;/pre&gt;&lt;/li&gt;

      &lt;li&gt;&lt;h3&gt;Explanation Templates (Learning Mode)&lt;/h3&gt;

        &lt;h4 id=&quot;ExpSQL&quot;&gt;Explain SQL&lt;/h4&gt;
 &lt;pre&gt; 
 Explain the following Microsoft Access SQL query step by step:


[Paste SQL]


Keep explanation simple and structured.

&lt;/pre&gt;

        &lt;h4 id=&quot;ExpVBA&quot;&gt;Explain VBA&lt;/h4&gt;
        
 &lt;pre&gt; 
 Explain the following VBA code:

[Paste Code]

Describe what each section does.

&lt;/pre&gt;&lt;/li&gt;

      &lt;li&gt;&lt;h3&gt;Database-Aware Smart Template (Advanced)&lt;/h3&gt;

&lt;pre&gt;Task: Generate SQL based on database structure


Tables:

Customers(CustomerID, Name, City)

Orders(OrderID, CustomerID, Amount)


Requirement:

Find top 3 customers by total order amount


Return only Microsoft Access SQL.

  &lt;/pre&gt;
   &lt;/li&gt;


        &lt;li&gt;&lt;h3&gt;Output Control Add-on (Very Important)&lt;/h3&gt;


&lt;p&gt;Append this to any prompt:&lt;/p&gt;

          &lt;pre&gt;Rules:

- Output only code

- No explanation

- No comments

&lt;/pre&gt;&lt;/li&gt;

        &lt;li&gt;&lt;h3&gt;Recommended Parameter Settings&lt;/h3&gt;
        &lt;pre&gt;        
        {

  &quot;temperature&quot;: 0.2,

  &quot;max_tokens&quot;: 150

}

&lt;/pre&gt;
        &lt;/li&gt;&lt;/ol&gt;

        &lt;h3&gt;How to Use This Library&lt;/h3&gt;
&lt;ol&gt;

  &lt;li&gt;&lt;p&gt;Pick a template&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace placeholders&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send to your local AI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy - Test - Refine.&lt;/p&gt;&lt;/li&gt;
        &lt;/ol&gt;


    &lt;p&gt;&lt;b&gt;Note:&amp;nbsp;&lt;/b&gt;The quality of AI output depends more on the prompt structure than the model itself.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
  &lt;h2&gt;Frequently Asked Questions.&lt;/h2&gt;
 &lt;ol&gt;&lt;li&gt;&lt;h4&gt;Can Microsoft Access connect to AI models?&lt;/h4&gt;&lt;p&gt;Yes. Microsoft Access can connect to local AI models through HTTP APIs such as Ollama.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;h4&gt;What is the best AI model for VBA Code generation?&lt;/h4&gt;
 
   &lt;p&gt;Qwen2.5-Coder and similar coding models generally produce better VBA and SQL output.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;h4&gt;Can I generate Microsoft Access SQL queries?&lt;/h4&gt;&lt;p&gt;Yes. AI models can translate natural language instructions into Access-compatible SQL.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;

  &lt;h3&gt;Demo Databases Download.&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/06/WrapperClass_Wizard.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1nqM-DgHjV8jpDf8BTk9YjbG3OmuMK16j/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioFf-79SroXZ4JkiqgZYv196vvwuIDU6wLEconUKqF-8uKB4XfA4P2yshkCX2o16u08fw9nN8LkTe8XvDgBDDTepmbEqtmBreKye0SKYfz10iaUmM1loO3uX7sYhQvQctArB6ZjjzRO1Rw/s320/zip.gif&quot; width=&quot;22&quot; /&gt;AI3_IntegrationV3.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/06/WrapperClass_Wizard.zip--&gt;
&lt;br /&gt;
  &lt;h2&gt;Related Articles&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-microsoft-access-for.html&quot; target=&quot;_Blank&quot;&gt;AI Integration in Microsoft Access Part 1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-access-vba-and-sql.html&quot; target=&quot;_Blank&quot;&gt;AI Integration in Access VBA and SQL Part 2&lt;/a&gt;&lt;/li&gt;

 &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
  &lt;/ol&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/4959130053872510427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2026/05/access-and-ai-integration-part-3.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/4959130053872510427'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/4959130053872510427'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2026/05/access-and-ai-integration-part-3.html' title='Understanding JSON, Temperature and Max Tokens in AI Integration (Part 3)'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJm9ZPPr1BvatMcWztXM35rVj0H07mwrCR8rB75Zo_3GFnkIDtc-O2soYkEtFikrP9bSKbzzkdubb3iNPjrfAEAPk_jFvFa5oIyoMIKrHtHYvT9DEgbCYllstlc_neJE4YOhXXok8dHLr5H3qpyNrvfcPdvBmrWavxPLM7rf79iYQGUOMXLlC2L9T_1Iu6/s72-c/AI3Form_DesignNew1.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-7887056395081550418</id><published>2026-04-27T17:18:00.012+05:30</published><updated>2026-06-29T21:38:23.738+05:30</updated><title type='text'>Generate Microsoft Access SQL and VBA with Local AI Models (Part 2)</title><content type='html'>&lt;h2 style=&quot;text-align: left;&quot;&gt;Generate Microsoft Access SQL and VBA with Local AI Models (Part 2).&lt;/h2&gt;
&lt;p&gt;Modernizing Microsoft Access applications with AI is not about replacing Access—it’s about extending it into a far more intelligent, responsive, and future-ready system. With the right integration approach, Access can evolve from a traditional desktop database into a smart, AI-assisted application platform.&lt;/p&gt;

&lt;p&gt;If you have not visited the first part of this series&lt;span style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;,&lt;a href=&quot;&quot; target=&quot;_blank&quot;&gt;&amp;nbsp;&lt;/a&gt;&lt;/span&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-microsoft-access-for.html?m=1&quot; target=&quot;_blank&quot;&gt;AI Integration in Microsoft Access for VBA Coding Part&amp;nbsp;&lt;/a&gt;&lt;span style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;&lt;a href=&quot;&quot; target=&quot;_blank&quot;&gt;1&lt;/a&gt;, then&lt;/span&gt;&amp;nbsp;please visit the Page and continue.&lt;/p&gt;
  
&lt;h3&gt;Intelligent Query &amp;amp; SQL Generation.&lt;/h3&gt;
&lt;p&gt;AI models can translate natural language into SQL queries, dramatically reducing the need for manual query design.&lt;/p&gt;

&lt;p&gt;A user types: “Show me dairy products sorted by name.”&lt;/p&gt;
&lt;p&gt;AI converts it into a valid Access SQL statement instantly&lt;/p&gt;
&lt;p&gt;This is especially powerful for non-technical users and rapid prototyping. Using local LLMs (via tools like Ollama), you can embed this capability directly into Access forms.&lt;/p&gt;

&lt;h3&gt;AI-Assisted VBA Coding&lt;/h3&gt;
&lt;p&gt;Writing and maintaining VBA code becomes faster and more reliable with AI assistance.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;p&gt;Generate boilerplate code for forms, reports, and modules&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Debug and refactor existing VBA procedures&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Auto-document your code for better maintainability&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Models such as Mistral or Qwen2.5-Coder can run locally and assist developers directly within Access.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Smart Data Entry &amp;amp; Validation&lt;/h3&gt;
&lt;p&gt;AI can enhance forms with intelligent suggestions and validation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Auto-complete fields based on historical data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detect anomalies (e.g., incorrect pricing, duplicate entries)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suggest corrections in real time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This reduces human error and improves data quality significantly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Natural Language Interface (NLI)&lt;/h3&gt;
&lt;p&gt;Instead of navigating complex forms and menus, users can interact with Access using plain language.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;“Add a new customer from Kochi with the pending invoice.”&lt;/li&gt;
  &lt;li&gt;“List the top 10 customers by sales this month.”&lt;/li&gt;
  &lt;li&gt;This can be implemented using prompt-driven interfaces embedded in Access forms.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Automated Reporting &amp;amp; Insights&lt;/h3&gt;
&lt;p&gt;AI can transform raw data into meaningful summaries:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Generate narrative reports (“Sales increased by 12% this quarter…”)&lt;/li&gt;
  &lt;li&gt;Identify trends and outliers automatically&lt;/li&gt;
  &lt;li&gt;Suggest actionable insights&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This moves Access from a data storage tool to a decision-support system.&lt;/p&gt;

&lt;p&gt;I assume that Ollama, Mistral, and qwen2.5-coder:3b are already installed on your Windows 10 or Windows 11 system. However, relying on Command Prompt–based trial runs is neither practical nor efficient for developing production-quality VBA code or generating SQL statements.&lt;/p&gt;

&lt;p&gt;Instead, we can design a user-friendly interface in Microsoft Access to execute AI prompts seamlessly. This approach will enable faster and more consistent generation of Access VBA code and SQL queries, significantly improving overall development efficiency.&lt;/p&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;A Simple Table with only two Fields.&lt;/h3&gt;&lt;p&gt;Table Name: &lt;b&gt;AIPrompt.&lt;/b&gt;&lt;/p&gt;&lt;center&gt;&lt;p&gt;&lt;b&gt;Table Structure:&lt;/b&gt;&lt;/p&gt;&lt;/center&gt;
&lt;center&gt;&lt;table bgcolor=&quot;#faf2f2&quot; border=&quot;1&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; style=&quot;width: 400px;&quot;&gt;&lt;caption&gt;&lt;font&gt;AIPrompt Table&lt;/font&gt;&lt;/caption&gt;
&lt;tbody&gt;
  &lt;tr&gt;&lt;th valign=&quot;top&quot; width=&quot;50%&quot;&gt;Field Name&lt;/th&gt;        &lt;th valign=&quot;top&quot; width=&quot;50%&quot;&gt;Field Type&lt;/th&gt;&lt;/tr&gt;&lt;/tbody&gt;
  &lt;tbody&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;Prompt&lt;/td&gt;        &lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;LongText&lt;/td&gt; &lt;/tr&gt;
  
  &lt;/tbody&gt;
  &lt;tbody&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;Result&lt;/td&gt;        &lt;td valign=&quot;top&quot; width=&quot;50%&quot;&gt;LongText&lt;/td&gt;  &lt;/tr&gt;
  
  &lt;/tbody&gt;
  
  &lt;/table&gt;&lt;/center&gt;

&lt;p&gt;A Simple Form in Design View is given below for reference:&lt;/p&gt;
&lt;center&gt;&lt;p&gt;&lt;b&gt;frmAIPrompt in Design View &lt;/b&gt;&lt;/p&gt;&lt;/center&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC5pCTDC0psiF6_EOGq4vn8HCzTC_Vm0Bh_-zrOBr9o5LKe4h0BP_14GEvPdeeha_xFGp3U232mEqS3RL1kS16hdvbc-rGOjz9K0GAtu_qmp-sZ3AaZfXO_m2y64nGY48Q1sq6SPN_yB2MY07CIWuWkXLKIc_8v03XjuPsUgdGVl7Erqtl7PCKiu9Rqi__/s1233/AI2_00N.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;805&quot; data-original-width=&quot;1233&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC5pCTDC0psiF6_EOGq4vn8HCzTC_Vm0Bh_-zrOBr9o5LKe4h0BP_14GEvPdeeha_xFGp3U232mEqS3RL1kS16hdvbc-rGOjz9K0GAtu_qmp-sZ3AaZfXO_m2y64nGY48Q1sq6SPN_yB2MY07CIWuWkXLKIc_8v03XjuPsUgdGVl7Erqtl7PCKiu9Rqi__/s320/AI2_00N.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;The AIPrompt table is linked to the form frmAIPrompt. The TextBox on the left has both its Control Source and Name properties set to the Prompt field of the table, while the TextBox on the right uses the Result field for its Control Source and Name properties.&lt;/p&gt;
&lt;p&gt;A command button is placed above the TextBoxes. In addition, a label with the caption “Working, please wait…” is positioned above the Prompt TextBox. This label remains hidden during normal use. When a prompt is executed by clicking the command button, the label becomes visible and stays on screen until the AI response is written to the Result TextBox.&lt;/p&gt;
&lt;p&gt;The Result TextBox is locked to prevent accidental edits, but it remains enabled so users can still select and copy its contents as needed.&lt;/p&gt; &lt;p&gt;In a previous session, we downloaded and installed three different programs on our computers. We will now provide a brief introduction to each of them.&lt;/p&gt;&lt;p&gt;1. &lt;b&gt;Ollama&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Ollama&lt;/b&gt;&amp;nbsp;is a lightweight runtime and management tool that lets you run large language models (LLMs) locally on your computer without relying on cloud-based AI services. It acts as a bridge between raw model files (such as Mistral or Qwen2.5-Coder) and user applications, making it easy to download, install, run, and interact with these models through simple commands or APIs.&lt;/p&gt;&lt;p&gt;In the context of the Local AI models, Ollama performs several key functions. &lt;br /&gt;&lt;br /&gt;First, it manages model lifecycle operations - you can pull (download), list, update, and remove models using straightforward commands like &lt;i&gt;Ollama pull mistral. &lt;br /&gt;&lt;/i&gt;&lt;br /&gt;Second, it provides a local inference engine, meaning it executes the model of your machine (CPU/GPU) and generates responses in real-time. &lt;br /&gt;&lt;br /&gt;Third, it offers a standardized API interface allowing developers to integrate local LLM capabilities into applications such as Microsoft Access, web apps, or automation tools.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Fourth, Ollama handles model configuration and optimization, including parameters like &lt;i&gt;temperature&lt;/i&gt; and &lt;i&gt;context size, &lt;/i&gt;simplifying what would otherwise be complex setup tasks.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Finally&lt;i&gt;,&lt;/i&gt; it ensures privacy and offline capability, since all data processing happens locally, an important advantage for sensitive or enterprise data. In short, Ollama transforms complex LLM deployment into a simple, developer-friendly workflow for running AI models locally.&lt;/p&gt;&lt;p&gt;2. &lt;b&gt;Mistral.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The Mistral Large Language Model (LLM) is a family of advanced generative AI models developed by Mistral AI. Designed to understand and generate human language with high efficiency and strong reasoning ability.&amp;nbsp; Built on transformer-based neural network architecture and can perform a wide range of tasks such as text generation, translation, summarization, and code writing by predicting patterns in language data.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Additionally, many Mistral models are released with open weight or open-source licenses, making them highly attractive for developers and enterprises seeking customizable, locally deployable AI solutions.&lt;/p&gt;&lt;p id=&quot;VBA&quot;&gt;3. &lt;b&gt;Qwen2.5-Coder:3B&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The Qwen2.5-coder:3B model is a compact, code-specialized large language model developed by Alibaba Cloud as part of the broader Qwen2.5 series, designed specifically for programming-related tasks such as code generation, compilation, debugging, and reasoning. It supports multiple programming languages and demonstrates solid performance in real-world development scenarios.&lt;/p&gt;&lt;p&gt;In addition to coding, it retains general language and mathematical reasoning abilities, and its availability in different sizes within the Qwen2.5-Coder family allows developers to choose models based on their computational constraints and application needs.&lt;/p&gt;
&lt;center&gt;&lt;h4&gt;frmAIPrompt in Form View&lt;/h4&gt;&lt;/center&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPAAw-AHLv_MWDCy2n_JEylgHx8ne_VvKETu4PkW_AQ_qQ9ZhGMAZFO1oDte6oX-SpN-t1nfow1EGKt4EVZWsng01FgsS5K7ciZ0pkxlO9rDWQmPWn28WduFBLe91McAOoRg3O_xmKl53z2XsKx4m8VjIJswV1_Wj7lMcpmkdammin8EBYHm_NwNZmK9YU/s1209/AI2_0N.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;799&quot; data-original-width=&quot;1209&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPAAw-AHLv_MWDCy2n_JEylgHx8ne_VvKETu4PkW_AQ_qQ9ZhGMAZFO1oDte6oX-SpN-t1nfow1EGKt4EVZWsng01FgsS5K7ciZ0pkxlO9rDWQmPWn28WduFBLe91McAOoRg3O_xmKl53z2XsKx4m8VjIJswV1_Wj7lMcpmkdammin8EBYHm_NwNZmK9YU/s320/AI2_0N.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Right-click the form image above to open a larger version in a new tab for clearer viewing. The left-side TextBox displays the AI prompt used to generate an Access wrapper class module for a command button control. The required details are entered on separate lines within the prompt.&lt;/p&gt;

&lt;p&gt;For simplicity, a basic prompt—such as one for an Access SQL statement or a VBA function—could have been used. However, this more detailed example demonstrates how to structure a multi-step prompt within a TextBox control. Use Ctrl + Enter to insert line breaks and organize the prompt into logical sections on separate lines.&lt;/p&gt;&lt;p&gt;When complete, click the &#39;AskAI&#39; Command Button to execute the Prompt.&lt;/p&gt;&lt;p&gt;Let us inspect the Command Button Click Event Procedure listed below:&lt;/p&gt;

&lt;pre&gt;Option Compare Database
Option Explicit

Private Sub cmdClose_Click()
If MsgBox(&quot;Close the Form?&quot;, vbYesNo + vbInformation, &quot;cmdClose()&quot;) = vbYes Then
    DoCmd.Close acForm, Me.Name
End If
End Sub

Private Sub cmdRun_Click()
Dim sPrompt As String
Dim sResult As String
Dim sModel As String
Dim sel_Model As Integer

Const m_Model = &quot;mistral&quot;
Const q_Model = &quot;qwen2.5-coder:3b&quot;

sel_Model = Me!Models


If sel_Model = 1 Then
    sModel = q_Model
Else
    sModel = m_Model
End If

Me.Label5.Visible = True
Me.Repaint

sPrompt = Me!Prompt
&#39; Convert VB Speial characters to
&#39;Java Script Object Notation compatible characters
&#39; Escapes special characters for JSON
    sPrompt = Replace(sPrompt, &quot;\&quot;, &quot;\\&quot;)        &#39; Backslash
    sPrompt = Replace(sPrompt, vbCrLf, &quot;\n&quot;)     &#39; Line break (Windows)
    sPrompt = Replace(sPrompt, vbCr, &quot;\n&quot;)      &#39;Cariage Return
    sPrompt = Replace(sPrompt, vbLf, &quot;\n&quot;)      &#39;Line Feed

sResult = AskLocalAI(sPrompt, sModel)

Me!Result = &quot;&quot;
Me!Result = sResult

Me.Label5.Visible = False
Me.Repaint

Me.Result.SetFocus

End Sub

&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;At the start of the procedure, the selected LLM model is initialized in the sModel variable. The AI prompt, stored in a Long Text field, may include special characters such as line breaks (Ctrl+Enter), double quotes, backslashes, and non-printable characters like carriage return and line feed (vbCrLf). Before submitting the prompt to the chosen AI model, these characters must be properly encoded into a valid JSON string—the format required by the AI for processing.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; The &lt;b&gt;response&lt;/b&gt; from the AI model is returned in JSON format. The required result must be extracted from the JSON string, specifically from the content between the &lt;b&gt;response&lt;/b&gt; and &lt;b&gt;end&lt;/b&gt; tags.
After reformatting the AI prompt, the &lt;b&gt;AskLocalAI()&lt;/b&gt; function is invoked, with the &lt;b&gt;prompt&lt;/b&gt; and &lt;b&gt;model&lt;/b&gt; name passed as parameters.
Once the response is returned by the AskLocalAI() function, it replaces any existing content and is inserted into the Result TextBox on the form.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The AI workflow itself is straightforward: clearly describe the task you want the AI to perform in the Prompt TextBox, ideally in a step-by-step manner. Providing detailed instructions yields more accurate and useful results than a brief, one-line request such as: “Create an SQL query to display Employees’ Last Name, First Name, and City from the Employees table.”&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; Avoid running the same Task with minor changes repeatedly.&lt;/p&gt;&lt;p&gt;You should continuously refine your ability to write effective AI prompts tailored to your specific task. Be as detailed and explicit as possible when describing your requirements, since clearer instructions lead to more accurate and useful outputs.&lt;/p&gt;
&lt;p&gt;When requesting VBA or SQL solutions, explicitly specify that you need Microsoft Access VBA or Microsoft Access SQL in your prompt. This ensures the generated code uses the correct syntax and conventions for Microsoft Access.&lt;/p&gt;
&lt;p&gt;If you request only VBA code without specifying the platform, it is typically assumed to be for Microsoft Excel. As a result, the code provided may not be compatible with Microsoft Access.&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;The AskLocalAI() Function&lt;/h4&gt;

&lt;pre&gt;Option Compare Database
Option Explicit
 
 Function AskLocalAI(aiPrompt As String, ModelName As String) As String

    Dim http As Object
    Dim JSON As String
    Dim Response As String
    Dim safePrompt As String
    Dim txtResponse As String


    Set http = CreateObject(&quot;MSXML2.XMLHTTP&quot;)
    
&#39;Escape Double Quptes in Prompt (important)
    safePrompt = Replace(aiPrompt, &quot;&quot;&quot;&quot;, &quot;\&quot;&quot;&quot;) &#39;double quote to JSON escape Code \&quot;

    JSON = &quot;{&quot;&quot;model&quot;&quot;:&quot;&quot;&quot; &amp;amp; ModelName &amp;amp; &quot;&quot;&quot;,&quot;&quot;prompt&quot;&quot;:&quot;&quot;&quot; &amp;amp; safePrompt &amp;amp; &quot;&quot;&quot;,&quot;&quot;stream&quot;&quot;:false}&quot;

    http.Open &quot;POST&quot;, &quot;http://localhost:11434/api/generate&quot;, False

    http.setRequestHeader &quot;Content-Type&quot;, &quot;application/json&quot;

    http.Send JSON

    Response = http.responseText
    
    txtResponse = ExtractText(Response)
    
&#39;Replace escape Code with VBA codes
txtResponse = Replace(txtResponse, &quot;\n&quot;, vbNewLine)
txtResponse = Replace(txtResponse, &quot;\u0026&quot;, &quot;&amp;amp;&quot;)
txtResponse = Replace(txtResponse, &quot;\u003c&quot;, &quot;&amp;lt;&quot;)
txtResponse = Replace(txtResponse, &quot;\u003e&quot;, &quot;&amp;gt;&quot;)
txtResponse = Replace(txtResponse, &quot;\&quot;, vbNull)

    AskLocalAI = txtResponse

 End Function
&lt;/pre&gt;
&lt;p&gt;The statement: &lt;i&gt;Set http = CreateObject(&quot;MSXML2.XMLHTTP&quot;)&lt;/i&gt;&amp;nbsp;creates an Instance of the&amp;nbsp;&lt;i&gt;MSXML2.XMLHTTP &lt;/i&gt;COM Object.&lt;/p&gt;&lt;p&gt;This object is primarily used to send HTTP requests to servers and receive responses (such as HTML, XML, or JSON data) without a web browser, making it a cornerstone API interaction and automated web tasks in VBA.&lt;/p&gt;&lt;p&gt;The Prompt that was passed to &lt;b&gt;AskLocalAI()&lt;/b&gt; is further checked for Double quotes (&quot;) in the Prompt; if found, then changes it to (\&quot;) JSON Escape code.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;JSON escape codes are backslash-prefixed sequences used to represent characters within a JSON string that would otherwise break the data&#39;s structure or are impossible to type directly.&amp;nbsp; Because JSON strings must be enclosed in double quotes, any literal double quote inside the string must be escaped so the JSON Parser does not mistake it for the end of the string&lt;/p&gt;&lt;p&gt;Next, the Input information, the Large Language Model Name, and the user&#39;s Task Prompt values are validated, formatted, and saved in the JSON String Variable, ready to pass to the Local Cloud Service.&lt;/p&gt;&lt;p&gt;The next two steps, the Local Host Cloud is open for API Service and initialized to accept the JSON input.&lt;/p&gt;&lt;p&gt;The statement:&amp;nbsp;&lt;b&gt;http.Send JSON,&lt;/b&gt;&amp;nbsp;transmit the JSON input to the user-selected LLM Model for action.&amp;nbsp;&lt;/p&gt;&lt;p&gt;We will get the response from the AI Model through the statement: &lt;i&gt;&lt;b&gt;Response = http.responseText&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;The Response variable may contain a significant amount of extraneous information, such as timestamps indicating when the request was received, action logs, and other system-generated metadata. This is typically followed by the actual &lt;b&gt;response&lt;/b&gt; to the requested information, which often ends with the word &lt;b&gt;“Done,”&lt;/b&gt; and may then be followed by additional system log details.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; We will explore JSON Syntax and Structure in detail next week.&lt;/p&gt;&lt;p&gt;The graphical representation of the Response looks like the following:&lt;/p&gt;&lt;p&gt;Log--------- &lt;i&gt;Response&lt;/i&gt; &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;i&gt;Done&lt;/i&gt;------------Log&lt;/p&gt;&lt;p&gt;We are interested only in retrieving the information between the words: &lt;i&gt;Response&lt;/i&gt; and &lt;i&gt;Done, from&lt;/i&gt; within the JSON Response String.&amp;nbsp;&lt;/p&gt;&lt;p&gt;There is a small Function to do that job. The VBA Code is given below.&lt;/p&gt;
&lt;pre&gt;Private Function ExtractText(ByVal jsonText As String) As String
    Dim startPos As Long
    Dim endPos As Long
    
    startPos = InStr(jsonText, &quot;&quot;&quot;response&quot;&quot;:&quot;&quot;&quot;) + 12
    endPos = InStr(startPos, jsonText, &quot;&quot;&quot;,&quot;&quot;done&quot;&quot;&quot;)
    
    If endPos &amp;gt; startPos Then
        ExtractText = Mid(jsonText, startPos, endPos - startPos)
    Else
        ExtractText = jsonText
    End If
End Function

&lt;br /&gt;&lt;/pre&gt;


&lt;p&gt;The first statement in the ExtractText() function searches for the tag &quot;&lt;b&gt;response&lt;/b&gt;&quot;:. If found, it calculates the character position immediately after this tag by adding the length of &quot;response&quot;: plus one (i.e., 12) and saves it in the&amp;nbsp;&lt;i&gt;startPos&lt;/i&gt; variable. This value marks the starting point of the AI-generated output.&lt;/p&gt;

&lt;p&gt;The next statement searches for the &quot;&lt;b&gt;done&lt;/b&gt;&quot; tag, which indicates the end of the relevant output, within the JSON string, and stores its position in the &lt;i&gt;endPos&lt;/i&gt; variable. With both the starting and ending positions identified, the function can extract the prompt result from the JSON string.&lt;/p&gt;

&lt;p&gt;The following statement validates these positions. If they are valid, it extracts the response text (from startPos to endPos) and returns the result. Otherwise, it returns the entire JSON string—including all extraneous details—to the calling function AskLocalAI().&lt;/p&gt;

&lt;p&gt;When the prompt response is extracted, it may still contain JSON-encoded characters (such as &quot;\u0026&quot; for &amp;amp; and &quot;\u003c&quot; for &amp;lt;) and similar codes. A series of additional statements is included to replace these escape sequences with their corresponding VBA-compatible characters.&lt;/p&gt;

&lt;p&gt;Finally, the processed response is returned to the cmdAskAI() command button click event procedure, where the result is used to populate the Result TextBox, replacing any existing content.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The &#39;Working, Please wait...&#39; label disappears. If the process takes too much time your System may hang for some time. Don&#39;t panic, give it time, and it will return with the result.&lt;/p&gt;


&lt;h3&gt;Prompt Engineering Toolkit for Access Developers&lt;/h3&gt;
&lt;h4&gt;Reusable AI Prompts for SQL and VBA&lt;/h4&gt;


&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Universal System Prompt (Use Everywhere)&lt;/p&gt;
&lt;pre&gt;You are a Microsoft Access expert.

Generate only valid Microsoft Access SQL or VBA code.

Do not include explanations, comments, or alternative options.

Follow proper syntax and best practices.
&lt;/pre&gt;&lt;/li&gt;


&lt;li&gt;&lt;p&gt;SQL Query Templates&lt;/p&gt;



&lt;h4&gt;Basic SELECT Query&lt;/h4&gt;
&lt;pre&gt;You are a Microsoft Access expert.

Generate only valid Microsoft Access SQL or VBA code.

Do not include explanations, comments, or alternative options.

Follow proper syntax and best practices.

Task: Create a Microsoft Access SQL SELECT query

Table: [TableName]

Fields: [Field1], [Field2], [Field3]

Filter: [Condition]

Sort: [Field ASC/DESC]


Return only SQL.

&lt;/pre&gt;

&lt;h4&gt;JOIN Query&lt;/h4&gt;
&lt;pre&gt;You are a Microsoft Access expert.

Generate only valid Microsoft Access SQL or VBA code.

Do not include explanations, comments, or alternative options.

Follow proper syntax and best practices.

Task: Create a Microsoft Access SQL query with JOIN

Tables:

- Customers (CustomerID, Name)

- Orders (OrderID, CustomerID, Amount)

Requirement:

Join Customers and Orders

Show Customer Name and Total Order Amount


Return only SQL.

&lt;/pre&gt;

&lt;h4&gt;TOP N Query&lt;/h4&gt;

&lt;pre&gt;Task: Create a Microsoft Access SQL query


Table: Orders

Fields: CustomerID, Amount

Requirement:

Return top 5 customers by total Amount


Return only SQL.

&lt;/pre&gt;

&lt;h4&gt;PARAMETER Query&lt;/h4&gt;

&lt;pre&gt;Task: Create a parameter query in Microsoft Access


Table: Orders

Fields: OrderID, OrderDate, Amount


Requirement:

Prompt user for Start Date and End Date


Return only SQL.
&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;&lt;p&gt;VBA Code Templates&lt;/p&gt;


&lt;h4&gt;Simple Function&lt;/h4&gt;

&lt;pre&gt;Task: Write a VBA function in Microsoft Access


Requirement:

Open a DAO Recordset for table Customers

Loop through records

Print Customer Name to Immediate Window


DO NOT:
- Explain the code
- Add Instruction text
- Add conclusion text
- Use markdown
- code fences&lt;br /&gt;

&lt;/pre&gt;

&lt;h4&gt; Form Event Procedure&lt;/h4&gt;

&lt;pre&gt;Task: Write VBA code for a Form Button Click event

Requirement:

On click:

- Open query &quot;qrySalesReport&quot;

- Display results

&lt;pre&gt;DO NOT:
- Explain the code
- Add Instruction text
- Add conclusion text
- Use markdown
- code fences&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;/pre&gt;

&lt;h4&gt;Error Handling Template&lt;/h4&gt;

&lt;pre&gt;Task: Write a VBA procedure with error handling


Requirement:

Open a recordset

Handle runtime errors properly

Show error message


&lt;pre&gt;DO NOT:
- Explain the code
- Add Instruction text
- Add conclusion text
- Use markdown
- code fences&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;/pre&gt;

&lt;h4&gt;Reusable Class Module&lt;/h4&gt;
&lt;pre&gt;Task: Create a VBA class module

Requirement:

Class Name: clsCustomer

Properties:

- CustomerID

- CustomerName


Include Property Let/Get procedures



&lt;pre&gt;DO NOT:
- Explain the code
- Add Instruction text
- Add conclusion text
- Use markdown
- code fences.&lt;/pre&gt;

&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Debugging Templates&lt;/p&gt;



&lt;h4&gt;Fix SQL Query&lt;/h4&gt;
&lt;pre&gt;Task: Correct the following Microsoft Access SQL query


SQL:

[Paste SQL here]


Return corrected SQL only.
&lt;/pre&gt;


&lt;h4&gt;Fix VBA Code&lt;/h4&gt;
&lt;pre&gt;Task: Debug the following VBA code


Code:

[Paste Code here]


Fix errors and return corrected code only.

&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Explanation Templates (Learning Mode)&lt;/p&gt;


&lt;h4&gt;Explain SQL&lt;/h4&gt;
&lt;pre&gt;Explain the following Microsoft Access SQL query step by step:


[Paste SQL]



Keep explanation simple and structured.

&lt;/pre&gt;

&lt;h4&gt;Explain VBA&lt;/h4&gt;
&lt;pre&gt;Explain the following VBA code:

[Paste Code]

Describe what each section does.

&lt;/pre&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Database-Aware Smart Template (Advanced)&lt;/p&gt;

&lt;pre&gt;Task: Generate SQL based on database structure


Tables:

Customers(CustomerID, Name, City)

Orders(OrderID, CustomerID, Amount)


Requirement:

Find top 3 customers by total order amount


Return only Microsoft Access SQL.

&lt;/pre&gt;&lt;/li&gt;


&lt;li&gt;&lt;p&gt;Output Control Add-on (Very Important)&lt;/p&gt;

&lt;p&gt;Append this to any prompt:&lt;/p&gt;

&lt;pre&gt;Rules:

- Output only code

- No explanation

- No comments
&lt;/pre&gt;&lt;/li&gt;


&lt;li&gt;&lt;p&gt;Recommended Parameter Settings.&lt;/p&gt;
&lt;pre&gt;{

  &quot;temperature&quot;: 0.2,

  &quot;max_tokens&quot;: 150

}
&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;How to Use This Library&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Pick a template&lt;/li&gt;
&lt;li&gt;Replace placeholders&lt;/li&gt;
&lt;li&gt;Send to your local AI&lt;/li&gt;
&lt;li&gt;Copy → Test → Refine&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt; Key Insight for Readers&lt;/h4&gt;

&lt;p&gt;The quality of AI output depends more on the prompt structure than the model itself.&lt;/p&gt;&lt;p&gt;Will continue Next Week.&lt;/p&gt;&lt;p&gt;Downloads:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Demo Databases Download.&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/06/WrapperClass_Wizard.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1tXl5otD3U7O6lCW_56XPOubXYRY0nKYu/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioFf-79SroXZ4JkiqgZYv196vvwuIDU6wLEconUKqF-8uKB4XfA4P2yshkCX2o16u08fw9nN8LkTe8XvDgBDDTepmbEqtmBreKye0SKYfz10iaUmM1loO3uX7sYhQvQctArB6ZjjzRO1Rw/s320/zip.gif&quot; width=&quot;22&quot; /&gt;AI LOCAL.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/06/WrapperClass_Wizard.zip--&gt;
&lt;br /&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2026/04/ai-integration-in-microsoft-access-for.html&quot; target=&quot;_Blank&quot;&gt;AI Integration in Microsoft Access Part 1&lt;/a&gt;&lt;/li&gt;

 &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/7887056395081550418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2026/04/ai-integration-in-access-vba-and-sql.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/7887056395081550418'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/7887056395081550418'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2026/04/ai-integration-in-access-vba-and-sql.html' title='Generate Microsoft Access SQL and VBA with Local AI Models (Part 2)'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC5pCTDC0psiF6_EOGq4vn8HCzTC_Vm0Bh_-zrOBr9o5LKe4h0BP_14GEvPdeeha_xFGp3U232mEqS3RL1kS16hdvbc-rGOjz9K0GAtu_qmp-sZ3AaZfXO_m2y64nGY48Q1sq6SPN_yB2MY07CIWuWkXLKIc_8v03XjuPsUgdGVl7Erqtl7PCKiu9Rqi__/s72-c/AI2_00N.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-7499383041024391964</id><published>2026-04-16T20:16:00.008+05:30</published><updated>2026-07-05T16:16:29.092+05:30</updated><title type='text'>How to Integrate AI into Microsoft Access VBA Using Ollama (Part 1)</title><content type='html'>&lt;h3&gt;Local AI for Microsoft Access SQL and VBA Coding - Part 1.&lt;/h3&gt;

&lt;p&gt;The idea of using Artificial Intelligence within Microsoft Access may sound complex at first, but recent advancements have made it surprisingly accessible—even on a standard Windows 10/11 PC. With lightweight local AI runtime, such as &#39;&lt;b&gt;Ollama&#39;&lt;/b&gt; and efficient coding-focused models like &lt;b&gt;Qwen2.5-Coder&lt;/b&gt;, Access developers can now experiment with AI-assisted SQL and &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;VBA generation&lt;/a&gt; directly from within Microsoft Access, without relying on cloud services.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_OjFm-zM22zNdn_Fc3eWNejT8Mmal5w7HVT4-mM0sJFGDcXmOrpTSHqDMTXAVASooRcyrhLVfdG25Lc6ZhRE1pS_EL8KX0xA5_7EhB7F7IIO2DaNLcvXmdttAV6_EvjjQd57JbCETTX4hbx39FQEzobLYmdU6wUzZJRHJ52k7nT5Vb85sx_NspSBPcC81/s1149/AI_Form.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;809&quot; data-original-width=&quot;1149&quot; height=&quot;225&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_OjFm-zM22zNdn_Fc3eWNejT8Mmal5w7HVT4-mM0sJFGDcXmOrpTSHqDMTXAVASooRcyrhLVfdG25Lc6ZhRE1pS_EL8KX0xA5_7EhB7F7IIO2DaNLcvXmdttAV6_EvjjQd57JbCETTX4hbx39FQEzobLYmdU6wUzZJRHJ52k7nT5Vb85sx_NspSBPcC81/s320/AI_Form.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in a New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;This first step is intentionally simple: install &lt;b&gt;Ollama&lt;/b&gt;, download a compact model such as &lt;b&gt;qwen2.5-coder:3b&lt;/b&gt;, and run a few test prompts. For example, you can ask the model to generate an SQL query to retrieve top customers or to write a basic VBA function to open a recordset. Within seconds, the AI responds with &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_blank&quot;&gt;structured output&lt;/a&gt; that you can study, refine, and adapt into your own applications. This hands-on approach helps demystify AI and demonstrates its immediate practical value.&lt;/p&gt;

&lt;p&gt;From a hardware perspective, one of the key advantages of smaller models like Qwen2.5-Coder (3B) is that they are optimized for modest systems. A modern dual-core or quad-core processor (Intel i5/Ryzen 5 or equivalent) with at least 8 GB RAM can run such models comfortably for basic tasks, although 16 GB RAM is recommended for smoother performance and multitasking. Since the model runs locally, you also benefit from improved data privacy and independence from internet connectivity.&lt;/p&gt;

&lt;p&gt;At this stage, the objective is not to build a full integration, but to gain familiarity and confidence. By interacting with the model through simple prompts in the Command Prompt, developers begin to understand how AI interprets instructions, generates SQL syntax, and structures &lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-ten.html&quot; target=&quot;_blank&quot;&gt;VBA procedures&lt;/a&gt;. This foundational experience is essential before moving on to deeper integration within Access using VBA and API calls.&lt;/p&gt;

&lt;p&gt;In the sections that follow, we will walk through the installation steps, demonstrate sample &lt;i&gt;prompts&lt;/i&gt;, and explore how even a basic setup can assist in writing queries and VBA code. Once you see how quickly AI can respond to your development needs, you may begin to view it not as a replacement but as a reliable assistant in your everyday Access workflow.&lt;/p&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;AI Environment for Microsoft Access Developers.&lt;/h3&gt;
&lt;p&gt;Setting up a local AI environment for Microsoft Access development is a powerful idea—especially for automating SQL generation, VBA code assistance, and database analysis without relying on cloud services.&lt;/p&gt;

&lt;p&gt;Here’s a clear, practical step-by-step guide tailored to the development workflow.&lt;/p&gt;

&lt;h4 id=&quot;Ollama&quot;&gt;1. Choose a Local AI Engine&lt;/h4&gt;

&lt;p&gt;We need a locally running LLM (Large Language Model).&lt;/p&gt;

&lt;p&gt;Recommended options:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;p&gt;Ollama (Best for simplicity)&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;LM Studio (GUI-based)&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;GPT4All&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Best choice for developers: &lt;b&gt;Ollama &lt;/b&gt;(lightweight + API support)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;2. Install Ollama (Core Engine)&lt;/b&gt;&lt;/p&gt;

&lt;h4&gt;Steps:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;p&gt;Download &lt;b&gt;OllamaSetup.exe&lt;/b&gt; for Windows from: &lt;a href=&quot;https://ollama.com&quot;&gt;https://ollama.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Install &lt;b&gt;OllamaSetup.exe&lt;/b&gt;&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Verify installation:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open Windows Command Prompt and Type:&lt;/p&gt;
&lt;pre&gt;&lt;p&gt;Download and Install the Large Language Model: &lt;b&gt;Mistral&lt;/b&gt;, like ChatGPT. The &#39;pull&#39; command downloads the model from source.&lt;/p&gt;&lt;p&gt;
&lt;i&gt;C:\Users\HP&amp;gt;&lt;/i&gt;ollama pull mistral  
&lt;i&gt;C:\Users\HP&amp;gt;&lt;/i&gt;ollama run mistral

&lt;/p&gt;&lt;p id=&quot;Qwen&quot;&gt;Download and Install the SQL and Code-generating AI model: &lt;b&gt;qwen2.5-coder:3b&lt;/b&gt; with 3 billion parameters. The model is downloaded and installed with the following command.&amp;nbsp;&lt;/p&gt;
&lt;i&gt;C:\Users\HP&amp;gt;&lt;/i&gt;ollama pull qwen2.5-coder:3b
&lt;i&gt;C:\Users\HP&amp;gt;&lt;/i&gt;ollama run qwen2.5-coder:3b
&lt;br /&gt;&#39;Display the Installed Model&#39;s information.&lt;br /&gt;
&lt;i&gt;C:\Users\HP&amp;gt;&lt;/i&gt;ollama --version
ollama version is 0.20.7

&lt;i&gt;C:\Users\HP&amp;gt;&lt;/i&gt;ollama list
NAME                ID              SIZE      MODIFIED
qwen2.5-coder:3b    f72c60cabf62    1.9 GB    7 weeks ago - if installed
mistral:latest      6577803aa9a0    4.4 GB    7 weeks ago - if installed

C:\Users\HP&amp;gt;
&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;The VBA code-generating AI is installed on your machine. You need an Intel i5 or i7 Machine for better performance.&lt;/p&gt; 

&lt;p&gt;&lt;b&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; The Coder AI &#39;prompt&#39; input line appears. Let us try it out in the Command Prompt.&lt;/p&gt; 

&lt;p&gt;Type &lt;b&gt;/?&lt;/b&gt; or &lt;b&gt;/help&lt;/b&gt; for help&lt;/p&gt;


&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; /?  

Available Commands:

  /set            Set session variables

  /show           Show model information

  /load &lt;model&gt;   Load a session or model

  /save &lt;model&gt;   Save your current session

  /clear          Clear session context

  /bye            Exit

  /?, /help       Help for a command

  /? shortcuts    Help for keyboard shortcuts

&lt;b&gt;Use &quot;&quot;&quot; to begin a multi-line message.
&lt;/b&gt;

&amp;gt;&amp;gt;&amp;gt; /show

Available Commands:

  /show info         Show details for this model

  /show license      Show model license

  /show modelfile    Show Modelfile for this model

  /show parameters   Show parameters for this model

  /show system       Show system message

  /show template     Show prompt template


&amp;gt;&amp;gt;&amp;gt; /show info

  Model

    architecture        qwen2

    parameters          3.1B

    context length      32768

    embedding length    2048

    quantization        Q4_K_M



  Capabilities

    completion

    tools

    insert

  System

    You are Qwen, created by Alibaba Cloud. You are a helpful assistant.



  License

    Qwen RESEARCH LICENSE AGREEMENT

    Qwen RESEARCH LICENSE AGREEMENT Release Date: September 19, 2024

    ...



&amp;gt;&amp;gt;&amp;gt; &lt;b&gt;Hello?&lt;/b&gt;

Hello! How can I assist you today?

&#39;SQL SELECT Query creation AI PROMPT:

&amp;gt;&amp;gt;&amp;gt; &lt;b&gt;&quot;&quot;&quot;Create SELECT SQL

... Table: Employees

... Fields: FirstName, LastName, City, Jobtitle

... Filter: Jobtitle = &quot;Sales Representative&quot;

... Sort: LastName&quot;&quot;&quot;&lt;/b&gt;

Certainly! Here is the SQL query that selects employees with the job title &quot;Sales Representative&quot;, 
filters them by city, and sorts the results by last name:


```sql

SELECT FirstName, LastName, City, Jobtitle

FROM Employees

WHERE Jobtitle = &#39;Sales Representative&#39;

ORDER BY LastName;

```

&lt;p&gt;This query will return a list of sales representatives from all cities, sorted alphabetically by their last names.&lt;/p&gt;

&lt;/model&gt;&lt;/model&gt;&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;AI Prompt&lt;/b&gt; for creating a VBA Function to calculate the Volume of a tree log.&lt;/p&gt;
&lt;p&gt;Type the following Prompt on the command line exactly as shown below. Start typing three quote characters next to each other, then the &lt;b&gt;Prompt&lt;/b&gt; text in multiple lines, by pressing the Enter Key on each line, and type 3 quotes at the end of the AI Prompt finish line, indicating the end of the Prompt, and press Enter Key to execute.&lt;/p&gt;

&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; &lt;b&gt;&quot;&quot;&quot;Create an MS Access VBA Function to calculate the Volume of a Tree Log
... Input Parameter values: Circumference value in Inches
... Log Length value: in Feet&quot;&quot;&quot;&lt;/b&gt;

&lt;p&gt;To create an MS Access VBA function that calculates the volume of a tree log using the provided parameters, you need to consider that the volume is calculated by assuming the cross-sectional area of the log is a circle. Here&#39;s a simple function that does this:
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1. Open Microsoft Access.&lt;/p&gt;&lt;p&gt;2. Press `Alt + F11` to open the VBA editor.&lt;/p&gt;&lt;p&gt;3. In the Project Explorer, right-click on &quot;Microsoft Access Objects&quot; and select &quot;Add &amp;gt; Module&quot;.&lt;/p&gt;&lt;p&gt;4. Copy and paste the following code into the module:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;```vba&lt;/p&gt;&lt;p&gt;Function CalculateVolumeOfLog(circumference As Double, logLength As Double) As Double&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &#39; Define the value of pi&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; Dim pi As Double&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; pi = 3.141592653589793&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &#39; Calculate the radius from the circumference&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; Dim radius As Double&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; radius = circumference / (2 * pi)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &#39; Convert log length from feet to inches&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; Dim logLengthInInches As Double&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; logLengthInInches = logLength * 12&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &#39; Calculate the volume of the log&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; Dim volume As Double&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; volume = pi * (radius ^ 2) * logLengthInInches&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &#39; Return the calculated volume&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; CalculateVolumeOfLog = volume&lt;/p&gt;&lt;p&gt;End Function&lt;/p&gt;&lt;p&gt;```&lt;/p&gt;&lt;p&gt;### Explanation:&lt;/p&gt;&lt;p&gt;- **Step 1**: The `pi` variable is set to its approximate value.&lt;/p&gt;&lt;p&gt;- **Step 2**: The radius \( r \) is calculated using the circumference in inches.&lt;/p&gt;&lt;p&gt;- **Step 3**: The log length in feet is converted to inches by multiplying it by 12.&lt;/p&gt;&lt;p&gt;- **Step 4**: The volume is calculated using the formula for the volume of a cylinder, where the radius is in inches, and the log length is in inches.&lt;/p&gt;&lt;p&gt;&amp;gt;&amp;gt;&amp;gt; &lt;b&gt;/Exit&lt;/b&gt;&lt;/p&gt;

&lt;/pre&gt;

&lt;p&gt;C:\Users\HP&amp;gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;b&gt;NB: &lt;/b&gt;&lt;i&gt;Click and drag over the required lines of content in the Command Prompt area and press Ctrl+C to copy. Paste it into a Text File or into the Global Module of&amp;nbsp; Access. Copy and paste the SQL into the Query SQL Editing Window. That is for now. We will use better methods when run from within MS Access.&lt;/i&gt;&lt;/p&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;The Machine hardware, Memory recommendation, and suitable Models.&lt;/h3&gt;


&lt;p&gt;Running Qwen2.5-Coder:3B locally on a Windows 10/11 PC (via Ollama) is quite feasible—even without a GPU—but the experience depends heavily on your hardware.&lt;/p&gt;

&lt;p&gt;Let’s make it practical and tailored for smooth day-to-day use.&lt;/p&gt;

&lt;p&gt;Minimum vs Recommended Hardware&lt;/p&gt;

&lt;p&gt;Minimum (Will run, but slower)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;p&gt;CPU: Dual-core (Intel i3 / Ryzen 3)&lt;/p&gt;&lt;/li&gt;

  &lt;li&gt;&lt;p&gt;RAM: 8 GB  &lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Storage: ~6–8 GB free (model + cache)&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;GPU: Not required&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Expect:&lt;/p&gt;
&lt;ul&gt;

  &lt;li&gt;&lt;p&gt;Slower responses (3–10 seconds per reply)&lt;/p&gt;&lt;/li&gt;

  &lt;li&gt;&lt;p&gt;Occasional lag with longer prompts&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recommended (Smooth experience)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;p&gt;CPU: 4–8 cores (Intel i5 / Ryzen 5 or better)&lt;/p&gt;&lt;/li&gt;

  &lt;li&gt;&lt;p&gt;RAM: 16 GB&lt;/p&gt;&lt;/li&gt;

  &lt;li&gt;&lt;p&gt;Storage: SSD with 10+ GB free&lt;/p&gt;&lt;/li&gt;

  &lt;li&gt;&lt;p&gt;GPU: Optional (integrated GPU is fine)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Expect:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fast responses (1–3 seconds typical)&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Comfortable coding + debugging workflow&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Optimal (Best performance)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CPU: 8+ cores (Intel i7 / Ryzen 7)&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;RAM: 32 GB&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Storage: NVMe SSD&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;GPU (optional but powerful):&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;NVIDIA with 6–8 GB VRAM (e.g., RTX 3060)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Expect:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Near-instant responses&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Handles long prompts + large codebases easily&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Model Size &amp;amp; Memory Usage&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Qwen2.5-Coder:3B (quantized via Ollama):&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Disk size: ~2–4 GB&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;RAM usage during run: ~4–6 GB&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So your system must have extra RAM beyond this for smooth multitasking.&lt;/p&gt;


&lt;p&gt;Key Performance Factors&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;p&gt;RAM (Most Important)&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&lt;p&gt;Less RAM → swapping → slow performance&lt;/p&gt;&lt;/li&gt;

 &lt;li&gt;&lt;p&gt;16 GB is the sweet spot&lt;/p&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;

  &lt;li&gt;&lt;p&gt;SSD vs HDD&lt;/p&gt;
    &lt;ul&gt;

&lt;li&gt;&lt;p&gt;SSD = fast model loading &lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;HDD = noticeable delay &lt;/p&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;
  
  &lt;p&gt;Strong recommendation: Use SSD&lt;/p&gt;


  &lt;li&gt;&lt;p&gt;CPU Threads&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;More cores = faster token generation &lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;LLMs are CPU - parallel friendly &lt;/p&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;

  &lt;li&gt;&lt;p&gt; GPU (Optional Boost)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ollama can use a GPU, if available &lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Not required for 3B models &lt;/p&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Realistic Performance (What You’ll Feel)&lt;/p&gt;


&lt;p&gt;&lt;b&gt;Hardware	        Experience&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;8GB RAM + HDD		Slow, sometimes frustrating&lt;/p&gt;

&lt;p&gt;8GB RAM + SSD		Usable, but limited&lt;/p&gt;

&lt;p&gt;16GB RAM + SSD		- Smooth &amp;amp; practical&lt;/p&gt;

&lt;p&gt;32GB + GPU			-  Excellent&lt;/p&gt;

&lt;br /&gt;
&lt;p&gt;For MS Access + Coding Use Case&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Generate SQL queries&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Work with VBA&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Write structured logic in Class Modules.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’ll benefit from:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;16 GB RAM (minimum target)&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;SSD (mandatory)&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Mid-range CPU (i5/Ryzen 5+)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Final Recommendation&lt;/p&gt;

&lt;p&gt;If you’re planning a stable setup:&lt;/p&gt;

&lt;p&gt;Best value configuration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;16 GB RAM&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;SSD&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Intel i5 / Ryzen 5&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will run Qwen2.5-Coder:3b smoothly without frustration&lt;/p&gt;


&lt;p&gt;&lt;b&gt;NB:&lt;/b&gt; If the 3b model hangs the Access System in the middle of a Code generating run, due to hardware limitations, be patient, it completes the work in the background and comes out. Consider installing the 1b Model: &lt;b&gt;qwen2.5-coder:1b&lt;/b&gt; (the lightweight 1 billion parameters Model).&lt;/p&gt;

&lt;p&gt;Will Continue &amp;gt;&amp;gt;&amp;gt; Next Week.&lt;/p&gt;
&lt;br /&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/7499383041024391964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2026/04/ai-integration-in-microsoft-access-for.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/7499383041024391964'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/7499383041024391964'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2026/04/ai-integration-in-microsoft-access-for.html' title='How to Integrate AI into Microsoft Access VBA Using Ollama (Part 1)'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_OjFm-zM22zNdn_Fc3eWNejT8Mmal5w7HVT4-mM0sJFGDcXmOrpTSHqDMTXAVASooRcyrhLVfdG25Lc6ZhRE1pS_EL8KX0xA5_7EhB7F7IIO2DaNLcvXmdttAV6_EvjjQd57JbCETTX4hbx39FQEzobLYmdU6wUzZJRHJ52k7nT5Vb85sx_NspSBPcC81/s72-c/AI_Form.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-4266494301482184244</id><published>2026-03-02T21:42:00.003+05:30</published><updated>2026-03-20T17:10:49.035+05:30</updated><title type='text'>Group-Wise Ranking Using Class Module</title><content type='html'>&lt;h3&gt;Group-Wise Ranking in Microsoft Access Using a Class Module&lt;/h3&gt;

&lt;h4&gt;A Reusable Object-Oriented Approach.&lt;/h4&gt;

&lt;p&gt;In earlier articles, we explored how to prepare a Rank List in Microsoft Access using procedural VBA. While that method works reliably, modern Access application design benefits greatly from encapsulating business logic inside Class Modules.&lt;/p&gt;

&lt;p&gt;Unlike database engines such as Microsoft SQL Server, which provide built-in ranking functions like RANK() and ROW_NUMBER(), Microsoft Access does not natively support group-wise ranking in SQL.&lt;/p&gt;

&lt;p&gt;This article demonstrates how to implement ranking logic using a dedicated class module, making the solution:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;p&gt;Reusable&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Maintainable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensible&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compatible with local and linked tables&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Why Use a Class Module?&lt;/h4&gt;
&lt;p&gt;Moving ranking logic into a class provides:&lt;/p&gt;

&lt;p&gt;✔ Encapsulation of ranking behavior.&lt;/p&gt;
&lt;p&gt;✔ Reusability across forms, reports, and automation tasks.&lt;/p&gt;
&lt;p&gt;✔ Cleaner separation of concerns.&lt;/p&gt;
&lt;p&gt;✔ Easier debugging and future enhancement.&lt;/p&gt;

&lt;p&gt;This design is especially useful in structured Access applications that follow modular architecture principles.&lt;/p&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;Design Overview&lt;/h3&gt;

&lt;p&gt;The class will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Accept a source table or query.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accept grouping and sorting fields.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accept ranking style (Dense / Competition / Sequential).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execute ranking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update a designated Rank field.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Create the Class Module.&lt;/p&gt;
&lt;p&gt;Create a new Class Module and name it:&lt;/p&gt;

&lt;h4&gt;clsRankList&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Insert the Following Code.&lt;/p&gt;&lt;pre&gt;Option Compare Database

Option Explicit


Private mSource As String

Private mGroupField As String

Private mValueField As String

Private mRankField As String

Private mRankingType As String


Public Property Let SourceTable(ByVal vValue As String)

    mSource = vValue

End Property


Public Property Let GroupField(ByVal vValue As String)

    mGroupField = vValue

End Property


Public Property Let ValueField(ByVal vValue As String)

    mValueField = vValue

End Property


Public Property Let RankField(ByVal vValue As String)

    mRankField = vValue

End Property


Public Property Let RankingType(ByVal vValue As String)

    mRankingType = UCase(vValue)

End Property


Public Sub ExecuteRanking()

    Dim db As DAO.Database

    Dim rs As DAO.Recordset

    Dim strSQL As String


    Dim CurrentGroup As Variant

    Dim PreviousValue As Variant

    Dim RankNo As Long

    Dim SkipCount As Long


    If mRankingType = &quot;&quot; Then mRankingType = &quot;DENSE&quot;

    Set db = CurrentDb


    strSQL = &quot;SELECT * FROM [&quot; &amp;amp; mSource &amp;amp; &quot;] &quot; &amp;amp; _

             &quot;ORDER BY [&quot; &amp;amp; mGroupField &amp;amp; &quot;], [&quot; &amp;amp; mValueField &amp;amp; &quot;] DESC;&quot;


    Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)

    If rs.EOF Then Exit Sub

    rs.MoveFirst

    CurrentGroup = Null

    PreviousValue = Null

    RankNo = 0

    SkipCount = 0

    Do While Not rs.EOF        

        If Nz(rs(mGroupField)) &amp;lt;&amp;gt; Nz(CurrentGroup) Then        

            CurrentGroup = rs(mGroupField)

            RankNo = 1

            SkipCount = 1

            PreviousValue = rs(mValueField)           

        Else            

            Select Case mRankingType

                Case &quot;DENSE&quot;

                    If rs(mValueField) &amp;lt;&amp;gt; PreviousValue Then

                        RankNo = RankNo + 1

                    End If            

                Case &quot;COMPETITION&quot;

                    If rs(mValueField) &amp;lt;&amp;gt; PreviousValue Then

                        RankNo = SkipCount

                    End If               

                Case &quot;SEQUENTIAL&quot;

                    RankNo = RankNo + 1                 

            End Select            

            SkipCount = SkipCount + 1

            PreviousValue = rs(mValueField)

        End If        

        rs.Edit

        rs(mRankField) = RankNo

        rs.Update       

        rs.MoveNext        

    Loop

    rs.Close

    Set rs = Nothing
    Set db = Nothing   

End Sub

&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Using the Class&lt;/p&gt;

&lt;p&gt;From a standard module, form, or automation routine:&lt;/p&gt;

&lt;pre&gt;Dim objRank As New clsRankList

With objRank

    .SourceTable = &quot;tblStudentMarks&quot;

    .GroupField = &quot;Class&quot;

    .ValueField = &quot;TotalMarks&quot;

    .RankField = &quot;Rank&quot;

    .RankingType = &quot;COMPETITION&quot;

    .ExecuteRanking

End With

Set objRank = Nothing

&lt;/pre&gt;

&lt;p&gt;Supported Ranking Types&lt;/p&gt;



&lt;p&gt;RankingType	Behavior&lt;/p&gt;

&lt;p&gt;DENSE	1, 2, 2, 3&lt;/p&gt;

&lt;p&gt;COMPETITION	1, 2, 2, 4&lt;/p&gt;

&lt;p&gt;SEQUENTIAL	1, 2, 3, 4&lt;/p&gt;

&lt;p&gt;If no ranking type is specified, DENSE is used by default.&lt;/p&gt;

&lt;p&gt;Advantages of This Approach.&lt;/p&gt;


&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clean Object-Oriented Design&lt;/p&gt;
&lt;p&gt;Encapsulates ranking behavior into a single reusable object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compatible with Linked Tables&lt;/p&gt;
&lt;p&gt;Uses dbOpenDynaset, so it works with ODBC sources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensible&lt;/p&gt;
&lt;p&gt;Future enhancements may include:&lt;/p&gt;
	&lt;ul&gt;
	&lt;li&gt;&lt;p&gt;Multiple group levels&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;Dynamic ORDER BY clauses&lt;/p&gt;

	&lt;p&gt;Returning ranked recordsets instead of updating tables&lt;/p&gt;

	&lt;p&gt;Error handling classes&lt;/p&gt;&lt;/li&gt;
	&lt;/ul&gt;


&lt;/li&gt;&lt;li&gt;&lt;p&gt;Integration-Friendly&lt;/p&gt;



&lt;p&gt;Works well with form wrappers and structured automation routines.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Performance Notes&lt;/p&gt;
&lt;ul&gt;

&lt;li&gt;&lt;p&gt;Efficient for moderate datasets.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Ensure indexes exist on GroupField and ValueField.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For very large datasets, consider server-side ranking.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;Encapsulating ranking logic inside a class module elevates the solution from a procedural workaround to a structured, reusable component.&lt;/p&gt;


&lt;ul&gt;
&lt;p&gt;For developers who build modular Microsoft Access applications, this approach promotes:&lt;/p&gt;

&lt;li&gt;&lt;p&gt;Clean architecture&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Reusability&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Maintainability&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Professional-grade design&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;
&lt;center&gt;--oOo--&lt;/center&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2010/01/auto-numbering-in-query-column.html&quot; target=&quot;_Blank&quot;&gt;Auto-numbering in Query Column&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2011/05/product-group-sequence-with-auto-numbers.html&quot; target=&quot;_Blank&quot;&gt;Product Group Sequence with Auto-Numbers.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2012/01/autonumber-with-date-and-sequence-number.html&quot; target=&quot;_Blank&quot;&gt;Auto-Number with Date and Sequence Numbers-1.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2012/11/autonumber-with-date-and-sequence.html&quot; target=&quot;_Blank&quot;&gt;Auto-Number with Date and Sequence Numbers-2.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2020/01/auto-numbers-in-query-column-version-2.html&quot; target=&quot;_Blank&quot;&gt;Auto-Number in Query Column Version-2.&lt;/a&gt;&lt;/li&gt;
  
&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/4266494301482184244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2026/03/group-wise-ranking-using-class-module.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/4266494301482184244'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/4266494301482184244'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2026/03/group-wise-ranking-using-class-module.html' title='Group-Wise Ranking Using Class Module'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-124761418939312132</id><published>2024-06-29T12:10:00.015+05:30</published><updated>2026-07-14T19:04:33.222+05:30</updated><title type='text'>Wrapper Class Template Wizard V2</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Class Module Template Creation Wizard V2.&lt;/h3&gt;&lt;p&gt;The earlier version of the &lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_blank&quot;&gt;Class Module Wizard&lt;/a&gt; was a testing platform for creating Wrapper Class Module templates. Although it served its purpose, the procedure adopted there is somewhat semi-automatic, and I am not satisfied with that either.&amp;nbsp;&lt;/p&gt;&lt;p&gt;This improved Version 2.0 of the Wizard can create several Class Module Templates for different Object Types in your form. This Version creates approximately 10 frequently used Object Wrapper Class Module Templates based on your selection at a time.&lt;/p&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;The Screenshot of the Class Template &lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html &quot; target=&quot;_blank&quot;&gt;Wizard&lt;/a&gt; is given below:&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSLInT_mMHalg0-M_bkiLx7cxAnipNNY0iETfr11eWwDYPuoB2HCIJSrciN3VkGEqOwmFA3Utv4nMrCWbZJcyz1bCuRDDW7MKK5R61D7GTBOeW-vXwc6E9_UrxmgOOD_PpBrIGRXCHZXUpNIg1Ewt6Emqp6Te6zn1zn89KYS59XAHfEv6ekMrup9qY0aic/s748/ClassModuleWizardV2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;636&quot; data-original-width=&quot;748&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSLInT_mMHalg0-M_bkiLx7cxAnipNNY0iETfr11eWwDYPuoB2HCIJSrciN3VkGEqOwmFA3Utv4nMrCWbZJcyz1bCuRDDW7MKK5R61D7GTBOeW-vXwc6E9_UrxmgOOD_PpBrIGRXCHZXUpNIg1Ewt6Emqp6Te6zn1zn89KYS59XAHfEv6ekMrup9qY0aic/s320/ClassModuleWizardV2.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;The ListBox&#39;s Source Data is from the &#39;ListItems&#39; Table. The Source Table Image is given below.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCaeTbzqpk-ecxfRyB-tzoyQsyJnfOY8oMq15w9E1QpsxRfIgVwEwYiAefpxH2zc4xWjqLKScxS_qpryT7LlNHOgHyWPiZvYajSLsSGtaROwr2JRtAAJs07ApORxnMTKBMXXj2R9UjzTsdA3kk8mHdlLF05T5dUuBASeicOX1vsumL3vfXrSN9vSpf7EvC/s1040/ClassWizardTable.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Class Wizard Table&quot; border=&quot;0&quot; data-original-height=&quot;528&quot; data-original-width=&quot;1040&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCaeTbzqpk-ecxfRyB-tzoyQsyJnfOY8oMq15w9E1QpsxRfIgVwEwYiAefpxH2zc4xWjqLKScxS_qpryT7LlNHOgHyWPiZvYajSLsSGtaROwr2JRtAAJs07ApORxnMTKBMXXj2R9UjzTsdA3kk8mHdlLF05T5dUuBASeicOX1vsumL3vfXrSN9vSpf7EvC/s320/ClassWizardTable.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;The Table has ten Records with six columns of data, but only the first three columns are shown on the ListBox. &lt;br /&gt;&lt;br /&gt;(1) The RecordID - &lt;i&gt;for easier retrieval of Wizard Function Parameters.&lt;/i&gt;&lt;br /&gt;(2) The Field/Control list File Name for creating on Disk - &lt;i&gt;The files will be created in the Current Project Folder&lt;/i&gt;.&lt;br /&gt;(3) The Class Module Template Name - &lt;i&gt;&amp;nbsp;suffixed with the word &#39;_Template&#39; is preferred, not mandatory.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;The following three Columns of data are used by the Wizard.&lt;/p&gt;&lt;p&gt;(4) The Wizard Function that creates the Class Template - &lt;i&gt;Applicable for all Types of Objects&lt;/i&gt;.&lt;br /&gt;(5) The Object TypeName - &lt;i&gt;self-explanatory.&lt;/i&gt;&lt;br /&gt;(6) Object Short Name - &lt;i&gt;you may change it to a more descriptive Name if required&lt;/i&gt;.&lt;br /&gt;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;How to Run the WrapperClassWizard from within a Database?&lt;/h3&gt;&lt;p&gt;Place the WrapperClass_Wizard.accdb database into a Trusted Folder.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Open your Database and open the VBE Window.&lt;/p&gt;&lt;p&gt;Select References... from the Tools menu, browse the disk, and find the Wizard Database.&amp;nbsp; Attach the Wizard Database to the Library List.&amp;nbsp; Put a check mark to add the Wizard Database to the selected List of Library Files.&lt;/p&gt;&lt;p&gt;Create a SELECT Query in your Project with the name ListItemsQ using the following SQL:&lt;/p&gt;
&lt;pre&gt;SELECT ListItems.*
FROM ListItems IN &#39;D:\DEMO\Code2\WrapperClass_Wizard.accdb&#39;;
&lt;/pre&gt;
&lt;p&gt;Change the WrapperClass_Wizard. accdb Database Path to the correct location.&lt;/p&gt;&lt;p&gt;You can create class module templates with the main object declarations (e.g., TextBox and Form, or any other &lt;a href=&quot;https://www.msaccesstips.com/2020/09/microsoft-treeview-control-tutorial.html&quot; target=&quot;_blank&quot;&gt;Control&lt;/a&gt; and Form) with their property procedures for up to 10 of the most frequently used controls on the form.&lt;/p&gt;&lt;p&gt;Additionally, you can add a sample OnGotFocus Event Subroutine Code for all the Data Field Names (TextBox and ComboBox Names) collected from the Form. To achieve this, insert a few lines of code (shown in red) in the Class_Init() Subroutine to collect each &lt;a href=&quot;https://www.msaccesstips.com/2021/11/activex-listview-control-tutorial-01.html&quot; target=&quot;_blank&quot;&gt;Control Type&lt;/a&gt;&amp;nbsp;from the Form and save them as separate text files on disk when the Form is in open state.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;If you plan to implement this Data Field Name saving procedure for two or more forms, the contents of this text file&amp;nbsp;on &lt;a href=&quot;https://www.msaccesstips.com/2022/05/get-disk-free-space-windows-api.html&quot; target=&quot;_blank&quot;&gt;Disk&lt;/a&gt; will be overwritten with the last open Form&#39;s Field Names.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The TextBox or ComboBox sample Event Subroutine can be created for a particular Form. First open the Form with its Class_Init() Subroutine Code Lines in red for a few seconds, and then close it before running the Class Template creation Wizard.&lt;/p&gt;&lt;p&gt;I recommend this procedure to collect the Data field names on the Form using Code, because all are inserted from the data source Table/Query.&amp;nbsp; Memorizing all their names correctly for event subroutine coding is impractical.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The code lines (marked in Red) are inserted into the Class_Init() subroutine to write out the Category-wise Field Names into their respective Files on Disk. All TextBox Field Names in one Text File, ComboBox Field Names in another, and so on. Below that is the Class_Init() Subroutine in the Class_ObjInit Class Module of the Employees Form, implemented with this procedure.&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private txt As Data_TxtBox
Private Cbo As Data_CboBox
Private cmd As Data_CmdButton

Private Coll As New Collection
Private Frm As Form

&#39;--------------------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;With Reusable Code
&#39;--------------------------------------------------------------------
&#39;The &#39;WrapperClassWizard.accdb&#39; attached to this Database
&#39;Check: Tools--&amp;gt; References...
&#39;--------------------------------------------------------------------
&#39;1. The &#39;Class_ObjInit&#39; Class saves TxtBox/Field Names, Command Button,
&#39;ComboBox Names, and others from the Open Form into TextBoxFields.txt,
&#39;CmdButtonList.txt &amp;amp; ComboBoxList.txt files in the same Database Folder.
&#39;
&#39;2. The &#39;WrapperClassWizard.accdb&#39; must be attached to the
&#39;Current Project to open up the Wizard Form by running
&#39;the Function: OpenClassWizard() from within a Command button Click.
&#39;
&#39;3. The Wizard Reads the Field Names from tbe above Text Files.
&#39;
&#39;4. The Wizard will use the Field/Control Names(if any) for the sample
&#39;Event Subroutine in the Template. If the file is empty then it will
&#39;create a sample Evet Subroutine without the Control names.
&#39;
&#39;5. This saves Coding time otherwise spent on creating a
&#39;New Wrapper Class Module from scratch and picking the
&#39;Field Names and other Control Names correctly
&#39;From the Form for Event Subroutines.
&#39;--------------------------------------------------------------------
&#39;Author:  a.p.r. pillai
&#39;Date  :  20/06/2024
&#39;Remarks: with Ready-made Data Entry Events Handler
&#39;       : in the Wrapper TextBox Class Module
&#39;       : Suitable for Columnar, Tabular or DataSheet Form
&#39;Rights:  All Rights(c) Reserved by www.msaccesstips.com
&#39;--------------------------------------------------------------------

Public Property Get o_Frm() As Form
    Set o_Frm = Frm
End Property

Public Property Set o_Frm(ByRef vFrm As Form)
    Set Frm = vFrm

    Class_Init
End Property

Private Sub Class_Init()
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;Dim ProjectPath As String&lt;/b&gt;&lt;/span&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;Dim txtPath As String&lt;/b&gt;&lt;/span&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;Dim ComboPath As String
Dim FieldListFile As String&lt;/b&gt;&lt;/span&gt;
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;Dim ComboBoxList As String&lt;/b&gt;&lt;/span&gt;
Dim ctl As Control

On Error GoTo ClassInit_Err

Const EP = &quot;[Event Procedure]&quot;

&#39;Save TextBox &amp;amp; CombBox Names into separate Text Files
&#39;for creating Event Subroutines in the Templates&lt;span style=&quot;color: red; font-weight: bold;&quot;&gt;
ProjectPath = CurrentProject.Path &amp;amp; &quot;\&quot;

FieldListFile = DLookup(&quot;FieldListFile&quot;, &quot;ListItemsQ&quot;, &quot;ID = &quot; &amp;amp; wizTextBox)
ComboBoxList = DLookup(&quot;FieldListFile&quot;, &quot;ListItemsQ&quot;, &quot;ID = &quot; &amp;amp; wizComboBox)

txtPath = ProjectPath &amp;amp; FieldListFile
ComboPath = ProjectPath &amp;amp; ComboBoxList

Open txtPath For Output As #1 &lt;/span&gt;&lt;span&gt;&#39;TextBoxFields.txt for writing&lt;/span&gt;&lt;span style=&quot;color: red; font-weight: bold;&quot;&gt;
Open ComboPath For Output As #2 &lt;/span&gt;&#39;ComboBoxList.txt&lt;span style=&quot;color: red; font-weight: bold;&quot;&gt;
&lt;/span&gt;
&#39;Instantiate the &#39;Data_txtBox&#39; Class for each TextBox
&#39;on the Form for streamlined Event Procedures Coding
For Each ctl In Frm.Controls
    Select Case TypeName(ctl)
        Case &quot;TextBox&quot;
    &lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;Print #1, ctl.Name&lt;/b&gt;&lt;/span&gt; &#39;write Field/TextBox Name in TextBoxFields.txt File
            Set txt = New Data_TxtBox
            Set txt.m_Frm = Frm
            Set txt.m_txt = ctl
            
&#39;//Colin Riddington Technique: Highlighting BackColor on GotFocus
                txt.m_txt.BackColor = 62207 &#39;yellow
                txt.m_txt.BackStyle = 0
    
                txt.m_txt.BeforeUpdate = EP
                txt.m_txt.OnDirty = EP
                
                Coll.Add txt &#39;Add Data_TxtBox Class Instance to Collection
                Set txt = Nothing &#39;Reset txt object
      
      Case &quot;CommandButton&quot;
           Set cmd = New Data_CmdButton
            Set cmd.Obj_Form = Frm
            Set cmd.cmd_Button = ctl
                
                cmd.cmd_Button.OnClick = EP
                
                Coll.Add cmd
                Set cmd = Nothing
                
      Case &quot;ComboBox&quot;
    &lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;Print #2, ctl.Name&lt;/b&gt;&lt;/span&gt; &#39;write ComboBox Names in ComboBoxList.txt File
            Set Cbo = New Data_CboBox
            Set Cbo.m_Frm = Frm
            Set Cbo.m_Cbo = ctl
    
&#39;//Colin Riddington Technique: Highlighting BackColor on GotFocus
                Cbo.m_Cbo.BackColor = 62207
                Cbo.m_Cbo.BackStyle = 0
                
                Cbo.m_Cbo.BeforeUpdate = EP
                Cbo.m_Cbo.OnDirty = EP
                
                Coll.Add Cbo
                Set Cbo = Nothing
                
        Case &quot;ListBox&quot;
            
    End Select
Next
&#39;Close all files
&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;Close #1
Close #2&lt;/b&gt;&lt;/span&gt;

ClassInit_Exit:
Exit Sub

ClassInit_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;Class_Init()&quot;
Resume ClassInit_Exit
End Sub

Private Sub Class_Terminate()
While Coll.Count &amp;gt; 0
    Coll.Remove 1
Wend
Set Coll = Nothing

End Sub
&lt;/pre&gt;
&lt;p&gt;The red lines are inserted in the required locations to collect the Data Field and ComboBox Names and record them in separate Text Files in the Project Folder as Input to the Class Module creation Wizard. Similarly, you can insert related Code lines for other Types of Controls on the Form.&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_blank&quot;&gt;Wizard&lt;/a&gt; will look for these files on the disk and check their contents. If control names are found, they will be used for building a sample Click Event Subroutine after the main object declarations and property procedure lines of code.&lt;/p&gt;&lt;p&gt;If the above lines are embedded in the Class_Init() subroutine, we should open the Employees Form for a few seconds and close it before running the wizard options. This will create the controls list in their respective text files, using the predefined file names taken from the wizard table ListItems, through the Select Query ListItemsQ.&lt;/p&gt;&lt;p&gt;The &lt;i&gt;TextBoxFields.txt&lt;/i&gt;&amp;nbsp;File contents created from the Employee Form Field Names are listed below for reference:&lt;/p&gt;
&lt;pre&gt;ID
Company
Last Name
First Name
E-mail Address
Job Title
Address
City
State/Province
ZIP/Postal Code
Country/Region&lt;/pre&gt;&lt;p&gt; &lt;/p&gt;&lt;h3&gt;The Sample Click Event Subroutine Structure Code.&lt;/h3&gt;&lt;div&gt;The sample Click Event Subroutine Code structure, created using the Field Names from the TextBoxFields.txt File, is given below.&lt;/div&gt;
&lt;pre&gt;Private Sub txtBox_Click()
   Select Case txtBox.Name
     Case &quot;ID&quot;
        &#39; Code
 
     Case &quot;Company&quot;
        &#39; Code
 
     Case &quot;Last Name&quot;
        &#39; Code
 
     Case &quot;First Name&quot;
        &#39; Code
 
     Case &quot;E-mail Address&quot;
        &#39; Code
 
     Case &quot;Job Title&quot;
        &#39; Code
 
     Case &quot;Address&quot;
        &#39; Code
 
     Case &quot;City&quot;
        &#39; Code
 
     Case &quot;State/Province&quot;
        &#39; Code
 
     Case &quot;ZIP/Postal Code&quot;
        &#39; Code
 
     Case &quot;Country/Region&quot;
        &#39; Code
 
 
   End Select
End Sub
&lt;/pre&gt;

&lt;p&gt;Remove the unwanted Control Names from the List if no Events are invoked from those controls.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Opening the ClassWizard Form.&lt;/h3&gt;&lt;p&gt; Open the ClassWizard Form by calling the Function OpenClassWizard()&amp;nbsp;from your Project through a &lt;a href=&quot;https://www.msaccesstips.com/2008/04/transparent-command-button.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; Click Event Subroutine, with the following sample VBA Code lines:&lt;/p&gt;
&lt;pre&gt;Private Sub Command25_Click()
	VBE.CodePanes.Item(1).show
	OpenClassWizard VBE.ActiveVBProject.Name
End Sub
&lt;/pre&gt;
&lt;p&gt;The OpenClassWizard() Function Code is given below.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; You should not create a Function with the same name: OpenClassWizard() in your Project, where the Wizard is attached as a Library database.&lt;/p&gt;
&lt;pre&gt;Dim ProjectName As String

&#39;Public Function to Open the Wizard Form
&#39;from the Host Application
Public Function OpenClassWizard(ByVal projName As String)
On Error GoTo OpenClassWizard_Err

ProjectName = projName
DoCmd.OpenForm &quot;ClassWizard&quot;, acNormal
    
OpenClassWizard_Exit:
Exit Function

OpenClassWizard_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;OpenClassWizard()&quot;
Resume OpenClassWizard_Exit
End Function
&lt;/pre&gt;

&lt;p&gt;When the Wizard Form is open in your Application Window, select one or more items from the List of Control Types, like TextBox, &lt;a href=&quot;https://www.msaccesstips.com/2006/09/command-button-animation.html&quot; target=&quot;_blank&quot;&gt;Command Buttons&lt;/a&gt;, or any other Class Module you need, and click the Run Wizard Command Button.&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The ClassWizard Form Module Code:&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private obj As New Wiz_ObjInit

Private Sub Form_load()
    Set obj.O_Form = Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set obj = Nothing
End Sub

&lt;/pre&gt;
&lt;h3&gt;The Wiz_ObjInit Intermediary Class Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private Lst As Wiz_ListBox
Private oFrm As Access.Form
Private cmd As Wiz_CmdButton
Private Coll As New Collection
&#39;----------------------------------------------------------
&#39;Streamlining Form Module Code in Stand-alone Class Modules
&#39;With Reusable Structured Event Subroutine Coding.
&#39;----------------------------------------------------------
&#39;Event Procedure Coding in Standalone Class Module is now
&#39;made easier with Readymade Object Wrapper Class Templates
&#39;Demo Event Subroutine is created with the Control Names.
&#39;----------------------------------------------------------
&#39;Program: Wrapper Class Template Wizard
&#39;Author:  a.p.r. pillai
&#39;Date  :  20/06/2024
&#39;Rights:  All Rights(c) Reserved by www.msaccesstips.com
&#39;----------------------------------------------------------

Public Property Get O_Form() As Form
   Set O_Form = oFrm
End Property
 
Public Property Set O_Form(ByRef objForm As Form)
   Set oFrm = objForm
   
   Class_Init
End Property

Private Sub Class_Init()
On Error GoTo Class_Init_Err
Dim ctl As Control
Const EP = &quot;[Event Procedure]&quot;
   
For Each ctl In oFrm.Controls
    Select Case TypeName(ctl)
        Case &quot;ListBox&quot;
            Set Lst = New Wiz_ListBox
            Set Lst.Obj_Form = oFrm
            Set Lst.Lst_Box = ctl
                Lst.Lst_Box.OnClick = EP
                
                Coll.Add Lst
            Set Lst = Nothing
            
        Case &quot;CommandButton&quot;
            Set cmd = New Wiz_CmdButton
            Set cmd.Obj_Form = oFrm
            Set cmd.Obj_cmdButton = ctl
                cmd.Obj_cmdButton.OnClick = EP
                
                Coll.Add cmd
            Set cmd = Nothing
            
    End Select
Next

Class_Init_Exit:
Exit Sub

Class_Init_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;Class_Init()&quot;
Resume Class_Init_Exit
End Sub

Private Sub Class_Terminate()
    While Coll.Count &amp;gt; 0
        Coll.Remove 1
    Wend
    Set Coll = Nothing
    Set Lst = Nothing
    
End Sub

&lt;/pre&gt;
&lt;p&gt;The Class_Init() Subroutine enables the Click Events of the ListBox and Command Button Controls.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;The ListBox Wrapper Class &#39;Wiz_ListBox&#39; Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit
 
Private WithEvents LstBox As Access.ListBox
Private Frm As Access.Form
&#39;----------------------------------------------------------
&#39;Streamlining Form Module Code in Stand-alone Class Modules
&#39;With Reusable Structured Event Subroutine Coding.
&#39;----------------------------------------------------------
&#39;Event Procedure Coding in Standalone Class Module is now
&#39;made easier with Readymade Object Wrapper Class Templates
&#39;Demo Event Subroutine is created with the Control Names.
&#39;----------------------------------------------------------
&#39;Program: Wrapper Class Template Wizard
&#39;Author:  a.p.r. pillai
&#39;Date  :  20/06/2024
&#39;Rights:  All Rights(c) Reserved by www.msaccesstips.com
&#39;----------------------------------------------------------

Public Property Get Obj_Form() As Form
   Set Obj_Form = Frm
End Property
 
Public Property Set Obj_Form(ByRef objForm As Form)
   Set Frm = objForm
End Property
 
Public Property Get Lst_Box() As Access.ListBox
   Set Lst_Box = LstBox
End Property
 
Public Property Set Lst_Box(ByRef objListB As Access.ListBox)
   Set LstBox = objListB
End Property

Private Sub LstBox_Click()
On Error GoTo LstBox_Click_Err
  Select Case LstBox.Name
    Case &quot;List1&quot;
        Dim lCount As Integer
        Dim tmpList As ListBox
        Dim j As Integer

        Set tmpList = Frm.List1
        lCount = tmpList.ListCount - 1

        For j = 0 To lCount
            If tmpList.Selected(j) Then
                Frm.cmdRun.Enabled = True
                Exit Sub
            Else
                Frm.cmdRun.Enabled = False
            End If
        Next

  End Select
  
LstBox_Click_Exit:
Exit Sub

LstBox_Click_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;LstBox_Click()&quot;
Resume LstBox_Click_Exit
End Sub

&lt;/pre&gt;

&lt;p&gt;The ListBox&#39;s Click Event checks whether any item is selected in the control. If found, then it enables the Command Button with the Caption &#39;Run Wizard&#39;; otherwise, the Command Button is disabled.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Command Button Wrapper Class &#39;Wiz_CmdButton&#39; Module Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit
 
Private WithEvents cmdButton As Access.CommandButton
Private Frm As Access.Form
&#39;----------------------------------------------------------
&#39;Streamlining Form Module Code in Stand-alone Class Modules
&#39;With Reusable Structured Event Subroutine Coding.
&#39;----------------------------------------------------------
&#39;Event Procedure Coding in Standalone Class Module is now
&#39;made easier with Readymade Object Wrapper Class Templates
&#39;Demo Event Subroutine is created with the Control Names.
&#39;----------------------------------------------------------
&#39;Program: Wrapper Class Template Wizard
&#39;Author:  a.p.r. pillai
&#39;Date  :  20/06/2024
&#39;Rights:  All Rights(c) Reserved by www.msaccesstips.com
&#39;----------------------------------------------------------

Public Property Get Obj_Form() As Access.Form
   Set Obj_Form = Frm
End Property
 
Public Property Set Obj_Form(ByRef objForm As Access.Form)
   Set Frm = objForm
End Property
 
Public Property Get Obj_cmdButton() As Access.CommandButton
   Set Obj_cmdButton = cmdButton
End Property
 
Public Property Set Obj_cmdButton(ByRef vcmdButton As Access.CommandButton)
   Set cmdButton = vcmdButton
End Property
 
Private Sub cmdButton_Click()
On Error GoTo cmdButtonClick_Err
   Select Case cmdButton.Name
     &lt;b&gt;Case &quot;cmdClose&quot;&lt;/b&gt;
        DoCmd.Close acForm, &quot;ClassWizard&quot;
        
        
     &lt;b&gt;Case &quot;cmdRun&quot;&lt;/b&gt;
        Dim modul As Module
        Dim flag As Boolean
        Dim vbcompo As vbcomponent
        Dim tmpList As ListBox
        Dim wiz As Integer
        Dim strWiz As String

        Dim FunctionName As String
        Dim FieldListFile As String
        Dim ClsTemplate As String
        Dim s_ObjTypeName As String
        Dim s_ObjName As String
        
        Dim msg As String
        Dim lCount As Integer
        Dim j As Integer, k As Integer
        Dim qot As String
        Dim objType As Long
        Dim Dt As Double
        Dim ClsSourceFile As String
        Dim ProjectName As String
        Dim Result As Boolean
        
        qot = Chr(34)
        Set tmpList = Frm.List1
        lCount = tmpList.ListCount - 1
        k = 0

        &#39;Validation Check
        msg = &quot;&quot;
        For j = 0 To lCount
          If tmpList.Selected(j) Then
                &#39;FieldList File
                FieldListFile = CurrentProject.Path &amp;amp; &quot;\&quot; &amp;amp; tmpList.Column(1, j)
        
                &#39;Chek for FieldList File on Disk
                    If Len(Dir(FieldListFile)) = 0 Then
                      Open FieldListFile For Output As #1
                        Print #1, Space(5)
                      Close #1
                    End If
        
                &#39;Class Template Name
                ClsTemplate = tmpList.Column(2, j)
                
                msg = &quot;&quot;
                FunctionName = tmpList.Column(3, j)
                If Len(Nz(FunctionName, &quot;&quot;)) = 0 Then
                    FunctionName = &quot;CreateClassTemplate&quot;
                End If
                
                s_ObjTypeName = tmpList.Column(4, j)
                If Len(Nz(s_ObjTypeName, &quot;&quot;)) = 0 Then &#39;Control Type Name column empty
                    msg = &quot;*** Object TypeName not specified!&quot;
                Else
                    objType = ControlTypeCheck(s_ObjTypeName) &#39;Is it a Valid Control TypeName
                    If objType = 9999 Then &#39;Name not in specified list
                        msg = &quot;*** object Typename: &quot; &amp;amp; UCase(s_ObjTypeName) &amp;amp; vbCr _
                        &amp;amp; &quot;Not in specified List?&quot;
                    End If
                End If
    
                s_ObjName = tmpList.Column(5, j)
                If Len(Nz(s_ObjName, &quot;&quot;)) = 0 Then &#39;Column is empty
                    msg = msg &amp;amp; vbCr &amp;amp; vbCr &amp;amp; &quot;User-Defined Object Name Column is Empty!&quot;
                End If
                If Len(msg) &amp;gt; 0 Then &#39;Errors Found
                    msg = msg &amp;amp; vbCr &amp;amp; vbCr &amp;amp; &quot;Errors Found in Item: &quot; &amp;amp; tmpList.Column(0, j) &amp;amp; _
                    vbCr &amp;amp; &quot;Rectify the Errors and Re-run!&quot;
                    MsgBox msg, vbCritical + vbOKCancel, &quot;cmdButton_Click()&quot;
                    Exit Sub
                Else &#39;No Errors then creaate Template
                &#39;Call the Wizard
Result = CreateClassTemplate(FieldListFile, ClsTemplate, s_ObjTypeName, s_ObjName)
                    If Not Result Then
                        MsgBox &quot;Errors Encountered for &#39;&quot; &amp;amp; ClsTemplate &amp;amp; &quot;&#39;&quot; &amp;amp; vbCr _
                        &amp;amp; &quot;Review/Modify the Parameter value(s) and Re-try.&quot;
                    End If
                End If
    End If

Next j
        MsgBox &quot;Class Module Templates Created successfully!&quot;

        &#39;Save created Template Class modules
        DoCmd.RunCommand acCmdCompileAndSaveAllModules

     &lt;b&gt;Case &quot;cmdHelp&quot;&lt;/b&gt;
        DoCmd.OpenForm &quot;Wiz_Help&quot;, acNormal
        
   End Select

cmdButtonClick_Exit:
Exit Sub

cmdButtonClick_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;cmdButtonClick()&quot;
Resume cmdButtonClick_Exit
End Sub

&lt;/pre&gt;
&lt;p&gt;It runs a series of checks on the Wizard parameters and validates them before calling the CreateClassTemplate() Function with its parameters.&lt;/p&gt;&lt;p&gt;The Wizard will retrieve the Parameters for the selected items from the ListItems Table and check for the Field List/Control Files of the selected options on the disk. If found, then it retrieves the list of controls, if any, for the sample Event Subroutine.&lt;/p&gt;&lt;p&gt;After validation of parameter values, it calls the Wizard Function CreateClassTemplate()&lt;b&gt;,&lt;/b&gt; which creates the Class Module Templates for the selected options, with predefined names in your Project&#39;s VBE Window&#39;s Navigation Pane.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;The &lt;i&gt;CreateClassTemplate()&lt;/i&gt; Wizard Function VBA Code is given below:&lt;/h3&gt;
&lt;pre&gt;Public Function CreateClassTemplate(ByVal FieldListFile As String, _
ByVal ClassTemplateName As String, ByVal strObjTypeName As String, _
ByVal strObjName As String) As Boolean

&#39;----------------------------------------------------------
&#39;Streamlining Form Module Code in Stand-alone Class Modules
&#39;With Reusable Structured Event Subroutine Coding.
&#39;----------------------------------------------------------
&#39;Event Procedure Coding in Standalone Class Module is now
&#39;made easier with Readymade Object Wrapper Class Templates
&#39;Demo Event Subroutine is created with the Control Names.
&#39;----------------------------------------------------------
&#39;Program: Wrapper Class Template Wizard
&#39;Author:  a.p.r. pillai
&#39;Date  :  20/06/2024
&#39;Rights:  All Rights(c) Reserved by www.msaccesstips.com
&#39;----------------------------------------------------------

On Error GoTo CreateClassTemplate_Err
Dim j As Long, k As Long, h As Long, CountLines As Long
Dim low As Long, high As Long
Dim FieldList() As String
Dim strItem As Variant
Dim strLines(1 To 33) As String
Dim msg As String
Dim idx As Integer
Dim spacex As String
Dim qot As String
Dim ClsPath As String
Dim vbcompo As vbcomponent

spacex = Chr(32)
qot = Chr(34)
idx = 1

strLines(idx) = &quot;VERSION 1.0 CLASS&quot;: GoSub NextIndex
strLines(idx) = &quot;BEGIN&quot;: GoSub NextIndex
strLines(idx) = &quot;  MultiUse = -1&quot;: GoSub NextIndex
strLines(idx) = &quot;End&quot;: GoSub NextIndex
strLines(idx) = &quot;Attribute VB_Name = &quot; &amp;amp; qot &amp;amp; ClassTemplateName &amp;amp; qot: GoSub NextIndex
strLines(idx) = &quot;Attribute VB_GlobalNameSpace = False&quot;: GoSub NextIndex
strLines(idx) = &quot;Attribute VB_Creatable = False&quot;: GoSub NextIndex
strLines(idx) = &quot;Attribute VB_PredeclaredId = False&quot;: GoSub NextIndex
strLines(idx) = &quot;Attribute VB_Exposed = False&quot;: GoSub NextIndex
strLines(idx) = &quot;Option Compare Database&quot;: GoSub NextIndex
strLines(idx) = &quot;Option Explicit&quot;: GoSub NextIndex
strLines(idx) = spacex: GoSub NextIndex
strLines(idx) = &quot;Private WithEvents &quot; &amp;amp; strObjName &amp;amp; &quot; as Access.&quot; &amp;amp; strObjTypeName: GoSub NextIndex
strLines(idx) = &quot;Private Frm as Access.Form&quot;: GoSub NextIndex
strLines(idx) = spacex: GoSub NextIndex
strLines(idx) = &quot;Public Property Get Obj_Form() as Access.Form&quot;: GoSub NextIndex
strLines(idx) = &quot;   Set Obj_Form = Frm&quot;: GoSub NextIndex
strLines(idx) = &quot;End Property&quot;: GoSub NextIndex
strLines(idx) = spacex: GoSub NextIndex
strLines(idx) = &quot;Public Property Set Obj_Form(ByRef objForm as Access.Form)&quot;: GoSub NextIndex
strLines(idx) = &quot;   Set Frm = objForm&quot;: GoSub NextIndex
strLines(idx) = &quot;End Property&quot;: GoSub NextIndex
strLines(idx) = spacex: GoSub NextIndex
strLines(idx) = &quot;Public Property Get Obj_&quot; &amp;amp; strObjName &amp;amp; &quot;() as Access.&quot; &amp;amp; strObjTypeName: GoSub NextIndex
strLines(idx) = &quot;   Set obj_&quot; &amp;amp; strObjName &amp;amp; &quot; = &quot; &amp;amp; strObjName: GoSub NextIndex
strLines(idx) = &quot;End Property&quot;: GoSub NextIndex
strLines(idx) = spacex: GoSub NextIndex
strLines(idx) = &quot;Public Property Set Obj_&quot; &amp;amp; strObjName &amp;amp; &quot;(ByRef v&quot; &amp;amp; strObjName &amp;amp; &quot; as Access.&quot; &amp;amp; strObjTypeName &amp;amp; &quot;)&quot;: GoSub NextIndex
strLines(idx) = &quot;   Set &quot; &amp;amp; strObjName &amp;amp; &quot; = v&quot; &amp;amp; strObjName: GoSub NextIndex
strLines(idx) = &quot;End Property&quot;: GoSub NextIndex
strLines(idx) = spacex: GoSub NextIndex
strLines(idx) = &quot;Private Sub &quot; &amp;amp; strObjName &amp;amp; &quot;_Click()&quot;: GoSub NextIndex
strLines(idx) = &quot;   Select Case &quot; &amp;amp; strObjName &amp;amp; &quot;.Name&quot;

&#39;Read the Field Names into Array
Open FieldListFile For Input As #1
strItem = &quot;&quot;
j = 0
While Not EOF(1)
    Input #1, strItem
 If Len(Trim(Nz(strItem, &quot; &quot;))) &amp;gt; 0 Then
    j = j + 1
    ReDim Preserve FieldList(1 To j) As String
    FieldList(j) = strItem
 End If
Wend
Close #1

If j &amp;gt; 0 Then &#39;If 0 then Field List File is empty
    low = LBound(FieldList)
    high = UBound(FieldList)
End If

&#39;Write the Array contents to file
ClsPath = CurrentProject.Path &amp;amp; &quot;\TempClass.cls&quot;
Open ClsPath For Output As #1
For k = 1 To idx
    Print #1, strLines(k)
Next

&#39;Subroutine Lines
If j &amp;gt; 0 Then &#39;if 0 then Field List file is empty
    For h = low To high
        Print #1, &quot;     Case &quot; &amp;amp; qot &amp;amp; FieldList(h) &amp;amp; qot
        Print #1, &quot;        &#39; Code&quot;
        Print #1, spacex
    Next
End If
    Print #1, spacex
    Print #1, &quot;   End Select&quot;
    Print #1, &quot;End Sub&quot;
    Print #1, spacex
Close #1

    &#39; Import the class module
Set vbcompo = Application.VBE.ActiveVBProject.VBComponents.Import(ClsPath)
    
    &#39; Verify if the imported module is a class module
    &#39;Compile and Save module
    If vbcompo.Type = vbext_ct_ClassModule Then
        CreateClassTemplate = True
        Kill ClsPath
    Else
        CreateClassTemplate = False
        MsgBox &quot;Import failed: Not a class module.&quot;
    End If

CreateClassTemplate_Exit:
Exit Function

NextIndex:
idx = idx + 1
Return

CreateClassTemplate_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;CreateClassTemplate()&quot;
Resume CreateClassTemplate_Exit
End Function

&lt;/pre&gt;
&lt;p&gt;Check the VBE navigation pane for the newly created Template Files. They may not appear immediately in the Database navigation pane.&lt;/p&gt;&lt;p&gt;The Wizard&#39;s VBA Code is straightforward. The first 33 lines of Code are standard, with the change of&amp;nbsp; Object Names and Type declarations inserted at appropriate positions using the Parameters obtained from the ListItems Table.&lt;/p&gt;&lt;p&gt;Next, it checks for the Field Names list file (or the Control Type-related Text File Names given in the ListItems Table) in the TextBoxFieldsList.txt. If Control Names are present in the Text File, they are loaded into an Array in memory.&lt;/p&gt;&lt;p&gt;After that, the first 33 VBA Code lines are written into the TempClass.cls Text File. If the Field List/Control Name lines are found in the Array, it creates a sample Click Event Subroutine Code within the Select Case . . . Case . . . End Select structure for ready-to-write Event Procedure Code wherever applicable.&lt;/p&gt;&lt;p&gt;This sample Event Subroutine structure can be copied into other Event Procedures, like BeforeUpdate(), GotFocus(), and others.&lt;/p&gt;&lt;p&gt;Finally, the TempClass.cls&amp;nbsp;Text File is Imported into the VBE Project&#39;s Code Pane. Look for the Class Modules with the _Template Suffix to spot them quickly.&lt;/p&gt;&lt;p&gt;If the Import action is unsuccessful, then display an Error Message. In that case, you should investigate and find the cause of the Error, correct it, and try again.&amp;nbsp;&lt;/p&gt;&lt;p&gt;You may highlight one or more required Object Template Options from the ListBox, and the Wizard creates them quickly. You can rename the Template Modules or copy the generated Code from the Template Module and paste it into a separate Class module for normal use. Modify the Object Names part and use it with other types of control.&lt;/p&gt;&lt;p&gt;Click the Help&amp;nbsp;Command Button to display the Help Form in your Application Window. The Help Form Image is shown below.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYjyM1yGHSjhQZIiWFiuUS7XS2Fu9IvXIHkXA5TmLWTdvwhBdbuwSjylY1bzZM4WGqa0DFMFanu0Ej_XhyphenhyphenBT_7gCrM84huZAxPwAqfqkE4P3bPWdrACKNNJeHf-2CcWwU1waNfWNvvsAxs01Bwe0ph6eCB4ry2maJNWY17kmIgOzi1BQh8Up7alVdud3GT/s1351/WizHelpForm.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;925&quot; data-original-width=&quot;1351&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYjyM1yGHSjhQZIiWFiuUS7XS2Fu9IvXIHkXA5TmLWTdvwhBdbuwSjylY1bzZM4WGqa0DFMFanu0Ej_XhyphenhyphenBT_7gCrM84huZAxPwAqfqkE4P3bPWdrACKNNJeHf-2CcWwU1waNfWNvvsAxs01Bwe0ph6eCB4ry2maJNWY17kmIgOzi1BQh8Up7alVdud3GT/s320/WizHelpForm.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The listItems Record ID Enumerations are given below.&lt;/p&gt;
&lt;pre&gt;Enum ParamID
    wizTextBox = 1
    wizCommandButton = 2
    wizComboBox = 3
    wizListBox = 4
    wizLabel = 5
    wizOptionGroup = 6
    wizOptionButton = 7
    wizCheckBox = 8
    wizToggleButton = 9
    wizTabControl = 10
End Enum

&lt;/pre&gt;
&lt;p&gt;The Control Type Validating Function Code Listing. &lt;/p&gt;
&lt;pre&gt;Public Function ControlTypeCheck(ByVal strctl As String) As Long
On Error GoTo ControlTypeCheck_Err
Dim ctrlType(1 To 10) As String
Dim ctrl(1 To 10) As Long
Dim j As Integer

For j = 1 To 10
 Select Case j
    Case 1: ctrlType(j) = &quot;Label&quot;: ctrl(j) = acLabel &#39;100
    Case 2: ctrlType(j) = &quot;CommandButton&quot;: ctrl(j) = acCommandButton &#39;104
    Case 3: ctrlType(j) = &quot;OptionButton&quot;: ctrl(j) = acOptionButton &#39;105
    Case 4: ctrlType(j) = &quot;CheckBox&quot;: ctrl(j) = acCheckBox &#39;106 
    Case 5: ctrlType(j) = &quot;OptionGroup&quot;: ctrl(j) = acOptionGroup &#39;107 
    Case 6: ctrlType(j) = &quot;TextBox&quot;: ctrl(j) = acTextBox &#39;109
    Case 7: ctrlType(j) = &quot;ListBox&quot;: ctrl(j) = acListBox &#39;110
    Case 8: ctrlType(j) = &quot;ComboBox&quot;: ctrl(j) = acComboBox &#39;111
    Case 9: ctrlType(j) = &quot;ToggleButton&quot;: ctrl(j) = acToggleButton &#39;122 
    Case 10: ctrlType(j) = &quot;TabControl&quot;: ctrl(j) = acTabCtl &#39;123  
End Select
Next

For j = LBound(ctrlType) To UBound(ctrlType)
    If ctrlType(j) = strctl Then
        ControlTypeCheck = ctrl(j): Exit For
    Else
       ControlTypeCheck = 9999 &#39;Error
    End If
Next

ControlTypeCheck_Exit:
Exit Function

ControlTypeCheck_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;ControlTypeCheck()&quot;
Resume ControlTypeCheck_Exit
End Function

&lt;/pre&gt;
&lt;p&gt;I hope you are enjoying the new approach to coding with reusable VBA and easier code maintenance, without the need to interfere with the Form Design View. The &#39;Streamlining Form Module Code in the Standalone Class Module&#39; also enhances code portability to other projects, offering a significant advantage.&lt;/p&gt;
&lt;h3&gt;Demo Databases Download.&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/06/WrapperClass_Wizard.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1mEX7pg3YMeX-hMnFq9GMUHtbpZ2UulIM/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioFf-79SroXZ4JkiqgZYv196vvwuIDU6wLEconUKqF-8uKB4XfA4P2yshkCX2o16u08fw9nN8LkTe8XvDgBDDTepmbEqtmBreKye0SKYfz10iaUmM1loO3uX7sYhQvQctArB6ZjjzRO1Rw/s320/zip.gif&quot; width=&quot;22&quot; /&gt;WrapperClass_Wizard.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/06/WrapperClass_Wizard.zip--&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/124761418939312132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/124761418939312132'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/124761418939312132'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html' title='Wrapper Class Template Wizard V2'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSLInT_mMHalg0-M_bkiLx7cxAnipNNY0iETfr11eWwDYPuoB2HCIJSrciN3VkGEqOwmFA3Utv4nMrCWbZJcyz1bCuRDDW7MKK5R61D7GTBOeW-vXwc6E9_UrxmgOOD_PpBrIGRXCHZXUpNIg1Ewt6Emqp6Te6zn1zn89KYS59XAHfEv6ekMrup9qY0aic/s72-c/ClassModuleWizardV2.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-5388844825088832526</id><published>2024-05-29T18:23:00.009+05:30</published><updated>2026-07-14T19:02:21.344+05:30</updated><title type='text'>Wrapper Class Module Creation Wizard</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Wrapper Class Module Wizard.&lt;/h3&gt;
&lt;p data-end=&quot;489&quot; data-start=&quot;82&quot;&gt;We organize the controls on a form into groups based on their type—such as &lt;span data-end=&quot;174&quot; data-start=&quot;157&quot;&gt;TextBox/Field&lt;/span&gt;, &lt;span data-end=&quot;193&quot; data-start=&quot;176&quot;&gt;&lt;a href=&quot;https://www.msaccesstips.com/2006/09/command-button-animation.html&quot; target=&quot;_blank&quot;&gt;CommandButton&lt;/a&gt;&lt;/span&gt;, or &lt;span data-end=&quot;210&quot; data-start=&quot;198&quot;&gt;ComboBox&lt;/span&gt;—and create separate wrapper class modules for each group to manage their event subroutine code. Each class module follows a consistent structure, starting with declarations of the form and control objects in the global area, followed by the corresponding property procedures.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;932&quot; data-start=&quot;491&quot;&gt;The event subroutines come next and require the correct &lt;span data-end=&quot;570&quot; data-start=&quot;547&quot;&gt;TextBox/Field names&lt;/span&gt; from the form to write the code under each &lt;span data-end=&quot;622&quot; data-start=&quot;614&quot;&gt;Case&lt;/span&gt; statement within a subroutine. Accurately memorizing control names can be difficult, and often forces developers to repeatedly consult the &lt;a href=&quot;https://www.msaccesstips.com/2009/11/creating-using-form-custom-property.html&quot; target=&quot;_blank&quot;&gt;property&lt;/a&gt; sheet of the controls. This results in constant switching between the class module and the form’s design view, making the process tedious and time-consuming.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;h3&gt;The ClassWizard Form Image.&amp;nbsp;&amp;nbsp;&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBPBRHUUAKn1rjZ_rQOsZUr0VAsFjjoc8Nh6RADDg7487S9HlnML9WoMHDzxbyBLS9glvDobz8rylMwc4BSq6Zg7R6r6pb1lDRsYvVi1JI1f8JWKv9quTmndw12szNhMudM1nWA3TQWvQN3_BuTawfDsMSvrAAe417DVtPLBJCNiYMQU0AAk5nVSBhSgoR/s1093/ClassTemplateWizard.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Class Template Wizard&quot; border=&quot;0&quot; data-original-height=&quot;839&quot; data-original-width=&quot;1093&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBPBRHUUAKn1rjZ_rQOsZUr0VAsFjjoc8Nh6RADDg7487S9HlnML9WoMHDzxbyBLS9glvDobz8rylMwc4BSq6Zg7R6r6pb1lDRsYvVi1JI1f8JWKv9quTmndw12szNhMudM1nWA3TQWvQN3_BuTawfDsMSvrAAe417DVtPLBJCNiYMQU0AAk5nVSBhSgoR/s320/ClassTemplateWizard.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;When a Form is open, we typically scan for different types of controls in the Form as part of the new &lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_blank&quot;&gt;Streamlined Event Subroutine Coding&lt;/a&gt; procedure. The control names can then be saved in text files, organized by control type—for example, TextBox names in one file, &lt;a href=&quot;https://www.msaccesstips.com/2008/04/transparent-command-button.html&quot; target=&quot;_blank&quot;&gt;CommandButton&lt;/a&gt; names in another, and ComboBox names in a separate file. This approach makes it easier to reference control names and minimizes the need to constantly switch between the class module and the form’s design view.&lt;/p&gt;&lt;p&gt;So, we now have the following necessary elements for building the Class&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_blank&quot;&gt;Wrapper Class&lt;/a&gt; Templates with Code:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Global Declaration of Objects.&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Standard Property Procedures for the declared Objects.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;The Control Names are collected from the Form and written into a Text File on Disk.&amp;nbsp; We can build a single Subroutine structure, with all the Field Names placed within the Select Case Statements.&lt;/li&gt;&lt;/ol&gt;&lt;p data-end=&quot;551&quot; data-start=&quot;78&quot;&gt;Once the &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_blank&quot;&gt;Wrapper Class Module&lt;/a&gt; Template (&lt;span data-end=&quot;143&quot; data-start=&quot;118&quot;&gt;ClassTextBox_Template&lt;/span&gt;) is generated with a sample &lt;span data-end=&quot;190&quot; data-start=&quot;172&quot;&gt;BeforeUpdate()&lt;/span&gt; event subroutine using the Class Wizard, you can reuse its structure for other events, such as &lt;span data-end=&quot;300&quot; data-start=&quot;286&quot;&gt;GotFocus()&lt;/span&gt; or &lt;span data-end=&quot;319&quot; data-start=&quot;304&quot;&gt;LostFocus()&lt;/span&gt;, by simply copying, pasting, and updating the event names. From there, you can add the specific code required for each event. Any unnecessary field names can be removed from the Case statements to keep the code clean and focused.&lt;/p&gt;
&lt;p&gt;The Wizard’s input file, &lt;span data-end=&quot;599&quot; data-start=&quot;578&quot;&gt;TextBoxFields.txt&lt;/span&gt;, stores the field names from the &lt;span data-end=&quot;644&quot; data-start=&quot;633&quot;&gt;Employees&lt;/span&gt; table. These names are captured when the Employee Form is open, and the &lt;span data-end=&quot;732&quot; data-start=&quot;716&quot;&gt;Class_Init()&lt;/span&gt; subroutine runs in the &lt;span data-end=&quot;773&quot; data-start=&quot;756&quot;&gt;Class_ObjInit&lt;/span&gt; &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-vba-class-object-arrays.html&quot; target=&quot;_blank&quot;&gt;Class Module&lt;/a&gt;. An example of this input file for the Class Wizard Program is shown below.&lt;/p&gt;&lt;p&gt;TextBoxFields.txt File contents.&lt;/p&gt;
&lt;pre&gt;ID
Company
Last Name
First Name
E-mail Address
Job Title
Address
City
State/Province
ZIP/Postal Code
Country/Region
&lt;/pre&gt;
&lt;p&gt;The above Field List File is created from the Employees Form&#39;s Class_Init() Subroutine in the Class_ObjInit Intermediary Class Module. &lt;/p&gt;&lt;p&gt;The Employees Form image given below, with some not-in-use CommandButtons and ComboBoxes added for trial run purposes.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_9IA5GfvBiPdi0GrFB39VcrJnaalZLucjrLWpCr3v_Df_yQuU78gqqupOs-N7i_jlmLewjHu8M0U9Dbp93lEKX3jHBeYnYtZ1dMj7qe-JQlhysTzDjQnMsE52nsRf6aMfFsmqpk0x0_d4MorYO9OF88IVcpISO-tleLoWlq-AIevOO7VaJ8elsr_yvTRo/s838/Employees_Form_Wizard.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Employees Form for Wizard&quot; border=&quot;0&quot; data-original-height=&quot;785&quot; data-original-width=&quot;838&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_9IA5GfvBiPdi0GrFB39VcrJnaalZLucjrLWpCr3v_Df_yQuU78gqqupOs-N7i_jlmLewjHu8M0U9Dbp93lEKX3jHBeYnYtZ1dMj7qe-JQlhysTzDjQnMsE52nsRf6aMfFsmqpk0x0_d4MorYO9OF88IVcpISO-tleLoWlq-AIevOO7VaJ8elsr_yvTRo/s320/Employees_Form_Wizard.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;The new Class_Init() Subroutine of the Employees Form, with the Text File creation Code, is listed below. &lt;/p&gt;
&lt;pre&gt;Private Sub Class_Init()
Dim ProjectPath As String
Dim txtPath As String
Dim cmdPath As String
Dim ComboPath As String
Dim ctl As Control

On Error GoTo ClassInit_Err

Const EP = &quot;[Event Procedure]&quot;

&#39;Save TextBox, CommandButton &amp;amp; CombBox Names
&#39;to the Text Files for creating Event Subroutine Template
ProjectPath = CurrentProject.Path &amp;amp; &quot;\&quot;

txtPath = ProjectPath &amp;amp; &quot;TextBoxFields.txt&quot;
cmdPath = ProjectPath &amp;amp; &quot;CmdButtonsList.txt&quot;
ComboPath = ProjectPath &amp;amp; &quot;ComboBoxList.txt&quot;

If Len(Dir(txtPath)) &amp;gt; 0 Then &#39;delete earlier file
  Kill txtPath
End If

If Len(Dir(cmdPath)) &amp;gt; 0 Then &#39;delete earlier file
  Kill cmdPath
End If

If Len(Dir(ComboPath)) &amp;gt; 0 Then &#39;delete earlier file
  Kill ComboPath
End If

Open txtPath For Output As #1 &#39;TextBoxFields.txt for writing
Open cmdPath For Output As #2 &#39;CmdButtonsList.txt
Open ComboPath For Output As #3 &#39;ComboBoxList.txt

&#39;Instantiate the &#39;Data_txtBox&#39; Class for each TextBox
&#39;on the Form for streamlined Event Procedures Coding
For Each ctl In Frm.Controls
    Select Case TypeName(ctl)
        Case &quot;TextBox&quot;
            Set txt = New Data_TxtBox
            Set txt.m_Frm = Frm
            Set txt.m_txt = ctl
    Print #1, ctl.Name &#39;write Field/TextBox Name in TextBoxFields.txt File
            
&#39;//Colin Riddington Technique: Highlighting BackColor on GotFocus
                txt.m_txt.BackColor = 62207 &#39;yellow
                txt.m_txt.BackStyle = 0
    
                txt.m_txt.BeforeUpdate = EP
                txt.m_txt.OnDirty = EP
                
                Coll.Add txt &#39;Add Data_TxtBox Class Instance to Collection
                Set txt = Nothing &#39;Reset txt object
      
      Case &quot;CommandButton&quot;
            Set cmd = New Data_CmdButton
            Set cmd.Obj_Form = Frm
            Set cmd.cmd_Button = ctl
    Print #2, ctl.Name &#39;write CmdButton Name in CmdButtonsList.txt File
                
                cmd.cmd_Button.OnClick = EP
                
                Coll.Add cmd
                Set cmd = Nothing
                
      Case &quot;ComboBox&quot;
            Set Cbo = New Data_CboBox
            Set Cbo.m_Frm = Frm
            Set Cbo.m_Cbo = ctl
    Print #3, ctl.Name &#39;write ComboBox Names in ComboBoxList.txt File
    
&#39;//Colin Riddington Technique: Highlighting BackColor on GotFocus
                Cbo.m_Cbo.BackColor = 62207
                Cbo.m_Cbo.BackStyle = 0
                
                Cbo.m_Cbo.BeforeUpdate = EP
                Cbo.m_Cbo.OnDirty = EP
                
                Coll.Add Cbo
                Set Cbo = Nothing
    End Select
Next
&#39;Close all the three files
Close #1
Close #2
Close #3

ClassInit_Exit:
Exit Sub

ClassInit_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;Class_Init()&quot;
Resume ClassInit_Exit
End Sub

&lt;/pre&gt;
&lt;h3&gt;The BASIC Language Text File Creation, Writing/Reading Statements:&lt;/h3&gt;
&lt;pre&gt;Public Sub sub writeText()
Dim strItem As String
strItem = &quot;www.msaccesstips.com&quot;

Open &quot;C:\myTextFile.txt&quot; For Output As #1 &#39;Open file in Output/writing Mode
   Print #1, strItem
Close #1

End Sub
&lt;/pre&gt;
&lt;h4&gt;Read the Text Data into a Variable&lt;/h4&gt;
&lt;pre&gt;Public Sub ReadText()
dim strItem as String

Open &quot;C:\myTextFile.txt&quot; For Input As #1 &#39;Open File in Input/Reading Mode
   Input #1, strItem
   debug.print strItem
Close #1

End Sub
&lt;/pre&gt;
&lt;p&gt;The &#39;As #1&#39; part indicates that this file is the first file in the Open state. If a second file is to be opened for Writing/Reading simultaneously, then that will be &#39;As #2&#39;.
&lt;/p&gt;&lt;h4&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;The sample &#39;&lt;/span&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;ClassTextBox_Template&lt;/span&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;&#39; VBA Code generated by the&lt;/span&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;ClassTemplateWizard&lt;/span&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-weight: 400;&quot;&gt;is listed below for reference.&lt;/span&gt;&lt;/h4&gt;&lt;h4&gt;The ClassTextBox_Template.&lt;/h4&gt;
 &lt;pre&gt;Option Compare Database
Option Explicit
 
Private WithEvents TextB As Access.TextBox
Private Frm As Access.Form
 
Public Property Get Obj_Form() As Form
   Set Obj_Form = Frm
End Property
 
Public Property Set Obj_Form(ByRef objForm As Form)
   Set Frm = objForm
End Property
 
Public Property Get Text_Box() As TextBox
   Set Text_Box = TextB
End Property
 
Public Property Set Text_Box(ByRef objTextB As TextBox)
   Set TextB = objTextB
End Property
 
Private Sub TextB_BeforeUpdate(Cancel As Integer)
   Select Case TextB.Name
     Case &quot;ID&quot;
        &#39; Code
 
     Case &quot;Company&quot;
        &#39; Code
 
     Case &quot;Last Name&quot;
        &#39; Code
 
     Case &quot;First Name&quot;
        &#39; Code
 
     Case &quot;E-mail Address&quot;
        &#39; Code
 
     Case &quot;Job Title&quot;
        &#39; Code
 
     Case &quot;Address&quot;
        &#39; Code
 
     Case &quot;City&quot;
        &#39; Code
 
     Case &quot;State/Province&quot;
        &#39; Code
 
     Case &quot;ZIP/Postal Code&quot;
        &#39; Code
 
     Case &quot;Country/Region&quot;
        &#39; Code
 
   End Select
End Sub

 &lt;/pre&gt;

&lt;p data-end=&quot;316&quot; data-start=&quot;86&quot;&gt;The &lt;span data-end=&quot;119&quot; data-start=&quot;90&quot;&gt;ClassTemplateWizard.accdb&lt;/span&gt; contains the Class Wizard Form. An image of the &lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_blank&quot;&gt;Wizard Form&lt;/a&gt; is provided at the top of this page. To use it, you must first attach this database as a &lt;span data-end=&quot;289&quot; data-start=&quot;269&quot;&gt;Library Database&lt;/span&gt; to your current project.&lt;/p&gt;
&lt;p data-end=&quot;502&quot; data-start=&quot;318&quot;&gt;Once attached, you can run the Public Function &lt;span data-end=&quot;386&quot; data-start=&quot;365&quot;&gt;OpenClassWizard()&lt;/span&gt; either by typing it directly in the Debug Window or by calling it from a Command Button’s Click Event Subroutine.&lt;/p&gt;
&lt;p data-end=&quot;667&quot; data-start=&quot;504&quot;&gt;After attaching &lt;span data-end=&quot;549&quot; data-start=&quot;520&quot;&gt;ClassTemplateWizard.accdb&lt;/span&gt; as a Library Database (via &lt;span data-end=&quot;602&quot; data-start=&quot;577&quot;&gt;Tools → References...&lt;/span&gt;), ensure it is checked in the list of available library files.&lt;/p&gt;
&lt;p&gt;Now, follow the steps below to create the Class Template file on disk:&lt;/p&gt;&lt;h3 data-end=&quot;162&quot; data-start=&quot;117&quot;&gt;Steps to Create the Class Template File&lt;/h3&gt;&lt;p&gt;
&lt;/p&gt;&lt;ol data-end=&quot;1355&quot; data-start=&quot;164&quot;&gt;
&lt;li data-end=&quot;584&quot; data-start=&quot;164&quot;&gt;
&lt;p data-end=&quot;245&quot; data-start=&quot;167&quot;&gt;&lt;span data-end=&quot;182&quot; data-start=&quot;167&quot;&gt;Open a Form&lt;/span&gt; (e.g., the Employees Form) and close it after a few seconds.&lt;/p&gt;
&lt;ul data-end=&quot;584&quot; data-start=&quot;249&quot;&gt;
&lt;li data-end=&quot;503&quot; data-start=&quot;249&quot;&gt;
&lt;p data-end=&quot;332&quot; data-start=&quot;251&quot;&gt;The &lt;code data-end=&quot;269&quot; data-start=&quot;255&quot;&gt;Class_Init()&lt;/code&gt; Subroutine creates three text files in your database folder:&lt;/p&gt;
&lt;ul data-end=&quot;503&quot; data-start=&quot;338&quot;&gt;
&lt;li data-end=&quot;387&quot; data-start=&quot;338&quot;&gt;
&lt;p data-end=&quot;387&quot; data-start=&quot;340&quot;&gt;&lt;span data-end=&quot;361&quot; data-start=&quot;340&quot;&gt;TextBoxFields.txt&lt;/span&gt; – list of TextBox names&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;448&quot; data-start=&quot;393&quot;&gt;
&lt;p data-end=&quot;448&quot; data-start=&quot;395&quot;&gt;&lt;span data-end=&quot;416&quot; data-start=&quot;395&quot;&gt;CmdButtonList.txt&lt;/span&gt; – list of CommandButton names&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;503&quot; data-start=&quot;454&quot;&gt;
&lt;p data-end=&quot;503&quot; data-start=&quot;456&quot;&gt;&lt;span data-end=&quot;476&quot; data-start=&quot;456&quot;&gt;ComboBoxList.txt&lt;/span&gt; – list of ComboBox names&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;584&quot; data-start=&quot;507&quot;&gt;
&lt;p data-end=&quot;584&quot; data-start=&quot;509&quot;&gt;These files are automatically overwritten each time a new form is opened.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;741&quot; data-start=&quot;586&quot;&gt;
&lt;p data-end=&quot;654&quot; data-start=&quot;589&quot;&gt;&lt;span data-end=&quot;629&quot; data-start=&quot;589&quot;&gt;Run the &lt;code data-end=&quot;618&quot; data-start=&quot;599&quot;&gt;OpenClassWizard()&lt;/code&gt; Function&lt;/span&gt; from the Debug Window.&lt;/p&gt;
&lt;ul data-end=&quot;741&quot; data-start=&quot;658&quot;&gt;
&lt;li data-end=&quot;741&quot; data-start=&quot;658&quot;&gt;
&lt;p data-end=&quot;741&quot; data-start=&quot;660&quot;&gt;The Wizard Form opens behind the VBA window. Minimize the VBA window to see it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;835&quot; data-start=&quot;743&quot;&gt;
&lt;p data-end=&quot;835&quot; data-start=&quot;746&quot;&gt;&lt;span data-end=&quot;776&quot; data-start=&quot;746&quot;&gt;Select &lt;code data-end=&quot;774&quot; data-start=&quot;755&quot;&gt;TextBoxFields.txt&lt;/code&gt;&lt;/span&gt; from the &lt;span data-end=&quot;807&quot; data-start=&quot;786&quot;&gt;left-hand ListBox&lt;/span&gt; in the Wizard input Form.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;913&quot; data-start=&quot;837&quot;&gt;
&lt;p data-end=&quot;913&quot; data-start=&quot;840&quot;&gt;&lt;span data-end=&quot;878&quot; data-start=&quot;840&quot;&gt;Select &lt;code data-end=&quot;876&quot; data-start=&quot;849&quot;&gt;ClassTextBox_Template.cls&lt;/code&gt;&lt;/span&gt; from the &lt;span data-end=&quot;910&quot; data-start=&quot;888&quot;&gt;right-hand ListBox&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;952&quot; data-start=&quot;915&quot;&gt;
&lt;p data-end=&quot;952&quot; data-start=&quot;918&quot;&gt;&lt;span data-end=&quot;950&quot; data-start=&quot;918&quot;&gt;Click the Run Wizard button&lt;/span&gt;&lt;strong data-end=&quot;950&quot; data-start=&quot;918&quot;&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1086&quot; data-start=&quot;954&quot;&gt;
&lt;p data-end=&quot;1086&quot; data-start=&quot;957&quot;&gt;A confirmation message will appear, informing you that &lt;span data-end=&quot;1041&quot; data-start=&quot;1012&quot;&gt;ClassTextBox_Template.cls&lt;/span&gt; has been created in your project’s folder.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1262&quot; data-start=&quot;1088&quot;&gt;
&lt;p data-end=&quot;1262&quot; data-start=&quot;1091&quot;&gt;In the VBA editor, &lt;span data-end=&quot;1145&quot; data-start=&quot;1110&quot;&gt;right-click the Navigation Pane&lt;/span&gt; (near your project’s Class Modules list, &lt;em data-end=&quot;1192&quot; data-start=&quot;1187&quot;&gt;not&lt;/em&gt; the attached Wizard database’s list) and choose &lt;span data-end=&quot;1259&quot; data-start=&quot;1241&quot;&gt;Import File...&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1355&quot; data-start=&quot;1264&quot;&gt;
&lt;p data-end=&quot;1355&quot; data-start=&quot;1267&quot;&gt;&lt;span data-end=&quot;1353&quot; data-start=&quot;1267&quot;&gt;Browse to your project folder, select &lt;code data-end=&quot;1334&quot; data-start=&quot;1307&quot;&gt;ClassTextBox_Template.cls&lt;/code&gt;, and click Open.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The ClassTextBox_Template Class is created among the &lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_blank&quot;&gt;Class Modules&lt;/a&gt; List in the VBA Navigation Pane.&amp;nbsp;&lt;/p&gt;&lt;p data-end=&quot;312&quot; data-start=&quot;78&quot;&gt;Even though the &lt;span data-end=&quot;123&quot; data-start=&quot;94&quot;&gt;ClassTextBox_Template.cls&lt;/span&gt; file is generated for a specific form, it can also be reused in other forms or imported into a new project. To adapt it for a different form, simply update the TextBox names accordingly.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;507&quot; data-start=&quot;314&quot;&gt;The Wizard functions are available in the &lt;span data-end=&quot;375&quot; data-start=&quot;356&quot;&gt;Standard Module&lt;/span&gt; of the &lt;span data-end=&quot;412&quot; data-start=&quot;383&quot;&gt;ClassTemplateWizard.accdb&lt;/span&gt; database. For testing purposes, you can use the sample database &lt;span data-end=&quot;504&quot; data-start=&quot;477&quot;&gt;ClassLibrary_Main.accdb&lt;/span&gt;.&lt;/p&gt;
&lt;h3&gt;Demo Databases Download.&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/05/ClassTemplateWizard.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1tUsT6Zz_37n8KZB5PP4JevrOecikM_K6/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioFf-79SroXZ4JkiqgZYv196vvwuIDU6wLEconUKqF-8uKB4XfA4P2yshkCX2o16u08fw9nN8LkTe8XvDgBDDTepmbEqtmBreKye0SKYfz10iaUmM1loO3uX7sYhQvQctArB6ZjjzRO1Rw/s320/zip.gif&quot; width=&quot;22&quot; /&gt;ClassTemplateWizard.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/05/ClassTemplateWizard.zip--&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/5388844825088832526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5388844825088832526'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5388844825088832526'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html' title='Wrapper Class Module Creation Wizard'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBPBRHUUAKn1rjZ_rQOsZUr0VAsFjjoc8Nh6RADDg7487S9HlnML9WoMHDzxbyBLS9glvDobz8rylMwc4BSq6Zg7R6r6pb1lDRsYvVi1JI1f8JWKv9quTmndw12szNhMudM1nWA3TQWvQN3_BuTawfDsMSvrAAe417DVtPLBJCNiYMQU0AAk5nVSBhSgoR/s72-c/ClassTemplateWizard.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-805125377438457779</id><published>2024-05-16T17:41:00.009+05:30</published><updated>2026-07-13T21:09:05.246+05:30</updated><title type='text'>Classes For All Data Entry Editing Forms</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;Ready-made Class Modules for Data-Entry, Editing, or Viewing.&lt;/h4&gt;
&lt;p&gt;All the TextBox and &lt;a href=&quot;https://www.msaccesstips.com/2009/01/combo-box-column-values.html&quot; target=&quot;_blank&quot;&gt;ComboBox&lt;/a&gt; Controls on the data-handling form, when enabled with the Dirty()&amp;nbsp;and&amp;nbsp; BeforeUpdate() Event Procedures, are fully protected from unintentional changes.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Manually writing code for every TextBox and ComboBox on a form can lead to duplication of work and inefficiency. Moreover, modifying event procedure names for each field to match the control name can be tedious. Typically, only essential fields undergo this kind of data protection exercise, leaving others vulnerable.&amp;nbsp;&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;

&lt;p&gt;To streamline this process, consider implementing a more automated or systematic approach, such as reusable code structures of Standalone &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html&quot; target=&quot;_blank&quot;&gt;Class Modules&lt;/a&gt;, that help to centralize and organize Event Procedures more efficiently.&lt;/p&gt;&lt;p&gt;Using the Class Modules for VBA coding enables a swift, automated solution that implements data protection methods across all fields on the form. By leveraging event Dirty() and BeforeUpdate() Subroutine &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;Code reuse&lt;/a&gt; techniques, these data-protecting procedures can be efficiently applied to all Text Boxes and Combo Boxes on the form. This streamlined approach ensures quick, consistent implementation of data protection measures, enhancing the overall robustness and security of the form&#39;s data handling processes.&lt;/p&gt;&lt;p&gt;With the following few Simple Steps, let us do a Demo Run to understand how it works:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Use the Form Wizard to create a Form: Columnar or Tabular Design using any Table/Query as data source.&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Open the Form in Design View.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;Display the Form Property Sheet and Select the Other&amp;nbsp;Tab.&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Change the Has Module Property Value to Yes.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;Display the Form Module.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Copy and Paste the following VBA Code into the Form Module.&lt;/p&gt;
  &lt;pre&gt;Option Compare Database
Option Explicit

Private Cls As New Class_ObjInit

Private Sub Form_Load()
Set Cls.o_Frm = Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Set Cls = Nothing
End Sub
  &lt;/pre&gt;

&lt;p&gt;Sample Form Image with the Employees Table.&lt;/p&gt;
&lt;p&gt;Save your Form, but do not open it at this time. We need to create the Class Modules first.&lt;/p&gt;
  &lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjstJCZ_ir4qX_nWqKWAWriVFpPeN9BhPUZ88oYci54kW6VaFHVMx0nDyh9m3qV34RlkZr56cMS-28jZznVIrCGk8IXhyk91jSqX0PLVrepK7FwUa-bXiQvbXwiO-NOtd7YkPqCb8pizZbRO2Hs1G3tx9HaaLt88s7z-m_IweHa2dwrrxHOj3Df0BfB8u2Y/s705/UniversalForm.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;705&quot; data-original-width=&quot;690&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjstJCZ_ir4qX_nWqKWAWriVFpPeN9BhPUZ88oYci54kW6VaFHVMx0nDyh9m3qV34RlkZr56cMS-28jZznVIrCGk8IXhyk91jSqX0PLVrepK7FwUa-bXiQvbXwiO-NOtd7YkPqCb8pizZbRO2Hs1G3tx9HaaLt88s7z-m_IweHa2dwrrxHOj3Df0BfB8u2Y/s320/UniversalForm.png&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;There are three ready-made &lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_blank&quot;&gt;Class Modules&lt;/a&gt;, with a single prewritten OnDirty() and BeforeUpdate() Event Procedures. The&amp;nbsp;Class_ObjInit&amp;nbsp;Class Module is instantiated in the global declaration area, with the object name&amp;nbsp;Cls.&amp;nbsp;When the Form is open, and in the Form_Load()&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;Event Procedure, the&amp;nbsp;Cls.o_Frm&amp;nbsp;&lt;/span&gt;Class Module&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;Property is assigned to the current Form Object,&lt;/span&gt;&amp;nbsp;Me.&amp;nbsp;&lt;/p&gt;&lt;p&gt;When the &lt;i&gt;Class_ObjInit&lt;/i&gt; Class Object is instantiated, the Data_TxtBox Class and the Data_CboBox Classes declared in the Class_ObjInit Class are also loaded into memory. We will create these Class Modules with the Event Subroutine Codes next.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;p&gt;Open the VBA Editing Window (ALT+F11)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;Create a Class Module, then click the&amp;nbsp;Properties Window&amp;nbsp;Icon (located between the Project Explorer and Object Browser Icons) to display the Class Module&#39;s Property Sheet. Change the Module Name from Class1 to &lt;i&gt;Class_ObjInit&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Copy the VBA Code given below, paste it into the &lt;i&gt;Class_ObjInit&lt;/i&gt; Class Module, and save it.&lt;/p&gt;
&lt;h3&gt;The &lt;i&gt;Class_ObjInit&lt;/i&gt; Class Module.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private txt As Data_TxtBox
Private Cbo As Data_CboBox
Private Coll As New Collection
Private frm As Form
Private DetSec As Section

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;With Reusable Code
&#39;------------------------------------------------------
&#39;Quick Data Entry Screen
&#39;Saving Table/Query Records in Collection Object
&#39;Author:  a.p.r. pillai
&#39;Date  :  10/05/2024
&#39;Remarks: with Ready-made Data Entry Events Handler
&#39;       : in the Wrapper TextBox Class Module
&#39;       : Suitable for Columnar, Tabular or DataSheet Form
&#39;Rights:  All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

Public Property Get o_Frm() As Form
    Set o_Frm = frm
End Property

Public Property Set o_Frm(ByRef vFrm As Form)
    Set frm = vFrm

    Class_Init
End Property

Private Sub Class_Init()
Dim fldNames() As String
Dim j As Long
Dim Path As String
Dim ctl As Control

On Error GoTo ClassInit_Err

Set DetSec = frm.Section(acDetail)

Const EP = &quot;[Event Procedure]&quot;

&#39;Save Form Detail Section Field Names
&#39;to this Text File for creating Event Subroutine Template

&lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;Path = CurrentProject.Path &amp;amp; &quot;\EventSubFields.txt&quot;
If Len(Dir(Path)) &amp;gt; 0 Then
  Kill Path
End If

Open Path For Output As #1&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #2b00fe;&quot;&gt;
&lt;/span&gt;
&#39;Instantiate the &#39;Data_txtBox&#39; Class for each TextBox
&#39;on the Form for streamlined Event Procedures Coding
j = 0
For Each ctl In DetSec.Controls
    Select Case TypeName(ctl)
        Case &quot;TextBox&quot;
        
        j = j + 1
        ReDim Preserve fldNames(1 To j) As String
        fldNames(j) = ctl.Name
        
            Set txt = New Data_TxtBox
            Set txt.m_Frm = frm
            Set txt.m_txt = ctl
&#39;//Colin Riddington Technique: Highlighting BackColor on GotFocus
                txt.m_txt.BackColor = 62207 &#39;RGB(&amp;amp;HFF, &amp;amp;HF2, &amp;amp;H0):Yellow Background
                txt.m_txt.BackStyle = 0 &#39;Transparent
            
    &lt;span style=&quot;color: red;&quot;&gt;&lt;b&gt;Print #1, ctl.Name&lt;/b&gt;&lt;/span&gt; &#39;write Field Name in EventSubFields.txt File
    
                txt.m_txt.BeforeUpdate = EP
                txt.m_txt.OnDirty = EP
                
                Coll.Add txt &#39;Add Data_TxtBox Class Instance to Collection
                Set txt = Nothing &#39;Reset txt object
      
      Case &quot;ComboBox&quot;
            Set Cbo = New Data_CboBox
            Set Cbo.m_Frm = frm
            Set Cbo.m_Cbo = ctl
            
&#39;//Colin Riddington Technique: Highlighting BackColor on GotFocus
                Cbo.m_Cbo.BackColor = 62207 &#39;RGB(&amp;amp;HFF, &amp;amp;HF2, &amp;amp;H0)
                Cbo.m_Cbo.BackStyle = 0
                
                Cbo.m_Cbo.BeforeUpdate = EP
                Cbo.m_Cbo.OnDirty = EP
                Coll.Add Cbo
                Set Cbo = Nothing
    End Select
Next
&lt;span style=&quot;color: red; font-weight: bold;&quot;&gt;Close #1 &lt;/span&gt;&#39;Close Text File

ClassInit_Exit:
Exit Sub

ClassInit_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;Class_Init()&quot;
Resume ClassInit_Exit
End Sub
&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;We instantiated the Class_ObjInit Class Module in the Form Module and assigned the Form object to its Property &lt;i&gt;o_Frm&lt;/i&gt;.&amp;nbsp; After the Form Object is assigned to the&amp;nbsp;&lt;i&gt;Set Property Procedure,&amp;nbsp;&lt;/i&gt;the Class_Init() Subroutine is called.&lt;/p&gt;
&lt;p&gt;The Code lines in red in this Module will create a Text File &#39;EventSubFields.txt&#39;&amp;nbsp;to save the Data Field Names from the detail section of the Form. The purpose of this Field List will be explained later on.&lt;/p&gt;&lt;p&gt;The Data_TxtBox&amp;nbsp;Class is instantiated for each &lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-five.html&quot; target=&quot;_blank&quot;&gt;TextBox&lt;/a&gt; Control; the&amp;nbsp;Data_CboBox&amp;nbsp;Class (we will create both these Class Modules next) is instantiated for each ComboBox Control on the Form; the Dirty() and BeforeUpdate() Events&amp;nbsp;are enabled by setting the text &quot;[Event Procedure]&quot; in their &lt;i&gt;OnDirty&lt;/i&gt; and &lt;i&gt;BeforeUpdate&lt;/i&gt; Event Properties.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;NB: &lt;i&gt;If you have not gone through this topic&#39;s earlier Pages, then you may find most of the discussion on this page somewhat strange. Find this Topic&#39;s earlier links at the end of this Page. You may visit those Pages starting from the first link. It starts with the Basics of this Coding concept of &#39;Form Module Event Subroutine coding in the Standalone Class Module&#39;.&amp;nbsp; The Class_ObjInit Class Module&#39;s Code and its usages are almost the same in all the earlier examples, too.&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;The&amp;nbsp;BackColor&amp;nbsp;Property is set to&amp;nbsp;Yellow, and the&amp;nbsp;BackStyle&amp;nbsp;Property is set to&amp;nbsp;&lt;i&gt;Transparent&lt;/i&gt;&amp;nbsp;so that the TextBox/ComboBox background is highlighted only when the Control is active.&lt;br /&gt;&lt;br /&gt;After these changes, the TextBox or ComboBox &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;Wrapper Class Module&lt;/a&gt; Instance is added as a &lt;i&gt;Collection Object Item&lt;/i&gt; to keep them active in memory.&amp;nbsp; When the Events are fired from the Controls on the Form, they are trapped in the TextBox Instance in the Collection Object and execute the Event Subroutine Code.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;i&gt;Remember, each TextBox on the Form has a Data_TxtBox Class Instance created, assigned with the TextBox Reference from the Form, and inserted into the Collection Object Item. When the Dirty() or BeforeUpdate() Event fires from a particular TextBox, it is captured in the Data_TxtBox Class Instance representing that TextBox and executes the Event Subroutines.&amp;nbsp;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;This is the new VBA Event Subroutine Coding approach for Form/Report Controls that I have designed for ease of VBA Coding in Standalone Class Modules. This Coding approach has the following advantages:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Reuse the Event Procedure Code without manual duplication of Event Procedures&lt;/li&gt;&lt;li&gt;&lt;p&gt;Need only one structured Event Subroutine per Event (say &lt;i&gt;BeforeUpdate()&lt;/i&gt;) for all Controls of the same Type (for all TextBoxes on the Form), and all the Event Procedure Codes are organized within a single Event Subroutine in a structured manner. Export this code to your other projects and customize it if necessary.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;Direct access to the Event Subroutines Code for maintenance without interfering with the Form/Report Design&lt;/li&gt;&lt;li&gt;&lt;p&gt;It eliminates the need for interacting with the Form/Report Design View for Code maintenance every time, resulting in faster Project completion.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;  
  &lt;/li&gt;&lt;li&gt;&lt;p&gt;Create another Class Module, change its name to &lt;b&gt;Data_TxtBox&lt;/b&gt;. Copy the following VBA Code, paste it into the Data_TxtBox Class Module, and save it:&lt;/p&gt;
&lt;h3&gt;The &lt;i&gt;Data_TxtBox&lt;/i&gt; TextBox Class Module Code.&lt;/h3&gt; 
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents mtxt As TextBox
Private mfrm As Form

Dim msgtxt As String
Const cr = vbCr

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;With Reusable Code
&#39;------------------------------------------------------
&#39;Quick Data Entry Screen
&#39;Author:  a.p.r. pillai
&#39;Date  :  10/05/2024
&#39;Remarks: with Ready-made Data Entry Events Handlers
&#39;       : in the Wrapper TextBox Class Module
&#39;       : Suitable for Columnar, Tabular or DataSheet Form
&#39;       : made for Table/Query.
&#39;Rights:  All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

Public Property Get m_Frm() As Form
    Set m_Frm = mfrm
End Property

Public Property Set m_Frm(ByRef vmFrm As Form)
    Set mfrm = vmFrm
End Property

Public Property Get m_txt() As TextBox
    Set m_txt = mtxt
End Property

Public Property Set m_txt(ByRef vmtxt As TextBox)
    Set mtxt = vmtxt
End Property

Private Sub mtxt_Dirty(Cancel As Integer)
&#39;Global area of Subroutine

&#39;If new Record Data Entry then ignore Dirty Event
If mfrm.NewRecord Then
 Exit Sub
End If

&#39;VBA Code Runs for all Fields in the Detail Section

msgtxt = &quot;Editing Field [&quot; &amp;amp; UCase(mtxt.Name) &amp;amp; &quot;]?: &quot; _
&amp;amp; mtxt.Value &amp;amp; cr &amp;amp; cr &amp;amp; &quot;Allow the Change?&quot;

    If MsgBox(msgtxt, vbYesNo + vbQuestion, _
    mtxt.Name &amp;amp; &quot;_BeforeUpdate()&quot;) = vbNo Then
        Cancel = True
        mtxt.Undo
    End If

&#39;Field Specific Code for validation checks
&#39;----------------------------------------------
&#39;If Field Specific Event handling is required
&#39;then make a Copy of the Data_TxtBox Class with
&#39;a New Name and use with Fieldname based Event Procedure.
&#39;----------------------------------------------
   Select Case mtxt.Name
     Case &quot;ID&quot;
        &#39; Code
 
     Case &quot;Company&quot;
        &#39; Code
        
     Case &quot;Last Name&quot;
        &#39; Code
        
     Case &quot;First Name&quot;
        &#39; Code
 

   End Select

End Sub


Private Sub mtxt_BeforeUpdate(Cancel As Integer)
&#39;Global area of Subroutine
&#39;VBA Code Runs for all Fields in the Detail Section

&#39;If new Record Data Entry then ignore BeforeUpdate Event
If mfrm.NewRecord Then
 Exit Sub
End If


msgtxt = mtxt.Name &amp;amp; &quot; Old Value: &quot; &amp;amp; mtxt.OldValue &amp;amp; _
cr &amp;amp; cr &amp;amp; &quot;Update to ?: &quot; &amp;amp; mtxt.Value

    If MsgBox(msgtxt, vbYesNo + vbQuestion, mtxt.Name &amp;amp; &quot;_BeforeUpdate()&quot;) = vbNo Then
        Cancel = True
        mtxt.Undo
    End If

&#39;----------------------------------------------
&#39;If Field Specific Event handling is required
&#39;then make a Copy of the Data_TxtBox Class with
&#39;a New Name and use it.
&#39;----------------------------------------------
&#39;Copy and Paste Cls_EventSub_Template Code here

   Select Case mtxt.Name &#39;Replace with
     Case &quot;ID&quot;
        &#39; Code
 
     Case &quot;Company&quot;
        &#39; Code
        
     Case &quot;Last Name&quot;
        &#39; Code
        
     Case &quot;First Name&quot;
        &#39; Code

 
   End Select


End Sub

&lt;/pre&gt;
  &lt;p&gt;The TextBox Class has the &lt;i&gt;mtxt_Dirty()&lt;/i&gt;&amp;nbsp;Event Procedure that monitors the active TextBox for data-change attempts. When a key press is detected in a Field, a message will appear asking whether the user wants to change the data. If the response is positive, then it allows changes to the field.&lt;br /&gt;&lt;br /&gt;When the changed data is about to be saved, the&amp;nbsp;&lt;i&gt;mtxt_BeforeUpdate()&lt;/i&gt;&amp;nbsp;Event fires, and the system prompts to reconfirm the changes. If the response is negative, then the changes are reversed, and the original value is restored.&lt;/p&gt;
  &lt;p&gt;The Dirty() and BeforeUpdate() Event Subroutines protect the data of all the Fields/TextBoxes in the Form&#39;s Detail Section.&lt;/p&gt;
    &lt;p&gt;Within the Select Case . . . End Select structure, some Field Names from the Employees Form are shown below. If we need to write VBA Code with specific requirements for Field(s), then we need to write them in this Structure under each Field Name. We will address this aspect and the appropriate steps to take later. For now, it is presented for demonstration purposes only.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Create another Class Module Named&amp;nbsp;Data_CboBox&amp;nbsp;for the ComboBox Controls on the Form. Copy the following VBA Code, paste it into the Data_CboBox Class Module, and save the Module.&lt;/p&gt;
&lt;h4&gt;The &lt;i&gt;Data_CboBox&lt;/i&gt; ComboBox Class Module Code.&lt;/h4&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents mCbo As ComboBox
Private mfrm As Form
Dim msgtxt As String
Const cr = vbCr

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;With Reusable Code
&#39;------------------------------------------------------
&#39;Quick Data Entry Screen
&#39;Author:  a.p.r. pillai
&#39;Date  :  10/05/2024
&#39;Remarks: with Ready-made Data Entry Events Handler
&#39;       : in the Wrapper TextBox Class Module
&#39;       : Suitable for Columnar, Tabular or DataSheet Form
&#39;       : made for Table/Query.
&#39;Rights:  All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

Public Property Get m_Frm() As Form
    Set m_Frm = mfrm
End Property

Public Property Set m_Frm(ByRef vmFrm As Form)
    Set mfrm = vmFrm
End Property

Public Property Get m_Cbo() As ComboBox
    Set m_Cbo = mCbo
End Property

Public Property Set m_Cbo(ByRef vmCbo As ComboBox)
    Set mCbo = vmCbo
End Property

Private Sub mCbo_Dirty(Cancel As Integer)
&#39;Global area of Subroutine

&#39;If new Record Data Entry then ignore Dirty Event
If mfrm.NewRecord Then
 Exit Sub
End If

&#39;VBA Code Runs for all Fields in the Detail Section

msgtxt = &quot;Editing ComboBox [&quot; &amp;amp; UCase(mCbo.Name) &amp;amp; &quot;]?: &quot; _
&amp;amp; mCbo.Value &amp;amp; cr &amp;amp; cr &amp;amp; &quot;Allow the Change?&quot;

    If MsgBox(msgtxt, vbYesNo + vbQuestion, mCbo.Name &amp;amp; &quot;_BeforeUpdate()&quot;) = vbNo Then
        Cancel = True
        mCbo.Undo
    End If

Select Case mCbo.Name
    Case &quot;Combo1&quot;
        &#39;Code
        
    Case &quot;Combo2&quot;
        &#39;Code
        
End Select
    
End Sub

Private Sub mCbo_BeforeUpdate(Cancel As Integer)
&#39;Global area of Subroutine
&#39;VBA Code Runs for all Fields in the Detail Section

&#39;If new Record Data Entry then ignore BeforeUpdate Event
If mfrm.NewRecord Then
 Exit Sub
End If


msgtxt = mCbo.Name &amp;amp; &quot; Old Value: &quot; &amp;amp; mCbo.OldValue &amp;amp; _
cr &amp;amp; cr &amp;amp; &quot;Update to ?: &quot; &amp;amp; mCbo.Value

    If MsgBox(msgtxt, vbYesNo + vbQuestion, mCbo.Name &amp;amp; &quot;_BeforeUpdate()&quot;) = vbNo Then
        Cancel = True
        mCbo.Undo
    End If


Select Case mCbo.Name
    Case &quot;Combo1&quot;
        &#39;Code
        
    Case &quot;Combo2&quot;
        &#39;Code
        
End Select
    
End Sub
&lt;/pre&gt;

&lt;p&gt;The ComboBox Event Procedure is the same as the TextBox Code.&lt;/p&gt;

&lt;p&gt;The active Field background will be highlighted yellow when the Field receives focus.&lt;br /&gt;&lt;br /&gt;Save all the Modules and compile them from the VBA Window to ensure that everything is ok.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Test Running the Form.&lt;/h3&gt;&lt;/li&gt;&lt;li&gt;Open the Form in Normal View.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Click on a field and press any key to begin editing. A confirmation message will appear, asking whether you want to proceed with editing the field. The OnDirty event is enabled on all TextBoxes and ComboBoxes to safeguard against accidental data changes.&lt;/p&gt;&lt;p&gt;If your response is Yes&lt;b&gt;,&lt;/b&gt; then you are allowed to edit the Field. Type one or two characters at the end of the existing text in the field, then press the Enter Key.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;While saving the changes, the BeforeUpdate() Event will fire, and a message will appear again asking you to reconfirm the update action. If your response is negative, then changes are reversed.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Data Entry, Editing, and Viewing.&lt;/h3&gt;&lt;p&gt;The Class Modules are designed to work with any Form created for Data Entry, Editing, or Data View.&amp;nbsp;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p data-end=&quot;332&quot; data-start=&quot;70&quot;&gt;The form can be created either with the Form Wizard or manually in Columnar, Tabular, or Datasheet layout, using a Table or Query as the data source. You may choose to include specific fields or all fields from the source table or query.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-end=&quot;332&quot; data-start=&quot;70&quot;&gt;After creating a Form, copy the VBA Code from the Form1 Module, paste it into the new Form Module, save the Form, and open it in normal view.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;After these two steps, the Form is ready with all supporting Programs, and the data is fully protected from changes. How much time does it take for the above two steps?&lt;/p&gt;&lt;p&gt;The Program will monitor the Fields in Text Boxes and ComboBoxes (if present) on the Form.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;331&quot; data-is-last-node=&quot;&quot; data-is-only-node=&quot;&quot; data-start=&quot;195&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p data-end=&quot;193&quot; data-start=&quot;46&quot;&gt;The Dirty() and BeforeUpdate() event procedures are applied to all TextBox and ComboBox controls (if present) on the form.&lt;/p&gt;&lt;p&gt;When the Form is in Data Entry Mode (for a new Record), the OnDirty() and BeforeUpdate() Events are disabled.&lt;/p&gt;&lt;h3&gt;Data Validation Checks.&lt;/h3&gt;
  
&lt;p&gt;Each Field&#39;s validation requirement is different. The Validation checks can be performed in two different ways.&amp;nbsp;&lt;/p&gt;&lt;p&gt;1. Through the Validation Rule and Validation Text Properties (recommended) of the Table or through these Properties of the TextBoxes in the Form.&lt;/p&gt;&lt;p&gt;2. Through VBA Code using Event Procedures.&lt;/p&gt;&lt;p&gt;In this Project, the recommended procedure is the Validation Rule option and the Validation Text Properties of the Field in Table Design View, or the same Properties of the TextBox Field on the Form. If it is already written in the Table Field Properties, then do not repeat it in the Form Field.&lt;/p&gt;&lt;p&gt;Assign an Error Message in the&amp;nbsp;Validation Text Property to display the message when the entered data is invalid. For example, the Date of Birth entered into the Date Field is invalid if it is greater than Today, and the message Text can be &#39;Future Date Invalid&#39;.&lt;/p&gt;&lt;p&gt;The Validation Rule Property accepts simple expressions to evaluate the entered data.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Example: The Last Name Field length is 15 characters or less, and the validation expression is:&lt;/p&gt;&lt;p&gt;&lt;i&gt;Validation Rule&lt;/i&gt;: Is Null OR Len([Last Name]) &amp;lt;= 15&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;i&gt;Validation Text&lt;/i&gt;: Last Name maximum 15 characters only.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The Validation Text message will appear when the Last Name field value exceeds 15 characters.&lt;/p&gt;&lt;p&gt;If certain data fields require validation, you can assign validation rules and messages either at the table field level or in the corresponding TextBox control on the form—but not necessarily in both. For more guidance on writing effective validation expressions, refer to &lt;a href=&quot;http://allenbrowne.com/ValidationRule.html&quot; target=&quot;_blank&quot;&gt;Allen Browne’s Microsoft Access Tips&lt;/a&gt; page.&lt;/p&gt;&lt;p data-end=&quot;819&quot; data-start=&quot;447&quot;&gt;If the validation requirements are more complex, you can handle them with VBA. Start by copying the three Class Modules mentioned above. Next, rename them so you can easily identify which form they belong to. Finally, write the VBA event procedures under the relevant field names, just as we did in the earlier tutorial examples.&lt;/p&gt;&lt;p data-end=&quot;819&quot; data-start=&quot;447&quot;&gt;An Access Application will have several Forms. Each Form&#39;s Controls Event Procedures can be streamlined into Event Procedure Codes in Standalone Class Modules. In such situations, identifying which Class Module belongs to which Form is difficult. To overcome this situation, we decided to add a Form name prefix to the Class Module Name.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For example, With Customized VBA Code for the Employees Form.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Emp_ObjInit&lt;/li&gt;&lt;li&gt;Emp_TxtBox&lt;/li&gt;&lt;li&gt;Emp_CboBox&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Then change the Class Module Name declared in the global area of the Form Module and in the Emp_ObjInit Module as shown in the following examples:&lt;/p&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;The Form Module Code Change is highlighted.&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8oNnZHZRDC8f0TE1TImIUg3J-i8Nl5-Z6Jy4GFdrVov5VFVVovbZg0Vht2d0NTfSYQYEKaGv6X7HdJvfGtv5XR9unOLiy-ZeQJdrhN2z5X9r4MWdbaHvBFi19DZBnEFAu8Az7uBzW4mJko378YhW3IuY8ThWKTWowGoczgTQSuj92RvBpF-XCipDHGYWs/s692/Emp_ObjInit.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Emp_ObjInit&quot; border=&quot;0&quot; data-original-height=&quot;409&quot; data-original-width=&quot;692&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8oNnZHZRDC8f0TE1TImIUg3J-i8Nl5-Z6Jy4GFdrVov5VFVVovbZg0Vht2d0NTfSYQYEKaGv6X7HdJvfGtv5XR9unOLiy-ZeQJdrhN2z5X9r4MWdbaHvBFi19DZBnEFAu8Az7uBzW4mJko378YhW3IuY8ThWKTWowGoczgTQSuj92RvBpF-XCipDHGYWs/s320/Emp_ObjInit.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;

&lt;h4&gt;The Wrapper Class Declarations in the &lt;i&gt;Emp_ObjInit&lt;/i&gt; Class Module.&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVHJ8jPyOaXz0EKcin1uhSRqiS_5Oe54FKYhZb4UIHi4bUv5655DUw8h_DecL5hhw8q06w_rQXUUZ2_p-_BXKCn6y9WwYb9LDGv97KnasRetnQTlvbXGcSpJRJtLmtZIQFVrJxyndYzSIcJdhh5YT7fnLibkZGQL-ws956JlsPefljmoTcU-wMCAuMHn2M/s650/Emp_Classes.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;387&quot; data-original-width=&quot;650&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVHJ8jPyOaXz0EKcin1uhSRqiS_5Oe54FKYhZb4UIHi4bUv5655DUw8h_DecL5hhw8q06w_rQXUUZ2_p-_BXKCn6y9WwYb9LDGv97KnasRetnQTlvbXGcSpJRJtLmtZIQFVrJxyndYzSIcJdhh5YT7fnLibkZGQL-ws956JlsPefljmoTcU-wMCAuMHn2M/s320/Emp_Classes.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p data-end=&quot;480&quot; data-start=&quot;89&quot;&gt;Keeping this requirement in mind, I devised a method to generate an event subroutine template using the data field names saved from the Form text boxes. This template can then be copied into a specific event subroutine, allowing you to write the code directly below the required fields. Any unwanted field references can simply be removed from the subroutine.&lt;/p&gt;
&lt;p data-end=&quot;632&quot; data-is-last-node=&quot;&quot; data-is-only-node=&quot;&quot; data-start=&quot;482&quot;&gt;&lt;/p&gt;&lt;p&gt;The Sample Subroutine Code generated from the Field Names collected from the Form and saved in the EventSubFields.txt File is given below for reference:&lt;/p&gt;
&lt;pre&gt;Private Sub txt_BeforeUpdate(Cancel As Integer)
   Select Case txt.Name
     Case &quot;ID&quot;
        &#39; Code
 
     Case &quot;Company&quot;
        &#39; Code
 
     Case &quot;Last Name&quot;
        &#39; Code
 
     Case &quot;First Name&quot;
        &#39; Code
 
     Case &quot;E-mail Address&quot;
        &#39; Code
 
     Case &quot;Job Title&quot;
        &#39; Code
 
     Case &quot;Address&quot;
        &#39; Code
 
     Case &quot;City&quot;
        &#39; Code
 
     Case &quot;State/Province&quot;
        &#39; Code
 
     Case &quot;ZIP/Postal Code&quot;
        &#39; Code
 
     Case &quot;Country/Region&quot;
        &#39; Code
 
   End Select
End Sub

&lt;/pre&gt;

&lt;p&gt;The above BeforeUpdate() Event Procedure Code Template is generated through the following procedure:&amp;nbsp;&lt;/p&gt;&lt;p data-end=&quot;398&quot; data-start=&quot;84&quot;&gt;When the form is open, the &lt;span data-end=&quot;130&quot; data-start=&quot;113&quot;&gt;Class_ObjInit&lt;/span&gt; class module’s &lt;span data-end=&quot;162&quot; data-start=&quot;146&quot;&gt;Class_Init()&lt;/span&gt; subroutine collects the field names from the Form and saves them in the &lt;span data-end=&quot;277&quot; data-start=&quot;255&quot;&gt;&lt;i&gt;EventSubFields.txt&lt;/i&gt;&lt;/span&gt; file, in the database folder. (Refer to the red-highlighted lines of code in the &lt;span data-end=&quot;383&quot; data-start=&quot;367&quot;&gt;Class_Init()&lt;/span&gt; subroutine.)&lt;/p&gt;
&lt;p data-end=&quot;682&quot; data-start=&quot;400&quot;&gt;Next, run the public function &lt;span data-end=&quot;453&quot; data-start=&quot;430&quot;&gt;CreateEventTemplate&lt;/span&gt; (from &lt;span data-end=&quot;471&quot; data-start=&quot;460&quot;&gt;Module1&lt;/span&gt;) in the Debug/Immediate window. This function will generate the event subroutine template in the class module &lt;span data-end=&quot;606&quot; data-start=&quot;582&quot;&gt;ClsEventSub_Template&lt;/span&gt;, using the field names stored earlier in the &lt;span data-end=&quot;674&quot; data-start=&quot;652&quot;&gt;&lt;i&gt;EventSubFields.txt&lt;/i&gt;&lt;/span&gt; file.&lt;/p&gt;
&lt;p data-end=&quot;827&quot; data-is-last-node=&quot;&quot; data-is-only-node=&quot;&quot; data-start=&quot;691&quot;&gt;&lt;/p&gt;&lt;p&gt;Procedure to create the &lt;i&gt;ClsEventSub_Template&lt;/i&gt; Class Module Code.&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Open the required Form for a few seconds, then close it.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Open the Immediate Window, type the function name CreateEventTemplate&lt;b&gt;,&lt;/b&gt; and press the Enter Key.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;The ClsEventSub_Template Class Module will have the Event Subroutine Template with all the Fields collected from the Form.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Highlight the entire Code, then copy and paste it into the TextBox&lt;b&gt; &lt;/b&gt;Wrapper Class&amp;nbsp;Module Emp_TxtBox, change the Event Subroutine Name (if necessary to match the Object declaration and the Subroutine Name), and write the Event Subroutine Code under the Field Name.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The unwanted field names may be removed from the Copied Subroutine.&lt;/p&gt;&lt;p&gt;If you follow the above steps for another Form, the ClsEventSub_Template will contain the Field Names from the last Form opened.&lt;/p&gt;
&lt;h3&gt;Demo Database Download&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/05/OneClass_DifferentForms.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1fu9rUBX2N58kD6AdsJ2kx2WwTkQejuCX/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioFf-79SroXZ4JkiqgZYv196vvwuIDU6wLEconUKqF-8uKB4XfA4P2yshkCX2o16u08fw9nN8LkTe8XvDgBDDTepmbEqtmBreKye0SKYfz10iaUmM1loO3uX7sYhQvQctArB6ZjjzRO1Rw/s320/zip.gif&quot; width=&quot;22&quot; /&gt;OneClass_DifferentForms.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/05/OneClass_DifferentForms.zip--&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/805125377438457779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/805125377438457779'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/805125377438457779'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html' title='Classes For All Data Entry Editing Forms'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjstJCZ_ir4qX_nWqKWAWriVFpPeN9BhPUZ88oYci54kW6VaFHVMx0nDyh9m3qV34RlkZr56cMS-28jZznVIrCGk8IXhyk91jSqX0PLVrepK7FwUa-bXiQvbXwiO-NOtd7YkPqCb8pizZbRO2Hs1G3tx9HaaLt88s7z-m_IweHa2dwrrxHOj3Df0BfB8u2Y/s72-c/UniversalForm.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-2964035937363816164</id><published>2024-04-29T21:43:00.016+05:30</published><updated>2026-07-13T15:16:24.706+05:30</updated><title type='text'>Table Query Records in Collection Object</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;Class Module and Collection Object.&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;h3 data-end=&quot;155&quot; data-start=&quot;117&quot;&gt;Steps to Create a Data View Form&lt;/h3&gt;
&lt;ol data-end=&quot;1770&quot; data-start=&quot;157&quot;&gt;
&lt;li data-end=&quot;306&quot; data-start=&quot;157&quot;&gt;
&lt;p data-end=&quot;181&quot; data-start=&quot;160&quot;&gt;&lt;strong data-end=&quot;179&quot; data-start=&quot;160&quot;&gt;Create the Form&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;306&quot; data-start=&quot;185&quot;&gt;
&lt;li data-end=&quot;306&quot; data-start=&quot;185&quot;&gt;
&lt;p data-end=&quot;306&quot; data-start=&quot;187&quot;&gt;Use the built-in &lt;strong data-end=&quot;226&quot; data-start=&quot;204&quot;&gt;Access &lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_blank&quot;&gt;Form Wizard&lt;/a&gt;&lt;/strong&gt; to create a Data View Form with the required fields from your table or query.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
 &lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;

&lt;/li&gt;
&lt;li data-end=&quot;722&quot; data-start=&quot;308&quot;&gt;
&lt;p data-end=&quot;350&quot; data-start=&quot;311&quot;&gt;&lt;strong data-end=&quot;348&quot; data-start=&quot;311&quot;&gt;Add a ComboBox in the Form Header&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;722&quot; data-start=&quot;354&quot;&gt;
&lt;li data-end=&quot;414&quot; data-start=&quot;354&quot;&gt;
&lt;p data-end=&quot;414&quot; data-start=&quot;356&quot;&gt;Insert a ComboBox in the &lt;span data-end=&quot;391&quot; data-start=&quot;381&quot;&gt;Header&lt;/span&gt; section of the form.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;544&quot; data-start=&quot;418&quot;&gt;
&lt;p data-end=&quot;544&quot; data-start=&quot;420&quot;&gt;Set its Row Source to a field with unique values (for example, &lt;span data-end=&quot;498&quot; data-start=&quot;483&quot;&gt;[Last Name]&lt;/span&gt;) from the form’s record source table/query.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;722&quot; data-start=&quot;548&quot;&gt;
&lt;p data-end=&quot;722&quot; data-start=&quot;550&quot;&gt;The ComboBox will serve as a record key, allowing you to randomly retrieve the selected record from the &lt;strong data-end=&quot;675&quot; data-start=&quot;654&quot;&gt;&lt;a href=&quot;https://www.msaccesstips.com/2018/12/ms-access-and-collection-object-basics.html&quot; target=&quot;_blank&quot;&gt;Collection Object&lt;/a&gt;&lt;/strong&gt; and display its values in unbound TextBoxes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1319&quot; data-start=&quot;724&quot;&gt;
&lt;p data-end=&quot;774&quot; data-start=&quot;727&quot;&gt;&lt;strong data-end=&quot;772&quot; data-start=&quot;727&quot;&gt;Insert a Hidden TextBox for the Key Field&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;1319&quot; data-start=&quot;778&quot;&gt;
&lt;li data-end=&quot;858&quot; data-start=&quot;778&quot;&gt;
&lt;p data-end=&quot;858&quot; data-start=&quot;780&quot;&gt;Add an unbound TextBox in the &lt;span data-end=&quot;820&quot; data-start=&quot;810&quot;&gt;Header&lt;/span&gt; of the form and name it &lt;code data-end=&quot;855&quot; data-start=&quot;845&quot;&gt;KeyField&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;906&quot; data-start=&quot;862&quot;&gt;
&lt;p data-end=&quot;906&quot; data-start=&quot;864&quot;&gt;Set its &lt;span data-end=&quot;883&quot; data-start=&quot;872&quot;&gt;Visible&lt;/span&gt; &lt;a href=&quot;https://www.msaccesstips.com/2009/11/creating-using-form-custom-property.html&quot; target=&quot;_blank&quot;&gt;property&lt;/a&gt; to &lt;code data-end=&quot;903&quot; data-start=&quot;896&quot;&gt;False&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1003&quot; data-start=&quot;910&quot;&gt;
&lt;p data-end=&quot;962&quot; data-start=&quot;912&quot;&gt;In its &lt;span data-end=&quot;937&quot; data-start=&quot;919&quot;&gt;Control Source&lt;/span&gt;, enter the expression:&lt;/p&gt;
&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;1003&quot; data-start=&quot;968&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre!&quot;&gt;=&lt;span class=&quot;hljs-string&quot;&gt;&quot;[Last Name]&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1214&quot; data-start=&quot;1007&quot;&gt;
&lt;p data-end=&quot;1214&quot; data-start=&quot;1009&quot;&gt;If &lt;span data-end=&quot;1027&quot; data-start=&quot;1012&quot;&gt;[Last Name]&lt;/span&gt; alone does not provide unique values, create a &lt;span data-end=&quot;1084&quot; data-start=&quot;1075&quot;&gt;query&lt;/span&gt; that concatenates &lt;span data-end=&quot;1117&quot; data-start=&quot;1103&quot;&gt;First Name&lt;/span&gt; and &lt;span data-end=&quot;1135&quot; data-start=&quot;1122&quot;&gt;Last Name&lt;/span&gt; into a single expression (e.g., &lt;code data-end=&quot;1210&quot; data-start=&quot;1168&quot;&gt;FullName: [FirstName] &amp;amp; &quot; &quot; &amp;amp; [LastName]&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1319&quot; data-start=&quot;1218&quot;&gt;
&lt;p data-end=&quot;1319&quot; data-start=&quot;1220&quot;&gt;Use this query as the form’s record source and populate the ComboBox with this new field instead.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1501&quot; data-start=&quot;1321&quot;&gt;
&lt;p data-end=&quot;1362&quot; data-start=&quot;1324&quot;&gt;&lt;strong data-end=&quot;1360&quot; data-start=&quot;1324&quot;&gt;Add a Close Button in the Footer&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;1501&quot; data-start=&quot;1366&quot;&gt;
&lt;li data-end=&quot;1424&quot; data-start=&quot;1366&quot;&gt;
&lt;p data-end=&quot;1424&quot; data-start=&quot;1368&quot;&gt;Insert a Command Button in the Form&amp;nbsp;&lt;span data-end=&quot;1409&quot; data-start=&quot;1399&quot;&gt;Footer.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1451&quot; data-start=&quot;1428&quot;&gt;
&lt;p data-end=&quot;1451&quot; data-start=&quot;1430&quot;&gt;Name it &lt;code data-end=&quot;1448&quot; data-start=&quot;1438&quot;&gt;cmdClose&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1501&quot; data-start=&quot;1455&quot;&gt;
&lt;p data-end=&quot;1501&quot; data-start=&quot;1457&quot;&gt;Set its &lt;span data-end=&quot;1476&quot; data-start=&quot;1465&quot;&gt;Caption&lt;/span&gt; property to &lt;span data-end=&quot;1498&quot; data-start=&quot;1489&quot;&gt;Close&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1678&quot; data-start=&quot;1503&quot;&gt;
&lt;p data-end=&quot;1525&quot; data-start=&quot;1506&quot;&gt;&lt;strong data-end=&quot;1523&quot; data-start=&quot;1506&quot;&gt;Copy VBA Code&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;1678&quot; data-start=&quot;1529&quot;&gt;
&lt;li data-end=&quot;1582&quot; data-start=&quot;1529&quot;&gt;
&lt;p data-end=&quot;1582&quot; data-start=&quot;1531&quot;&gt;Open the &lt;span data-end=&quot;1556&quot; data-start=&quot;1540&quot;&gt;Form1 Module&lt;/span&gt; from the demo database.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1678&quot; data-start=&quot;1586&quot;&gt;
&lt;p data-end=&quot;1678&quot; data-start=&quot;1588&quot;&gt;Copy its VBA code and paste it into the module of your newly created &lt;span data-end=&quot;1675&quot; data-start=&quot;1657&quot;&gt;Employees Form&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1770&quot; data-start=&quot;1680&quot;&gt;
&lt;p data-end=&quot;1703&quot; data-start=&quot;1683&quot;&gt;&lt;strong data-end=&quot;1701&quot; data-start=&quot;1683&quot;&gt;Save and Close&lt;/strong&gt;&lt;/p&gt;
&lt;ul data-end=&quot;1770&quot; data-start=&quot;1707&quot;&gt;
&lt;li data-end=&quot;1725&quot; data-start=&quot;1707&quot;&gt;
&lt;p data-end=&quot;1725&quot; data-start=&quot;1709&quot;&gt;Save the form.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1770&quot; data-start=&quot;1729&quot;&gt;
&lt;p data-end=&quot;1770&quot; data-start=&quot;1731&quot;&gt;Close the form to complete the setup.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3T_GAUQJDc5wsAZEDmEVToJsSGEufub4hSr6wnLZR8hvc4N6fFUCZpDY5F8-KwjFKWVCWsR4Oupk6e8yWr45StEMB82kAin4LAQWlNZaPJUR1PHX5j06HNpH7odPGX0REB-_e4pdKiDg8sI0gd8Gx-nupGZOOEbb9T6FT60Wftg0nuozzZALsTMaZcEMy/s1124/CollDataView.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;804&quot; data-original-width=&quot;1124&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3T_GAUQJDc5wsAZEDmEVToJsSGEufub4hSr6wnLZR8hvc4N6fFUCZpDY5F8-KwjFKWVCWsR4Oupk6e8yWr45StEMB82kAin4LAQWlNZaPJUR1PHX5j06HNpH7odPGX0REB-_e4pdKiDg8sI0gd8Gx-nupGZOOEbb9T6FT60Wftg0nuozzZALsTMaZcEMy/s320/CollDataView.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p data-end=&quot;332&quot; data-start=&quot;90&quot;&gt;The &lt;span data-end=&quot;112&quot; data-start=&quot;94&quot;&gt;Data View Form&lt;/span&gt; runs on the ready-made VBA code in the &lt;span data-end=&quot;178&quot; data-start=&quot;152&quot;&gt;DATA_View Class Module&lt;/span&gt;. This &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html&quot; target=&quot;_blank&quot;&gt;Class Module&lt;/a&gt; is fully reusable—any form created using the same method with any Table or Query as the source data can use it without modification.&lt;/p&gt;
&lt;p data-end=&quot;679&quot; data-start=&quot;334&quot;&gt;Once the form is opened in &lt;span data-end=&quot;376&quot; data-start=&quot;361&quot;&gt;Normal View&lt;/span&gt;, simply select an item from the ComboBox. The record with the matching key value is instantly retrieved from the &lt;span data-end=&quot;511&quot; data-start=&quot;490&quot;&gt;Collection Object&lt;/span&gt; and displayed in the unbound TextBoxes. Since this form is designed strictly for &lt;span data-end=&quot;609&quot; data-start=&quot;593&quot;&gt;data viewing&lt;/span&gt;, all TextBoxes are locked to prevent editing.&lt;/p&gt;
&lt;p data-end=&quot;741&quot; data-start=&quot;681&quot;&gt;Creating this form is extremely quick and straightforward:&lt;/p&gt;
&lt;ul data-end=&quot;1055&quot; data-start=&quot;742&quot;&gt;
&lt;li data-end=&quot;798&quot; data-start=&quot;742&quot;&gt;
&lt;p data-end=&quot;798&quot; data-start=&quot;744&quot;&gt;You don’t need to write any code in the Form Module.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;880&quot; data-start=&quot;799&quot;&gt;
&lt;p data-end=&quot;880&quot; data-start=&quot;801&quot;&gt;The &lt;span data-end=&quot;820&quot; data-start=&quot;805&quot;&gt;Form Wizard&lt;/span&gt; automatically places and arranges the TextBoxes properly.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1055&quot; data-start=&quot;881&quot;&gt;
&lt;p data-end=&quot;1055&quot; data-start=&quot;883&quot;&gt;With just the simple steps outlined earlier, the entire setup can be completed in about &lt;span data-end=&quot;987&quot; data-start=&quot;971&quot;&gt;five minutes&lt;/span&gt;—and the form is ready to run with the &lt;span data-end=&quot;1052&quot; data-start=&quot;1026&quot;&gt;DATA_View Class Module&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The Ready-made Reusable Form Module Code:&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private Cls As New DATA_View

Private Sub Form_Load()
Set Cls.o_frm = Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Set Cls = Nothing
End Sub

&lt;/pre&gt;

&lt;p&gt;
The DATA_View Class Object is instantiated in the Employees Form Module, and the current Form Object is assigned to the o_Frm() Property of the DATA_View Object.
&lt;/p&gt;&lt;h3&gt;The Ready-made Reusable &lt;i&gt;DATA_View&lt;/i&gt; Class Module Code.&lt;/h3&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;Option Compare Database
Option Explicit

Private WithEvents cbo As ComboBox
Private WithEvents cmd As CommandButton
Private oFrm As Form
Private frmSec As Section

Private Coll As New Collection
Private txtBox() As String
Private strTable As String

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;With Reusable Code
&#39;------------------------------------------------------
&#39;Quick Data View Screen
&#39;Saving Table/Query Records in Collection Object
&#39;Author:  a.p.r. pillai
&#39;Date  :  26/04/2024
&#39;Remarks: Keep Recordset in Collectuon Object
&#39;       : and Retrieve specific record using Key
&#39;Rights:  All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

Public Property Get o_frm() As Form
    Set o_frm = oFrm
End Property

Public Property Set o_frm(ByRef vfrm As Form)
    Set oFrm = vfrm
    
    Set frmSec = oFrm.Section(acDetail)
    Call Class_Init
End Property

Private Sub Class_Init()
Dim db As Database
Dim rst As Recordset
Dim flds As Integer
Dim ctl As Control
Dim k As Integer
Dim Rec() As Variant, strKey As String
Dim vKeyName As String

strTable = oFrm.RecordSource

Set cmd = oFrm.cmdClose
    cmd.OnClick = &quot;[Event Procedure]&quot;
    
Set cbo = oFrm.cboName
cbo.OnClick = &quot;[Event Procedure]&quot;

&#39;Make the Data Field TextBoxes Unbound
&#39;Save the Field Names on the Form into the txtBox() Array
flds = 0
For Each ctl In frmSec.Controls
    Select Case TypeName(ctl)
        Case &quot;TextBox&quot;
           ctl.ControlSource = &quot;&quot;
           flds = flds + 1
           ReDim Preserve txtBox(1 To flds) As String
           
&#39;Get the selected Field Names from the
&#39;TextBoxes on the Form&#39;s Detail Section
           txtBox(flds) = ctl.Name
           ctl.Locked = True
    End Select
Next
&#39;Set ComboBox Default Value
&#39;Change Form Properties
oFrm.cboName.DefaultValue = &quot;=[cboName].[column](0,0)&quot;
oFrm.RecordSelectors = False
oFrm.NavigationButtons = False
oFrm.ScrollBars = 0

&#39;Load the Table/Query Records into Collection Object
ReDim Rec(1 To flds) As Variant

Set db = CurrentDb
Set rst = db.OpenRecordset(strTable, dbOpenSnapshot)

&#39;------------------------------
vKeyName = oFrm!KeyField &#39;Collection Key Field Value
&#39;------------------------------

Do While Not rst.EOF
    For k = 1 To flds
       Rec(k) = rst.Fields(txtBox(k)).Value
    Next

&#39;Key Field Name in the Form Fields
&#39;=========================================
   strKey = rst.Fields(vKeyName).Value
&#39;=========================================
    Coll.Add Rec, strKey &#39;Save Rec() Array
    rst.MoveNext
Loop

Set rst = Nothing
Set db = Nothing

End Sub

Private Sub cbo_Click()
Dim strKy As String, Record As Variant
Dim j As Long, L As Long, H As Long

&#39;Get Selected Collection Key from ComboBox
strKy = cbo.Value
 
&#39;Retrieve the record using Key from Collection
&#39;and load into Variant Array Record
  
  Record = Coll(strKy)
  
  L = LBound(Record)
  H = UBound(Record)
  
&#39;Add Field Values into corresponding Text Boxes
  For j = L To H
    oFrm(txtBox(j)) = Record(j) &#39;Display in Unbound TextBox
  Next
  oFrm.Requery
  
End Sub

Private Sub cmd_Click()
    DoCmd.Close acForm, oFrm.Name
End Sub

Private Sub Class_Terminate()
Do While Coll.Count &amp;gt; 0
    Coll.Remove 1
Loop

End Sub
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP77rmI63Qir9B673wyOditISH4FhOnFE5B7yM9H_KF4AqwczvTqdqEMS3Qwt2-E92vosvW8VRyyKWc_y1UlcKjkUkMPpjtpOIGPouRFaPuHRMsLISEJbbdoR_5Bxlrba8uiOEebBr8P35rRMEwdtTB_wbrl1XCgu-VC0BB49Wwa10-6SNVoqpCPm5KHUP/s1133/CollDataView2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Records in Collection Object&quot; border=&quot;0&quot; data-original-height=&quot;869&quot; data-original-width=&quot;1133&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP77rmI63Qir9B673wyOditISH4FhOnFE5B7yM9H_KF4AqwczvTqdqEMS3Qwt2-E92vosvW8VRyyKWc_y1UlcKjkUkMPpjtpOIGPouRFaPuHRMsLISEJbbdoR_5Bxlrba8uiOEebBr8P35rRMEwdtTB_wbrl1XCgu-VC0BB49Wwa10-6SNVoqpCPm5KHUP/s320/CollDataView2.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Data_View VBA Code Segment-wise Review.&lt;/h3&gt;
&lt;p&gt;&lt;strong data-end=&quot;81&quot; data-start=&quot;72&quot;&gt;Note:&lt;/strong&gt; You can instantiate the single &lt;span data-end=&quot;139&quot; data-start=&quot;113&quot;&gt;DATA_View Class Module&lt;/span&gt; across multiple data display forms within the same project. If needed, you can even keep several of these forms open simultaneously and work with them independently. There’s no need to duplicate the Class Module or its VBA code—one module efficiently serves them all.&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Global Declarations.&lt;/h3&gt;&lt;p data-end=&quot;325&quot; data-start=&quot;82&quot;&gt;The &lt;span data-end=&quot;98&quot; data-start=&quot;86&quot;&gt;ComboBox&lt;/span&gt; and &lt;span data-end=&quot;121&quot; data-start=&quot;103&quot;&gt;&lt;a href=&quot;https://www.msaccesstips.com/2011/06/creating-animated-command-button-with.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt;&lt;/span&gt; controls are declared with the &lt;code data-end=&quot;165&quot; data-start=&quot;153&quot;&gt;WithEvents&lt;/code&gt; keyword to capture their events when triggered on the form. Following this, a &lt;span data-end=&quot;259&quot; data-start=&quot;244&quot;&gt;Form object&lt;/span&gt; (&lt;code data-end=&quot;267&quot; data-start=&quot;261&quot;&gt;oFrm&lt;/code&gt;) and a &lt;span data-end=&quot;298&quot; data-start=&quot;275&quot;&gt;Form Section&lt;/span&gt;&lt;strong data-end=&quot;298&quot; data-start=&quot;275&quot;&gt; &lt;/strong&gt;&lt;span data-end=&quot;298&quot; data-start=&quot;275&quot;&gt;object&lt;/span&gt; (&lt;code data-end=&quot;308&quot; data-start=&quot;300&quot;&gt;frmSec&lt;/code&gt;) are declared.&lt;/p&gt;&lt;p data-end=&quot;575&quot; data-start=&quot;327&quot;&gt;A &lt;span data-end=&quot;350&quot; data-start=&quot;329&quot;&gt;Collection object&lt;/span&gt; (&lt;code data-end=&quot;358&quot; data-start=&quot;352&quot;&gt;Coll&lt;/code&gt;) is then instantiated, along with the &lt;code data-end=&quot;407&quot; data-start=&quot;397&quot;&gt;txtBox()&lt;/code&gt; array (a string array with an unspecified number of elements) and the string variable &lt;code data-end=&quot;504&quot; data-start=&quot;494&quot;&gt;strTable&lt;/code&gt;, which stores the name of the form’s record source (table or query).&lt;/p&gt;&lt;p&gt;

&lt;/p&gt;&lt;p data-end=&quot;1016&quot; data-start=&quot;577&quot;&gt;The next section defines the &lt;span data-end=&quot;646&quot; data-start=&quot;606&quot;&gt;Form &lt;i&gt;Get&lt;/i&gt; and &lt;i&gt;Set&lt;/i&gt; property procedures&lt;/span&gt; used to capture the active form object passed from the &lt;code data-end=&quot;715&quot; data-start=&quot;702&quot;&gt;Form_Load()&lt;/code&gt; Event procedure. In the &lt;code data-end=&quot;767&quot; data-start=&quot;762&quot;&gt;Set&lt;/code&gt; property procedure, after assigning the &lt;code data-end=&quot;814&quot; data-start=&quot;808&quot;&gt;vFrm&lt;/code&gt; parameter (the received form object) to the &lt;code data-end=&quot;865&quot; data-start=&quot;859&quot;&gt;oFrm&lt;/code&gt; property, the Employees form’s &lt;span data-end=&quot;925&quot; data-start=&quot;897&quot;&gt;Detail section reference&lt;/span&gt; is assigned to the &lt;code data-end=&quot;953&quot; data-start=&quot;945&quot;&gt;frmSec&lt;/code&gt; object, and after that the&amp;nbsp;&lt;code data-end=&quot;992&quot; data-start=&quot;978&quot;&gt;Class_Init()&lt;/code&gt;&amp;nbsp;subroutine is called.&lt;/p&gt;&lt;p&gt;At the beginning of the Class_Init() Subroutine the statement: &lt;/p&gt;&lt;pre&gt;strTable = oFrm.RecordSource&lt;/pre&gt;&lt;p&gt;reads the Form&#39;s Record Source Property value and retains it in the strTable Variable. &lt;/p&gt;&lt;p&gt;The Command Button and Combobox Object &lt;a href=&quot;https://www.msaccesstips.com/2009/03/ms-access-and-reference-library.html&quot; target=&quot;_blank&quot;&gt;References&lt;/a&gt; from the Form are assigned to the cmd and cbo Objects, respectively, and are enabled with the click Events.&lt;/p&gt;
&lt;pre&gt;&#39;Make the Data Field TextBoxes Unbound
&#39;Save the Field Names on the Form into the txtBox() Array
flds = 0
For Each ctl In frmSec.Controls
    Select Case TypeName(ctl)
        Case &quot;TextBox&quot;
           ctl.ControlSource = &quot;&quot;
           flds = flds + 1
           ReDim Preserve txtBox(1 To flds) As String
           
&#39;Get the selected Field Names from the
&#39;TextBoxes on the Form&#39;s Detail Section
           txtBox(flds) = ctl.Name
           ctl.Locked = True
    End Select
Next
&#39;Set ComboBox Default Value
&#39;Change Form Properties
oFrm.cboName.DefaultValue = &quot;=[cboName].[column](0,0)&quot;
oFrm.RecordSelectors = False
oFrm.NavigationButtons = False
oFrm.ScrollBars = 0
&amp;nbsp;&lt;/pre&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;85&quot;&gt;The &lt;code data-end=&quot;99&quot; data-start=&quot;89&quot;&gt;For…Next&lt;/code&gt; loop scans through the &lt;span data-end=&quot;141&quot; data-start=&quot;123&quot;&gt;Detail section&lt;/span&gt; of the form, retrieves the names of all &lt;span data-end=&quot;203&quot; data-start=&quot;183&quot;&gt;TextBox controls&lt;/span&gt; (which correspond to the source data field names) and loads them into the &lt;code data-end=&quot;288&quot; data-start=&quot;278&quot;&gt;txtBox()&lt;/code&gt; array. At the same time, it calculates the total number of TextBox controls and stores this value in the &lt;code data-end=&quot;400&quot; data-start=&quot;394&quot;&gt;Flds&lt;/code&gt; variable.&lt;/p&gt;
&lt;p data-end=&quot;752&quot; data-start=&quot;414&quot;&gt;Each TextBox is then made &lt;span data-end=&quot;451&quot; data-start=&quot;440&quot;&gt;unbound&lt;/span&gt; by setting its &lt;code data-end=&quot;482&quot; data-start=&quot;467&quot;&gt;ControlSource&lt;/code&gt; property to an empty string (&lt;code data-end=&quot;536&quot; data-start=&quot;512&quot;&gt;ctl.ControlSource = &quot;&quot;&lt;/code&gt;). The&amp;nbsp;&lt;code data-end=&quot;553&quot; data-start=&quot;543&quot;&gt;txtBox() array&lt;/code&gt;&amp;nbsp;is&amp;nbsp;&lt;span data-end=&quot;592&quot; data-start=&quot;563&quot;&gt;dynamically&amp;nbsp;&lt;/span&gt;&lt;span data-end=&quot;592&quot; data-start=&quot;563&quot;&gt;redimensioned&lt;/span&gt;&lt;span style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;at each iteration, increasing its size by one element while preserving the data already stored. The final count of fields is captured in the &lt;code data-end=&quot;740&quot; data-start=&quot;734&quot;&gt;Flds&lt;/code&gt; variable.&lt;/p&gt;
&lt;p&gt;This approach ensures that the code automatically adapts to any changes—fields added or removed from the form by the user—without requiring manual adjustments. The ComboBox&#39;s default Value is set with the Statement: =[cboName].[column](0,0).&lt;/p&gt;&lt;p&gt;The next four statements change the Form Properties.&lt;/p&gt;&lt;pre&gt;vKeyName = oFrm!KeyField&lt;/pre&gt;&lt;p&gt;The expression value, such as &#39;&lt;code data-end=&quot;116&quot; data-start=&quot;100&quot;&gt;=&quot;[Last Name]&quot;&#39;&lt;/code&gt;, is read and the &lt;span data-end=&quot;151&quot; data-start=&quot;134&quot;&gt;KeyField name&lt;/span&gt; (&lt;code data-end=&quot;164&quot; data-start=&quot;153&quot;&gt;Last Name&lt;/code&gt;) is assigned to the variable &lt;code data-end=&quot;204&quot; data-start=&quot;194&quot;&gt;vKeyName&lt;/code&gt;. The field used as the &lt;span data-end=&quot;253&quot; data-start=&quot;228&quot;&gt;Collection Object key&lt;/span&gt; must contain &lt;span data-end=&quot;284&quot; data-start=&quot;267&quot;&gt;unique values&lt;/span&gt;, and the same field data must also be present in the ComboBox &lt;code data-end=&quot;356&quot; data-start=&quot;347&quot;&gt;cboName&lt;/code&gt;. This ensures that selecting an item from the ComboBox can be used to &lt;span data-end=&quot;473&quot; data-start=&quot;427&quot;&gt;randomly retrieve the corresponding record&lt;/span&gt; from the Collection Object.ReDim Rec(1 To flds) As Variant&lt;/p&gt;&lt;pre&gt;Set db = CurrentDb
Set rst = db.OpenRecordset(strTable, dbOpenSnapshot)

&#39;----------------------------
vKeyName = oFrm!KeyField
&#39;----------------------------

Do While Not rst.EOF
    For k = 1 To flds
       Rec(k) = rst.Fields(txtBox(k)).Value
    Next

&#39;Key Value Field Name in the Form Fields
&#39;=========================================
   strKey = rst.Fields(vKeyName).Value
&#39;=========================================
    Coll.Add Rec, strKey
    rst.MoveNext
Loop
&lt;/pre&gt;

&lt;p data-end=&quot;631&quot; data-start=&quot;80&quot;&gt;&lt;code data-end=&quot;91&quot; data-start=&quot;84&quot;&gt;Rec()&lt;/code&gt;&amp;nbsp; The array is redimensioned to match the number of data fields on the form. The field values are then read from the source table or query, one record at a time, and stored in the corresponding elements of the &lt;code data-end=&quot;303&quot; data-start=&quot;296&quot;&gt;Rec()&lt;/code&gt; array. Each completed &lt;code data-end=&quot;333&quot; data-start=&quot;326&quot;&gt;Rec()&lt;/code&gt; array is added as a single item in the Collection object, with the &lt;span data-end=&quot;420&quot; data-start=&quot;401&quot;&gt;Last Name field&lt;/span&gt; used as the collection item key (the second parameter of the Collection object’s &lt;code data-end=&quot;509&quot; data-start=&quot;502&quot;&gt;Add()&lt;/code&gt; method). Through this process, all source data records are efficiently loaded into memory within the Collection object.&lt;/p&gt;&lt;p data-end=&quot;580&quot; data-start=&quot;62&quot;&gt;&lt;strong data-end=&quot;71&quot; data-start=&quot;62&quot;&gt;Note:&lt;/strong&gt; &lt;i&gt;The source table or query may contain more fields than those placed on the form by the Form Wizard. However, the program only processes the fields whose names appear on the form; any additional fields in the source are ignored. You may freely add or remove fields from the form or rearrange their positions as needed. Just ensure that the &lt;span data-end=&quot;428&quot; data-start=&quot;411&quot;&gt;Name property&lt;/span&gt; of each field remains unchanged and matches a corresponding field in the record source table or query. No modifications to the VBA code are required.&lt;/i&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The cbo_Click() Event Subroutine.&lt;/h3&gt;
&lt;pre&gt;Private Sub cbo_Click()
Dim strKy As String, Record As Variant
Dim j As Long, L As Long, H As Long

&#39;Get Selected Collection Key from ComboBox
strKy = cbo.Value
 
&#39;Retrieve the record using Key from Collection
&#39;and load into Variant Array R
  
  Record = Coll(strKy)
  
  L = LBound(Record)
  H = UBound(Record)
  
&#39;Add Field Values into corresponding Text Boxes
  For j = L To H
    oFrm(txtBox(j)) = Record(j)
  Next
  oFrm.Requery
  
End Sub

&lt;/pre&gt;
&lt;p data-end=&quot;263&quot; data-start=&quot;78&quot;&gt;When a user selects an item from the ComboBox, the selected value is used as the Collection Object Item Key to retrieve the corresponding record and load it into the &lt;code data-end=&quot;254&quot; data-start=&quot;244&quot;&gt;Record()&lt;/code&gt; array.&lt;/p&gt;&lt;p data-end=&quot;529&quot; data-start=&quot;265&quot;&gt;The array element values are read in the same order they were stored in memory, and the unbound TextBoxes are populated accordingly, based on the order in which their names were read from the form. Since the TextBoxes are locked, their contents cannot be edited.&lt;/p&gt;&lt;p data-end=&quot;768&quot; data-start=&quot;531&quot;&gt;The &lt;span data-end=&quot;561&quot; data-start=&quot;535&quot;&gt;Data_View Class Module&lt;/span&gt; and accompanying Form Module code can be reused for any form created using this procedure, without modification. Ensure that the ComboBox is named &lt;span data-end=&quot;720&quot; data-start=&quot;709&quot;&gt;cboName,&lt;/span&gt; and the Command Button is named &lt;span data-end=&quot;765&quot; data-start=&quot;753&quot;&gt;cmdClose&lt;/span&gt;.&lt;/p&gt;&lt;p data-end=&quot;913&quot; data-start=&quot;770&quot;&gt;Data field names are taken directly from the &lt;span data-end=&quot;832&quot; data-start=&quot;815&quot;&gt;Name property&lt;/span&gt; of the TextBoxes created by the Form Wizard in the Detail section of the form.&lt;/p&gt;&lt;p&gt;



&lt;/p&gt;&lt;p data-end=&quot;1035&quot; data-start=&quot;915&quot;&gt;This approach allows you to create a fully functional Data View Form in just minutes, complete with ready-to-use code.&lt;/p&gt;
&lt;h3&gt;Demo Database Download&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/04/Data_InColl.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1XlTkXqveegbFUevExku4jCE4OUWrYifF/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioFf-79SroXZ4JkiqgZYv196vvwuIDU6wLEconUKqF-8uKB4XfA4P2yshkCX2o16u08fw9nN8LkTe8XvDgBDDTepmbEqtmBreKye0SKYfz10iaUmM1loO3uX7sYhQvQctArB6ZjjzRO1Rw/s320/zip.gif&quot; width=&quot;22&quot; /&gt;Data_InColl.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/04/Data_InColl.zip--&gt;
&lt;br /&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;

</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/2964035937363816164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/2964035937363816164'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/2964035937363816164'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html' title='Table Query Records in Collection Object'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3T_GAUQJDc5wsAZEDmEVToJsSGEufub4hSr6wnLZR8hvc4N6fFUCZpDY5F8-KwjFKWVCWsR4Oupk6e8yWr45StEMB82kAin4LAQWlNZaPJUR1PHX5j06HNpH7odPGX0REB-_e4pdKiDg8sI0gd8Gx-nupGZOOEbb9T6FT60Wftg0nuozzZALsTMaZcEMy/s72-c/CollDataView.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-7953644924771526294</id><published>2024-04-22T23:02:00.005+05:30</published><updated>2026-07-13T15:11:34.945+05:30</updated><title type='text'>Streamline Filter By Character Sort</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Data Filter by Character and Sort on Form.&lt;/h3&gt;&lt;p&gt;Version 1.0 of this Article was &lt;a href=&quot;https://www.msaccesstips.com/2009/04/filter-by-character-and-sort.html&quot; target=&quot;_blank&quot;&gt;originally published in April 2009&lt;/a&gt;&amp;nbsp;and upgraded with a significant change in the Demo Application Version 2.0. In this version, the Event Subroutines are executed from the &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html&quot; target=&quot;_blank&quot;&gt;standalone class module&lt;/a&gt;, rather than from the form module.&lt;/p&gt;&lt;p&gt;After realizing the advantages of Event Procedures Coding in Standalone Class Modules, I found it difficult to revert to the traditional, less organized, and time-consuming Form/Report Module VBA Coding procedures.&lt;/p&gt;&lt;p data-end=&quot;254&quot; data-start=&quot;68&quot;&gt;In traditional coding, modifying the code of a specific event subroutine in a Form Module—especially when dealing with multiple types of controls—usually involves several manual steps.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Open the Form in Design View.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Select the required Control.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;Display its Property Sheet.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Select the specific Event Property.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;Click on the Build Button to open the Event Procedure.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Write/Modify the Code.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;Save the Form with the Code.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Open the Form in Normal View to test the change.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p data-end=&quot;811&quot; data-start=&quot;93&quot;&gt;Typically, it takes about eight steps to reach a specific event procedure in the Form Module to write, edit, and save changes. While it’s true that multiple event procedures can be modified once the form is open, steps 2 through 6 must still be repeated for each individual event procedure. This repetitive process is both tedious and time-consuming, especially when performed numerous times during development. At the same time, designing the user interface also consumes significant effort, as both activities often occur in parallel. Furthermore, any code written directly in the Form Module remains locked there and cannot be reused elsewhere, except for public functions written in a Standard Module.&lt;/p&gt;&lt;p&gt;If you’re a beginner VBA programmer, learning the language alongside user interface design is best accomplished through the traditional method. If you’re an experienced developer, I encourage you to experiment with streamlined VBA Event procedure coding in Standalone Class Modules and see firsthand how it compares to the traditional coding style.&amp;nbsp;&lt;/p&gt;&lt;p&gt;This approach can offer valuable insights and significantly boost coding efficiency, saving a substantial amount of time in project development. Moreover, the reusable VBA code in Standalone Class Modules can be easily exported and integrated into other projects, further enhancing productivity.&lt;/p&gt;&lt;p&gt;Streamlined event procedure coding involves more than just moving the code from the form module to the standalone class module. It&#39;s about organizing the event procedure code in a structured, concise manner that promotes reusability without duplicating code for multiple objects of the same type in the form module. This approach enhances code maintainability and reduces redundancy, resulting in a more efficient and manageable codebase.&lt;/p&gt;&lt;p&gt;Direct access to the &lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html &quot; target=&quot;_blank&quot;&gt;Structured Event Subroutines&lt;/a&gt; in the Standalone Class Module eliminates the struggle with the form design view to reach a particular event subroutine. This direct access streamlines the development process, making it easier to locate and modify event procedures without the hassle of navigating through the form&#39;s design view.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Example of Structured Event Subroutine Coding:&lt;/h3&gt;&lt;p&gt;The BeforeUpdate &lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_blank&quot;&gt;Event Procedure Code&lt;/a&gt; of several TextBoxes can be written within a single BeforeUpdate() Event Subroutine.&lt;/p&gt;

&lt;pre&gt;Private Sub txt_BeforeUpdate(Cancel As Integer)

&#39;When the BeforeUpdate Event is captured the txt object will have
&#39;the Name of the Object fired the Event
Select Case txt.Name

Case &quot;Quantity&quot;
    &#39;Code
  
  Case &quot;UnitPrice&quot;
    &#39;Code
  
  Case &quot;SaleTax&quot;
    &#39; Code
  
  Case . . .
  
End Select
End Sub
&lt;/pre&gt;

&lt;p&gt;The &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;seventh episode&lt;/a&gt; in this series of articles is a prime example of event subroutine code Reuse and illustrates an organized, structured approach to event procedure coding. By writing just one set of GotFocus and LostFocus Event Subroutines, you can efficiently manage the behavior of 25 or more text boxes on the form when they gain or lose focus. This example offers a straightforward demonstration of how to implement streamlined event procedure coding in a standalone class module, emphasizing code reusability and reduced redundancy.&lt;/p&gt;&lt;p&gt;Microsoft Access controls, such as TextBoxes, &lt;a href=&quot;https://www.msaccesstips.com/2019/07/withevents-textbox-commandbutton.html&quot; target=&quot;_blank&quot;&gt;Command Buttons&lt;/a&gt;, and others, rely on event-defining, event-firing, and event-capturing mechanisms, which form the foundation of streamlined event subroutine coding. I explored these concepts in detail during my presentation to the &lt;a href=&quot;https://accessusergroups.org/europe/&quot; target=&quot;_blank&quot;&gt;Access User Groups&lt;/a&gt; (Europe) on January 3, 2024. The presentation is available as a YouTube video on the Access User Groups (Europe) channel, titled&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;&lt;a href=&quot;&quot; target=&quot;_blank&quot;&gt;&lt;em&gt;&quot;Streamlined Event Procedure Coding in Standalone Class Modules&lt;/em&gt;&lt;/a&gt;,&quot; which offers&lt;/span&gt;&amp;nbsp;valuable insights into this coding approach.&lt;/p&gt;&lt;p&gt;In our current project &#39;&lt;i&gt;Filter by Character and Sort&lt;/i&gt;&#39;, the Customers Form’s record source is derived from the CustomersQ query, which contains multiple records. To enhance user experience and efficiency, we’ll implement a technique that swiftly filters records by allowing users to type the first one or more characters from the customer’s selected Data Field. Utilizing the form’s filter settings, matching records will be quickly identified based on the characters typed into a text box control. This feature will streamline the process of locating specific customer records, improving overall usability.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Customers Form Image-1 Normal Data View.&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD2TIQm52IzmTAOmnLAABOFfLYnW4cxfdSoqiaLeN_F06oc-kIqhvH1NUndTP7e6zJN136bBzOWm4FzY6ONjN2GS6N5I4NAzqvb_Axgv_wfeqj4_m5jCPsQsWlIQzd89lcu7XOg0znHBi9Pnrv2842kJ_RLnjQBAAsU_jHyM4w52urjhxqtGFxhzautxVY/s853/FilterByChar1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;698&quot; data-original-width=&quot;853&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD2TIQm52IzmTAOmnLAABOFfLYnW4cxfdSoqiaLeN_F06oc-kIqhvH1NUndTP7e6zJN136bBzOWm4FzY6ONjN2GS6N5I4NAzqvb_Axgv_wfeqj4_m5jCPsQsWlIQzd89lcu7XOg0znHBi9Pnrv2842kJ_RLnjQBAAsU_jHyM4w52urjhxqtGFxhzautxVY/s320/FilterByChar1.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;Customers Form Image-2 with Filtered Data.&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG5tNI4a19uEezgruXiEnZMNXjgFglk-eA6GfrgqoVBhFmYtnJGC9mjTh2Cv0KNuc7foBw5oCQ8AyLB1j0h5lkEIEbBf5rrN3XLJASoknMmzU3fUy3VTE4tzmFUO_E3IkR0mZC3o_D_BHifR49u2pKXi2GOPsLUSjVbgodyk1KZ6nu3MAAOK8nes1VJ-rt/s851/FilterByChar2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;701&quot; data-original-width=&quot;851&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG5tNI4a19uEezgruXiEnZMNXjgFglk-eA6GfrgqoVBhFmYtnJGC9mjTh2Cv0KNuc7foBw5oCQ8AyLB1j0h5lkEIEbBf5rrN3XLJASoknMmzU3fUy3VTE4tzmFUO_E3IkR0mZC3o_D_BHifR49u2pKXi2GOPsLUSjVbgodyk1KZ6nu3MAAOK8nes1VJ-rt/s320/FilterByChar2.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The yellow-highlighted TextBox serves as the filter input control. Above it, a &lt;a href=&quot;https://www.msaccesstips.com/2013/12/updating-combobox-when-not-in-list-is.html&quot; target=&quot;_blank&quot;&gt;ComboBox&lt;/a&gt; lets the users select the field to search—in this case, the &lt;em data-end=&quot;233&quot; data-start=&quot;222&quot;&gt;Last Name&lt;/em&gt; field. As text is entered into the filter box, the system matches the beginning of the selected field’s value and filters the records accordingly. This setup enables efficient, quick record searches based on starting characters, making it easier to locate specific names that meet the criteria.&lt;/p&gt;&lt;p&gt;In this example, three records are initially filtered, each with a Last Name beginning with the letter &lt;em data-end=&quot;172&quot; data-start=&quot;169&quot;&gt;G&lt;/em&gt;. When you type ‘r’ after ‘G’ in the yellow-highlighted filter box, the first record (which contains ‘Go…’) no longer matches and is removed from the results. This dynamic filtering approach provides precise and efficient record retrieval, updating in real time as users type, and making it easier to quickly locate records that meet the search criteria.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkQr9bkXRb5To3M7GbHJ25yOVnnnZV0hG4v8TtTNH4mCznOuRbpSAqP4ZYp-wu98_Q9ajb9soLmHnHKA0vYjAXm1mtUqXvidwKgwAP2desXJ2oPtAQiTwnM75K25iv_y5SIFbh7xNagVwk0S-AK5WBABYHCnm28EE7iXeIdUu3PfOLvpdarkseSoe3inyp/s854/FilterByChar3.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;701&quot; data-original-width=&quot;854&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkQr9bkXRb5To3M7GbHJ25yOVnnnZV0hG4v8TtTNH4mCznOuRbpSAqP4ZYp-wu98_Q9ajb9soLmHnHKA0vYjAXm1mtUqXvidwKgwAP2desXJ2oPtAQiTwnM75K25iv_y5SIFbh7xNagVwk0S-AK5WBABYHCnm28EE7iXeIdUu3PfOLvpdarkseSoe3inyp/s320/FilterByChar3.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;When the Backspace key is pressed to remove the last character from the filter TextBox, the data instantly updates to reflect the new filtering criteria based on the remaining characters. If no characters remain, the filter is cleared, and the full dataset is displayed in the form’s detail section. This ensures a seamless, real-time filtering experience that intuitively responds to user input.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Cls_ObjInit Class Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents frm As Access.Form
Private WithEvents txt As Access.TextBox
Private WithEvents cmd As Access.CommandButton
Private WithEvents cbo As Access.ComboBox

Dim txt2Filter

Public Property Get m_Frm() As Access.Form
    Set m_Frm = frm
End Property

Public Property Set m_Frm(ByRef vFrm As Access.Form)
    Set frm = vFrm
    
    Call Class_Init
End Property

Private Sub Class_Init()
Const EP = &quot;[Event Procedure]&quot;

Set txt = frm.FilterText
Set cmd = frm.cmdClose
Set cbo = frm.cboFields

With frm
    .OnLoad = EP
    .OnUnload = EP
End With

With txt
    .OnKeyUp = EP
End With

With cmd
    .OnClick = EP
End With

With cbo
    .OnClick = EP
End With

End Sub

Private Sub cbo_Click()
    frm.FilterText = &quot;&quot;
    txt2Filter = &quot;&quot;
    frm.Filter = &quot;&quot;
    frm.FilterText.SetFocus
    frm.FilterOn = False
End Sub

Private Sub txt_KeyUp(KeyCode As Integer, Shift As Integer)
Dim C As Integer, sort As String
Dim L As String

On Error GoTo txt_KeyUp_Err
C = KeyCode

With frm
Select Case C
    Case 8 &#39;backspace key
        txt2Filter = Nz(![FilterText], &quot;&quot;)
        If Len(txt2Filter) = 1 Or Len(txt2Filter) = 0 Then
            txt2Filter = &quot;&quot;
            .FilterOn = False &#39; remove filter
            frm.Recalc
            
        Else
            txt2Filter = Left(txt2Filter, Len(txt2Filter) - 1) &#39;delete the last character
            If Len(txt2Filter) = 0 Then
                .FilterOn = False &#39; remove filter
                
            Else &#39;set filter and enable
                .Filter = &quot;[&quot; &amp;amp; ![cboFields] &amp;amp; &quot;]&quot; &amp;amp; &quot; like &#39;&quot; &amp;amp; txt2Filter &amp;amp; &quot;*&#39;&quot;
                ![FilterText] = txt2Filter
                
                &#39;position cursor position at the end of the text
                If Len(!FilterText) &amp;gt; 0 Then
                    .Section(acFooter).SetTabOrder
                    ![FilterText].SelLength = Len(![FilterText])
                    SendKeys &quot;{END}&quot; &#39;position cursor at right end of text
                End If
                
                .FilterOn = True
            End If
        End If
       
    Case 37 &#39;right arrow key, prevent text highlighting
        SendKeys &quot;{END}&quot; &#39;position cursor at right end of text
    
    Case 32, 48 To 57, 65 To 90, 97 To 122 &#39;space, 0 to 9, A to Z, a to z keys
        txt2Filter = txt2Filter &amp;amp; Chr$(C)
        
        &#39;First letter of words to uppercase
        ![FilterText] = StrConv(txt2Filter, vbProperCase)
        SendKeys &quot;{END}&quot;
        GoSub SetFilter
End Select
End With

txt_KeyUp_Exit:
Exit Sub

SetFilter:
With frm
  .Refresh
  If Len(txt2Filter) = 0 Then
        .FilterOn = False &#39; remove filter
  Else &#39;set filter and enable
        .Filter = &quot;[&quot; &amp;amp; ![cboFields] &amp;amp; &quot;]&quot; &amp;amp; &quot; like &#39;&quot; &amp;amp; txt2Filter &amp;amp; &quot;*&#39;&quot;
        .FilterOn = True
  
  &#39; Set sort order
        sort = IIf(!Frame10 = 1, &quot;ASC&quot;, &quot;DESC&quot;)
        .OrderBy = &quot;[&quot; &amp;amp; !cboFields &amp;amp; &quot;] &quot; &amp;amp; sort
        .OrderByOn = True
  
        .Section(acFooter).SetTabOrder &#39;Form Footer Section Active
  &#39;position cursor at end of text
        ![FilterText].SelLength = Len(![FilterText])
        SendKeys &quot;{END}&quot;
  End If
End With
Return

txt_KeyUp_Err:
MsgBox Err.Description, , &quot;txt_KeyUp()&quot;
Resume txt_KeyUp_Exit
End Sub

Private Sub cmd_Click()
    DoCmd.Close acForm, frm.Name
End Sub

&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p data-end=&quot;296&quot; data-start=&quot;113&quot;&gt;There are three &lt;a href=&quot;https://www.msaccesstips.com/2021/11/activex-listview-control-tutorial-01.html&quot; target=&quot;_blank&quot;&gt;controls&lt;/a&gt; in the footer of the form, each triggering simple events that run corresponding code—except for the TextBox, which handles a more complex &lt;span data-end=&quot;287&quot; data-start=&quot;276&quot;&gt;KeyUp()&lt;/span&gt; event.&lt;/p&gt;&lt;p data-end=&quot;471&quot; data-start=&quot;298&quot;&gt;In this scenario, creating separate Wrapper Class Objects for the TextBox, ComboBox, and &lt;a href=&quot;https://www.msaccesstips.com/2011/06/creating-animated-command-button-with.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt;&amp;nbsp;is not necessary&amp;nbsp;since only one instance of each exists on the form.&lt;/p&gt;&lt;p data-end=&quot;799&quot; data-start=&quot;473&quot;&gt;Within the &lt;span data-end=&quot;499&quot; data-start=&quot;484&quot;&gt;Cls_ObjInit&lt;/span&gt; class module, the main object instances are declared in the global section using the &lt;span data-end=&quot;599&quot; data-start=&quot;585&quot;&gt;WithEvents&lt;/span&gt; keyword, enabling Event capture and execution of their respective subroutines. Additionally, a Variant-type variable, &lt;span data-end=&quot;732&quot; data-start=&quot;718&quot;&gt;txt2Filter&lt;/span&gt;, is declared globally, followed by the Form Property procedures.&lt;/p&gt;&lt;p data-end=&quot;986&quot; data-start=&quot;801&quot;&gt;The &lt;span data-end=&quot;821&quot; data-start=&quot;805&quot;&gt;Class_Init()&lt;/span&gt; subroutine is then called from the &lt;span data-end=&quot;872&quot; data-start=&quot;857&quot;&gt;Set m_Frm()&lt;/span&gt; property procedure after receiving the form object from the &lt;span data-end=&quot;948&quot; data-start=&quot;933&quot;&gt;Form_Load()&lt;/span&gt; event procedure in the form module.&lt;/p&gt;&lt;p data-end=&quot;1140&quot; data-start=&quot;988&quot;&gt;Next, the &lt;span data-end=&quot;1005&quot; data-start=&quot;998&quot;&gt;txt&lt;/span&gt;, &lt;span data-end=&quot;1014&quot; data-start=&quot;1007&quot;&gt;cmd&lt;/span&gt;, and &lt;span data-end=&quot;1027&quot; data-start=&quot;1020&quot;&gt;cbo&lt;/span&gt; objects are assigned &lt;a href=&quot;https://www.msaccesstips.com/2013/08/external-references-in-conditional.html&quot; target=&quot;_blank&quot;&gt;references&lt;/a&gt; to their respective controls on the form and enabled with the required events.&lt;/p&gt;&lt;p&gt;




&lt;/p&gt;&lt;ul data-end=&quot;1522&quot; data-start=&quot;1142&quot;&gt;
&lt;li data-end=&quot;1276&quot; data-start=&quot;1142&quot;&gt;
&lt;p data-end=&quot;1276&quot; data-start=&quot;1144&quot;&gt;The &lt;span data-end=&quot;1172&quot; data-start=&quot;1148&quot;&gt;ComboBox Click event&lt;/span&gt; selects a field name to serve as the Filter target. This action resets any previously applied filter.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1332&quot; data-start=&quot;1277&quot;&gt;
&lt;p data-end=&quot;1332&quot; data-start=&quot;1279&quot;&gt;The &lt;span data-end=&quot;1313&quot; data-start=&quot;1283&quot;&gt;Command Button Click event&lt;/span&gt; closes the form.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1522&quot; data-start=&quot;1333&quot;&gt;
&lt;p data-end=&quot;1522&quot; data-start=&quot;1335&quot;&gt;The &lt;span data-end=&quot;1362&quot; data-start=&quot;1339&quot;&gt;TextBox KeyUp event&lt;/span&gt; captures valid keystrokes, builds the input string character by character, and applies it &lt;a href=&quot;https://www.msaccesstips.com/2011/07/dynamic-dlookup-in-query-column.html&quot; target=&quot;_blank&quot;&gt;dynamically&lt;/a&gt; as a filter to the field selected in the ComboBox.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The txt_KeyUp() Event Subroutine Code.&lt;/h3&gt;
&lt;pre&gt;Private Sub txt_KeyUp(KeyCode As Integer, Shift As Integer)
Dim C As Integer, sort As String
Dim L As String

On Error GoTo txt_KeyUp_Err
C = KeyCode

With frm
Select Case C
    Case 8 &#39;backspace key
        txt2Filter = Nz(![FilterText], &quot;&quot;)
        If Len(txt2Filter) = 1 Or Len(txt2Filter) = 0 Then
            txt2Filter = &quot;&quot;
            .FilterOn = False &#39; remove filter
            frm.Recalc
            
        Else
            txt2Filter = Left(txt2Filter, Len(txt2Filter) - 1) &#39;delete the last character
            If Len(txt2Filter) = 0 Then
                .FilterOn = False &#39; remove filter
                
            Else &#39;set filter and enable
                .Filter = &quot;[&quot; &amp;amp; ![cboFields] &amp;amp; &quot;]&quot; &amp;amp; &quot; like &#39;&quot; &amp;amp; txt2Filter &amp;amp; &quot;*&#39;&quot;
                ![FilterText] = txt2Filter
                
                &#39;position cursor position at the end of the text
                If Len(!FilterText) &amp;gt; 0 Then
                    .Section(acFooter).SetTabOrder
                    ![FilterText].SelLength = Len(![FilterText])
                    SendKeys &quot;{END}&quot; &#39;position cursor at right end of text
                End If
                
                .FilterOn = True
            End If
        End If
       
    Case 37 &#39;right arrow key, prevent text highlighting
        SendKeys &quot;{END}&quot; &#39;position cursor at right end of text
    
    Case 32, 48 To 57, 65 To 90, 97 To 122 &#39;space, 0 to 9, A to Z, a to z keys
        txt2Filter = txt2Filter &amp;amp; Chr$(C)
        
        &#39;First letter of words to uppercase
        ![FilterText] = StrConv(txt2Filter, vbProperCase)
        SendKeys &quot;{END}&quot;
        GoSub SetFilter
End Select
End With

txt_KeyUp_Exit:
Exit Sub

SetFilter:
With frm
  .Refresh
  If Len(txt2Filter) = 0 Then
        .FilterOn = False &#39; remove filter
  Else &#39;set filter and enable
        .Filter = &quot;[&quot; &amp;amp; ![cboFields] &amp;amp; &quot;]&quot; &amp;amp; &quot; like &#39;&quot; &amp;amp; txt2Filter &amp;amp; &quot;*&#39;&quot;
        .FilterOn = True
  
  &#39; Set sort order
        sort = IIf(!Frame10 = 1, &quot;ASC&quot;, &quot;DESC&quot;)
        .OrderBy = &quot;[&quot; &amp;amp; !cboFields &amp;amp; &quot;] &quot; &amp;amp; sort
        .OrderByOn = True
  
        .Section(acFooter).SetTabOrder &#39;Form Footer Section Active
  &#39;position cursor at end of text
        ![FilterText].SelLength = Len(![FilterText])
        SendKeys &quot;{END}&quot;
  End If
End With
Return

txt_KeyUp_Err:
MsgBox Err.Description, , &quot;txt_KeyUp()&quot;
Resume txt_KeyUp_Exit
End Sub
&lt;/pre&gt;

&lt;div&gt;The Sub KeyUp()&lt;b&gt; &lt;/b&gt;Event Subroutine takes only the Key Code from the Keys&amp;nbsp;0-9, A-Z, and a-z. The Backspace key removes the last character entered into the Filter Text input Textbox. The right-arrow character Code is also valid, which moves the &lt;b&gt;I&lt;/b&gt; bar to the END of the Filter text and prevents selecting the full text when the Input text box is refreshed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Backspace keypress will truncate the right-most character from the Filter input Text, and the Filter action is refreshed. When the Filter input control is empty, the data filter is reset, and full data is displayed on the Form.&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Form Module Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

&#39;Global declaration
Private obj As New Cls_ObjInit

Private Sub Form_load()
    Set obj.m_Frm = Me
    Application.SetOption &quot;Behavior Entering Field&quot;, 2
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Application.SetOption &quot;Behavior Entering Field&quot;, 0
    Set obj = Nothing
End Sub
&lt;/pre&gt;
&lt;h3&gt;Filter By Character in ComboBox Items.&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuSKarB3r8fZwr21f2i_47K9qDhZkjoyXH4s35CyArC9Uu0yVuWm5CmY1XmXPyrBhyphenhyphenU0k2XVAbOzQFrtYoAFCJ8P44EVljHY-2VNfTz5SZ-48koJOTPjlyqN8BOUG4mUBazRqtwPrxuytvocsZZ-gGdmrcmsqaESEgumgg6BqqNgHrsnTjBfKgadxRopJJ/s820/ComboBox_Filter.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Filter By Character In ComboBox&quot; border=&quot;0&quot; data-original-height=&quot;621&quot; data-original-width=&quot;820&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuSKarB3r8fZwr21f2i_47K9qDhZkjoyXH4s35CyArC9Uu0yVuWm5CmY1XmXPyrBhyphenhyphenU0k2XVAbOzQFrtYoAFCJ8P44EVljHY-2VNfTz5SZ-48koJOTPjlyqN8BOUG4mUBazRqtwPrxuytvocsZZ-gGdmrcmsqaESEgumgg6BqqNgHrsnTjBfKgadxRopJJ/s320/ComboBox_Filter.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p data-end=&quot;387&quot; data-start=&quot;123&quot;&gt;The screenshot above shows the second form, &lt;span data-end=&quot;186&quot; data-start=&quot;167&quot;&gt;Customers_Combo&lt;/span&gt;, which demonstrates the &lt;em data-end=&quot;232&quot; data-start=&quot;211&quot;&gt;Filter by Character&lt;/em&gt; feature applied to ComboBox items. The &lt;span data-end=&quot;283&quot; data-start=&quot;272&quot;&gt;KeyUp()&lt;/span&gt; event subroutine is almost identical to the filter method used in the first form we reviewed earlier.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;536&quot; data-start=&quot;389&quot;&gt;For this form, a new class module named &lt;span data-end=&quot;444&quot; data-start=&quot;429&quot;&gt;Cbo_ObjInit&lt;/span&gt; has been introduced. The VBA code for the &lt;span data-end=&quot;502&quot; data-start=&quot;487&quot;&gt;Cbo_ObjInit&lt;/span&gt; class module is provided below:&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents frm As Access.Form
Private WithEvents txt As Access.TextBox
Private WithEvents cmd As Access.CommandButton
Private cbo As Access.ComboBox

Dim txt2Filter

Public Property Get m_Frm() As Access.Form
    Set m_Frm = frm
End Property

Public Property Set m_Frm(ByRef vFrm As Access.Form)
    Set frm = vFrm
    
    Call Class_Init
End Property

Private Sub Class_Init()
Const EP = &quot;[Event Procedure]&quot;

Set txt = frm.FilterText
Set cmd = frm.cmdExit
Set cbo = frm.cboCust

With frm
    .OnLoad = EP
    .OnUnload = EP
End With

With txt
    .OnKeyUp = EP
End With

With cmd
    .OnClick = EP
End With


End Sub

Private Sub txt_KeyUp(KeyCode As Integer, Shift As Integer)
Dim i As Integer
Dim SQL As String
Dim SQL1 As String
Dim SQL2 As String


On Error GoTo txtKeyUp_Err
SQL = &quot;SELECT CustomersQ.* FROM CustomersQ ORDER BY CustomersQ.[Last Name];&quot;

SQL1 = &quot;SELECT CustomersQ.* FROM CustomersQ &quot;
SQL2 = &quot;WHERE (((CustomersQ.[Last Name]) Like &#39;&quot; &#39;&quot;Gr*&quot;));

i = KeyCode

Select Case i
    Case 8 &#39;backspace key
        frm.Refresh
        If Len(txt2Filter) = 1 Or Len(txt2Filter) = 0 Then
            txt2Filter = &quot;&quot;
        Else
            txt2Filter = Left(txt2Filter, Len(txt2Filter) - 1) &#39;delete the last character
        End If
        GoSub SetFilter
    Case 37 &#39;right arrow keys
        SendKeys &quot;{END}&quot;
    Case 32, 48 To 57, 65 To 90, 97 To 122 &#39;space, 0 to 9, A to Z, a to z keys
        txt2Filter = txt2Filter &amp;amp; Chr$(i)
        frm![FilterText] = StrConv(txt2Filter, vbProperCase)
        GoSub SetFilter
End Select

txtKeyUp_Exit:
Exit Sub

SetFilter:
  If Len(Nz(txt2Filter, &quot;&quot;)) = 0 Then
    With frm
        .cboCust.RowSource = SQL
        .cboCust.Requery
        .cboCust.SetFocus
        .cboCust.Dropdown
    End With
  Else &#39;set filter and enable
        SQL = SQL1 &amp;amp; SQL2 &amp;amp; txt2Filter &amp;amp; &quot;*&#39;));&quot;
    With frm
        .cboCust.RowSource = SQL
        .cboCust.Requery
        .cboCust.SetFocus
        .cboCust.Dropdown
    End With
  End If
Return

txtKeyUp_Err:
MsgBox Err.Description, , &quot;txtKeyUp()&quot;
Resume txtKeyUp_Exit
End Sub

Private Sub cmd_Click()
    DoCmd.Close acForm, frm.Name
End Sub

&lt;/pre&gt;
&lt;p data-end=&quot;284&quot; data-start=&quot;86&quot;&gt;In the earlier approach, we applied the &lt;span data-end=&quot;148&quot; data-start=&quot;126&quot;&gt;Form Filter method&lt;/span&gt;, where the characters entered into a TextBox served as filter criteria to restrict the records displayed in the form’s record source.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;539&quot; data-start=&quot;286&quot;&gt;In contrast, the &lt;span data-end=&quot;322&quot; data-start=&quot;303&quot;&gt;ComboBox method&lt;/span&gt; &lt;a href=&quot;https://www.msaccesstips.com/2011/07/dynamic-dlookup-in-query-column.html&quot; target=&quot;_blank&quot;&gt;dynamically&lt;/a&gt; builds an SQL statement from the input filter text entered into a TextBox. This SQL is then assigned to the ComboBox&amp;nbsp;&lt;span data-end=&quot;452&quot; data-start=&quot;438&quot;&gt;Row Source&lt;/span&gt;, refreshing its contents in real time based on the updated criteria.&lt;/p&gt;
&lt;h3&gt;
Download Demo Database
&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/04/FilterByChar2016.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1HTes5hjc4PPducmgZHj9qnDX0Rlv23ua/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioFf-79SroXZ4JkiqgZYv196vvwuIDU6wLEconUKqF-8uKB4XfA4P2yshkCX2o16u08fw9nN8LkTe8XvDgBDDTepmbEqtmBreKye0SKYfz10iaUmM1loO3uX7sYhQvQctArB6ZjjzRO1Rw/s320/zip.gif&quot; width=&quot;22&quot; /&gt;FilterByChar2016.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/04/FilterByChar2016.zip--&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;

</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/7953644924771526294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/7953644924771526294'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/7953644924771526294'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html' title='Streamline Filter By Character Sort'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD2TIQm52IzmTAOmnLAABOFfLYnW4cxfdSoqiaLeN_F06oc-kIqhvH1NUndTP7e6zJN136bBzOWm4FzY6ONjN2GS6N5I4NAzqvb_Axgv_wfeqj4_m5jCPsQsWlIQzd89lcu7XOg0znHBi9Pnrv2842kJ_RLnjQBAAsU_jHyM4w52urjhxqtGFxhzautxVY/s72-c/FilterByChar1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-1976638996803269086</id><published>2024-03-29T18:25:00.011+05:30</published><updated>2026-07-12T23:00:38.191+05:30</updated><title type='text'>Streamline Zoom-in Control Data Editing</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Editing Large Text Box Contents in Zoom-in Control.&lt;/h3&gt;
&lt;p&gt;This topic was originally published in August 2007 under the title &lt;em data-end=&quot;166&quot; data-start=&quot;133&quot;&gt;‘&lt;a href=&quot;https://www.msaccesstips.com/2007/08/edit-data-in-zoom-in-control.html&quot; target=&quot;_blank&quot;&gt;Edit Data in Zoom-in Control.’&lt;/a&gt;&lt;/em&gt; In that example, a custom shortcut menu was created and linked to the form to activate the zoom-in control, allowing users to edit the textbox contents containing multiple lines of data, similar to the Notes field in the Employees table.&lt;/p&gt;&lt;p&gt;&lt;span face=&quot;Söhne, ui-sans-serif, system-ui, -apple-system, &amp;quot;Segoe UI&amp;quot;, Roboto, Ubuntu, Cantarell, &amp;quot;Noto Sans&amp;quot;, sans-serif, &amp;quot;Helvetica Neue&amp;quot;, Arial, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Noto Color Emoji&amp;quot;&quot; style=&quot;background-color: white; color: #0d0d0d; font-size: 16px; white-space-collapse: preserve;&quot;&gt;The earlier version of the customized &lt;a href=&quot;https://www.msaccesstips.com/2007/07/custom-menus-and-tool-bars2.html&quot; target=&quot;_blank&quot;&gt;Shortcut Menu&lt;/a&gt; for the Employees Form is shown below for reference.&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO8XxWVDaFf6h8jvxoUEdg6OTqGgSSHiWDSpAf6Wd2dNWOVjKEnHUv4tzi5yaP-ZK_8uNJi9UcIW4gSdgtlh3zz7pYc3Y8lQwoeQfZDnJgcFEVee4h_hPLPMhGacBmGMOaWoBI3qSF0YzGl_ATAxUknuVNcfsabVSfL7UXeBecjjfc-ZPhs2ClcxJpCO-q/s819/ZoomShortCut.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;814&quot; data-original-width=&quot;819&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO8XxWVDaFf6h8jvxoUEdg6OTqGgSSHiWDSpAf6Wd2dNWOVjKEnHUv4tzi5yaP-ZK_8uNJi9UcIW4gSdgtlh3zz7pYc3Y8lQwoeQfZDnJgcFEVee4h_hPLPMhGacBmGMOaWoBI3qSF0YzGl_ATAxUknuVNcfsabVSfL7UXeBecjjfc-ZPhs2ClcxJpCO-q/s320/ZoomShortCut.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The built-in Shortcut Menu was customised by designing a new button image, highlighted in the Form image by a red oval shape. This button, resembling a CRT screen, is programmed with the necessary code to execute on clicking. However, designing a new button image within the existing shortcut menu is very difficult.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;p&gt;&amp;nbsp;Opening the Zoom Control is a two-step process: first, right-click the TextBox to display the Shortcut Menu, then select the Zoom option to open the Zoom-in Form with the active TextBox Contents.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Now, we have a more efficient method: simply right-click on a TextBox to open the Zoom-in Form prefilled with its data. After editing the contents, click the [Save] &lt;a href=&quot;https://www.msaccesstips.com/2009/01/command-button-animation-2.html&quot; target=&quot;_blank&quot;&gt;command button&lt;/a&gt; on the Zoom Form to update the original TextBox with the revised text.&lt;/p&gt;&lt;p&gt;The New Version of Zoom-in Form Image.&lt;/p&gt;&lt;p&gt;The New Employees Form with the Zoom-in Control with the Notes Field Data is given below:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg10lWWWkIfF_cOenskhxqRjFy2BcdMA0SksJKppRgWTJcd9o7vf5mOMfL3AOycfqU293QIWrf9uzeVXd0LRz03ky2UDW5-qYdM2ykwg0IY4pvcc-LZfmaQRu0jiQ2TF6UGtUyE1VFlC7qkH8cMMF5w26JgrM1q-7UgqwgxXfCu4SaKVyDIH2d00UoSPW7t/s1105/ZoomFormNew.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;707&quot; data-original-width=&quot;1105&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg10lWWWkIfF_cOenskhxqRjFy2BcdMA0SksJKppRgWTJcd9o7vf5mOMfL3AOycfqU293QIWrf9uzeVXd0LRz03ky2UDW5-qYdM2ykwg0IY4pvcc-LZfmaQRu0jiQ2TF6UGtUyE1VFlC7qkH8cMMF5w26JgrM1q-7UgqwgxXfCu4SaKVyDIH2d00UoSPW7t/s320/ZoomFormNew.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;In addition to copying the data from the Employees Notes TextBox into the larger TextBox on the Zoom Form, the formatting attributes from the original TextBox on the Employees Form are also applied, ensuring consistency in appearance.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Main Public Functions.&lt;/h3&gt;&lt;p&gt;There are two Public Functions that run this procedure.&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The ZoomOpen() Function.&lt;/h3&gt;
&lt;pre&gt;Public Function ZoomOpen()
&#39;------------------------------------------------------
&#39;Function : Edit Data in Zoom-in Control.
&#39;Author   : a.p.r.pillai
&#39;Date     : 29/07/2007, 26/03/2024
&#39;Rights(c): www.msaccesstips.com
&#39;------------------------------------------------------
Dim varVal, ctl As Control, intFontWeight As Integer
Dim strFont As String, intFontSize As Integer
Dim boolFontstyle As Boolean
Dim lngfontColor As Long, boolFontUnderline As Boolean
Dim bkgColor As Long

On Error GoTo ZoomOpen_Err

Set ctl = Screen.ActiveControl
With ctl
   strFont = .FontName
   intFontSize = .FontSize
   intFontWeight = .FontWeight
   boolFontstyle = .FontItalic
   boolFontUnderline = .FontUnderline
   lngfontColor = .ForeColor
   &#39;bkgColor = .BackColor
End With

   varVal = Screen.ActiveControl.Value
   DoCmd.OpenForm &quot;Zoom&quot;, acNormal

With Screen.ActiveForm.Controls(&quot;TxtZoom&quot;)
   .Value = varVal
   .FontName = strFont
   .FontSize = intFontSize
   .FontWeight = intFontWeight
   .FontItalic = boolFontstyle
   .FontUnderline = boolFontUnderline
   .ForeColor = lngfontColor
   &#39;.BackColor = bkgColor
End With

ZoomOpen_Exit:
Exit Function

ZoomOpen_Err:
Resume ZoomOpen_Exit
End Function
&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;When you right-click a TextBox, the ZoomOpen() function is executed. It copies the TextBox contents into a Variant variable, opens the Zoom-in Form, and transfers the data into the larger TextBox. The original formatting attributes from the source text box are also applied to ensure the text appears the same in the Zoom-in TextBox.&lt;/p&gt;&lt;p&gt;After editing the text in the Zoom-in control, click the&amp;nbsp;[Save]&amp;nbsp;&lt;a href=&quot;https://www.msaccesstips.com/2008/04/colorfull-command-buttons.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; to save the changes into the original text box of the Employees Form, and close the Zoom-in Form.&lt;/p&gt;&lt;p&gt;The Zoom-in Form can be dragged and moved to a convenient position in the Application Window.&amp;nbsp; The Zoom Form will open in Popup and Modal Mode, and you must close it to access other controls or Forms.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The&amp;nbsp;SaveZoomData() Function.&lt;/h3&gt;&lt;p&gt;The [Save] Command Button Click Runs the SaveZoomData() Function.&amp;nbsp; The VBA Code is given below.&lt;/p&gt;
&lt;pre&gt;Public Function SaveZoomData()
&#39;------------------------------------------------------
&#39;Function : Save Edited Data in the Control
&#39;Author   : a.p.r.pillai
&#39;Date     : 29/07/2007, 26/03/2024
&#39;Rights(c): www.msaccesstips.com
&#39;------------------------------------------------------
Dim vartxtZoom, strControl As String

On Error GoTo SaveZoomData_Err

 vartxtZoom = Forms(&quot;Zoom&quot;).Controls(&quot;txtZoom&quot;).Value

 DoCmd.Close acForm, &quot;zoom&quot;
 
 If Screen.ActiveControl.Locked = True Then
   strControl = Screen.ActiveControl.Name
   MsgBox strControl &amp;amp; &quot; is Read-Only, Changes discarded!&quot;
   Exit Function
 Else
    If IsNull(vartxtZoom) = False And Len(vartxtZoom) &amp;gt; 0 Then
        Screen.ActiveControl.Value = vartxtZoom
    End If
 End If
 
SaveZoomData_Exit:
Exit Function

SaveZoomData_Err:
Resume SaveZoomData_Exit
End Function

&lt;/pre&gt;&lt;p&gt;The SaveZoomData() Function saves the edited data into its Source TextBox. If the Textbox is locked, the edited data cannot be saved.&lt;/p&gt;&lt;p&gt;In both the above Functions, we used the Screen Object to address the active Form or active Text Box control without using their object names directly, e.g., Screen.ActiveForm, Screen.ActiveControl that has the Focus.&lt;/p&gt;&lt;p&gt;As I stated earlier, all you need to do is right-click on the TextBox to open the Zoom-in control and present the TextBox contents in the Zoom Window for editing.&amp;nbsp;&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;&lt;p&gt;For those who prefer a shortcut menu to open the Zoom Control, I created a small macro-based menu that can be assigned to the Form&amp;nbsp;&lt;em data-end=&quot;202&quot; data-start=&quot;183&quot;&gt;Shortcut Menu Bar&lt;/em&gt; property or to the same &lt;a href=&quot;https://www.msaccesstips.com/2007/08/saving-data-on-forms-not-in-table.html&quot; target=&quot;_blank&quot;&gt;property&lt;/a&gt; of any individual control on the Form. When applied at the Form level, the shortcut menu will appear whenever you right-click anywhere on the Form, not just on a specific control such as a TextBox.&amp;nbsp;The Macro Shortcut Menu Options.&lt;/p&gt;&lt;p&gt;There are two Shortcut Menu options to display in the Macro.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Open Zoom&lt;/li&gt;&lt;li&gt;Cancel&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The macro Commands for the Shortcut Menu Bar are listed in the McrZoom Macro Image shown below:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3LomSYjsrTso-Jt2HjM6bdQ1UbslZ0RZ8lML7zfMmcvlu4zM3FOOMWQ766agssHbiXqmszo7zgu3zHlczgfWNmX4SlVrtdqLGT-Q2QloFSWWMujKN6ATgYuUmhxKWooGdkDpKWKaG8IADmgcM5qJGzN6-7WLsxHdc0_sEJixgvi464IoiFP-rSDZjWj8-/s422/Macro%20SubMacro.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;422&quot; data-original-width=&quot;399&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3LomSYjsrTso-Jt2HjM6bdQ1UbslZ0RZ8lML7zfMmcvlu4zM3FOOMWQ766agssHbiXqmszo7zgu3zHlczgfWNmX4SlVrtdqLGT-Q2QloFSWWMujKN6ATgYuUmhxKWooGdkDpKWKaG8IADmgcM5qJGzN6-7WLsxHdc0_sEJixgvi464IoiFP-rSDZjWj8-/s320/Macro%20SubMacro.png&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The macro shown above provides two options. The first option runs the &lt;code data-end=&quot;139&quot; data-start=&quot;127&quot;&gt;ZoomOpen()&lt;/code&gt; function, which opens the Zoom Form and loads the text from the active TextBox into the Zoom Control for editing. The second option simply cancels the right-click event.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;2. Create the Menu Macro.&lt;/h3&gt;&lt;p&gt;We need to create a Menu Macro and insert the Menu Options Macro &lt;i&gt;McrZoom.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;The Menu Macro Image is given below:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUDXBMay_-y31rSfAwJFUaJuWbFgt7mTVfQOHJmQ-8Oyjalp3s3deE0qRaAGE9Ayq1kpoc2LCzZ1pRRj2Qbm442ocuIWUjWigN1JMlOi0pJh_pGgMgpkZ0srdjxAjxhZ0-86OF4xiX2Qxg4mTXfJmOja82E8-L3f2T_57H6ZddraMR0NrQYDbmu0CoZzPU/s485/Macro%20Menu.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;309&quot; data-original-width=&quot;485&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUDXBMay_-y31rSfAwJFUaJuWbFgt7mTVfQOHJmQ-8Oyjalp3s3deE0qRaAGE9Ayq1kpoc2LCzZ1pRRj2Qbm442ocuIWUjWigN1JMlOi0pJh_pGgMgpkZ0srdjxAjxhZ0-86OF4xiX2Qxg4mTXfJmOja82E8-L3f2T_57H6ZddraMR0NrQYDbmu0CoZzPU/s320/Macro%20Menu.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open a Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;The Menu Macro name is McrControlShortcut.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The &#39;&lt;i&gt;Shortcut Menu Bar&lt;/i&gt;&#39; Property of Form and Controls.&lt;/h3&gt;&lt;p&gt;The Menu Macro can be inserted into the Shortcut Menu Bar&amp;nbsp;Property of the Form or in the same Property of the Controls on the Form.&lt;/p&gt;&lt;p&gt;When added to the Form Property, the Menu appears wherever you right-click on the Form. When added to a specific Control&#39;s Shortcut Menu Bar Property, the Menu appears for that Control.&lt;/p&gt;&lt;p&gt;Most controls on the form have the &#39;Shortcut Menu Bar&#39; property, allowing you to insert a menu macro name to display the shortcut menu. When inserted into the TextBox&#39;s property, you can even right-click on the child label of the TextBox to bring up the shortcut menu.&lt;/p&gt;&lt;p&gt;Normally, in the OnClick Event Property of a Command Button or a TextBox, we can insert a Macro or a Public Function Name that executes when it receives a Mouse Button Click.&lt;/p&gt;&lt;p&gt;Despite the &#39;Shortcut Menu Bar&#39; property expecting a menu bar, it directly executes the macro or function name inserted into this property when the control receives a Right-click Event. Additionally, it briefly displays a small empty menu bar.&lt;/p&gt;&lt;p&gt;Examples:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Text0.Shortcut Menu Bar = &quot;Macro2&quot;&lt;/li&gt;&lt;li&gt;Text0.Shortcut Menu Bar = &quot;=ZoomOpen()&quot;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;We will experiment with both methods. Created the Macro Menu as above for easy implementation as well.&lt;/p&gt;&lt;p&gt;In this round of streamlining VBA code, we do not employ any object-level wrapper classes. Instead, we use only the interface class &lt;em data-end=&quot;224&quot; data-start=&quot;211&quot;&gt;Cls_ObjInit&lt;/em&gt;, which we can experiment with both approaches for utilizing the Zoom control.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Zoom Form with txtZoom TextBox.&lt;/h3&gt;&lt;p&gt;The Zoom Form Image is given below for Reference.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZXu6Ex0P0-eFlb0MWlxVqGgqqEPkNMlcqsAyk9O01vSEGtry9UAhmNtaAlN9NZk7Xh04t_Zn9DCrwSg9vT8-sgQBfQ_MUGBHgWprsNN_r28W8DCG-qtxSptBtK-AHZdqBD_4Na8fBDIpvhNp_GUwbo95T3J2a1hxJUVjlNOraPJs8OhjEdQzaAIzy-VZn/s869/ZoomFormImage.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;457&quot; data-original-width=&quot;869&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZXu6Ex0P0-eFlb0MWlxVqGgqqEPkNMlcqsAyk9O01vSEGtry9UAhmNtaAlN9NZk7Xh04t_Zn9DCrwSg9vT8-sgQBfQ_MUGBHgWprsNN_r28W8DCG-qtxSptBtK-AHZdqBD_4Na8fBDIpvhNp_GUwbo95T3J2a1hxJUVjlNOraPJs8OhjEdQzaAIzy-VZn/s320/ZoomFormImage.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open a large image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The Zoom Form has two Command Buttons. One to save the edited data into its Source Textbox, and the other to cancel the operation. Both Command Button Click Subroutines are written in the Form Module.&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private Sub cmdSave_Click()
  Call SaveZoomData
End Sub

Private Sub cmdCancel_Click()
  DoCmd.Close acForm, &quot;Zoom&quot;
End Sub
&lt;/pre&gt;

&lt;h3&gt;The Interface Class Module Cls_ObjInit&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private frm As Access.Form

Public Property Get m_Frm() As Form
  Set m_Frm = frm
End Property

Public Property Set m_Frm(ByRef vForm As Form)
  Set frm = vForm
  
  Call Class_Init
End Property

Private Sub Class_Init()
Dim opt As String

opt = &quot;McrControlShortcut&quot;

&#39;opt = &quot;=ZoomOpen()&quot; &#39;Call Function directly on Right-Click
&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;frm.ShortcutMenu = True &#39;True by default
Call SetupControls(opt)
       
End Sub

Private Sub SetupControls(ByVal strOpt As String)
Dim ctl As Control

For Each ctl In frm.Controls
  Select Case ctl.ControlType
Case acTextBox
    &#39;ctl.ShortcutMenuBar = StrOpt &#39;For all TextBoxes
            
      Select Case ctl.Name &#39;Only selected TextBoxes
          Case &quot;Title&quot;, &quot;Address&quot;, &quot;Notes&quot;
          
            ctl.ShortcutMenuBar = strOpt
            
      End Select

  End Select
Next
End Sub

Private Sub Class_Terminate()
Dim opt As String

opt = &quot;&quot;
Call SetupControls(opt)

End Sub

&lt;/pre&gt;
&lt;p data-end=&quot;258&quot; data-start=&quot;119&quot;&gt;The &lt;span data-end=&quot;138&quot; data-start=&quot;123&quot;&gt;Cls_ObjInit&lt;/span&gt; interface class declares a Form object in the global area, followed by the property procedures for handling the Form.&lt;/p&gt;&lt;p data-end=&quot;656&quot; data-start=&quot;260&quot;&gt;After receiving the active Form object through the &lt;code data-end=&quot;316&quot; data-start=&quot;311&quot;&gt;frm&lt;/code&gt; property, the &lt;span data-end=&quot;347&quot; data-start=&quot;331&quot;&gt;Class_Init()&lt;/span&gt; subroutine is executed. Both &lt;span data-end=&quot;393&quot; data-start=&quot;377&quot;&gt;Class_Init()&lt;/span&gt; and &lt;span data-end=&quot;419&quot; data-start=&quot;398&quot;&gt;Class_Terminate()&lt;/span&gt; call the common &lt;span data-end=&quot;455&quot; data-start=&quot;436&quot;&gt;SetUpControls()&lt;/span&gt; subroutine. This routine is responsible for either assigning the macro-based shortcut menu to the &lt;em data-end=&quot;573&quot; data-start=&quot;554&quot;&gt;Shortcut Menu Bar&lt;/em&gt; property of the Employees Form or directly invoking the &lt;span data-end=&quot;644&quot; data-start=&quot;630&quot;&gt;ZoomOpen()&lt;/span&gt; function.&lt;/p&gt;&lt;p data-end=&quot;836&quot; data-start=&quot;658&quot;&gt;The &lt;span data-end=&quot;683&quot; data-start=&quot;662&quot;&gt;Class_Terminate()&lt;/span&gt; subroutine resets the &lt;em data-end=&quot;725&quot; data-start=&quot;706&quot;&gt;Shortcut Menu Bar&lt;/em&gt; property, ensuring that changes made by the standalone class module &lt;span data-end=&quot;809&quot; data-start=&quot;794&quot;&gt;Cls_ObjInit&lt;/span&gt; are applied dynamically.&lt;/p&gt;&lt;p&gt;


&lt;/p&gt;&lt;p data-end=&quot;1061&quot; data-start=&quot;838&quot;&gt;With a small adjustment to the &lt;span data-end=&quot;885&quot; data-start=&quot;869&quot;&gt;Class_Init()&lt;/span&gt; subroutine, you can configure the &lt;em data-end=&quot;939&quot; data-start=&quot;920&quot;&gt;Shortcut Menu Bar&lt;/em&gt; property either for all TextBoxes (or any other control) on the Form or a specific one.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Trial Runs.&lt;/h3&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;568&quot; data-start=&quot;530&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p data-end=&quot;528&quot; data-start=&quot;126&quot;&gt;In the &lt;span data-end=&quot;149&quot; data-start=&quot;133&quot;&gt;Class_Init()&lt;/span&gt; subroutine, we plan to call the &lt;span data-end=&quot;201&quot; data-start=&quot;182&quot;&gt;SetUpControls()&lt;/span&gt; subroutine to dynamically configure the &lt;em data-end=&quot;261&quot; data-start=&quot;242&quot;&gt;Shortcut Menu Bar&lt;/em&gt; property of the TextBox controls. To better understand its behavior, we will experiment with two alternate settings, applying them one at a time. This trial approach allows us to observe how each configuration affects the functionality of the Zoom Control feature.&lt;/p&gt;
&lt;pre&gt;opt = &quot;McrControlShortcut&quot;

&#39;opt = &quot;=ZoomOpen()&quot; &#39;Call Function directly on Right-Click

frm.ShortcutMenu = True &#39;True by default
&amp;nbsp;&lt;/pre&gt;
&lt;p data-end=&quot;368&quot; data-start=&quot;126&quot;&gt;By default, the &lt;span data-end=&quot;175&quot; data-start=&quot;143&quot;&gt;second line of code is kept disabled&lt;/span&gt;. Remember that the setting &lt;code data-end=&quot;239&quot; data-start=&quot;214&quot;&gt;frm.ShortcutMenu = True&lt;/code&gt; is the default for the form. If the shortcut menu does not appear as expected, check this property in the form and correct it.&lt;/p&gt;&lt;p data-end=&quot;854&quot; data-start=&quot;370&quot;&gt;Before invoking the &lt;span data-end=&quot;409&quot; data-start=&quot;390&quot;&gt;SetUpControls()&lt;/span&gt; subroutine, the parameter variable &lt;code data-end=&quot;450&quot; data-start=&quot;445&quot;&gt;Opt&lt;/code&gt; is initialized with the macro menu name &lt;span data-end=&quot;515&quot; data-start=&quot;491&quot;&gt;&quot;McrControlShortcut&quot;&lt;/span&gt;. The subroutine then assigns this macro name to the TextBox control’s Property&amp;nbsp;&lt;em data-end=&quot;605&quot; data-start=&quot;586&quot;&gt;Shortcut Menu Bar&lt;/em&gt;. When this option is active, right-clicking the TextBox displays the custom shortcut menu. Choosing &lt;span data-end=&quot;730&quot; data-start=&quot;715&quot;&gt;“Open Zoom”&lt;/span&gt; from the menu runs the public function:&amp;nbsp;&lt;code data-end=&quot;782&quot; data-start=&quot;770&quot;&gt;ZoomOpen()&lt;/code&gt;, while the &lt;span data-end=&quot;806&quot; data-start=&quot;794&quot;&gt;“Cancel”&lt;/span&gt; option simply cancels the right-click action.&lt;/p&gt;&lt;p&gt;

&lt;/p&gt;&lt;p data-end=&quot;1040&quot; data-start=&quot;856&quot;&gt;When the second option in the &lt;span data-end=&quot;902&quot; data-start=&quot;886&quot;&gt;Class_Init()&lt;/span&gt; subroutine is enabled, the right-click event bypasses the macro and executes the &lt;code data-end=&quot;1028&quot; data-start=&quot;1016&quot;&gt;ZoomOpen()&lt;/code&gt; function.&lt;/p&gt;
&lt;p data-end=&quot;451&quot; data-start=&quot;74&quot;&gt;Similarly, the &lt;span data-end=&quot;107&quot; data-start=&quot;89&quot;&gt;SetUpControl()&lt;/span&gt; subroutine has two options. The default method assigns the &lt;em data-end=&quot;210&quot; data-start=&quot;191&quot;&gt;Shortcut Menu Bar&lt;/em&gt; property only to selected TextBox controls where data is likely to exceed the visible boundary. In this example, the fields include &lt;span data-end=&quot;372&quot; data-start=&quot;343&quot;&gt;Title, Address, and Notes&lt;/span&gt;. Additional fields can be included as needed, depending on the requirements.&lt;/p&gt;
&lt;p&gt;If we plan to implement it on all the TextBoxes on the Form, then the &lt;i&gt;&#39;ctl.ShortcutMenuBar = StrOpt&lt;/i&gt; can be enabled, and the following lines of VBA Code can be removed. &lt;/p&gt;
&lt;pre&gt;      Select Case ctl.Name &#39;Only selected TextBoxes
          Case &quot;Title&quot;, &quot;Address&quot;, &quot;Notes&quot;
          
            ctl.ShortcutMenuBar = strOpt
            
      End Select
&lt;/pre&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;The Employees Form Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Dim Cl As New Cls_ObjInit

Private Sub Form_Load()
Set Cl.m_Frm = Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Set Cl = Nothing
End Sub

&lt;/pre&gt;
&lt;p&gt;The Interface Class Cls_ObjInit is declared and instantiated in the global declaration area of the Employees Form. In the Form_Load() Event Procedure, the Current Form Object is passed to the Form Property Procedure, and from there the Class_Init() Subroutine is called to set the Shortcut Menu Bar Property of the TextBoxes in the Employees Form.&lt;/p&gt;
&lt;p&gt;This trick also works on the Tabular and Datasheet Forms. Two Demo Forms, Tabular and Datasheet Employee Forms, are also provided in the Demo Database.&lt;/p&gt;
&lt;h3&gt;Download the Demo Database.&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/03/DataEditing Zoom-in Control.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1K9iK5FDy_cIOo-J_6vNfTP1N-oStFhnG/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioFf-79SroXZ4JkiqgZYv196vvwuIDU6wLEconUKqF-8uKB4XfA4P2yshkCX2o16u08fw9nN8LkTe8XvDgBDDTepmbEqtmBreKye0SKYfz10iaUmM1loO3uX7sYhQvQctArB6ZjjzRO1Rw/s320/zip.gif&quot; width=&quot;22&quot; /&gt;DataEditing Zoom-in Control.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/03/DataEditing Zoom-in Control.zip--&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/1976638996803269086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/1976638996803269086'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/1976638996803269086'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html' title='Streamline Zoom-in Control Data Editing'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO8XxWVDaFf6h8jvxoUEdg6OTqGgSSHiWDSpAf6Wd2dNWOVjKEnHUv4tzi5yaP-ZK_8uNJi9UcIW4gSdgtlh3zz7pYc3Y8lQwoeQfZDnJgcFEVee4h_hPLPMhGacBmGMOaWoBI3qSF0YzGl_ATAxUknuVNcfsabVSfL7UXeBecjjfc-ZPhs2ClcxJpCO-q/s72-c/ZoomShortCut.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-1939475871597766898</id><published>2024-03-19T15:12:00.007+05:30</published><updated>2026-07-12T22:38:13.638+05:30</updated><title type='text'>Streamlining Code Reminder Popup Form</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Reminder Popup Form.&lt;/h2&gt;&lt;p&gt;Understanding the significance of reminders is paramount. When it comes to important occasions such as a family member&#39;s or a friend&#39;s birthday, adequate preparation time is crucial. Being notified at least two days beforehand, we don&#39;t overlook these events amidst our busy schedules and other pressing commitments.&lt;/p&gt;&lt;p&gt;When considering business-related activities, let&#39;s examine the Inventory System&#39;s advance notification of the Pharmacy&#39;s re-order status as an example. It&#39;s imperative to print a list of medicines that fall below the minimum stock level or reach reorder levels on the 25th of each month to facilitate stock replenishment by placing orders in advance.&lt;/p&gt;&lt;p&gt;Seasonal demand requires higher stock levels of certain medicines during winter. By reviewing usage patterns from previous years, we can identify high-demand medicines and place advance orders with suppliers to ensure adequate availability before the season begins.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;&lt;p&gt;Tasks that require advanced alerts or scheduled notifications can be programmed to trigger a pop-up form or report with the relevant information, ensuring timely attention and prompt action. The Birthday Experiment.&lt;/p&gt;&lt;p&gt;Here, we will demonstrate this feature using the Employees table, which has been extended with two additional fields:&amp;nbsp;&lt;em data-end=&quot;201&quot; data-start=&quot;190&quot;&gt;BirthDate&lt;/em&gt; and &lt;em data-end=&quot;213&quot; data-start=&quot;206&quot;&gt;BFlag&lt;/em&gt;. The &lt;em data-end=&quot;230&quot; data-start=&quot;219&quot;&gt;BirthDate&lt;/em&gt; field contains the assumed date of birth for each employee. For calculation purposes, the day and month of birth are combined with the current year (e.g., 14-March-1961 becomes 14-March-2024) to determine the birthdate. The logical field &lt;em data-end=&quot;483&quot; data-start=&quot;476&quot;&gt;BFlag&lt;/em&gt; is updated to True once the birthday greeting has been printed from the alert pop-up form.&lt;/p&gt;&lt;p&gt;The Alerts are programmed to run in three stages:&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;A pop-up form appears 48 hours before the individual&#39;s birthday and recurs again on the eve of the celebration.&lt;/li&gt;&lt;li&gt;&lt;p&gt;The pop-up form will display on the birthday when the &lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_blank&quot;&gt;database&lt;/a&gt; is accessed. A straightforward birthday greeting card in PDF format is generated directly from the pop-up. Upon completing the card printing process, the Employees Table field BFlag is marked to True, ensuring that the pop-up won&#39;t reappear during subsequent database openings.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;If the Birthday Greetings are not printed and the BFlag Field is not set to True, then the alert pop-up will appear for the next two days after the due date, indicating overdue case(s).&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Initially, we establish an input Query named &lt;i&gt;Birthday_RemData&lt;/i&gt;&amp;nbsp;that includes a new column to record each employee&#39;s birthdate for the Current Year, sourced from the actual BirthDate field in the &lt;i&gt;Employees1 &lt;/i&gt;table. The Birthday_RemData Query is the foundational dataset for categorizing data into the above three categories for pop-up forms.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Employees1 Table Image.&lt;/h3&gt;&lt;p&gt;The Employees1 Table image is shown below, with the required Fields for ready reference.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvD81ONnzze_glOR6qcp_-Bb31-fTpWTo9lMgHZBd6KFli0nloQuBodJ8v27ZqceF1HiS4pGPHS7OGWYMf8iBhQXiXXfCpQMG55mz_6fedp2PPJiAlJ0BtzFTX2YmW5hFKaoAlIr-_LZh8EJr52SFls5hnrLyVXhBHuO0LaUHYWa967d496Lusu0jLvG_9/s834/EmployeeBirthday.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;332&quot; data-original-width=&quot;834&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvD81ONnzze_glOR6qcp_-Bb31-fTpWTo9lMgHZBd6KFli0nloQuBodJ8v27ZqceF1HiS4pGPHS7OGWYMf8iBhQXiXXfCpQMG55mz_6fedp2PPJiAlJ0BtzFTX2YmW5hFKaoAlIr-_LZh8EJr52SFls5hnrLyVXhBHuO0LaUHYWa967d496Lusu0jLvG_9/s320/EmployeeBirthday.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Reminder: Data Filtering Queries.&lt;/h3&gt;&lt;p&gt;The SQL of the Input Query, with the current year Date of Birth, is calculated for each Employee, from the actual Date of Birth in the Table given below:&lt;/p&gt;&lt;p&gt;Query Name: BirthDay_RemData (Birthday Reminder Input Data).&lt;/p&gt;
&lt;pre&gt;SELECT Employees1.EmployeeID, 
[FirstName] &amp;amp; &quot; &quot; &amp;amp; [LastName] AS Name, 
Employees1.BirthDate, 
Employees1.BFlag, 
DateDiff(&quot;yyyy&quot;,[birthdate],Date()) AS Age, 
DateValue(Format([BirthDate],&quot;dd/mm&quot;) &amp;amp; &quot;-&quot; &amp;amp; CStr(Year(Date()))) AS DueDate
FROM Employees1;
&lt;/pre&gt;
&lt;p&gt;1. Query:&amp;nbsp;RemindQ1_OnDate - to filter data for the Popup on the actual BirthDay:&lt;/p&gt;
&lt;pre&gt;SELECT BirthDay_RemData.*
FROM BirthDay_RemData
WHERE (((BirthDay_RemData.DueDate)=Date()) AND ((BirthDay_RemData.BFlag)=False));
&lt;/pre&gt;
&lt;p&gt;2. Query:&amp;nbsp;RemindQ2_Advance - to filter data for the Popup that appears two days before the BirthDay:&lt;/p&gt;
&lt;pre&gt;SELECT BirthDay_RemData.*
FROM BirthDay_RemData
WHERE (((BirthDay_RemData.BFlag)=False) AND (([DueDate]-1)=Date()))
OR (((BirthDay_RemData.BFlag)=False) AND (([DueDate]-2)=Date()));

&lt;/pre&gt;
&lt;p&gt;3. Query:&amp;nbsp;RemindQ3_OverDue - to filter data for the Popup that appears two days after the BirthDay, if the birthday card is not printed on the Birthday.:&lt;/p&gt;
&lt;pre&gt;SELECT BirthDay_RemData.*
FROM BirthDay_RemData
WHERE (((BirthDay_RemData.BFlag)=False) AND (([DueDate]+1)=Date())) 
OR (((BirthDay_RemData.BFlag)=False) AND (([DueDate]+2)=Date()));

&lt;/pre&gt;

&lt;p&gt;The RemindQ1_OnDate Query is the source Data of the&amp;nbsp;Reminder1 Popup Form. The Reminder2 and Reminder3 Forms are linked to the RemindQ2_Advance and RemindQ3_Overdue Queries, respectively. All three are Tabular Forms.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Reminder: POPUP Forms.&lt;/h3&gt;&lt;p&gt;1. The Reminder1 Popup Form Image is given below for reference.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkcNUP93kAmHnqliSEARFqnvRU5IS9_LwJukwf1eu5rn0MoVBEB47kH4JNYGY3bxszAGt8MfAS3fAhpT7IxKaZCOVSTvHao8K_kottCPuLCw00xrgT39W5DJdAEwiDF1nl0-CSf9v1fe7kOR09bVeadVO5VRNoversgCtn1EnrgeOg1qooCd_zJHdER6XD/s858/BirthDayPopup1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Birthday Popup Form&quot; border=&quot;0&quot; data-original-height=&quot;650&quot; data-original-width=&quot;858&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkcNUP93kAmHnqliSEARFqnvRU5IS9_LwJukwf1eu5rn0MoVBEB47kH4JNYGY3bxszAGt8MfAS3fAhpT7IxKaZCOVSTvHao8K_kottCPuLCw00xrgT39W5DJdAEwiDF1nl0-CSf9v1fe7kOR09bVeadVO5VRNoversgCtn1EnrgeOg1qooCd_zJHdER6XD/s320/BirthDayPopup1.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The employee records with birthdays matching today’s date will be displayed on the Form, showing their actual date of birth and the birthday for the current year in separate columns. You can print the greeting card by clicking the “Print PDF Greeting” &lt;a href=&quot;https://www.msaccesstips.com/2008/04/transparent-command-button.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt;. The default path of the greeting’s target location can be temporarily altered directly in the text box. You can make the change permanent in the Default Value &lt;a href=&quot;https://www.msaccesstips.com/2008/09/source-connect-str-property-and-odbc.html&quot; target=&quot;_blank&quot;&gt;Property&lt;/a&gt; of the text box in the design view.&lt;/p&gt;&lt;p&gt;The Advance and Overdue Reminder Popups may show differently in Day/Month in both columns. The Printing option is not available in the Advanced and Overdue Popup Forms&amp;nbsp;Footer Section.&lt;/p&gt;&lt;p&gt;The Greetings PDF file will be saved to the path indicated in the &lt;a href=&quot;https://www.msaccesstips.com/2019/04/withevents-button-combo-list-textbox-tab.html&quot; target=&quot;_blank&quot;&gt;TextBox&lt;/a&gt;&amp;nbsp;in the Footer Section of the Form. The path displayed in the TextBox is set in the TextBox Default Value &lt;a href=&quot;https://www.msaccesstips.com/2009/11/creating-using-form-custom-property.html&quot; target=&quot;_blank&quot;&gt;Property&lt;/a&gt;, which you can modify to save it to your preferred path.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Sample Greetings Card.&lt;/h3&gt;&lt;p&gt;The sample Greetings Card image is given below for reference.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx3x6gmXeQ6CGPBpduxpOI5cDA39bpbIVxgVGaOXEtc6LMEPSaDP0CqwHOTcaJi1dXv_W3F2E29tK-quvZIpKfRuUT6F9EybTgtVXCnTqENq5aHvYBc3d8K6XTq_HBYzgK8KkhwyCHdEVo7cZOwHu9ytfjuFyLbZjvVt1tKfLue45UDjK2HmpRKuPUBZxj/s864/BirthdayPDF.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;812&quot; data-original-width=&quot;864&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx3x6gmXeQ6CGPBpduxpOI5cDA39bpbIVxgVGaOXEtc6LMEPSaDP0CqwHOTcaJi1dXv_W3F2E29tK-quvZIpKfRuUT6F9EybTgtVXCnTqENq5aHvYBc3d8K6XTq_HBYzgK8KkhwyCHdEVo7cZOwHu9ytfjuFyLbZjvVt1tKfLue45UDjK2HmpRKuPUBZxj/s320/BirthdayPDF.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The other two Popup Form Images are given below for information.&lt;/p&gt;&lt;p&gt;2. Alert about upcoming Birthdays:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL2cC3u_PqAggVt7eiaSH2FWkbKqkUiYUnoqzSLGfxaH_j7uYW-kLYDcqZHJcIgjsblZ1uVX_TDJuYXWTLjGsEH4vZZQf7o5cpkTwg_sXLL0zr4lNFGh1adCiIzzZs6x-7l9WT0-PhOsXYA3QAFkRiyf1zYCTsR_O9KmSWNywQV_CpC2G24M7ssUp_Bpyv/s850/BirthDayAdvanceInfo.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;452&quot; data-original-width=&quot;850&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL2cC3u_PqAggVt7eiaSH2FWkbKqkUiYUnoqzSLGfxaH_j7uYW-kLYDcqZHJcIgjsblZ1uVX_TDJuYXWTLjGsEH4vZZQf7o5cpkTwg_sXLL0zr4lNFGh1adCiIzzZs6x-7l9WT0-PhOsXYA3QAFkRiyf1zYCTsR_O9KmSWNywQV_CpC2G24M7ssUp_Bpyv/s320/BirthDayAdvanceInfo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;3. Alerts about the missed Birthday Celebrations:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiRh7LuYTeEIptRXvMzgp7v38xQym0tUFeslT6AW3iV2tPlv71PykNQqCc-ieknNcWpahdMHVU941PiJT4mgUpIYYRTRbTnTqcA_bw72nnqZcMS_36GGR1xgZaW5ni2GujNTxbEEaH72-Le1bM2GI1w2BYBkzCkPf2MYwg2jA-eGtCktRI7QcBVaZlQiDx/s852/BirthDayMissedInfo.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;456&quot; data-original-width=&quot;852&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiRh7LuYTeEIptRXvMzgp7v38xQym0tUFeslT6AW3iV2tPlv71PykNQqCc-ieknNcWpahdMHVU941PiJT4mgUpIYYRTRbTnTqcA_bw72nnqZcMS_36GGR1xgZaW5ni2GujNTxbEEaH72-Le1bM2GI1w2BYBkzCkPf2MYwg2jA-eGtCktRI7QcBVaZlQiDx/s320/BirthDayMissedInfo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;How do the Popup Form(s) open automatically if the Employee&#39;s Date of Birth meets any of the criteria specified above?&lt;/p&gt;&lt;p&gt;It is easy; when the database is open, it checks for records in the three Queries (i.e., RemindQ1_OnDate, RemindQ2_Advance, and RemindQ3_OverDue) and opens the Alert Form linked to the Queries. For this purpose, a small Function is created in the Standard &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html &quot; target=&quot;_blank&quot;&gt;Module&lt;/a&gt;.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The VBA Code of the Checkpopup() Function.&lt;/h3&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;Public Function Checkpopup()
&#39;========================================================
&#39;Project: Reminder Popup Form
&#39;Author : a.p.r. pillai
&#39;Date   : March, 2024
&#39;Rights : All Rights(c) Reserved by www.msaccesstips.com
&#39;Remarks: Opens up preset Reminder Popup Form(s)
&#39;       : on pre-scheuled Date/Month
&#39;Example: Employees&#39; Date-of-Birth Reminder.
&#39;========================================================
Dim i, j, k As Integer
i = DCount(&quot;*&quot;, &quot;RemindQ1_OnDate&quot;)
If i &amp;gt; 0 Then
    DoCmd.OpenForm &quot;Reminder1&quot;, acNormal
End If

j = DCount(&quot;*&quot;, &quot;RemindQ2_Advance&quot;)
If j &amp;gt; 0 Then
    DoCmd.OpenForm &quot;Reminder2&quot;, acNormal
End If

k = DCount(&quot;*&quot;, &quot;RemindQ3_OverDue&quot;)
If k &amp;gt; 0 Then
    DoCmd.OpenForm &quot;Reminder3&quot;, acNormal
End If

End Function
&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Running the Popup Forms.&lt;/h3&gt;&lt;p&gt;Now all we need to do is call this Function immediately after opening the Database. The first choice to create a Macro named AutoExec&amp;nbsp;(the Auto Execute Macro) and call the Function using the &lt;i&gt;RunCode&lt;/i&gt; Command. The name of the Macro must be &lt;i&gt;AutoExec&lt;/i&gt; to run immediately when the Database is open. Another option is to drag this Macro, place it on the &lt;a href=&quot;https://www.msaccesstips.com/2021/03/ms-access-and-creating-desktop-shortcuts.html&quot; target=&quot;_blank&quot;&gt;Desktop as a Shortcut.&lt;/a&gt; Double-click on it to open the Database and run the Macro.&lt;/p&gt;
&lt;p&gt;Another option is to run the Function from the Form_Load() Event Subroutine of the first Form that opens when the database is open.&lt;/p&gt;
&lt;p&gt;If there is no urgency, call the Function when the Employees Form is open; then PopUp Form(s) will appear if any of the three data-filtering Queries, or all of them, have data after a brief 3-second delay.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;p&gt;This is good for experimenting with this trick and learning to devise a better method for Advanced Alerts, on-the-day or Overdue Alerts in your other Projects.&lt;/p&gt;
&lt;h3&gt;The Employee Form-based Popup.&lt;/h3&gt;
&lt;p&gt;There are three employee Forms for each Reminder category. All of them can be opened from a small Main Form. The Image of the Main Form is given below.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTTPcaDrEqheIBbLkgNPXxE19DbvpzZboJ1m9LGt3uGjkfXpDhJ89V-LKWQLOdtK9QE7XXXtHyXJJkncP8DokT5rrGVSjeG_RbfUysc6D9eUv-qBJbVvZ2AJBwWGgEVHZgBY1Xg4Kokly13zZZq1GsNu4mU9eYzGkOUKV3X1iz678bQYKMmrr59bN_IZe_/s654/ReminderMain.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Remainder Main Form&quot; border=&quot;0&quot; data-original-height=&quot;540&quot; data-original-width=&quot;654&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTTPcaDrEqheIBbLkgNPXxE19DbvpzZboJ1m9LGt3uGjkfXpDhJ89V-LKWQLOdtK9QE7XXXtHyXJJkncP8DokT5rrGVSjeG_RbfUysc6D9eUv-qBJbVvZ2AJBwWGgEVHZgBY1Xg4Kokly13zZZq1GsNu4mU9eYzGkOUKV3X1iz678bQYKMmrr59bN_IZe_/s320/ReminderMain.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The Employees Form Image of the First Option:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE48GTayBZYQuDX8sXGTxV9hLBS8sLaZGdogscXlL_dg49gu4ohqesqonPgiQTS7XFRqp_mXffs5Gq2XclGn2uoUPgEx7m6S6DZTyVu7PuOgpW_6n_RGvKdsoAhECEmbglDRdfNUSM6lUbi12-oqc2Cs4ue3GYaVt4TOD4HLsmdvbZtd2D57lItrx5TFNI/s1121/Employee1Reminder.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;724&quot; data-original-width=&quot;1121&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE48GTayBZYQuDX8sXGTxV9hLBS8sLaZGdogscXlL_dg49gu4ohqesqonPgiQTS7XFRqp_mXffs5Gq2XclGn2uoUPgEx7m6S6DZTyVu7PuOgpW_6n_RGvKdsoAhECEmbglDRdfNUSM6lUbi12-oqc2Cs4ue3GYaVt4TOD4HLsmdvbZtd2D57lItrx5TFNI/s320/Employee1Reminder.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;When you open this Form, there is a delay of about 3 seconds; the Reminder1_OnDate Popup Form will open with the Employees&#39; Records having their BirthDate today. If there are no records, the [Open Reminder] Command Button is disabled. If the pop-up doesn&#39;t appear, change the BirthDate of one or two employees to match the Day and Month (don&#39;t change the year) to match the current Date.&lt;/p&gt;&lt;p&gt;If you close the Reminder Form by mistake, use the CommandButton that opens the Reminder Form.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;There are two other Forms for experimenting with Reminders of forthcoming or overdue Reminder setups.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Streamlining VBA Event Subroutine Codes.&lt;/h3&gt;&lt;p&gt;Now coming to the &lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_blank&quot;&gt;Streamlined VBA&lt;/a&gt; Coding Part, there are three Employee Forms with two CommandButtons. The Employee information is for display purposes only. If you plan to edit the employee&#39;s Birthdate through this Form, you are welcome, but the validation check is not performed, and full responsibility is yours. All three Forms are linked to the same Employees1 Table.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Since all three forms have two command buttons each, we need only one CommandButton Wrapper Class to handle the Events of Command Button Clicks. But we will use three different Class_Init() Interface Classes (Intermediary Class) to create separate Instances for all three Employee Forms, so that their Identity References will remain separately in memory. The 3-second TimerInterval running Subroutine is also run from within this Class Module and then opens the Popup Form.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Command Button Wrapper Class: &lt;i&gt;Rm1_cmdButton&lt;/i&gt; - Employee Forms.&lt;/h3&gt;
&lt;pre&gt; 
Option Compare Database
Option Explicit

Private WithEvents cmd As Access.CommandButton
Private mfrm As Form
Dim t As Integer
&#39;========================================================
&#39;Project: Reminder Popup Form
&#39;Author : a.p.r. pillai
&#39;Date   : March, 2024
&#39;Rights : All Rights(c) Reserved by www.msaccesstips.com
&#39;Remarks: Opens up preset Reminder Popup Form(s)
&#39;       : on pre-scheuled Date/Month
&#39;Example: Employees&#39; Date-of-Birth Reminder.
&#39;========================================================

Public Property Get m_Frm() As Access.Form
  Set m_Frm = mfrm
End Property

Public Property Set m_Frm(ByRef vfrm As Access.Form)
  Set mfrm = vfrm
End Property

Public Property Get m_cmd() As Access.CommandButton
  Set m_cmd = cmd
End Property

Public Property Set m_cmd(ByRef vcmd As Access.CommandButton)
  Set cmd = vcmd
End Property

Private Sub cmd_Click()
  Select Case cmd.Name
    Case &quot;cmdReminder1&quot;
        DoCmd.OpenForm &quot;Reminder1&quot;, acNormal
    Case &quot;cmdReminder2&quot;
        DoCmd.OpenForm &quot;Reminder2&quot;, acNormal
    Case &quot;cmdReminder3&quot;
        DoCmd.OpenForm &quot;Reminder3&quot;, acNormal
        
    Case &quot;cmdExit1&quot;
        DoCmd.Close acForm, &quot;Employees1&quot;
    Case &quot;cmdExit2&quot;
        DoCmd.Close acForm, &quot;Employees2&quot;
    Case &quot;cmdExit3&quot;
        DoCmd.Close acForm, &quot;Employees3&quot;
  End Select
End Sub

&lt;/pre&gt;
&lt;p&gt;We need only one Click-Event Subroutine in the Class Module to handle the &lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; Clicks from all three Forms. The Code is not messy and remains clean and directly accessible, rather than through the Form Design View. The Event Procedure Code is self-explanatory.&lt;/p&gt;

&lt;p&gt;Three different Interface Class Modules for different Employee Forms. We don&#39;t create Instances of the Interface Class. Hence, we need to create three different Interface Classes. Moreover, it runs the TimerInterval Subroutine for three different Forms.&lt;/p&gt;
&lt;h3&gt;Interface Class of Employees1 Form: &lt;i&gt;Rm1_Init&lt;/i&gt; Class VBA Code.&lt;/h3&gt;
&lt;pre&gt; Option Compare Database
Option Explicit

Private cmd As Rm1_CmdButton
Private WithEvents frm As Form

Private Coll As New Collection
Dim t As Integer

&#39;========================================================
&#39;Project: Reminder Popup Form
&#39;Author : a.p.r. pillai
&#39;Date   : March, 2024
&#39;Rights : All Rights(c) Reserved by www.msaccesstips.com
&#39;Remarks: Opens up preset Reminder Popup Form(s)
&#39;       : on pre-scheuled Date/Month
&#39;Example: Employees&#39; Date-of-Birth Reminder.
&#39;========================================================

Public Property Get m_Frm() As Form
  Set m_Frm = frm
  
End Property

Public Property Set m_Frm(ByRef vfrm As Form)
  Set frm = vfrm
  
  Call Class_Init
  
End Property

Private Sub Class_Init()
Dim ctl As Control
Const EP = &quot;[Event Procedure]&quot;

frm.OnTimer = EP

For Each ctl In frm.Controls
    Select Case TypeName(ctl)
        Case &quot;CommandButton&quot;
          Select Case ctl.Name
            Case &quot;cmdReminder1&quot;, &quot;cmdExit1&quot;
            Set cmd = New Rm1_CmdButton
            Set cmd.m_Frm = frm
            Set cmd.m_cmd = ctl
                cmd.m_cmd.OnClick = EP
                Coll.Add cmd
            Set cmd = Nothing
          End Select
    End Select
Next

t = 0
frm.TimerInterval = 1000
End Sub

Private Sub frm_Timer()
Dim icount As Long
On Error GoTo frmTimer_Err

t = t + 1
If t = 3 Then
    frm.TimerInterval = 0
icount = DCount(&quot;*&quot;, &quot;RemindQ1_OnDate&quot;)
    If icount &amp;gt; 0 Then
        t = 0
        frm.cmdReminder1.Enabled = True
        Call PopupOpen(&quot;Reminder1&quot;)
    Else
        frm.cmdReminder1.Enabled = False
        frm.Requery
    End If
End If

frmTimer_Exit:
Exit Sub

frmTimer_Err:
MsgBox Err.Description, , &quot;frmTimer()&quot;
Resume frmTimer_Exit
End Sub

Private Sub Class_Terminate()
Do While Coll.Count &amp;gt; 0
    Coll.Remove 1
Loop

End Sub
&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;This class module is declared within the Employee1 Form Module, where a &lt;a href=&quot;https://www.msaccesstips.com/2013/08/external-references-in-conditional.html&quot; target=&quot;_blank&quot;&gt;reference&lt;/a&gt; to the Employee1 form is passed to the `frm` object. The `Class_Initialize` procedure is then invoked. At the beginning of this procedure, the &lt;i&gt;Employee1&lt;/i&gt; Form&#39;s Timer event is enabled, followed by the creation of Command Button instances and the initialization of their event handling procedures.&lt;/p&gt;

&lt;p&gt;The Timer Interval is set to 1000 milliseconds (1 second), and the Timer event runs for three consecutive intervals (3 seconds). After this 3-second delay, the record count of the `ReminderQ1_OnDate` query is retrieved. If the record count is greater than 0, the `Reminder1_OnDate` popup form is opened to display the corresponding reminder records.&lt;/p&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;Interface Class of Employees2 Form: Rm2_Init Class.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private cmd As Rm1_CmdButton
Private WithEvents frm As Form

Private Coll As New Collection
Dim t As Integer
&#39;========================================================
&#39;Project: Reminder Popup Form
&#39;Author : a.p.r. pillai
&#39;Date   : March, 2024
&#39;Rights : All Rights(c) Reserved by www.msaccesstips.com
&#39;Remarks: Opens up preset Reminder Popup Form(s)
&#39;       : on pre-scheuled Date/Month
&#39;Example: Employees&#39; Date-of-Birth Reminder.
&#39;========================================================

Public Property Get m_Frm() As Form
  Set m_Frm = frm
  
End Property

Public Property Set m_Frm(ByRef vfrm As Form)
  Set frm = vfrm
  
  Call Class_Init
  
End Property

Private Sub Class_Init()
Dim ctl As Control
Const EP = &quot;[Event Procedure]&quot;

frm.OnTimer = EP

For Each ctl In frm.Controls
    Select Case TypeName(ctl)
        Case &quot;CommandButton&quot;
          Select Case ctl.Name
            Case &quot;cmdReminder2&quot;, &quot;cmdExit2&quot;
            Set cmd = New Rm1_CmdButton
            Set cmd.m_Frm = frm
            Set cmd.m_cmd = ctl
                cmd.m_cmd.OnClick = EP
                Coll.Add cmd
            Set cmd = Nothing
          End Select
    End Select
Next

t = 0
frm.TimerInterval = 1000
End Sub

Private Sub frm_Timer()
Dim icount As Long
On Error GoTo frmTimer_Err

t = t + 1
If t = 3 Then
    frm.TimerInterval = 0
icount = DCount(&quot;*&quot;, &quot;RemindQ2_Advance&quot;)
    If icount &amp;gt; 0 Then
        t = 0
        frm.cmdReminder2.Enabled = True
        frm.Requery
  
        Call PopupOpen(&quot;Reminder2&quot;)
    Else
        frm.cmdReminder2.Enabled = False
        frm.Requery
    End If
End If

frmTimer_Exit:
Exit Sub

frmTimer_Err:
MsgBox Err.Description, , &quot;frmTimer()&quot;
Resume frmTimer_Exit
End Sub

Private Sub Class_Terminate()
Do While Coll.Count &amp;gt; 0
    Coll.Remove 1
Loop

End Sub

&lt;/pre&gt;
&lt;p&gt;The only difference in this Module is the query name and CommandButton Names. We use the same Rm1_CmdButton Wrapper Class.&lt;/p&gt;&lt;p&gt;Rm3_Init Interface Class also has the same VBA Code with different Query and Command Button Names. &lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private cmd As Rm1_CmdButton
Private WithEvents frm As Form

Private Coll As New Collection
Dim t As Integer
&#39;========================================================
&#39;Project: Reminder Popup Form
&#39;Author : a.p.r. pillai
&#39;Date   : March, 2024
&#39;Rights : All Rights(c) Reserved by www.msaccesstips.com
&#39;Remarks: Opens up preset Reminder Popup Form(s)
&#39;       : on pre-scheuled Date/Month
&#39;Example: Employees&#39; Date-of-Birth Reminder.
&#39;========================================================

Public Property Get m_Frm() As Form
  Set m_Frm = frm
  
End Property

Public Property Set m_Frm(ByRef vfrm As Form)
  Set frm = vfrm
  
  Call Class_Init
  
End Property

Private Sub Class_Init()
Dim ctl As Control
Const EP = &quot;[Event Procedure]&quot;

&#39;frm.OnTimer = EP

For Each ctl In frm.Controls
    Select Case TypeName(ctl)
        Case &quot;CommandButton&quot;
          Select Case ctl.Name
            Case &quot;cmdReminder3&quot;, &quot;cmdExit3&quot;
                Set cmd = New Rm1_CmdButton
                Set cmd.m_Frm = frm
                    cmd.m_Frm.OnTimer = EP
                Set cmd.m_cmd = ctl
                    cmd.m_cmd.OnClick = EP
                    Coll.Add cmd
            Set cmd = Nothing
        End Select
    End Select
Next

t = 0
frm.TimerInterval = 1000

End Sub

Private Sub frm_Timer()
Dim icount As Long
&#39;On Error GoTo frmTimer_Err

t = t + 1
If t = 3 Then
    frm.TimerInterval = 0
  icount = DCount(&quot;*&quot;, &quot;RemindQ3_OverDue&quot;)
    If icount &amp;gt; 0 Then
        t = 0
        frm.cmdReminder3.Enabled = True
        frm.Requery
  
        Call PopupOpen(&quot;Reminder3&quot;)
    Else
        frm.cmdReminder3.Enabled = False
        frm.Requery
    End If
End If

frmTimer_Exit:
Exit Sub

frmTimer_Err:
MsgBox Err.Description, , &quot;frmTimer()&quot;
Resume frmTimer_Exit
End Sub

Private Sub Class_Terminate()
Do While Coll.Count &amp;gt; 0
    Coll.Remove 1
Loop

End Sub

&lt;/pre&gt;
&lt;h3&gt;The Popup Forms&#39; Wrapper Class and Interface Class Module VBA Code.&lt;/h3&gt;
&lt;p&gt;Only one &lt;a href=&quot;https://www.msaccesstips.com/2018/11/vba-base-class-and-derived-object-2.html&quot; target=&quot;_blank&quot;&gt;Wrapper Class&lt;/a&gt; Module and one Interface Class are required for all three Popup Forms to handle the Event Procedures of Command Buttons. All three Forms have only Command Button click events handled in the Wrapper Class Sub_CmdButton and Interface Class Module.&lt;/p&gt;
&lt;h3&gt;The Sub_CmdButton Wrapper Class Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents cmd As Access.CommandButton
Private frm As Form
&#39;========================================================
&#39;Project: Reminder Popup Form
&#39;Author : a.p.r. pillai
&#39;Date   : March, 2024
&#39;Rights : All Rights(c) Reserved by www.msaccesstips.com
&#39;Remarks: Opens up preset Reminder Popup Form(s)
&#39;       : on pre-scheuled Date/Month
&#39;Example: Employees&#39; Date-of-Birth Reminder.
&#39;========================================================

Public Property Get m_Frm() As Access.Form
  Set m_Frm = frm
End Property

Public Property Set m_Frm(ByRef vfrm As Access.Form)
  Set frm = vfrm
End Property

Public Property Get m_cmd() As Access.CommandButton
  Set m_cmd = cmd
End Property

Public Property Set m_cmd(ByRef vcmd As Access.CommandButton)
  Set cmd = vcmd
End Property

Private Sub cmd_Click()
  Select Case cmd.Name
   Case &quot;cmdPrint1&quot;
        Call GreetingsPrint
        
    Case &quot;cmdCancel1&quot;
        DoCmd.Close acForm, &quot;Reminder1&quot;
    Case &quot;cmdCancel2&quot;
        DoCmd.Close acForm, &quot;Reminder2&quot;
    Case &quot;cmdCancel3&quot;
        DoCmd.Close acForm, &quot;Reminder3&quot;
  End Select
End Sub

Private Sub GreetingsPrint()
Dim strSQL As String
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim qryDef As DAO.QueryDef
Dim EID As Integer
Dim OutFile As String

&#39;On Error GoTo GreetingsPrint_Err

Set db = CurrentDb
Set rst = db.OpenRecordset(&quot;RemindQ1_OnDate&quot;, dbOpenDynaset)

rst.MoveLast
rst.MoveFirst

Do While Not rst.EOF And Not rst.BOF
    EID = rst![EmployeeID]
    strSQL = &quot;SELECT RemindQ1_OnDate.* FROM RemindQ1_OnDate &quot;
    strSQL = strSQL &amp;amp; &quot;WHERE (((RemindQ1_OnDate.EmployeeID)= &quot;
    strSQL = strSQL &amp;amp; EID &amp;amp; &quot;));&quot;

Set qryDef = db.QueryDefs(&quot;BirthDayQ1OnDate_PDF&quot;)
    qryDef.SQL = strSQL
    db.QueryDefs.Refresh

DoCmd.OpenReport &quot;Greetings1_PDF&quot;, acViewPreview
If MsgBox(&quot;Birthday Greetings Print Initiated, Proceed?&quot;, vbYesNo, &quot;Greetings Print()&quot;) = vbNo Then
DoCmd.Close acReport, &quot;Greetings1_PDF&quot;
   Exit Sub
End If
DoCmd.Close acReport, &quot;Greetings1_PDF&quot;

OutFile = frm!Path &amp;amp; DLookup(&quot;Name&quot;, &quot;BirthdayQ1OnDate_PDF&quot;, &quot;EmployeeID = &quot; &amp;amp; EID) &amp;amp; &quot;.pdf&quot;
DoCmd.OutputTo acOutputReport, &quot;Greetings1_PDF&quot;, &quot;PDFFormat(*.pdf)&quot;, OutFile, False, &quot;&quot;, 0, acExportQualityPrint

rst.MoveNext
Loop

  rst.Close
  Set rst = Nothing
  Set db = Nothing


DoCmd.SetWarnings False
&#39;Delete earlier saved records
DoCmd.OpenQuery &quot;BirthDayReminder1_Del&quot;, acViewNormal

&#39;Add latest records
DoCmd.OpenQuery &quot;BDay_SavedQ1&quot;, acViewNormal

&#39;Flag the Employee Record as Greetings Printed
&#39;Reset the floags on January 1st, Next Year
DoCmd.OpenQuery &quot;BirthDayQ_UpdateFlag1&quot;, acViewNormal
DoCmd.SetWarnings True

MsgBox &quot;Greetings PDFs are saved in Path: &quot; &amp;amp; frm!Path

GreetingsPrint_Exit:
Exit Sub

GreetingsPrint_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;GreetingsPrint_Click()&quot;
Resume GreetingsPrint_Exit
End Sub
&lt;/pre&gt;
&lt;p&gt;In the cmd_Click() Event Subroutine, the cmdPrint1 Command Button Click on the Reminder1 Form calls the GreetingsPrint() Subroutine, and prints the Birthday Greetings in PDF format. It updates the Employees1 Table, marking the BFlag logical Field as True to prevent it from appearing in the Employee record again in the Popup Form. The Greetings will be printed separately for each Employee Record.&lt;/p&gt;&lt;p&gt;After printing the Popup Form, the records will be saved into a separate temporary Table: Birthday_Reminder1.&lt;/p&gt;
&lt;h3&gt;The Sub_Init Interface Class Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private cmd As Sub_CmdButton
Private frm As Form
Private Coll As New Collection

Public Property Get m_Frm() As Form
  Set m_Frm = frm
  
End Property

Public Property Set m_Frm(ByRef vfrm As Form)
  Set frm = vfrm
  
  Call Class_Init
  
End Property

Private Sub Class_Init()
Dim ctl As Control
Const EP = &quot;[Event Procedure]&quot;

&#39;Set frm2 = frm.BReminderSub1.Form
For Each ctl In frm.Controls
    Select Case TypeName(ctl)
        Case &quot;CommandButton&quot;
          Select Case ctl.Name
            Case &quot;cmdPrint1&quot;, &quot;cmdCancel1&quot;, _
            &quot;cmdCancel2&quot;, &quot;cmdCancel3&quot;
            Set cmd = New Sub_CmdButton
            Set cmd.m_Frm = frm
            Set cmd.m_cmd = ctl
                cmd.m_cmd.OnClick = EP
                Coll.Add cmd
            Set cmd = Nothing
        End Select
    End Select
Next
End Sub

Private Sub Class_Terminate()
Do While Coll.Count &amp;gt; 0
    Coll.Remove 1
Loop

End Sub

&lt;/pre&gt; 
&lt;p&gt;All three Popup Forms: Reminder1, Reminder2, and Reminder3 have Command Buttons with unique Names to Close the Forms, and all of them are included in the Class_Init() Subroutine. Because of their unique names, we could handle their Event Procedures in a Single Wrapper Class Module.&lt;/p&gt;&lt;p&gt;Even though the Code requirement is simple, the Standalone &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;Class Module VBA Coding&lt;/a&gt; gives you much flexibility for maintaining Code in a centralized location. It needs only one Click Event Subroutine for several CommandButton Click Events.&lt;/p&gt;
&lt;h3&gt;Demo Database Download&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/03/RemnderPopup2.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1IrWO7gqFYc2s8fk7qg241rMpjq4VTiKo/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioFf-79SroXZ4JkiqgZYv196vvwuIDU6wLEconUKqF-8uKB4XfA4P2yshkCX2o16u08fw9nN8LkTe8XvDgBDDTepmbEqtmBreKye0SKYfz10iaUmM1loO3uX7sYhQvQctArB6ZjjzRO1Rw/s320/zip.gif&quot; width=&quot;22&quot; /&gt;RemnderPopup2.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/03/RemnderPopup2.zip--&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/1939475871597766898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/1939475871597766898'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/1939475871597766898'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html' title='Streamlining Code Reminder Popup Form'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvD81ONnzze_glOR6qcp_-Bb31-fTpWTo9lMgHZBd6KFli0nloQuBodJ8v27ZqceF1HiS4pGPHS7OGWYMf8iBhQXiXXfCpQMG55mz_6fedp2PPJiAlJ0BtzFTX2YmW5hFKaoAlIr-_LZh8EJr52SFls5hnrLyVXhBHuO0LaUHYWa967d496Lusu0jLvG_9/s72-c/EmployeeBirthday.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-2743524632942007436</id><published>2024-02-29T13:43:00.010+05:30</published><updated>2026-07-12T20:19:04.105+05:30</updated><title type='text'>Streamlining Code Database Compacting Utility</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Database Compact/Repair Utility.&lt;/h3&gt;&lt;p&gt;The &#39;Compact on Close&#39; Option in Microsoft Access. When enabled under File --&amp;gt; Current Database --&amp;gt; Application Options, this feature automatically compacts the database when you open and close it. Additionally, you can manually select the Compact/Repair option from the File menu to Compact and repair the active database. If you need to compact an external file, you can select the &quot;Compact and Repair&quot; option from the Database Tools Menu.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;p&gt;If you prefer not to perform the Compact and Repair process daily, you can run the Compact/Repair Utility for multiple Databases together, such as weekly or biweekly. In this case, you can conveniently select those Databases from the &lt;a href=&quot;https://www.msaccesstips.com/2022/05/get-disk-free-space-windows-api.html&quot; target=&quot;_blank&quot;&gt;Disk&lt;/a&gt; and add them to a ListBox, as illustrated in the form image below.&lt;/p&gt;
 &lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
  &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivnGfeCLtSqcXe0WElcadGd-8uAbEEMql9Mkl9DLBv54KNreDgU1XXJpVLaAiXCNse8amsOqfgQydJDNh8POIW7YtjCi_0N21QsN8YShXgrbNr6mSOl4ijRZQJCX4zvrfu7_J-MS7QKx3wi8X8sbL-qk1pO1QmNP1MxCeEe3s6X5TlEqDQpFSkFTGBHvvg/s762/CompactRepair.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;762&quot; data-original-width=&quot;705&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivnGfeCLtSqcXe0WElcadGd-8uAbEEMql9Mkl9DLBv54KNreDgU1XXJpVLaAiXCNse8amsOqfgQydJDNh8POIW7YtjCi_0N21QsN8YShXgrbNr6mSOl4ijRZQJCX4zvrfu7_J-MS7QKx3wi8X8sbL-qk1pO1QmNP1MxCeEe3s6X5TlEqDQpFSkFTGBHvvg/s320/CompactRepair.png&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The ListBox is configured with the Multi-Select option, allowing you to choose multiple databases and run the Compact/Repair operation using the corresponding command button. Each selected database will be compacted individually, and its updated file size (in kilobytes) will be displayed in the second column of the ListBox. The FileBrowser Control.&lt;/p&gt;&lt;p&gt;The &lt;b&gt;&#39;&lt;/b&gt;Add Databases&lt;b&gt;&#39;&lt;/b&gt;&amp;nbsp;&lt;a href=&quot;https://www.msaccesstips.com/2019/07/withevents-textbox-commandbutton.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; opens the File Browser Dialog Control, and you can select one or more Databases from your disk and add them to the ListBox.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimR5olnFz6bU7DzIMl2v-zKgdVGRq_8DShVF8vHsR0D1Oz7WIDamYpjFdmnejl7zdZa6PPd0iHpFwK5Y0ZzBbCtn90mvfa1zjoK8yllq9TwDIkK-B0FD6-JtR8_RRHMEYIGkRsHG-nwgvdF_F0Qefo9BgQ_pbc3FtpGPlK_E29LVZuKMb6EjEkmS1zs71h/s943/CompactFileBrowser.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;698&quot; data-original-width=&quot;943&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimR5olnFz6bU7DzIMl2v-zKgdVGRq_8DShVF8vHsR0D1Oz7WIDamYpjFdmnejl7zdZa6PPd0iHpFwK5Y0ZzBbCtn90mvfa1zjoK8yllq9TwDIkK-B0FD6-JtR8_RRHMEYIGkRsHG-nwgvdF_F0Qefo9BgQ_pbc3FtpGPlK_E29LVZuKMb6EjEkmS1zs71h/s320/CompactFileBrowser.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open a large image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The Compact/Repair Function is Running.&lt;/h3&gt;&lt;p&gt;The selected files from the Disk are added to the DirectoryList Table, the Source Table of the ListBox. As per your Compact/Repair schedule, you may open this Compact/Repair Utility, select the required files from the &lt;a href=&quot;https://www.msaccesstips.com/2019/04/withevents-button-combo-list-textbox-tab.html &quot; target=&quot;_blank&quot;&gt;ListBox&lt;/a&gt;, then click on the &#39;Compact/Repair&#39; Command Button.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVBXDoXwEETxvRCBlO9-lW-qlKPcaJrPX1knWd2kfAg2pJ8tRTPhveVP9FC22LPayiNqzbrhJb8zaDkWcO6rIxt9wLv7jhPS1CcsppTKH6Qfc1ab2TIxyCh79inbeo2Wjr1qbJWAwEOlk3a7MbT6q8chTQ5Cz0y6nHenDXGRIWmANgsIAb7ryeQA0_hyphenhyphenjT/s765/CompactList.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;765&quot; data-original-width=&quot;702&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVBXDoXwEETxvRCBlO9-lW-qlKPcaJrPX1knWd2kfAg2pJ8tRTPhveVP9FC22LPayiNqzbrhJb8zaDkWcO6rIxt9wLv7jhPS1CcsppTKH6Qfc1ab2TIxyCh79inbeo2Wjr1qbJWAwEOlk3a7MbT6q8chTQ5Cz0y6nHenDXGRIWmANgsIAb7ryeQA0_hyphenhyphenjT/s320/CompactList.png&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Preparing for Compact/Repair.&lt;/h3&gt;&lt;p&gt;In the Compact/Repair Utility Program, the Database is first backed up to a temporary location. The default Backup Path shown in the Text Box above the &lt;a href=&quot;https://www.msaccesstips.com/2006/09/command-button-animation.html &quot; target=&quot;_blank&quot;&gt;Command Buttons&lt;/a&gt; is D:\Tmp\.&amp;nbsp; It is defined in the Default Value Property of the &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;TextBox&lt;/a&gt; and used by the Compact/Repair Utility Program.&amp;nbsp;&lt;/p&gt;&lt;p&gt;If you would like to take any &lt;a href=&quot;https://www.msaccesstips.com/2008/05/database-daily-backup.html&quot; target=&quot;_blank&quot;&gt;Database Backup&lt;/a&gt; to a different location, change the Target path &#39;C:\Backup\&#39; in the TextBox, before running the Compact/Repair option.&amp;nbsp;&lt;/p&gt;&lt;p&gt;If you prefer a different location permanently, open the Form in Design View, display the TextBox Property Sheet, and set the Default Value Property to your preferred location, like D:\Backup\&lt;b&gt;,&lt;/b&gt;&amp;nbsp;and ensure that the last character in the path is a backslash.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; When the same database is compacted again, the old backup file will be replaced with the new one. Till that time, the Backup File will remain safe in that location.&lt;/p&gt;&lt;p&gt;The Compacting Procedure goes through the following steps:&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;The Source File is copied to the backup location to keep a copy of the Database safe before the Source file is compacted.&lt;/li&gt;&lt;li&gt;&lt;p&gt;The &#39;DBEngine.CompactDatabase()&lt;b&gt;&#39;&lt;/b&gt; command is run to perform Compact and Repair operations on the database, and repairs the data if Database corruption is detected. In the event of data corruption, there is a risk of data loss, and the specific information regarding the errors encountered is preserved in the System Table MSysCompactErrors. To mitigate such situations, it is advisable to restore the data from previously created database backups, if available.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;All objects from the source database, including both user-created and system objects, are transferred into a new database. The new temporary database is &quot;&lt;b&gt;db1.accdb&lt;/b&gt;&quot; (or &quot;db1.mdb&quot; depending on the file format) and is located in the designated backup path: &lt;b&gt;D:\tmp\db1.accdb&lt;/b&gt;. The replication process excludes the system&#39;s temporary work files, ensuring a comprehensive transfer of objects while omitting non-essential temporary data.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Deletes the Source File from its home location.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;The Compacted&amp;nbsp;&lt;b&gt;D:\tmp\db1.accdb&lt;/b&gt; file is transferred to the home location with its original Database name.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt;&amp;nbsp;The Access System goes through the same procedure when you run the Compacting operation directly from the Access System, except for the Database Backup procedure.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Streamlined VBA Coding in Standalone Class Module.&lt;/h3&gt;&lt;p&gt;Having gained insights into the utility highlighted in the previous introduction, it is now opportune to explore the &lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_blank&quot;&gt;streamlined event subroutine&lt;/a&gt; coding procedure implemented in this specific project. The necessary VBA code for event subroutines is meticulously designed in a standalone class module, enhancing code maintenance and debugging. This organized code structure within the standalone Class Module facilitates easy transportation to other projects, safeguarding valuable work from being entangled with less critical code in form modules. By adopting this streamlined coding approach, the practice of reusing identical code segments across controls of the same type within the form is encouraged, eliminating duplicative coding efforts.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Command Button Wrapper Class.&lt;/h3&gt;

&lt;p&gt;There is a single Wrapper Class dedicated to the Command Button controls, along with a separate Interface (Intermediary) Class Module. The Interface Class is responsible for creating and managing instances of the Command Button Wrapper Class while facilitating Click Event handling. A `Collection` object is used to store and manage all Command Button Wrapper Class instances, enabling the monitoring and capture of Command Button Click events generated within the Compact/Repair form.&lt;/p&gt;

&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;The Command Button Wrapper Class VBA Code.&lt;/h4&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private cmdfrm As Form
Private WithEvents cmd As CommandButton

Private strPath As String
Private bkupPath As String
Dim lst As ListBox
Dim lstcount As Integer
Dim xtn As String

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;Database Compact/Repair Utility
&#39;Author: a.p.r. pillai
&#39;Date  : 20/02/2024
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

&#39;Form&#39;s Property GET/SET Procedures
Public Property Get cmd_Frm() As Form
    Set cmd_Frm = cmdfrm
End Property

Public Property Set cmd_Frm(ByRef cfrm As Form)
    Set cmdfrm = cfrm
End Property

&#39;Command Button Property GET/SET Procedures
Public Property Get c_cmd() As CommandButton
    Set c_cmd = cmd
End Property

Public Property Set c_cmd(ByRef pcmd As CommandButton)
    Set cmd = pcmd
    
    Call DefaultPath
    
End Property

&#39;The Click Event Subroutines
Private Sub cmd_Click()
On Error GoTo cmd_Click_Err
Select Case cmd.Name
  Case &quot;cmdQuit&quot;
    If MsgBox(&quot;Close Compact_Repair Form?&quot;, vbOKCancel + vbQuestion, &quot;cmd_Click&quot;) = vbOK Then
        DoCmd.Close acForm, cmdfrm.Name
        Exit Sub
    End If

    Case &quot;cmdFileDialog&quot;
        Call FileDialog &#39;Display selected Path &amp;amp; files
        cmdfrm.dbList.Requery
        
    Case &quot;cmdCompact&quot;
        Call DBPrepare
        
    Case &quot;cmdDelete&quot;
        Call DBDelete
        
End Select

cmd_Click_Exit:
Exit Sub

cmd_Click_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;cmd_Click()&quot;
Resume cmd_Click_Exit
End Sub

Private Sub DBDelete()
&#39;Delete the selected Items from the DirectoryList Table
Dim delCount As Integer
Dim j As Integer
Dim k As Integer
Dim DB As Database
Dim dbName As String
Dim msg As String
Dim Rst As Recordset
Dim opt As Integer

On Error GoTo DBDelete_Err
opt = 0

msg = &quot;1. Delete Selected.&quot; &amp;amp; vbCr &amp;amp; vbCr _
&amp;amp; &quot;2. Delete All from List.&quot; &amp;amp; vbCr &amp;amp; vbCr _
&amp;amp; &quot;3. Cancel Deletion.&quot;
While opt &amp;lt; 1 Or opt &amp;gt; 3
    opt = InputBox(msg, &quot;Select Option.&quot;, 3)
Wend
Select Case opt
    Case 1
        GoTo Selected
    Case 2
      msg = &quot;Empty the Database List...?&quot;
      If MsgBox(msg, vbYesNo + vbCritical, &quot;DeleteList()&quot;) = vbNo Then
        Exit Sub
      Else
        DoCmd.SetWarnings False
        DoCmd.OpenQuery &quot;DeleteAll_ListQ&quot;
        DoCmd.SetWarnings True
        cmdfrm.dbList.Requery
        cmdfrm.cmdDelete.eabled = False
        Exit Sub
      End If
    Case 3
        Exit Sub
End Select

Selected:
delCount = CheckList()
If delCount &amp;gt; 0 Then
    msg = &quot;Delete &quot; &amp;amp; delCount &amp;amp; &quot; Items.&quot; &amp;amp; vbCr &amp;amp; vbCr &amp;amp; &quot;Proceed...?&quot;
    If MsgBox(msg, vbYesNo, &quot;DBDelete()&quot;) = vbNo Then
        Exit Sub
    End If
    
    Set DB = CurrentDb
    Set Rst = DB.OpenRecordset(&quot;DirectoryList&quot;, dbOpenDynaset)
    Set lst = cmdfrm.dbList
    
For j = 0 To lstcount
    If lst.Selected(j) Then
      dbName = lst.Column(0, j)
      Rst.FindFirst &quot;Path = &#39;&quot; &amp;amp; dbName &amp;amp; &quot;&#39;&quot;
      If Not Rst.NoMatch Then
        Rst.Delete
        Rst.Requery
      End If
    End If
Next
Rst.Close
Set Rst = Nothing
Set DB = Nothing

lst.Requery
    MsgBox delCount &amp;amp; &quot; Item(s) Deleted From List.&quot;, , &quot;DBDelete()&quot;
Else
    MsgBox delCount &amp;amp; &quot; Item(s) Selected for Deletion!&quot;, , &quot;DBDelete()&quot;
End If

DBDelete_Exit:
Exit Sub

DBDelete_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;DBDelete()&quot;
Resume DBDelete_Exit
End Sub

Private Sub DBPrepare()
&#39;Preparatory Procedure for Compacting
&#39;the selected Databases individually
Dim xselcount As Integer
Dim dbName As String
Dim ldbName As String
Dim strTmp As String
Dim i As Integer
Dim j As Integer
Dim timr As Double
Dim fs, f
Dim lockfile As String
Dim msg As String

bkupPath = cmdfrm!BackupPath
&#39;create a Backup Folder
On Error Resume Next
Set fs = CreateObject(&quot;Scripting.FileSystemObject&quot;)
Set f = fs.GetFolder(bkupPath)
    If Err = 76 Or Err &amp;gt; 0 Then
       Err.Clear
       fs.createfolder (bkupPath)
    End If

On Error GoTo DBPrepare_Err

&#39;Remove existing workfiles from backup location
xselcount = CheckList()
If xselcount = 0 Then
msg = &quot;Select Database(s) from List for Compacting!&quot;
MsgBox msg, , &quot;DBPrepare()&quot;
    Exit Sub
End If

&#39;Ensure selected database is not active
msg = &quot;Ensure that Selected Databases are not in Use. &quot; _
&amp;amp; vbCrLf &amp;amp; &quot;Proceed...?&quot;

If MsgBox(msg, vbYesNo + vbDefaultButton2 + vbQuestion, _
&quot;DBPrepare()&quot;) = vbNo Then
   Exit Sub
End If

&#39;Check the selected database is active or not
&#39;if inactive then submit it to DBCompact() Program.
For j = 0 To lstcount
    If lst.Selected(j) Then
       dbName = Trim(lst.Column(0, j))
       i = InStrRev(dbName, &quot;.&quot;)
       xtn = Mid(dbName, i) &#39;extract extension
       lockfile = IIf(xtn = &quot;.mdb&quot;, &quot;ldb&quot;, &quot;laccdb&quot;)
       ldbName = Left(dbName, i)
       ldbName = ldbName &amp;amp; lockfile &#39;for checking the presense of lock file.
       If Len(Dir(ldbName)) &amp;gt; 0 Then &#39;database is active
          MsgBox &quot;Database: &quot; &amp;amp; dbName &amp;amp; vbCrLf &amp;amp; &quot;is active. Skipping to the Next in list.&quot;
          GoTo nextstep
       End If

    &#39;Prepare for Compacting and to display the status messages.
       msg = &quot;Compact/Repair: &quot; &amp;amp; dbName &amp;amp; vbCrLf &amp;amp; &quot;Proceed...?&quot;
       If MsgBox(msg, vbQuestion + vbDefaultButton2 + vbYesNo, &quot;DBPrepare()&quot;) = vbYes Then
            cmdfrm.lblNote.Visible = False
            cmdfrm.lblStat.Caption = &quot;Working, Please wait...&quot;
            DoEvents

    Call DBCompact(dbName) &#39;Run Compacting

            cmdfrm.lblStat.Caption = &quot;&quot;
            DoEvents

nextstep:
            Sleep 5
        End If
    End If
Next

msg = &quot;Selected Database(s) Compacted Successfully.&quot;
MsgBox msg, , &quot;DBPrepare()&quot;

    Sleep 3

cmdfrm.lblNote.Visible = True
cmdfrm.lblStat.Caption = &quot;&quot;


strTmp = bkupPath &amp;amp; &quot;db1&quot; &amp;amp; xtn &#39;Delete the temporary file
Call KillTempFile(strTmp)

Set fs = Nothing
Set f = Nothing
Set lst = Nothing

DBPrepare_Exit:
Exit Sub

DBPrepare_Err:
MsgBox Err.Description, , &quot;DBPrepare()&quot;
Resume DBPrepare_Exit
End Sub

Private Sub DBCompact(ByVal strdb As String)
&#39;Compact/Repair Database received as Parameter
Dim t As Long
Dim xdir As String
Dim strbk As String
Dim strTmp As String
Dim tmp As String
Dim chkFile As String
Dim msg As String

On Error GoTo dbCompact_Err

tmp = cmdfrm!BackupPath

strTmp = tmp &amp;amp; &quot;db1&quot; &amp;amp; xtn

chkFile = strTmp
Call KillTempFile(chkFile)

t = InStrRev(strdb, &quot;\&quot;)
If t &amp;gt; 0 Then
   strbk = Mid(strdb, t + 1)
End If
strbk = tmp &amp;amp; strbk

chkFile = strbk
Call KillTempFile(chkFile)

&#39;Make a Copy in d:\tmp folder for safe keep
msg = &quot;Taking Backup of &quot; &amp;amp; strdb &amp;amp; vbCrLf _
&amp;amp; &quot;to &quot; &amp;amp; tmp
cmdfrm.lblMsg.Caption = msg
DoEvents

&#39;Take a Backup of Original File to the Backup Location
   FileCopy strdb, strbk

msg = &quot;Transferring Objects from &quot; &amp;amp; strdb &amp;amp; vbCrLf _
&amp;amp; &quot;to &quot; &amp;amp; tmp &amp;amp; &quot;db1&quot; &amp;amp; xtn
cmdfrm.lblMsg.Caption = msg
DoEvents

&#39;https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/dbengine-compactdatabase-method-dao
&#39;Compact Database to D:\tmp\db1.accdb
   DBEngine.CompactDatabase strdb, strTmp
   
&#39; Delete uncompacted Database and Copy Compacted db1.mdb with
&#39; the Original Name
msg = &quot;Creating &quot; &amp;amp; strdb &amp;amp; &quot; from &quot; &amp;amp; tmp &amp;amp; &quot;db1&quot; &amp;amp; xtn
cmdfrm.lblMsg.Caption = msg
DoEvents

&#39;Delete uncompacted file
chkFile = strdb
Call KillTempFile(chkFile)

&#39;Create Compacted File with its original name in its home location
    DBEngine.CompactDatabase strTmp, strdb

msg = strdb &amp;amp; &quot; Compacted/Repaired Successfully.&quot;

cmdfrm.lblMsg.Caption = msg
DoEvents

Call dbListUpdate(strdb) &#39;Update the DirectoryList Table

dbCompact_Exit:
Exit Sub

dbCompact_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;dbCompact()&quot;
Resume dbCompact_Exit
End Sub

Private Function CheckList() As Integer
&#39;Take selected items Count
Dim k As Integer
Dim xcount As Integer

On Error GoTo CheckList_Err

Set lst = cmdfrm.dbList
lstcount = DCount(&quot;*&quot;, &quot;DirectoryList&quot;)

xcount = 0
For k = 0 To lstcount
If lst.Selected(k) Then
    xcount = xcount + 1
End If
Next

If xcount = 0 Then
   MsgBox &quot;No Database(s)Selected.&quot;
   Exit Function
End If

CheckList = xcount

CheckList_Exit:
Exit Function

CheckList_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;CheckList()&quot;
Resume CheckList_Exit
End Function

Private Sub dbListUpdate(ByVal cmpPath As String)
&#39;Update the File Size of the Database after Compacting
On Error GoTo dbListUpdate_Err
Dim sPath As String
Dim i As Variant
Dim DB As Database
Dim Rst As Recordset
Set DB = CurrentDb
Set Rst = DB.OpenRecordset(&quot;DirectoryList&quot;, dbOpenDynaset)

Rst.MoveFirst
Rst.FindFirst &quot;Path = &#39;&quot; &amp;amp; cmpPath &amp;amp; &quot;&#39;&quot;
If Not Rst.NoMatch Then
    sPath = Rst!Path
    Rst.Edit
    Rst!FileLengthKB = FileLen(sPath) / 1024 &#39;Db size after compacting
    Rst.Update
End If

Rst.Close
cmdfrm.dbList.Requery

dbListUpdate_Exit:
Set Rst = Nothing
Set DB = Nothing
Exit Sub

dbListUpdate_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;dbListUpdate()&quot;
Resume dbListUpdate_Exit
End Sub

Private Sub DefaultPath()
Dim strLoc As String
&#39;Default path for CommonDialog Control
   strLoc = CurrentProject.Path &amp;amp; &quot;\*.accdb&quot;
   strPath = strLoc &#39;Assign to Global Variable strPath
   
End Sub

Private Sub FileDialog()
On Error GoTo cmdFileDialog_Err

&#39;Requires reference to Microsoft Office 12.0 Object Library.
Dim fDialog As Office.FileDialog
Dim DB As DAO.Database
Dim Rst As DAO.Recordset
Dim defPath As String
Dim varFile As Variant
Dim strfiles As String

   &#39;Set up the File Dialog.
   Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
   With fDialog
      &#39;Allow user to make multiple selections of disk files.
      .AllowMultiSelect = True
      .InitialFileName = Dir(strPath)
      .InitialView = msoFileDialogViewDetails
      &#39;Set the title of the dialog box.
      .Title = &quot;Please select one or more files&quot;

      &#39;Clear out the current filters, and add our own.
      .Filters.Clear
      .Filters.Add &quot;Access Databases&quot;, &quot;*.mdb; *.accdb&quot;
      .Filters.Add &quot;Access Projects&quot;, &quot;*.adp&quot;
      .Filters.Add &quot;All Files&quot;, &quot;*.*&quot;
      .FilterIndex = 1
      &#39;.Execute
      &#39;Show the dialog box. If the .Show method returns True, the
      &#39;user picked at least one file. If the .Show method returns
      &#39;False, the user clicked Cancel.
    If .Show = True Then
        Set DB = CurrentDb
        Set Rst = DB.OpenRecordset(&quot;DirectoryList&quot;, dbOpenDynaset)
        &#39;Add all selected files to the DirectoryList Table
        defPath = &quot;&quot;
      For Each varFile In .SelectedItems
         If defPath = &quot;&quot; Then
            defPath = Left(varFile, InStrRev(varFile, &quot;\&quot;))
            defPath = defPath &amp;amp; &quot;*.*&quot;
            strPath = defPath
         End If
            Rst.AddNew
            Rst![Path] = varFile
            Rst![FileLengthKB] = FileLen(varFile) / 1024
            Rst.Update
      Next
            cmdfrm.cmdDelete.Enabled = True
        Else
            MsgBox &quot;You clicked Cancel in the file dialog box.&quot;
        End If
      
   End With

cmdFileDialog_Exit:
Exit Sub

cmdFileDialog_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;cmdFileDialog_Click()&quot;
Resume cmdFileDialog_Exit
End Sub

Private Sub KillTempFile(ByVal filename As String)
On Error GoTo KillTempFile_Err
&#39;Manage Temporary Files
    If Len(Dir(filename)) &amp;gt; 0 Then
        Kill filename
    End If

KillTempFile_Exit:
Exit Sub

KillTempFile_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;KillTempFile()&quot;
Resume KillTempFile_Exit
End Sub

&lt;/pre&gt;
&lt;p&gt;The Command Button Wrapper Class starts with the main Properties, the Form Object, and Command Button Control declarations. The CommandButton Control is declared and qualified with the Keyword &lt;i&gt;WithEvents&lt;/i&gt;&amp;nbsp;for Click Event Capturing when fired from the Form.&lt;/p&gt;&lt;p&gt;A few local Variables are also declared in the global area of the Class Module, followed by the Form and Command Button &lt;i&gt;Get&lt;/i&gt; and&lt;b&gt; &lt;/b&gt;&lt;i&gt;Set&lt;/i&gt; Property Procedures.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Despite four Command Buttons on the Form, a single Click Event Subroutine within the Command Button Wrapper Class suffices. This streamlined approach captures all four Command Button Clicks in the same Event Subroutine, allowing the execution of their respective Event Procedures. This efficiency is achievable through the implementation of streamlined Event Procedure coding.&lt;/p&gt;&lt;p&gt;&lt;span face=&quot;Söhne, ui-sans-serif, system-ui, -apple-system, &amp;quot;Segoe UI&amp;quot;, Roboto, Ubuntu, Cantarell, &amp;quot;Noto Sans&amp;quot;, sans-serif, &amp;quot;Helvetica Neue&amp;quot;, Arial, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Noto Color Emoji&amp;quot;&quot; style=&quot;background-color: white; color: #0d0d0d; font-size: 16px; white-space-collapse: preserve;&quot;&gt;When examining the Event Subroutine Code in order of priority, the first step is adding the databases slated for the Compact/Repair procedure to the ListBox. This is accomplished through the Click Event of the Command Button labeled &#39;Add Databases,&#39; with the name &#39;CmdFileDialog.&#39; The Click Event, in turn, invokes the FileDialog() Subroutine.&lt;/span&gt;&amp;nbsp;The Code Segment is given below:&lt;/p&gt;
&lt;pre&gt;Private Sub FileDialog()
On Error GoTo cmdFileDialog_Err

&#39;Requires reference to Microsoft Office 12.0 Object Library.
Dim fDialog As Office.FileDialog
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim defPath As String
Dim varFile As Variant
Dim strfiles As String

   &#39;Set up the File Dialog.
   Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
   With fDialog
      &#39;Allow user to make multiple selections of disk files.
      .AllowMultiSelect = True
      .InitialFileName = Dir(strPath)
      .InitialView = msoFileDialogViewDetails
      &#39;Set the title of the dialog box.
      .Title = &quot;Please select one or more files&quot;

      &#39;Clear out the current filters, and add our own.
      .Filters.Clear
      .Filters.Add &quot;Access Databases&quot;, &quot;*.mdb; *.accdb&quot;
      .Filters.Add &quot;Access Projects&quot;, &quot;*.adp&quot;
      .Filters.Add &quot;All Files&quot;, &quot;*.*&quot;
      .FilterIndex = 1
      &#39;.Execute
      &#39;Show the dialog box. If the .Show method returns True, the
      &#39;user picked at least one file. If the .Show method returns
      &#39;False, the user clicked Cancel.
    If .Show = True Then
        Set db = CurrentDb
        Set rst = db.OpenRecordset(&quot;DirectoryList&quot;, dbOpenDynaset)
        &#39;Add all selected files to the DirectoryList Table
        defPath = &quot;&quot;
      For Each varFile In .SelectedItems
         If defPath = &quot;&quot; Then
            defPath = Left(varFile, InStrRev(varFile, &quot;\&quot;))
            defPath = defPath &amp;amp; &quot;*.*&quot;
            strPath = defPath
         End If
            rst.AddNew
            rst![Path] = varFile
            rst![FileLengthKB] = FileLen(varFile) / 1024
            rst.Update
      Next
            cmdfrm.cmdDelete.Enabled = True
        Else
            MsgBox &quot;You clicked Cancel in the file dialog box.&quot;
        End If
      
   End With

cmdFileDialog_Exit:
Exit Sub

cmdFileDialog_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;cmdFileDialog_Click()&quot;
Resume cmdFileDialog_Exit
End Sub
&lt;/pre&gt;
&lt;p&gt;This is the same &lt;i&gt;Office.FileDialog&lt;/i&gt; Control (the File Browser Control) and the Program we used in the earlier Episode with the title &lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html#FileBrowser&quot; target=&quot;_blank&quot;&gt;External Files&#39; List in Hyperlinks&lt;/a&gt; published earlier. If you click this link, you will be directed to the specific part of the Page that gives the function details.&lt;/p&gt;&lt;p&gt;In this scenario, utilise the DirectoryList Table to store the databases selected from the disk, which subsequently populate the ListBox on the Form. The table encompasses two fields: Path and FileLengthKB. The former accommodates the full Pathname of the database, while the latter calculates the file size in kilobytes when added to the table. Following the Compact/Repair operations, this table updates to reflect the altered file sizes.&lt;/p&gt;&lt;p&gt;Users can select one or more databases from the list and initiate the Compact/Repair process by clicking on the designated Command Button. This action triggers execution of the DBPrepare() Subroutine, which in turn identifies the selected database(s) in the ListBox and passes them to the DBCompact() Subroutine for the Compact/Repair operation.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The DBPrepare() Subroutine VBA Code.&lt;/h3&gt;
&lt;pre&gt;Private Sub DBPrepare()
&#39;Preparatory Procedure for Compacting
&#39;the selected Databases individually
Dim xselcount As Integer
Dim dbName As String
Dim ldbName As String
Dim strTmp As String
Dim i As Integer
Dim j As Integer
Dim timr As Double
Dim fs, f
Dim lockfile As String
Dim msg As String

bkupPath = cmdfrm!BackupPath
&#39;create a Backup Folder
On Error Resume Next
Set fs = CreateObject(&quot;Scripting.FileSystemObject&quot;)
Set f = fs.GetFolder(bkupPath)
    If Err = 76 Or Err &amp;gt; 0 Then
       Err.Clear
       fs.createfolder (bkupPath)
    End If

On Error GoTo DBPrepare_Err

&#39;Remove existing workfiles from backup location
xselcount = CheckList()
If xselcount = 0 Then
msg = &quot;Select Database(s) from List for Compacting!&quot;
MsgBox msg, , &quot;DBPrepare()&quot;
    Exit Sub
End If

&#39;Ensure selected database is not active
msg = &quot;Ensure that Selected Databases are not in Use. &quot; _
&amp;amp; vbCrLf &amp;amp; &quot;Proceed...?&quot;

If MsgBox(msg, vbYesNo + vbDefaultButton2 + vbQuestion, _
&quot;DBPrepare()&quot;) = vbNo Then
   Exit Sub
End If

&#39;Check the selected database is active or not
&#39;if inactive then submit it to DBCompact() Program.
For j = 0 To lstcount
    If lst.Selected(j) Then
       dbName = Trim(lst.Column(0, j))
       i = InStrRev(dbName, &quot;.&quot;)
       xtn = Mid(dbName, i) &#39;extract extension
       lockfile = IIf(xtn = &quot;.mdb&quot;, &quot;ldb&quot;, &quot;laccdb&quot;)
       ldbName = Left(dbName, i)
       ldbName = ldbName &amp;amp; lockfile &#39;for checking the presense of lock file.
       If Len(Dir(ldbName)) &amp;gt; 0 Then &#39;database is active
          MsgBox &quot;Database: &quot; &amp;amp; dbName &amp;amp; vbCrLf &amp;amp; &quot;is active. Skipping to the Next in list.&quot;
          GoTo nextstep
       End If

    &#39;Prepare for Compacting and to display the status messages.
       msg = &quot;Compact/Repair: &quot; &amp;amp; dbName &amp;amp; vbCrLf &amp;amp; &quot;Proceed...?&quot;
       If MsgBox(msg, vbQuestion + vbDefaultButton2 + vbYesNo, &quot;DBPrepare()&quot;) = vbYes Then
            cmdfrm.lblNote.Visible = False
            cmdfrm.lblStat.Caption = &quot;Working, Please wait...&quot;
            DoEvents

    Call DBCompact(dbName) &#39;Run Compacting

            cmdfrm.lblStat.Caption = &quot;&quot;
            DoEvents

nextstep:
            Sleep 5
        End If
    End If
Next

msg = &quot;Selected Database(s) Compacted Successfully.&quot;
MsgBox msg, , &quot;DBPrepare()&quot;

    Sleep 3

cmdfrm.lblNote.Visible = True
cmdfrm.lblStat.Caption = &quot;&quot;


strTmp = bkupPath &amp;amp; &quot;db1&quot; &amp;amp; xtn &#39;Delete the temporary file
Call KillTempFile(strTmp)

Set fs = Nothing
Set f = Nothing
Set lst = Nothing

DBPrepare_Exit:
Exit Sub

DBPrepare_Err:
MsgBox Err.Description, , &quot;DBPrepare()&quot;
Resume DBPrepare_Exit
End Sub
&lt;/pre&gt;
&lt;p&gt;The above DBPrepare() Subroutine selects the User-selected Databases individually, passes them to the actual Compacting Subroutine DBCompact() for Compact/Repair operations, and restores the Database to its home location.&lt;/p&gt;
&lt;h4&gt;The DBCompact Subroutine VBA Code.&lt;/h4&gt;
&lt;p&gt;Private Sub DBCompact(ByVal strdb As String)&lt;/p&gt;&lt;pre&gt;&#39;Compact/Repair Database received as Parameter
Dim t As Long
Dim xdir As String
Dim strbk As String
Dim strTmp As String
Dim tmp As String
Dim chkFile As String
Dim msg As String

On Error GoTo dbCompact_Err

tmp = cmdfrm!BackupPath

strTmp = tmp &amp;amp; &quot;db1&quot; &amp;amp; xtn

chkFile = strTmp
Call KillTempFile(chkFile)

t = InStrRev(strdb, &quot;\&quot;)
If t &amp;gt; 0 Then
   strbk = Mid(strdb, t + 1)
End If
strbk = tmp &amp;amp; strbk

chkFile = strbk
Call KillTempFile(chkFile)

&#39;Make a Copy in d:\tmp folder for safe keep
msg = &quot;Taking Backup of &quot; &amp;amp; strdb &amp;amp; vbCrLf _
&amp;amp; &quot;to &quot; &amp;amp; tmp
cmdfrm.lblMsg.Caption = msg
DoEvents

&#39;Take a Backup of Original File to the Backup Location
   FileCopy strdb, strbk

msg = &quot;Transferring Objects from &quot; &amp;amp; strdb &amp;amp; vbCrLf _
&amp;amp; &quot;to &quot; &amp;amp; tmp &amp;amp; &quot;db1&quot; &amp;amp; xtn
cmdfrm.lblMsg.Caption = msg
DoEvents

&#39;https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/dbengine-compactdatabase-method-dao
&#39;Compact Database to D:\tmp\db1.accdb
   DBEngine.CompactDatabase strdb, strTmp
   
&#39; Delete uncompacted Database and Copy Compacted db1.mdb with
&#39; the Original Name
msg = &quot;Creating &quot; &amp;amp; strdb &amp;amp; &quot; from &quot; &amp;amp; tmp &amp;amp; &quot;db1&quot; &amp;amp; xtn
cmdfrm.lblMsg.Caption = msg
DoEvents

&#39;Delete uncompacted file
chkFile = strdb
Call KillTempFile(chkFile)

&#39;Create Compacted File with its original name in its home location
    DBEngine.CompactDatabase strTmp, strdb

msg = strdb &amp;amp; &quot; Compacted/Repaired Successfully.&quot;

cmdfrm.lblMsg.Caption = msg
DoEvents

Call dbListUpdate(strdb) &#39;Update the DirectoryList Table

dbCompact_Exit:
Exit Sub

dbCompact_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;dbCompact()&quot;
Resume dbCompact_Exit
End Sub

&lt;/pre&gt;
&lt;p&gt;There are three other small supporting Subroutines called from both the DBPrepare() and DBCompact() Subroutines.&lt;/p&gt;&lt;p&gt;The CheckList() Subroutine.&lt;/p&gt;
&lt;pre&gt;Private Function CheckList() As Integer
&#39;Take selected items Count
Dim k As Integer
Dim xcount As Integer

On Error GoTo CheckList_Err

Set lst = cmdfrm.dbList
lstcount = DCount(&quot;*&quot;, &quot;DirectoryList&quot;)

xcount = 0
For k = 0 To lstcount
If lst.Selected(k) Then
    xcount = xcount + 1
End If
Next

If xcount = 0 Then
   MsgBox &quot;No Database(s)Selected.&quot;
   Exit Function
End If

CheckList = xcount

CheckList_Exit:
Exit Function

CheckList_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;CheckList()&quot;
Resume CheckList_Exit
End Function
&lt;/pre&gt;

&lt;p&gt;The above Subroutine checks whether any Item is selected in the ListBox and takes its count when the &#39;Compact/Repair&#39; or &#39;Delete from List&#39; Command Button is clicked. If selected, then the selected operation is performed.&lt;/p&gt;
&lt;h3&gt;The dbListUpdate() Subroutine in VBA.&lt;/h3&gt;&lt;pre&gt;Private Sub dbListUpdate(ByVal cmpPath As String)
&#39;Update the File Size of the Database after Compacting
On Error GoTo dbListUpdate_Err
Dim sPath As String
Dim i As Variant
Dim DB As Database
Dim Rst As Recordset
Set DB = CurrentDb
Set Rst = DB.OpenRecordset(&quot;DirectoryList&quot;, dbOpenDynaset)

Rst.MoveFirst
Rst.FindFirst &quot;Path = &#39;&quot; &amp;amp; cmpPath &amp;amp; &quot;&#39;&quot;
If Not Rst.NoMatch Then
    sPath = Rst!Path
    Rst.Edit
    Rst!FileLengthKB = FileLen(sPath) / 1024 &#39;Db size after compacting
    Rst.Update
End If

Rst.Close
cmdfrm.dbList.Requery

dbListUpdate_Exit:
Set Rst = Nothing
Set DB = Nothing
Exit Sub

dbListUpdate_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;dbListUpdate()&quot;
Resume dbListUpdate_Exit
End Sub

&lt;/pre&gt;
&lt;p&gt;This Program is called from the DBCompact() Subroutine to update the File Size in Kilobytes in the list box after compacting the Database.&lt;/p&gt;
&lt;h3&gt;The DBDelete() Subroutine.&lt;/h3&gt;
&lt;pre&gt;Private Sub DBDelete()
&#39;Delete the selected Items from the DirectoryList Table
Dim delCount As Integer
Dim j As Integer
Dim k As Integer
Dim DB As Database
Dim dbName As String
Dim msg As String
Dim Rst As Recordset
Dim opt As Integer

On Error GoTo DBDelete_Err
opt = 0

msg = &quot;1. Delete Selected.&quot; &amp;amp; vbCr &amp;amp; vbCr _
&amp;amp; &quot;2. Delete All from List.&quot; &amp;amp; vbCr &amp;amp; vbCr _
&amp;amp; &quot;3. Cancel Deletion.&quot;
While opt &amp;lt; 1 Or opt &amp;gt; 3
    opt = InputBox(msg, &quot;Select Option.&quot;, 3)
Wend
Select Case opt
    Case 1
        GoTo Selected
    Case 2
      msg = &quot;Empty the Database List...?&quot;
      If MsgBox(msg, vbYesNo + vbCritical, &quot;DeleteList()&quot;) = vbNo Then
        Exit Sub
      Else
        DoCmd.SetWarnings False
        DoCmd.OpenQuery &quot;DeleteAll_ListQ&quot;
        DoCmd.SetWarnings True
        cmdfrm.dbList.Requery
        cmdfrm.cmdDelete.eabled = False
        Exit Sub
      End If
    Case 3
        Exit Sub
End Select

Selected:
delCount = CheckList()
If delCount &amp;gt; 0 Then
    msg = &quot;Delete &quot; &amp;amp; delCount &amp;amp; &quot; Items.&quot; &amp;amp; vbCr &amp;amp; vbCr &amp;amp; &quot;Proceed...?&quot;
    If MsgBox(msg, vbYesNo, &quot;DBDelete()&quot;) = vbNo Then
        Exit Sub
    End If
    
    Set DB = CurrentDb
    Set Rst = DB.OpenRecordset(&quot;DirectoryList&quot;, dbOpenDynaset)
    Set lst = cmdfrm.dbList
    
For j = 0 To lstcount
    If lst.Selected(j) Then
      dbName = lst.Column(0, j)
      Rst.FindFirst &quot;Path = &#39;&quot; &amp;amp; dbName &amp;amp; &quot;&#39;&quot;
      If Not Rst.NoMatch Then
        Rst.Delete
        Rst.Requery
      End If
    End If
Next
Rst.Close
Set Rst = Nothing
Set DB = Nothing

lst.Requery
    MsgBox delCount &amp;amp; &quot; Item(s) Deleted From List.&quot;, , &quot;DBDelete()&quot;
Else
    MsgBox delCount &amp;amp; &quot; Item(s) Selected for Deletion!&quot;, , &quot;DBDelete()&quot;
End If

DBDelete_Exit:
Exit Sub

DBDelete_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;DBDelete()&quot;
Resume DBDelete_Exit
End Sub
&lt;/pre&gt;
&lt;p&gt;To remove some databases from the ListBox, you must select them from the ListBox and click the &#39;Delete from List&#39; Command Button. The DBDelete() Subroutine is called; the selected items will be deleted from the &lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_blank&quot;&gt;DirectoryList&lt;/a&gt; table, and the ListBox updated to reflect the change.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;The KillTempFile() Subroutine.&lt;/h3&gt;
&lt;pre&gt;Private Sub KillTempFile(ByVal filename As String)
On Error GoTo KillTempFile_Err
&#39;Manage Temporary Files
    If Len(Dir(filename)) &amp;gt; 0 Then
        Kill filename
    End If

KillTempFile_Exit:
Exit Sub

KillTempFile_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;KillTempFile()&quot;
Resume KillTempFile_Exit
End Sub

&lt;/pre&gt;
&lt;p&gt;The Compact/Repair Program creates Temporary Databases for System use and deletes them using the above Subroutine. This Subroutine is called from within the DBPrepare() and DBCompact() Subroutines.&lt;/p&gt;
&lt;h3&gt;The FLst_ObjInit Interface Class Module VBA Code. &lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private cmd As FLst_CmdButton
Private frm As Access.Form
Private Coll As New Collection

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;Database Compact/Repair Utility
&#39;Author: a.p.r. pillai
&#39;Date  : 20/02/2024
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

Public Property Get Ini_Frm() As Access.Form
    Set Ini_Frm = frm.m_cFrm
End Property

Public Property Set Ini_Frm(ByRef pFrm As Access.Form)
    Set frm = pFrm
    
    Call Class_Init
End Property

Private Sub Class_Init()
On Error GoTo Class_Init_Err
Dim ctl As Control
Dim listcount As Long
Const EP = &quot;[Event Procedure]&quot;

listcount = DCount(&quot;*&quot;, &quot;DirectoryList&quot;)

&#39;If ListBox is empty then disable
&#39;cmdDelete Command Button
If listcount = 0 Then
    frm.cmdDelete.Enabled = False
Else
    frm.cmdDelete.Enabled = True
End If

For Each ctl In frm.Controls
Select Case TypeName(ctl)
      Case &quot;CommandButton&quot;
        Select Case ctl.Name
            Case &quot;cmdFileDialog&quot;, &quot;cmdCompact&quot;, _
            &quot;cmdDelete&quot;, &quot;cmdQuit&quot;
            
                Set cmd = New FLst_CmdButton
                Set cmd.cmd_Frm = frm
                Set cmd.c_cmd = ctl
        
                    cmd.c_cmd.OnClick = EP
                Coll.Add cmd
                Set cmd = Nothing
        End Select
End Select
Next

Class_Init_Exit:
Exit Sub

Class_Init_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;Class_Init()&quot;
Resume Class_Init_Exit
End Sub

Private Sub Class_Terminate()
Do While Coll.Count &amp;gt; 0
    Coll.Remove 1
Loop
End Sub
&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Within the global declaration area, the FLst_CmdButton Class, the Form Object frm, and the Collection Object Coll&amp;nbsp;are declared. This is succeeded by the inclusion of &lt;i&gt;Get&lt;/i&gt;/&lt;i&gt;Set&lt;/i&gt; Property Procedures for the frm&amp;nbsp;property. In adherence to common practice, the active Form Object is passed from the Form_Load() Event Procedure to the &lt;i&gt;pFrm&lt;/i&gt;&amp;nbsp;parameter. Subsequently, it is assigned to the Form Object &lt;i&gt;frm&lt;/i&gt; in the FLst_ObjInit Class Module.&lt;/p&gt;&lt;p&gt;Upon obtaining a reference to the active Form object within the Interface Class and assigning it to the frm Object through the &lt;i&gt;Set&lt;/i&gt; Property Procedure, the Class_Init() Subroutine is initiated.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Within the Class_Init() Subroutine, a constant named &quot;EP&quot; is created to represent the [Event Procedure] text. Following this, a check is implemented to determine the status of the DirectoryList Table, which serves as the source data for the ListBox. If the DirectoryList table is empty, the [Delete from List] Command Button on the Form is disabled.&lt;/p&gt;&lt;p&gt;Within the subsequent For...Next Loop, the program iterates through the Command Buttons on the Form. When a &lt;a href=&quot;https://www.msaccesstips.com/2012/09/command-button-color-change-on-mouse.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; is identified, an individual instance of the Command Button Wrapper Class is instantiated. This instance is then assigned the respective Control Reference, and the necessary Events, specifically the Click Events in this case, are enabled. These instances are subsequently stored in the &lt;a href=&quot;https://www.msaccesstips.com/2018/12/ms-access-and-collection-object-basics.html&quot; target=&quot;_blank&quot;&gt;Collection Object&lt;/a&gt;&amp;nbsp;to retain them in memory.&lt;/p&gt;&lt;p&gt;You may take note of the following Statements:&lt;/p&gt;
&lt;pre&gt;                Set cmd = New FLst_CmdButton
                Set cmd.cmd_Frm = frm
                Set cmd.c_cmd = ctl
        
                    cmd.c_cmd.OnClick = EP
                Coll.Add cmd
                Set cmd = Nothing&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The first statement creates an instance of the FLst_CmdButton Class in memory. Its &lt;i&gt;cmd_frm&lt;/i&gt;&amp;nbsp;Property is then configured with the active form object frm, and the current Command Button control Reference in &lt;i&gt;ctl&lt;/i&gt;&amp;nbsp;is transmitted to the c_cmd&amp;nbsp;Property. When these two properties are armed with the references of the Form and Command Button, the resulting instance of the Command Button Wrapper Class effectively mirrors the properties and characteristics of the corresponding Command Button on the Form.&lt;/p&gt;&lt;p&gt;The subsequent statement, cmd.c_cmd.OnClick = EP&amp;nbsp;is functionally equivalent to specifying the text [Event Procedure] of the Command Button in the OnClick Event Property. Following the activation of the Event Procedure, the current instance of the Wrapper Class is added to the Collection Object in memory. This enables the CommandButton Event capturing and subsequently executes the associated Event Procedure in the Wrapper Class Module.&lt;/p&gt;
&lt;p&gt;You should not ignore the next statement:&amp;nbsp;Set cmd = Nothing.&lt;/p&gt;
&lt;p&gt;At this point, you may be in doubt. When we execute the above statement, it will erase the Wrapper Class Instance we created in memory.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;While the resemblance may be apparent, there is a crucial distinction. The inclusion of this instance of the Wrapper Class Object in the Collection Object ensures that the Collection Object remains active, retaining the Wrapper Class Instance in memory until the Form is closed and subsequently cleared.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The reason we need to execute &lt;i&gt;Set cmd = Nothing&lt;/i&gt;&amp;nbsp;is to avoid creating the CmdButton Wrapper Class Instance for another Command Button on the Form without clearing the previous one from memory. Without this step, attempts to create a second instance of the Command Button Wrapper Class could overwrite the earlier instance in the same memory location. Thus, resetting the&amp;nbsp;&lt;i&gt;cmd&lt;/i&gt;&amp;nbsp;ensures that a new instance can be created without interference with the earlier Instance of the Wrapper Class.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If we don&#39;t execute the&amp;nbsp;Set &lt;i&gt;cmd = Nothing&lt;/i&gt;&lt;b&gt;,&lt;/b&gt;&amp;nbsp;then only the last Command Button&#39;s Event will remain valid, and others will keep overwriting the earlier Instances.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;After the&amp;nbsp;&lt;i&gt;cmd&lt;/i&gt; object is reset,&amp;nbsp;creating another Command Button Wrapper Class instance searches for an available memory area to create a new instance. This ensures the proper allocation of memory for the new instance, preventing any interference with existing instances.&lt;/li&gt;&lt;li&gt;&lt;p&gt;So, please don&#39;t ignore this statement. Since it is a logical issue, you may need help finding it so easily when debugging.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The &lt;i&gt;Compact_Repair&lt;/i&gt; Form Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Dim Obj As New FLst_ObjInit

Private Sub Form_Load()
DoCmd.Restore
Set Obj.Ini_Frm = Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set Obj = Nothing
End Sub
&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;As customary, we have instantiated the Interface Class FLst_ObjInit in the global declaration section of the Form&#39;s Class Module. This declaration ensures that all three sets of &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html&quot; target=&quot;_blank&quot;&gt;Class Modules&lt;/a&gt;—Wrapper Class, Interface Class, and Form Class Module—are loaded into memory.&lt;/p&gt;&lt;p&gt;In the Form_Load() event procedure,&amp;nbsp;the&amp;nbsp;&#39;obj.Ini_Frm&#39; property of the Interface Class is assigned the reference to the active Form object, denoted by Me. This initiates a series of actions, and within moments, the system is primed to handle programmed events and their respective functions.&lt;/p&gt;&lt;p&gt;I hope this utility Program proves to be a valuable tool for optimizing your Access applications over an extended period, and the best part is that it comes at no cost.&lt;/p&gt;&lt;h3&gt;The Download Link for the&amp;nbsp;&lt;i&gt;Compact/Repair Utility&lt;/i&gt; is given below:&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/02/CompactingRepairing.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1kH5GedUrb1L2PtiWcGGFixCm6jPMjALp/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;CompactingRepairing.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/02/CompactingRepairing.zip--&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/2743524632942007436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/2743524632942007436'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/2743524632942007436'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html' title='Streamlining Code Database Compacting Utility'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivnGfeCLtSqcXe0WElcadGd-8uAbEEMql9Mkl9DLBv54KNreDgU1XXJpVLaAiXCNse8amsOqfgQydJDNh8POIW7YtjCi_0N21QsN8YShXgrbNr6mSOl4ijRZQJCX4zvrfu7_J-MS7QKx3wi8X8sbL-qk1pO1QmNP1MxCeEe3s6X5TlEqDQpFSkFTGBHvvg/s72-c/CompactRepair.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-5658992861531869454</id><published>2024-02-14T21:35:00.014+05:30</published><updated>2026-07-12T18:45:17.539+05:30</updated><title type='text'>Streamlining Code  Synchronized Floating POPup Form.</title><content type='html'>&lt;h3&gt;Streamlining Form Module Code in Standalone Class Module.
&lt;/h3&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Synchronized Floating Popup Form.&lt;/h3&gt;&lt;p&gt;The article on the &lt;a href=&quot;https://www.msaccesstips.com/2009/02/synchronized-floating-popup-form.html&quot; target=&quot;_blank&quot;&gt;Synchronized Floating Popup Form&lt;/a&gt; was originally published in February 2009. The notable difference is that once written in the Form Module, the Event Subroutine code is now executed from the Standalone &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html&quot; target=&quot;_blank&quot;&gt;Class Module&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;All events raised by the form and its controls—such as TextBoxes and Command Buttons—are now handled within the standalone class module, with their corresponding event subroutines executed outside the form module. &lt;/p&gt;&lt;p&gt;This represents a paradigm shift: VBA code that would normally reside in the form module is instead executed from a standalone class module, significantly reducing the amount of code required in the form module. As a result, the Form primarily serves as the user interface for designing and displaying controls.&lt;/p&gt;

&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;p&gt;VBA coding, code management, and debugging can now be performed independently, without opening Forms in Design View or navigating through control event properties to access the required code in the form module. You can always find your Object group-level streamlined Event Subroutine Code in one place in the &lt;a href=&quot;https://www.msaccesstips.com/2019/04/withevents-ms-access-class-module.html&quot; target=&quot;_blank&quot;&gt;Standalone Class Module&lt;/a&gt;.&amp;nbsp;There will be only one BeforeUpdate() Event Subroutine needed for 25 or more TextBoxes on the Form, even if all 25 of them need different sets of Code. If you have already visited the earlier Episodes of this Topic, you already know it by now.&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5SdBaIubpGvFt_fBlXLYZtDKvDM-ZBoJTv3rGZdyRdHFzh0KDhyphenhyphen3UjUIdSGaf4YaSHK0hjCAPj-XXSfkvlEpR-bHu9-kw7F06qjHjv-YupsLdhe4hxcZseXuXNxqNNdTeUD_7Ko952khCbU8CxZOJ4bFwxRmYhHPExCFf4q74mcjwpPg6_ucgpB1TBW2b/s1056/Synchronized2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Synchronized Popup Form&quot; border=&quot;0&quot; data-original-height=&quot;649&quot; data-original-width=&quot;1056&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5SdBaIubpGvFt_fBlXLYZtDKvDM-ZBoJTv3rGZdyRdHFzh0KDhyphenhyphen3UjUIdSGaf4YaSHK0hjCAPj-XXSfkvlEpR-bHu9-kw7F06qjHjv-YupsLdhe4hxcZseXuXNxqNNdTeUD_7Ko952khCbU8CxZOJ4bFwxRmYhHPExCFf4q74mcjwpPg6_ucgpB1TBW2b/s320/Synchronized2.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;Synchronized&amp;nbsp; Floating Popup Forms.&lt;/h3&gt;&lt;p&gt;The Employee record is structured into two distinct logical sets of information. The initial part encompasses Official Information, while the subsequent part entails personal information, including details such as address and phone number. To enhance user experience, these two sets of information are displayed in two separate, independent forms. Notably, the Personal Information section is not mandated to remain visible at all times on the screen. Instead, it can be accessed and displayed dynamically by clicking the &quot;Personal Info&quot; command button.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Moreover, as the navigation control advances to the next record on the first Form, it triggers an immediate update of the corresponding data on the second Form, guaranteeing seamless synchronization between the two forms. This ensures that the information displayed on both forms remains consistently aligned as the user navigates through the records.&lt;/p&gt;&lt;p&gt;The second form can be removed from the Screen by clicking on the Close Command Button. It can be displayed by selecting the Personal Info Command Button when needed.&lt;/p&gt;&lt;p&gt;The OnDirty and BeforeUpdate Events are enabled for all TextBoxes and ComboBoxes to safeguard data integrity.&amp;nbsp;&lt;/p&gt;&lt;p&gt;There are several TextBoxes, two Combo boxes, and two Command Buttons on the Form. The second Form has several text boxes and a Command Button.&lt;/p&gt;&lt;p&gt;To achieve the desired functionality, we need three Wrapper Classes—one for TextBoxes, one for Command Buttons, and one for &lt;a href=&quot;https://www.msaccesstips.com/2009/01/combo-box-column-values.html&quot; target=&quot;_blank&quot;&gt;Combo Boxes&lt;/a&gt;—along with the Intermediary Class Module (Interface Class). The Interface Class is responsible for creating Wrapper Class instances, initializing them with the corresponding Object references, and saving them dynamically in a Collection Object in memory. This approach ensures that when the events are fired from the form, they can be captured in the respective Wrapper Classes and run the required Event Procedures. This modular and organized structure enhances code manageability and promotes effective event handling across different types of controls on the form.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The TextBox Wrapper Class VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents Txt As Access.TextBox
Private tfrm As Access.Form
&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;TextBox Events
&#39;Author: a.p.r. pillai
&#39;Date  : 16/01/2024
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------
&#39;======== Form Object Property Procedure =========
Public Property Get t_Frm() As Access.Form
    Set t_Frm = tfrm
End Property

Public Property Set t_Frm(ByRef vFrm As Access.Form)
    Set tfrm = vFrm
End Property

&#39;======== TextBox Object Property Procedure =========
Public Property Get t_txt() As Access.TextBox
    Set t_txt = Txt
End Property

Public Property Set t_txt(ByRef vtxt As Access.TextBox)
    Set Txt = vtxt
End Property

&#39;======== Event Subroutine =========
Private Sub txt_Dirty(cancel As Integer)
If MsgBox(&quot;Are you Editing &quot; &amp;amp; Txt.Name &amp;amp; &quot; Field?&quot;, vbYesNo + vbCritical, Txt.Name &amp;amp; &quot; Dirty()&quot;) = vbNo Then
    cancel = True
End If
End Sub

Private Sub txt_BeforeUpdate(cancel As Integer)
If MsgBox(&quot;Save the Changes &quot; &amp;amp; Txt.Name &amp;amp; &quot; Field?&quot;, vbYesNo + vbCritical, Txt.Name &amp;amp; &quot; Dirty()&quot;) = vbNo Then
    cancel = True
End If
End Sub&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The TextBox Wrapper Class streamlines the process with just two Event Procedures, each containing a few lines of reusable code. This significantly simplifies the handling of all TextBoxes on both forms. Contrast this with the scenario where you&#39;d have to repetitively write these concise lines of code for each TextBox in both Form Modules. The Wrapper Class approach promotes code efficiency and enhances maintainability by consolidating common functionality in a centralized location.&lt;/p&gt;&lt;p&gt;A crucial aspect worth highlighting is the utilisation of the same TextBoxWrapper Class Instances for all Text Boxes across two distinct forms. This showcases the versatility of the new coding approach. This flexibility is particularly beneficial in scenarios involving one or more SubForms within the Main Form, as it allows a unified, efficient management of TextBox events and functionality, promoting a cohesive and streamlined development process.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The Command Button Wrapper Class VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents cmd As Access.CommandButton
Private cFrm As Access.Form
Private uFrm As Access.Form
Private strSQL As String

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;CommandButton Events
&#39;Author: a.p.r. pillai
&#39;Date  : 16/01/2024
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------
Public Property Get c_Frm() As Access.Form
    Set c_Frm = cFrm
End Property

Public Property Set c_Frm(ByRef vFrm As Access.Form)
    Set cFrm = vFrm
    Set uFrm = Forms(&quot;Employee_Sub&quot;)
End Property

Public Property Get c_cmd() As Access.CommandButton
    Set c_cmd = cmd
End Property

Public Property Set c_cmd(ByRef vcmd As Access.CommandButton)
    Set cmd = vcmd
End Property

&#39;====Event Subroutines====
Private Sub cmd_Click()
    Select Case cmd.Name
        Case &quot;cmdClose&quot;
            If MsgBox(&quot;Close the Main Form?&quot;, _
            vbYesNo + vbCritical, cmd.Name &amp;amp; &quot;_Click()&quot;) = vbNo Then
                &#39;Do Nothing
            Else
                DoCmd.Close acForm, &quot;Employee_Sub&quot;
                DoCmd.Close acForm, cFrm.Name
            End If
        
        Case &quot;cmdPersonalInfo&quot;
                strSQL = &quot;SELECT Employees.* FROM Employees &quot;
                strSQL = strSQL &amp;amp; &quot;WHERE ([EmployeeID] = &quot; &amp;amp; cFrm![EmployeeID] &amp;amp; &quot;);&quot;
                uFrm.RecordSource = strSQL
                uFrm.Requery
                uFrm.Visible = True
                cFrm.ActiveControl.SetFocus
        
        Case &quot;cmdCloseSub&quot;
                uFrm.Visible = False
    End Select
End Sub&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Having two &lt;a href=&quot;https://www.msaccesstips.com/2009/01/command-button-animation-2.html&quot; target=&quot;_blank&quot;&gt;Command Buttons&lt;/a&gt; on the Main Form and an additional one on the Second Form to close is common. Writing the Command Button Click Event Subroutines in the same Wrapper Class Module as demonstrated above streamlines code organization. Each Command Button corresponds to a dedicated Wrapper Class Instance, and these instances are assigned their respective Control &lt;a href=&quot;https://www.msaccesstips.com/2009/03/ms-access-and-reference-library.html&quot; target=&quot;_blank&quot;&gt;References&lt;/a&gt; from both forms.&lt;/p&gt;&lt;p&gt;Using control references as keys is crucial for the system to accurately identify the correct instance of the Wrapper Class, ensuring that the appropriate Event Subroutine is executed for each Command Button click. This approach enhances code clarity, maintainability, and reusability across different forms and controls.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The ComboBox Wrapper Class VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents cbo As Access.ComboBox
Private bFrm As Access.Form

&#39;-------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;-------------------------------------------------------
&#39;CommandButton Events
&#39;Author: a.p.r. pillai
&#39;Date  : 16/01/2024
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;-------------------------------------------------------
Public Property Get b_Frm() As Access.Form
    Set b_Frm = bFrm
End Property

Public Property Set b_Frm(ByRef vFrm As Access.Form)
    Set bFrm = vFrm
End Property

Public Property Get b_cbo() As Access.ComboBox
    Set b_cbo = cbo
End Property

Public Property Set b_cbo(ByRef vcbo As Access.ComboBox)
    Set cbo = vcbo
End Property

&#39;==== ComboBox Event Subroutine ====
Private Sub cbo_Dirty(cancel As Integer)
If MsgBox(&quot;Are you Editing &quot; &amp;amp; cbo.Name &amp;amp; &quot; Control?&quot;, _
vbYesNo + vbCritical, cbo.Name &amp;amp; &quot; Dirty()&quot;) = vbNo Then
    cancel = True
End If
End Sub

Private Sub cbo_BeforeUpdate(cancel As Integer)
If MsgBox(&quot;Save the Changes &quot; &amp;amp; cbo.Name &amp;amp; &quot; Control?&quot;, _
vbYesNo + vbCritical, cbo.Name &amp;amp; &quot; Dirty()&quot;) = vbNo Then
    cancel = True
End If
End Sub

&lt;/pre&gt;
&lt;p&gt;There are two Combo Boxes on the Main Form. The ComboBoxes are also enabled with the OnDirty() and BeforeUpdate() Event Subroutines to safeguard the data from unintentional changes or to apply changes with the User&#39;s consent.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Interface Class Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private ocmd As ClsCmdButton &#39;Wrapper Class
Private oTxt As ClsTextBox   &#39;Wrapper Class
Private ocbo As ClsCombo     &#39;Wrapper Class

Private WithEvents Frm As Access.Form &#39;Employees_Main
Private sFrm As Access.Form &#39;Employee_Sub

Private coll As New Collection
Private strSQL As String

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;Wrapper Classes Initialization
&#39;Author: a.p.r. pillai
&#39;Date  : 16/01/2024
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

Public Property Get i_Frm() As Access.Form
    Set i_Frm = Frm
End Property

Public Property Set i_Frm(ByRef vFrm As Access.Form)
    Set Frm = vFrm
    
    Call Class_Init
End Property

Private Sub Class_Init()
Dim ctl As Control
Const EP = &quot;[Event Procedure]&quot;

&#39;Open the 2nd Form
DoCmd.OpenForm &quot;Employee_Sub&quot;, , , , , acHidden

&#39;Assign the Form Reference to sFrm Object
Set sFrm = Forms(&quot;Employee_Sub&quot;)

&#39;Enable the OnCurrent Event of the Employees_Main Form
Frm.OnCurrent = EP

For Each ctl In Frm.Controls &#39;Employees_Main Form Controls
    Select Case TypeName(ctl)
        Case &quot;CommandButton&quot;
        
          Select Case ctl.Name &#39;
            Case &quot;cmdClose&quot;, &quot;cmdPersonalInfo&quot;
                Set ocmd = New ClsCmdButton &#39;Create new instance
                Set ocmd.c_Frm = Frm &#39;Assign Main Form Reference
                Set ocmd.c_cmd = ctl &#39;Pass current CommandButton Object Reference
                    ocmd.c_cmd.OnClick = EP &#39;Enable OnClick Event
                    coll.Add ocmd &#39;Add the instance to Collection Object
                Set ocmd = Nothing &#39;Reset Wrapper Class instance
          End Select
          
            Case &quot;TextBox&quot;
                Set oTxt = New ClsTextBox
                Set oTxt.t_Frm = Frm
                Set oTxt.t_txt = ctl
                    oTxt.t_txt.OnDirty = EP
                    oTxt.t_txt.BeforeUpdate = EP
                    oTxt.t_txt.BackColor = RGB(&amp;amp;HFF, &amp;amp;HF2, &amp;amp;H0)
                    oTxt.t_txt.BackStyle = 0
                    coll.Add oTxt
                Set oTxt = Nothing
                
            Case &quot;ComboBox&quot;
                Set ocbo = New ClsCombo
                Set ocbo.b_Frm = Frm
                Set ocbo.b_cbo = ctl
                    ocbo.b_cbo.OnDirty = EP
                    ocbo.b_cbo.BeforeUpdate = EP
                    ocbo.b_cbo.BackColor = RGB(&amp;amp;HFF, &amp;amp;HF2, &amp;amp;H0)
                    ocbo.b_cbo.BackStyle = 0
                    coll.Add ocbo
                Set ocbo = Nothing

    End Select
Next

For Each ctl In sFrm.Controls &#39;Employees_Sub Form Controls
    Select Case TypeName(ctl)
        Case &quot;CommandButton&quot;
        
          Select Case ctl.Name
            Case &quot;cmdCloseSub&quot;
                Set ocmd = New ClsCmdButton &#39;Instantiate
                Set ocmd.c_Frm = sFrm
                Set ocmd.c_cmd = ctl
                    ocmd.c_cmd.OnClick = EP
                    
                    coll.Add ocmd           &#39;Add to Collection
                Set ocmd = Nothing
          End Select
          
            Case &quot;TextBox&quot;
                Set oTxt = New ClsTextBox   &#39;Instantiate
                Set oTxt.t_Frm = sFrm
                Set oTxt.t_txt = ctl
                    oTxt.t_txt.OnDirty = EP
                    oTxt.t_txt.BeforeUpdate = EP
                    oTxt.t_txt.BackColor = RGB(&amp;amp;HFF, &amp;amp;HF2, &amp;amp;H0)
                    oTxt.t_txt.BackStyle = 0
                    coll.Add oTxt           &#39;Add to Collection
                Set oTxt = Nothing
    End Select
Next

End Sub

Private Sub frm_Current()
If IsLoaded(&quot;Employee_Sub&quot;) Then
   strSQL = &quot;SELECT Employees.* FROM Employees &quot;
   strSQL = strSQL &amp;amp; &quot;WHERE ([EmployeeID] = &quot; &amp;amp; Frm![EmployeeID] &amp;amp; &quot;);&quot;
   sFrm.RecordSource = strSQL
   Frm.SetFocus
End If

Private Sub Class_Terminate()
Set Frm = Nothing
Set sFrm = Nothing
Do While coll.Count &amp;gt; 0
    coll.Remove 1
Loop

End Sub

&lt;/pre&gt;&lt;p&gt;The Wrapper Classes are declared as Properties of the Interface Class. Two Form Object Properties are declared to scan for Controls on Employees_Main and Employee_Sub Forms.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The Frm&amp;nbsp;Object is qualified with the keyword &lt;a href=&quot;https://www.msaccesstips.com/2019/05/withevents-in-class-module-and-data.html&quot; target=&quot;_blank&quot;&gt;WithEvents&lt;/a&gt;&amp;nbsp;to enable the OnCurrent Event of the Employees_Main Form to update the Employee_Sub Form data based on the movement of Records on the Main Form.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The Collection Object and a String Variable strSQL are Properties declared in the Global Area.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The Property Procedures for the Frm&amp;nbsp;Object are declared next to receive the Main Form Object Reference from the Form_Load() Event Procedure of the Employees_Main Form. After assigning the Main Form Reference to the Frm Object,&amp;nbsp;the Class_Init Subroutine is called to create the Wrapper Class Instances and Initialize Procedures.&lt;/p&gt;&lt;p&gt;At the beginning of the Class_Init() Subroutine, the Employee_Sub Form is opened in &lt;i&gt;Hidden&lt;/i&gt; Mode and kept in memory. The sFrm&amp;nbsp;Form object is assigned the Reference of the Employee_Sub Form.&lt;/p&gt;&lt;p&gt;The following statement enables the Main Form&#39;s OnCurrent Event to fire the Event when the record is moved from one to the other through the Record Navigation Control:&lt;/p&gt;&lt;pre&gt;&#39;Enable the OnCurrent Event of the Employees_Main Form
Frm.OnCurrent = EP&lt;/pre&gt;&lt;p&gt;There are three sets of Objects on the Employees_Main Form: TextBoxes, Command Buttons, and Combo Boxes. The Employee_Sub Form has a few TextBoxes and a single Command Button to create Wrapper Class Instances and assign their related Object References.&lt;/p&gt;&lt;p&gt;The following VBA Code Segment scans the Employees_Main Form for TextBoxes, Command Buttons, and ComboBoxes:&lt;/p&gt;&lt;pre&gt;For Each ctl In Frm.Controls &#39;Employees_Main Form Controls
    Select Case TypeName(ctl)
        Case &quot;CommandButton&quot;
        
          Select Case ctl.Name &#39;
            Case &lt;span style=&quot;color: red;&quot;&gt;&quot;cmdClose&quot;, &quot;cmdPersonalInfo&quot;&lt;/span&gt;
                Set ocmd = New ClsCmdButton     &#39;Create new instance
                Set ocmd.c_Frm = Frm            &#39;Assign Main Form Reference
                Set ocmd.c_cmd = ctl            &#39;Pass current CommandButton Object Reference
                    ocmd.c_cmd.OnClick = EP     &#39;Enable OnClick Event
                    coll.Add ocmd               &#39;Add the instance to Collection Object
                Set ocmd = Nothing              &#39;Reset Wrapper Class instance
          End Select
          
            Case &lt;span style=&quot;color: red;&quot;&gt;&quot;TextBox&quot;&lt;/span&gt;
                Set oTxt = New ClsTextBox
                Set oTxt.t_Frm = Frm
                Set oTxt.t_txt = ctl
                    oTxt.t_txt.OnDirty = EP
                    oTxt.t_txt.BeforeUpdate = EP
                    
                   &lt;span style=&quot;color: red;&quot;&gt; oTxt.t_txt.BackColor = RGB(255, 242,0) &#39;Yellow Color
                    oTxt.t_txt.BackStyle = 0&lt;/span&gt;
                    
                    coll.Add oTxt
                Set oTxt = Nothing
                
            Case &lt;span style=&quot;color: red;&quot;&gt;&quot;ComboBox&quot;&lt;/span&gt;
                Set ocbo = New ClsCombo
                Set ocbo.b_Frm = Frm
                Set ocbo.b_cbo = ctl
                    ocbo.b_cbo.OnDirty = EP
                    ocbo.b_cbo.BeforeUpdate = EP
                    
                    &lt;span style=&quot;color: red;&quot;&gt;ocbo.b_cbo.BackColor = RGB(255, 242, 0) &#39;Yellow Color
                    ocbo.b_cbo.BackStyle = 0&lt;/span&gt;
                    
                    coll.Add ocbo
                Set ocbo = Nothing

    End Select
Next&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;The provided code segment checks the presence of Command Button, TextBox, and ComboBox controls on the Employees_Main Form. It creates instances of the corresponding Wrapper Classes, sets the Wrapper Class property values, enables the controls&#39; OnDirty and BeforeUpdate Events, and then adds these instances to the Collection Object in memory. This systematic approach ensures that the necessary controls are properly encapsulated within their respective Wrapper Class Instances and facilitates organized event handling through the centralized Collection.&lt;/p&gt;&lt;p&gt;The dynamic modification of the BackColor and BackStyle properties of TextBox and ComboBox Controls enhances user interaction on the form. Specifically, these properties are adjusted to highlight the backcolor in yellow when the control is active. The BackStyle property is set to Transparent, ensuring the yellow background Color is only displayed when the TextBox or ComboBox is in focus, contributing to a visually intuitive and user-friendly design.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Employee_Sub Form Controls VBA Code Segment.&lt;/h3&gt;
&lt;pre&gt;&lt;pre&gt;&#39;Assign the Form Reference to sFrm Object
Set sFrm = Forms(&quot;Employee_Sub&quot;)&lt;/pre&gt;For Each ctl In sFrm.Controls &#39;Employees_Sub Form Controls
    Select Case TypeName(ctl)
        Case &quot;CommandButton&quot;
        
          Select Case ctl.Name
            Case &quot;cmdCloseSub&quot;
                Set ocmd = New ClsCmdButton &#39;Instantiate
                Set ocmd.c_Frm = sFrm
                Set ocmd.c_cmd = ctl
                    ocmd.c_cmd.OnClick = EP
                    
                    coll.Add ocmd           &#39;Add to Collection
                Set ocmd = Nothing
          End Select
          
            Case &quot;TextBox&quot;
                Set oTxt = New ClsTextBox   &#39;Instantiate
                Set oTxt.t_Frm = sFrm
                Set oTxt.t_txt = ctl
                    oTxt.t_txt.OnDirty = EP
                    oTxt.t_txt.BeforeUpdate = EP
                    
                    oTxt.t_txt.BackColor = RGB(&amp;amp;HFF, &amp;amp;HF2, &amp;amp;H0)
                    oTxt.t_txt.BackStyle = 0
                    
                    coll.Add oTxt           &#39;Add to Collection
                Set oTxt = Nothing
    End Select
Next

&lt;/pre&gt;
&lt;p&gt;The second form contains TextBoxes, each equipped with OnDirty() and BeforeUpdate() Event Procedures, akin to the Main Form. If additional Event Subroutines are deemed necessary for these TextBoxes, beyond OnDirty() and BeforeUpdate(), they can be conveniently authored within the same Wrapper Class. The beauty of this approach lies in the uniqueness of references assigned to each&amp;nbsp; TextBox. This ensures that the references are tied to the respective objects, enabling the system to accurately locate and execute the correct Event Procedure for each TextBox through the associated Wrapper Class Instances.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Form_Current() Event Subroutine.&lt;/h3&gt;
&lt;pre&gt;Private Sub frm_Current()
If IsLoaded(&quot;Employee_Sub&quot;) Then
   strSQL = &quot;SELECT Employees.* FROM Employees &quot;
   strSQL = strSQL &amp;amp; &quot;WHERE ([EmployeeID] = &quot; &amp;amp; Frm![EmployeeID] &amp;amp; &quot;);&quot;
   sFrm.RecordSource = strSQL
   Frm.SetFocus
End If
End Sub

Private Sub Class_Terminate()
Set Frm = Nothing
Set sFrm = Nothing
Do While coll.Count &amp;gt; 0
    coll.Remove 1
Loop
End Sub
&lt;/pre&gt;&lt;p&gt;When the Record Navigation Button is employed to navigate to the next or previous record on the Employees_Main Form, the Form_Current() Event is triggered and captured by the Subroutine frm_Current() provided above. In response, a SQL query is formulated using the EmployeeID value as a key to filter the data from the employee record. Subsequently, this Query utilises the second form Record Source of Employee_Sub, ensuring personal info Data synchronization with the record currently displayed on the Employees_Main Form. This approach facilitates seamless coordination between the two forms, providing updated and synchronized information based on the selected record.&lt;/p&gt;
&lt;p&gt;The &lt;i&gt;Sub Class Terminate()&lt;/i&gt; Subroutine works like the Form_Unload() Event Subroutine. When you close the Form, the Form_Unload() Event Procedure fires if it is present on the Form before the Form is actually closed. This Subroutine clears the Form&#39;s declarations, removes all the Wrapper Class Instances from the &lt;a href=&quot;https://www.msaccesstips.com/2018/12/ms-access-and-collection-object-basics.html&quot; target=&quot;_blank&quot;&gt;Collection Object&lt;/a&gt;, and finally removes the Collection Object itself from memory.&lt;/p&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;The Employees_Main Form Module Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private obj As New ClsObject_Init

Private Sub Form_Load()
    Set obj.i_Frm = Me
End Sub

Private Sub Form_Unload(cancel As Integer)
    Set obj = Nothing
If IsLoaded(&quot;Employee_Sub&quot;) Then
  DoCmd.Close acForm, &quot;Employee_Sub&quot;
End If
End Sub

&lt;/pre&gt;
&lt;p&gt;Declares the Interface Object ClsObj_Init Class Module and instantiates it with the Object Name obj in the Global Declaration area of the Form Module.&amp;nbsp;&lt;/p&gt;&lt;p&gt;In the Form_Load() Event Subroutine, the Form Object Me is passed to the Frm Property of ClsObj_Init Interface Class through the Property Procedure i_Frm() in this statement:&amp;nbsp;&lt;i&gt;Set obj.i_frm = Me.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;In the Form_Unload() Event Procedure, the statement Set obj = Nothing&amp;nbsp;attempts to clear the ClsObj_Init Interface Class from memory. This will trigger the Sub Class_Terminate()&amp;nbsp;Subroutine we discussed above.&lt;/p&gt;&lt;p&gt;Hope you enjoyed the new way of Coding, and your feedback is highly appreciated.&lt;/p&gt;
&lt;h3&gt;Demo Database Download&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/02/SynchronizedForms2K.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1cY-htq0qLBzobUJ13KC8QWEOIODI9H1S/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;SynchronizedForms2K.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/02/SynchronizedForms2K.zip--&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/5658992861531869454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5658992861531869454'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5658992861531869454'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html' title='Streamlining Code  Synchronized Floating POPup Form.'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5SdBaIubpGvFt_fBlXLYZtDKvDM-ZBoJTv3rGZdyRdHFzh0KDhyphenhyphen3UjUIdSGaf4YaSHK0hjCAPj-XXSfkvlEpR-bHu9-kw7F06qjHjv-YupsLdhe4hxcZseXuXNxqNNdTeUD_7Ko952khCbU8CxZOJ4bFwxRmYhHPExCFf4q74mcjwpPg6_ucgpB1TBW2b/s72-c/Synchronized2.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-5335354154801710782</id><published>2024-02-01T17:26:00.012+05:30</published><updated>2026-07-12T15:56:01.037+05:30</updated><title type='text'>One TextBox and Three Wrapper Class Instances.</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlining Event Subroutines in a Standalone Class Module.&lt;/h3&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;The Standalone Class Module Coding Rules overview.&lt;/h4&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;One &lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_blank&quot;&gt;Wrapper Class Module&lt;/a&gt; for several objects of the same type (E.g., TextBox) in the Form: ClsTextBox.&lt;/li&gt;&lt;li&gt;&lt;p&gt;One Event Subroutine per Event for several Objects of the same type on the Form.&lt;/p&gt;&lt;p&gt;Example: &lt;/p&gt;
&lt;pre&gt;Private Sub txt_AfterUpdate()
    Select Case TypeName(Ctl)
       Case &quot;TextBox&quot;
       
          Select Case Ctl.Name 
              Case &quot;Text0&quot;
                  &#39;Code
                  
              Case &quot;Text2&quot;,&quot;Text4&quot;,&quot;Text6&quot;
                  &#39;Code
                  
              Case &quot;Text8&quot;
                  &#39;Code
          End Select
          
   End Select
End Sub&lt;/pre&gt;
&lt;/li&gt;
  &lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
  &lt;li&gt;&lt;p&gt;Wrapper Class instances are established, with an individual Instance designated for each TextBox on the form. Subsequently, each Instance is assigned its corresponding TextBox Reference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let us examine the Class_Init() Subroutine VBA Code and see how this process is initiated in the Intermediary (or Interface) Class Module - ClsObj_Init.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
 &lt;pre&gt; Private Sub Class_Init()
 Dim Ctl As Control
 
 For Each Ctl In Frm.Controls
   Select Case TypeName(Ctl)
     Case &quot;TextBox&quot;
       Set txt = New ClsTextBox
       Set txt.m_frm = Frm
       Set txt.m_txt = Ctl
       
           txt.m_txt.AfterUpdate = &quot;[Event Procedure]&quot;
           
           Coll.Add txt
       Set txt = Nothing
   End Select
Next
&lt;/pre&gt;
  
  &lt;/li&gt;&lt;li&gt;The above Subroutine modifies the AfterUpdate Event Property Values with&amp;nbsp;the text&amp;nbsp; [Event&lt;b&gt; &lt;/b&gt;Procedure] option at run-time.&lt;/li&gt;&lt;li&gt;&lt;p&gt;After typing something in the TextBox and pressing the Enter Key, the AfterUpdate Event fires.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If the AfterUpdate Property is assigned with a Macro or Public Function Name&lt;b&gt;,&lt;/b&gt; then the Event will call the Macro or Function directly. The Form doesn&#39;t need a Class Module to run these two options.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;As we are all aware, typically, we write one Subroutine per Event and create one Wrapper Class Instance per &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;TextBox&lt;/a&gt;. However, what happens if we deviate from this convention and create three Wrapper Class Instances with an AfterUpdate Event Subroutine for a single TextBox (e.g., Text0) and assign all three Instances the same Text0&amp;nbsp;Reference&lt;b&gt; &lt;/b&gt;(the Memory Address of Text0 TextBox)&lt;b&gt;?&lt;/b&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;p&gt;How does the AfterUpdate Event fire from all three Instances? All of them together or one after the other?&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;What will happen if three different Macro Names or Function Names are assigned to the AfterUpdate Property, for all three Wrapper Class Instances, like the example Code segment shown below:&lt;/p&gt;
&lt;pre&gt;	For j = 1 To 3 &#39;To create three Instances
             Set ctxt = New ClsTextBox
             Set ctxt.txt = ctl &#39;Text0 Reference
                 ctxt.param = j
                    
                &#39;Macro1, Macro2, Macro3
    		 ctxt.txt.AfterUpdate = &quot;Macro&quot; &amp;amp; CStr(j) 

                 coll.Add ctxt
             Set ctxt = Nothing
        Next
&lt;/pre&gt;
&lt;p&gt;To conduct this experiment and explore the outcomes, we require a TextBox on a Form named Text0, along with the TextBox Wrapper Class Module and the Intermediary (or Interface) Class Module to set up the necessary elements.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The Image of the Form is given below:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifS5gYvmH4yjLc5sAJXQJvs59NqjjaqOHF_MixZO3kkq83i5VhvV8aZ2CetFEkNPGPGE1MMMxktc6ohRJlpz4pCs6RxaEKLnXYr-DOyCxbpjXRYkJssSizSiA1JbsMxU3F6hzDBRis9PpDxAZZZeCvKHIGmpLJI-hgF1wba5Wcdqfwb7ndDVpS6sfxTbkf/s1036/Text0Instances.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Text0 Instances&quot; border=&quot;0&quot; data-original-height=&quot;833&quot; data-original-width=&quot;1036&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifS5gYvmH4yjLc5sAJXQJvs59NqjjaqOHF_MixZO3kkq83i5VhvV8aZ2CetFEkNPGPGE1MMMxktc6ohRJlpz4pCs6RxaEKLnXYr-DOyCxbpjXRYkJssSizSiA1JbsMxU3F6hzDBRis9PpDxAZZZeCvKHIGmpLJI-hgF1wba5Wcdqfwb7ndDVpS6sfxTbkf/s320/Text0Instances.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;Wrapper Class Module: ClsTextBox VBA Code.&lt;/h3&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;Option Compare Database
Option Explicit

Public WithEvents txt As Access.TextBox
Public param As Integer

Private Sub txt_AfterUpdate() 
Dim x As Variant
Dim msg As String

msg = &quot;INSTANCE OF &quot; &amp;amp; UCase(txt.Name)
Select Case param
    Case 1
        &#39;DoCmd.RunMacro &quot;Macro1&quot;
        &#39;x = DisplayText1()

        MsgBox &quot;1st &quot; &amp;amp; msg
    Case 2
        &#39;DoCmd.RunMacro &quot;Macro2&quot;
        &#39;x = DisplayText2()

        MsgBox &quot;2nd &quot; &amp;amp; msg
    Case 3
        &#39;DoCmd.RunMacro &quot;Macro3&quot;
        &#39;x = DisplayText3()

        MsgBox &quot;3rd &quot; &amp;amp; msg
End Select
End Sub
&lt;/pre&gt;
&lt;h3&gt;Review of Wrapper Class Code.&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_blank&quot;&gt;TextBox&lt;/a&gt; Object Txt&amp;nbsp;is declared with Public Scope and qualified with the Keyword WithEvents.&amp;nbsp;There is another Property&amp;nbsp;parameter also declared with Public Scope.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Following this, the Sub txt_AfterUpdate() Event procedure will execute three times, one after the other. This occurs for the same event procedure but originates from three distinct Wrapper Class instances. The execution order aligns with the instances&#39; creation sequence. The event procedure of the first instance runs first, then the second, and the third one last.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;p&gt;To discern the order of Wrapper Class instance creation and the event execution sequence, a sequence number is passed to the param variable. When the AfterUpdate event subroutine is executed, the param value is displayed in a message text. This approach allows us to identify the Wrapper Class instance in which the message is displayed and in proper order.&lt;/p&gt;&lt;p&gt;The Macro and Function Name demo running &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html&quot; target=&quot;_blank&quot;&gt;VBA Code&lt;/a&gt; lines are temporarily disabled for testing&amp;nbsp;[Event Procedure] alone.&amp;nbsp;&lt;/p&gt;&lt;h3&gt;The Intermediary or Interface Class Module ClsObj_Init VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private ctxt As ClsTextBox
Private frm As Form

Private WithEvents cmd As CommandButton
Dim coll As New Collection

Public Property Get m_Frm() As Form
    Set m_Frm = frm
End Property

Public Property Set m_Frm(ByVal vFrm As Form)
    Set frm = vFrm
    
    Call Class_Init
End Property

Private Sub Class_Init()
Dim ctl As Control
Dim j As Integer
Const EP = &quot;[Event Procedure]&quot;
    
For Each ctl In frm.Controls
    Select Case TypeName(ctl)
        Case &quot;TextBox&quot;
            Select Case ctl.Name
                Case &quot;Text0&quot; &#39;The Text0 Object Reference.
                  For j = 1 To 3
                    Set ctxt = New ClsTextBox
                     Set ctxt.txt = ctl
                        ctxt.param = j
                        
    &#39;ctxt.txt.AfterUpdate = &quot;Macro&quot; &amp;amp; CStr(j) &#39;Macro1, 2, 3
    &#39;ctxt.txt.AfterUpdate = &quot;=DisplayText&quot; &amp;amp; CStr(j) &amp;amp; &quot;()&quot;

    ctxt.txt.AfterUpdate = &quot;[Event Procedure]&quot;
                        coll.Add ctxt
                    Set ctxt = Nothing
                  Next
            End Select
        Case &quot;CommandButton&quot;
          Select Case ctl.Name
            Case &quot;CmdClose&quot;
              Set cmd = frm.cmdClose
                cmd.OnClick = &quot;[Event Procedure]&quot;
          End Select
    End Select
 Next
End Sub

Private Sub cmd_Click()
DoCmd.Close acForm, frm.Name
End Sub

&lt;/pre&gt;
&lt;p&gt;As usual, the first two lines of Code in the global area declare the TextBox Wrapper Class Object ctxt&amp;nbsp;and the Form object frm.&lt;/p&gt;
&lt;p&gt;A &lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-ten.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; on the form requires a Click Event to close the form. To capture the event firing in the Interface Class Module on the form, a Command Button object is declared qualified with the Keyword &lt;i&gt;WithEvents&amp;nbsp;&lt;/i&gt;in the global area. It&#39;s important to note that since there is only one Command Button on the form, handling the Click Event in the Interface Class Module can be done without a Wrapper Class.&lt;/p&gt;&lt;p&gt;A &lt;a href=&quot;https://www.msaccesstips.com/2018/12/ms-access-and-collection-object-basics.html&quot; target=&quot;_blank&quot;&gt;Collection object&lt;/a&gt; is declared to store all TextBox Object instances in memory, enabling the capture of events fired on the Form and the execution of the corresponding event subroutines.&lt;/p&gt;
&lt;p&gt;When the Form is open, the Form Object is passed to the Form object&#39;s &lt;i&gt;Set Property Procedure&lt;/i&gt;. The Object reference is assigned to the frm Property.&lt;/p&gt;&lt;p&gt;Next, the Class_Init() Subroutine is called.&lt;/p&gt;
&lt;p&gt;In the For ... Next loop, the Code scans the Form for the Text0 TextBox. Once found, the inner For...Next loop is configured to run for three cycles, creating three instances of the Wrapper Class Object ctxt. All three instances are assigned the same Text0&amp;nbsp;control reference. It&#39;s worth noting that this can be achieved without using the For...Next loop by duplicating the code three times. However, for consistency, we adhere to the coding style employed thus far.&lt;/p&gt;&lt;p&gt;When the Wrapper Class instances are created, the sequence number is passed to the Property &#39;ctxt.param&#39;. This number is then displayed in the MsgBox within the AfterUpdate Subroutine. This approach is beneficial for identifying the execution order of the event subroutines, which mirrors the sequence in which the object instances are created.&lt;/p&gt;&lt;p&gt;If you manually create an AfterUpdate Event Subroutine in the Form Module in addition to the three instances, that Form Module Event Subroutine will execute first, followed by the Subroutines in the Wrapper Class instances. This sequence ensures that any manually added code in the Form Module takes precedence over the dynamically created instances.&lt;/p&gt;
&lt;p&gt;As you have seen in the AfterUpdate Event Subroutine, we can check the sequence number in the param Property (see the Code segment below), and based on its order, call three different Sets of Programs when a single AfterUpdate or similar Event fires.&lt;/p&gt;
&lt;pre&gt;msg = &quot;INSTANCE OF &quot; &amp;amp; UCase(txt.Name)
Select Case param
    Case 1
        &#39;DoCmd.RunMacro &quot;Macro1&quot;
        &#39;x = DisplayText1()

        MsgBox &quot;1st &quot; &amp;amp; msg
    Case 2
        &#39;DoCmd.RunMacro &quot;Macro2&quot;
        &#39;x = DisplayText2()

        MsgBox &quot;2nd &quot; &amp;amp; msg
    Case 3
        &#39;DoCmd.RunMacro &quot;Macro3&quot;
        &#39;x = DisplayText3()

        MsgBox &quot;3rd &quot; &amp;amp; msg
End Select
&lt;/pre&gt;
&lt;p&gt;The test run of the Event Subroutine Image (message from the first Instance) is given below:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzAKEd1XlqpbkienEJmCaY8Bvc1atLHo8km59pam0a2G06ZrKJEX1_qG7sYR2pzfZdAfflblxz3EUygvKebH8tb0DYrRliZRBB4ruU6-DLXf3hXEZKssNbowK8RAODHJCN3L-rx-_l2oIAh7o6ltz89-tho7oyYIEJJmYWlRX4Zg624mSVMOWyQo7tYFCL/s1034/Text0InstancesView.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Event Procedure Message&quot; border=&quot;0&quot; data-original-height=&quot;831&quot; data-original-width=&quot;1034&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzAKEd1XlqpbkienEJmCaY8Bvc1atLHo8km59pam0a2G06ZrKJEX1_qG7sYR2pzfZdAfflblxz3EUygvKebH8tb0DYrRliZRBB4ruU6-DLXf3hXEZKssNbowK8RAODHJCN3L-rx-_l2oIAh7o6ltz89-tho7oyYIEJJmYWlRX4Zg624mSVMOWyQo7tYFCL/s320/Text0InstancesView.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The provided screenshot captures the moment when the message is displayed from the AfterUpdate() Event Subroutine, indicating the message originates from the first instance of the ClsTextBox Wrapper Class. Subsequently, two similar messages follow, each indicating the 2nd and 3rd instances, respectively.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Experiments with Macro Names: Macro1, Macro2, and Macro3&lt;/h3&gt;
&lt;p&gt;In the upcoming experiment, we will replace the text [Event Procedure] with the Macro names Macro1, Macro2, and Macro3 to trigger the AfterUpdate Event. It&#39;s important to note that no alterations will be made to the TextBox Wrapper Class VBA Code. Below is the modified code for the Class_Init() Subroutine in the Interface Module for your reference.&lt;/p&gt;
&lt;pre&gt;Private Sub Class_Init()
Dim ctl As Control
Dim j As Integer
Const EP = &quot;[Event Procedure]&quot;
    
For Each ctl In frm.Controls
    Select Case TypeName(ctl)
        Case &quot;TextBox&quot;
            Select Case ctl.Name
                Case &quot;Text0&quot;
                  For j = 1 To 3
                    Set ctxt = New ClsTextBox
                     Set ctxt.txt = ctl
                        ctxt.param = j
                        
        &#39;Macro1, Macro2, Macro3              
    	ctxt.txt.AfterUpdate = &quot;Macro&quot; &amp;amp; CStr(j)
        
                       coll.Add ctxt
                    Set ctxt = Nothing
                  Next
            End Select
        Case &quot;CommandButton&quot;
          Select Case ctl.Name
            Case &quot;CmdClose&quot;
              Set cmd = frm.cmdClose
                cmd.OnClick = &quot;[Event Procedure]&quot;
          End Select
    End Select
 Next
End Sub

&lt;/pre&gt;
&lt;p&gt;All three Macros have a Message Box Function that displays a message with the Macro Version numbers 1, 2, and 3, as shown below:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT6-I5e7LTFs7mm-Lm-hEjFGEfs3GOXM4KvPHT_MkC7zG0VBBHHzP58bxitKwSeOUSNtx5CFuq0UBDjMWckD12uBUeM632lFj01uLa58eiJSTsO3-pUZUS_0jgTlOTwgGKsPY0kSgohl3bEP2OGnshayv7OSBCFgtKXPWLTrl84ggAUijv0v24tg_BmB9J/s805/Mac123.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;639&quot; data-original-width=&quot;805&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT6-I5e7LTFs7mm-Lm-hEjFGEfs3GOXM4KvPHT_MkC7zG0VBBHHzP58bxitKwSeOUSNtx5CFuq0UBDjMWckD12uBUeM632lFj01uLa58eiJSTsO3-pUZUS_0jgTlOTwgGKsPY0kSgohl3bEP2OGnshayv7OSBCFgtKXPWLTrl84ggAUijv0v24tg_BmB9J/s320/Mac123.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;In the Initializing Class_Init() Subroutine, the AfterUpdate Property is assigned with the Macro Names: Macro1, Macro2, and Macro3, as we normally do with the&amp;nbsp;[Event Procedure] Option.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The following are the VBA code modifications; enter some text into the TextBox and press the Enter key to trigger the `AfterUpdate` event. You will then see a message displayed exclusively by `Macro3`. As emphasized earlier, neither the Form Class Module nor the Wrapper Class is needed to invoke the macro or function specified in the `AfterUpdate` event property or any other event property.&lt;/p&gt;&lt;p&gt;Running Public Functions: =DisplayText1(), =DisplayText2(), =DisplayText3().&lt;/p&gt;
&lt;p&gt;It is worth noting that the standard module contains three functions, the names shown above. Each function uses the `MsgBox` function to display a message indicating the sequence number reflected in its name.&lt;/p&gt;

&lt;p&gt;If you replace the line that sets the `AfterUpdate` event property in the `Class_Init()` procedure with the code shown above and then open the form, triggering the `AfterUpdate` event will display a message generated exclusively by the `DisplayText3()` function.&lt;/p&gt;
&lt;pre&gt;ctxt.txt.AfterUpdate = &quot;=DisplayText&quot; &amp;amp; CStr(j) &amp;amp; &quot;()&quot;&lt;/pre&gt;
&lt;p&gt;In contrast to the [Event Procedure] option, which invokes the RaiseEvent action, the macro and Function name coding pertains to the modifications of the AfterUpdate Event Property of the TextBox on the Property Sheet. This manual alteration involves replacing the existing name with three different names successively, with the final one prevailing.&lt;/p&gt;
&lt;h3&gt;How to Run Macros or Functions.&lt;/h3&gt;
&lt;p&gt;Indeed, the experimental approach undertaken served as an extraordinary demonstration, underscoring the crucial point that macro or function names coded in the Event Property are executed directly by the system. The Wrapper Class Instance is entirely bypassed in this process. Whether the names are manually written in the Event Property or scripted through the Class_Init() Subroutine, the modifications are consistently made directly to the TextBox Property.&lt;/p&gt;
&lt;p&gt;To alleviate potential confusion, a recommended approach is to consistently go for the &lt;i&gt;[Event Procedure]&lt;/i&gt;&lt;b&gt; &lt;/b&gt;option and then call the macro or function from within the TextBox Wrapper Class Instance-based subroutine. An illustrative example is provided below:&lt;/p&gt;
&lt;pre&gt;Private Sub txt_AfterUpdate() 
Dim x As Variant

Select Case txt.Name
    Case &quot;Text0&quot;
        &#39;DoCmd.RunMacro &quot;Macro1&quot; &#39; Run Macro
        &#39;x = DisplayText1()      &#39; Run Function

        MsgBox &quot;TextBox&quot; &amp;amp; txt.Name
End Select
&lt;/pre&gt;
&lt;p&gt;By adopting this method, clarity is enhanced, and the direct execution of macros or functions from the Event Property remains seamless within the designated Textbox Wrapper Class Instance. &lt;/p&gt;
&lt;h3&gt;Demo Database Download&lt;/h3&gt;
&lt;!--Download Link /downloads/2024/02/MultipleInstances.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/14QcXRdn8X9-DKml3q9NLSsX-GzJtg0bU/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;MultipleInstances.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/02/MultipleInstances.zip--&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/5335354154801710782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5335354154801710782'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/5335354154801710782'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html' title='One TextBox and Three Wrapper Class Instances.'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifS5gYvmH4yjLc5sAJXQJvs59NqjjaqOHF_MixZO3kkq83i5VhvV8aZ2CetFEkNPGPGE1MMMxktc6ohRJlpz4pCs6RxaEKLnXYr-DOyCxbpjXRYkJssSizSiA1JbsMxU3F6hzDBRis9PpDxAZZZeCvKHIGmpLJI-hgF1wba5Wcdqfwb7ndDVpS6sfxTbkf/s72-c/Text0Instances.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-4814018468211790426</id><published>2024-01-20T20:42:00.006+05:30</published><updated>2026-07-12T15:19:10.266+05:30</updated><title type='text'>The Event Firing Mechanism in Access Objects</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlining&amp;nbsp; Event Subroutine Code in Standalone Class Module.&lt;/h3&gt;&lt;h4 style=&quot;text-align: left;&quot;&gt;How Does the Event Firing Mechanism Work within Access Objects?&lt;/h4&gt;&lt;p&gt;This topic was briefly touched on during the Presentation of&amp;nbsp; &lt;a href=&quot;https://youtu.be/AjvjN3h1ipY&quot; target=&quot;_blank&quot;&gt;Streamlining Form Module Code&lt;/a&gt;&amp;nbsp;in the Standalone Class Module for &lt;a href=&quot;https://accessusergroups.org/europe/&quot; target=&quot;_blank&quot;&gt;Access User Groups (Europe)&lt;/a&gt;&amp;nbsp;Chapter.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The Event-related keywords: &lt;i&gt;Event, RaiseEvent,&lt;/i&gt; and &lt;i&gt;WithEvents&lt;/i&gt;.&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;i&gt;Event&lt;/i&gt; - used to define an Event.&lt;/li&gt;&lt;li&gt;&lt;i&gt;RaiseEvent&lt;/i&gt; - to Invoke the Event.&lt;/li&gt;&lt;li&gt;&lt;i&gt;WithEvents&lt;/i&gt; - to capture the fired Event and execute the Event Subroutine Code.&lt;/li&gt;&lt;/ol&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;p&gt;In the preceding articles, we gained insights into&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;using Event-related Keywords and crafting&amp;nbsp;&lt;a href=&quot;&quot; target=&quot;_blank&quot;&gt;Event Subroutines&amp;nbsp;&lt;/a&gt;within Standalone Class Modules rather than in&lt;/span&gt;&amp;nbsp;the Form Module. Notably, the Event and WithEvents keywords were prominently featured in the Object Browser, as illustrated below:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKeutMvjQFAWvdx0_OImSshjdj-c4UTG4LJRS3MiP38vddUrA1YMDFt54aJxIbJV_bpNzZNP2cxPwdIcGtVY-X8D1J03yIqib1VWdR24_OIRTHD3u94Kr5aGxbbzI6v06DNGKcsBUtEOkdOFHTB2VYUCfVzgiRY_9WLjkqENMEb-tsDnBBM1pMe-fAPVhq/s985/Slide4Image.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;528&quot; data-original-width=&quot;985&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKeutMvjQFAWvdx0_OImSshjdj-c4UTG4LJRS3MiP38vddUrA1YMDFt54aJxIbJV_bpNzZNP2cxPwdIcGtVY-X8D1J03yIqib1VWdR24_OIRTHD3u94Kr5aGxbbzI6v06DNGKcsBUtEOkdOFHTB2VYUCfVzgiRY_9WLjkqENMEb-tsDnBBM1pMe-fAPVhq/s320/Slide4Image.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;However,&amp;nbsp;RaiseEvent&amp;nbsp;is an internal event-firing mechanism that supports multiple options via a dedicated event-related property. This Event is invoked from the Class Object functions as a system program. It assesses the specified option in the event property and executes the selected choice, be it a macro, function (user-defined or built-in), or the text [Event Procedure]. This, in turn, triggers the &lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_blank&quot;&gt;RaiseEvent&lt;/a&gt;, like the functionality of the Call Statement in VBA.&lt;/p&gt;&lt;p&gt;The following Link gives the details about the RaiseEvent Statement:&amp;nbsp;&lt;a href=&quot;https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/raiseevent-statement&quot; target=&quot;_blank&quot;&gt;https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/raiseevent-statement&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The authentic Object Event-firing mechanism is an internal program in the Access System. For instance, the AfterUpdate Event encompasses an AfterUpdateMacro, typically kept hidden from the Object Browser Window. To reveal it, one can simply right-click and select the &#39;&lt;i&gt;Show Hidden Members&lt;/i&gt;&#39; option. Analogously, other Object Events, such as CommandButton Click, feature the OnClick Event property to specify the execution option. Furthermore, there&#39;s the OnClickMacro, which evaluates the given value in the OnClick Property, facilitating the execution of the designated option.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Assumptions Based on Observation.&lt;/h3&gt;&lt;p&gt;Upon scrutinizing the execution pattern of the specified option within the Event Property, I found it worthwhile to attempt to create a straightforward subroutine that emulates the methodology employed in the Event mechanism. This endeavor aims to replicate the mechanism by which the event executes the designated option specified in the Property Sheet.&lt;/p&gt;&lt;p&gt;An interesting observation emerges: when a macro name or function name is specified in the Event Property, it triggers the execution of the designated macro or built-in function, as well as user-defined functions in a standard module. Notably, for these two options, there is no requisite attachment of a &lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;Class Module&lt;/a&gt; to the Form, and the &#39;Has Module&#39; Property of the Form can be set to False.&lt;/p&gt;&lt;p&gt;We require only one instance of the TextBox control and one instance each of two Command Button controls, each with a different name, in the intermediary class module. All three object instances are declared using the `WithEvents` keyword, enabling their event procedures to be implemented within the `Card_ObjInit` class.&lt;/p&gt;

&lt;p&gt;In this scenario, adopting object-level wrapper classes would likely result in a larger VBA codebase for event handling. Following the recommended design guidelines would require wrapper classes, particularly for the Command Button controls. In addition, a `Collection` object would be necessary to maintain wrapper class instances in memory, ensuring that their event procedures remain available and are executed correctly.&lt;/p&gt;

&lt;p&gt;However, given the simplicity of the form interface and the limited number of events to be managed, this approach may introduce unnecessary complexity and resource overhead. If the streamlined solution implemented in the intermediary class module is sufficient to handle these events, it provides a more efficient implementation. The choice should therefore be based on adherence to design guidelines with the practical resource requirements of the specific form.&lt;/p&gt;

&lt;p&gt;Accordingly, in this case, we chose to manage all event handling directly within the `Card_ObjInit` class module.&lt;/p&gt;&lt;p&gt;The Event Running Form Image is given below:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFFtW1k6CfShwXUDHTUCSaTxmJnzRdHDCcj3N7jPpAcM3dP24dL5Xwq5ejbOcY7fdvLOda1zsda3bH5WQ2BQg028SqLSt-uic8ceMze0_hdh2pTcdw1glZtyI6pCPKDFfQQOwEzYXrtEcz-Df623m_AFpOwNf-tftyA6lOgoSxFioQK9whTuvfyPH0DlDx/s1059/RaiseEventDemo.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;855&quot; data-original-width=&quot;1059&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFFtW1k6CfShwXUDHTUCSaTxmJnzRdHDCcj3N7jPpAcM3dP24dL5Xwq5ejbOcY7fdvLOda1zsda3bH5WQ2BQg028SqLSt-uic8ceMze0_hdh2pTcdw1glZtyI6pCPKDFfQQOwEzYXrtEcz-Df623m_AFpOwNf-tftyA6lOgoSxFioQK9whTuvfyPH0DlDx/s320/RaiseEventDemo.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The above Form is divided into two Parts:&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;The upper portion of the form, delineated by the thick horizontal black line in the middle, serves as our experimental ground for exploring the event execution method. Here, we endeavor to unravel the intricacies of the event-running mechanism within the Access System.&lt;/li&gt;&lt;li&gt;&lt;p&gt;In the Section below the horizontal line, we will run the same Event Options as we normally do in the AfterUpdate Property of a TextBox.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;In the initial section, a ListBox offers a range of options that can be selected by a simple click. Upon selection, the chosen option promptly populates the Text2 TextBox Control above. Analogous to the AfterUpdate Event Property in the TextBox&#39;s Property Sheet, the specified option in the TextBox Control executes within our Event Subroutine &lt;i&gt;AfterUpdateMac()&lt;/i&gt;.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The event-running Subroutine, AfterUpdateMac(), is written in the Standalone Class Module &lt;i&gt;ClsAfterUpdateMacro&lt;/i&gt;.&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The ClsAfterUpdateMacro Class Module VBA Code.&lt;/h3&gt;&lt;p&gt;The Class Module with the Subroutine &lt;b&gt;AfterUpdateMac()&lt;/b&gt; VBA Code is given below:&lt;/p&gt;

&lt;pre style=&quot;text-align: left;&quot;&gt;Option Compare Database
Option Explicit

&#39;User-Defined Event
Public Event AfterUpdat(ByVal txt As String)
Private After_Update As String
&#39;Options: Macro,Function,&quot;[Event Procedure]&quot;

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;AfterUpdateMac() Event Processing Subroutine
&#39;Author: a.p.r. pillai
&#39;Date  : 19/01/2024
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

Public Property Get OnAfterUpdate() As String
 OnAfterUpdate = After_Update
End Property

Public Property Let OnAfterUpdate(ByVal vNewValue As String)
 After_Update = vNewValue
 
 Call AfterUpdateMac
End Property

Private Sub AfterUpdateMac()
&#39;Evaluate the given option
&#39;and Run the Event action
Dim opt As String
Dim vx As Variant

On Error GoTo AfterUpdateMac_Err

opt = Nz(After_Update, &quot;&quot;)

If Len(opt) = 0 Then
    Exit Sub
ElseIf UCase(opt) = &quot;[EVENT PROCEDURE]&quot; Then
    &#39;RaiseEvent: Call Event Subroutine
    RaiseEvent AfterUpdat(&quot;RaiseEvent MESSAGE TEXT&quot;)
ElseIf Left(opt, 1) = &quot;=&quot; Then
    &#39;Expression
    opt = Mid(opt, 2)
    vx = Eval(opt)
Else
    &#39;Run Macro
    DoCmd.RunMacro opt
End If

AfterUpdateMac_Exit:
Exit Sub

AfterUpdateMac_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;AfterUpdateMac_Err()&quot;
Resume AfterUpdateMac_Exit
End Sub
&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Review of the Class Module Code.&lt;/h3&gt;&lt;p&gt;In the Global declaration area, an Event is defined with the name&amp;nbsp;&lt;i&gt;&lt;b&gt;&lt;span style=&quot;font-family: monospace;&quot;&gt;Update&lt;/span&gt;&lt;code&gt;After(ByVal txt As String)&lt;/code&gt;&lt;/b&gt;&lt;/i&gt;. The two words in AfterUpdate are switched to avoid it being mistaken for the AfterUpdate() System Event Procedure. intentionally. Another Property,&amp;nbsp;After_Update As String, is also declared for inserting the Event running option, analogous to the AfterUpdate Property of the TextBox.&lt;/p&gt;
&lt;p&gt;Then, the &lt;i&gt;Get&lt;/i&gt;&lt;b&gt; &lt;/b&gt;and &lt;i&gt;Let&lt;/i&gt;&lt;i&gt;&lt;b&gt; &lt;/b&gt;&lt;/i&gt;Property Procedures are used to get the selected option from the Form and pass it on to the &#39;AfterUpdateMacro&lt;b&gt;()&#39;&amp;nbsp;&lt;/b&gt;to execute the Option. The &#39;&lt;i&gt;AfterUpdateMac()&lt;/i&gt;&#39; is trying to mimic the action of the AfterUpdateMacro&amp;nbsp;hidden Property/Procedure of the TextBox we saw in the Object Browser Image given at the top of this Page.&lt;/p&gt;&lt;p&gt;The options that we can normally insert into an Event Property are given in a ListBox.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;A Macro with the name &lt;i&gt;Macro1&lt;/i&gt;&lt;/li&gt;&lt;li&gt;The Function/Expression =DisplayText()&amp;nbsp;to call the Function in the Standard Module&amp;nbsp;&lt;/li&gt;&lt;li&gt;The String [Event Procedure] to call the declared Event Subroutine in the Form Module.&lt;/li&gt;&lt;li&gt;Other built-in Functions like MsgBox() and InputBox().&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span face=&quot;&amp;quot;Google Sans&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, sans-serif&quot; style=&quot;background-color: white; color: #1f1f1f; font-size: 16px;&quot;&gt;By clicking an option, you insert it into the After_Update Property and activate a process within the Class Module that evaluates and executes the chosen option.&lt;/span&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The AfterUpdateMac() Subroutine VBA Code.&lt;/h3&gt;&lt;p&gt;Let us have a closer look at the AfterUpdateMac() Subroutine Code.&lt;/p&gt;
&lt;pre&gt;Private Sub AfterUpdateMac()
&#39;Evaluate the given option
&#39;and Run the Event action
Dim opt As String
Dim vx As Variant

On Error GoTo AfterUpdateMac_Err

opt = Nz(After_Update, &quot;&quot;)

If Len(opt) = 0 Then
    Exit Sub
ElseIf UCase(opt) = &quot;[EVENT PROCEDURE]&quot; Then
    &#39;RaiseEvent: Call Event Subroutine
    &lt;i&gt;RaiseEvent&lt;/i&gt; &lt;b&gt;UpdateAfter(&quot;RaiseEvent MESSAGE TEXT&quot;)&lt;/b&gt;
ElseIf Left(opt, 1) = &quot;=&quot; Then
    &#39;Expression
    opt = Mid(opt, 2)
    vx = Eval(opt)
Else
    &#39;Run Macro
    DoCmd.RunMacro opt
End If

AfterUpdateMac_Exit:
Exit Sub

AfterUpdateMac_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;AfterUpdateMac_Err()&quot;
Resume AfterUpdateMac_Exit
End Sub&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Within the subroutine, two local variables, &lt;i&gt;opt&lt;/i&gt; and &lt;i&gt;vx&lt;/i&gt;,&amp;nbsp;are declared. The selected option, inserted into the Text2 TextBox Control on the form, is assigned to the &lt;i&gt;After_Update&lt;/i&gt; Property declared in the global area of the Class Module. The statement opt = Nz(After_Update, &quot;&quot;) checks whether the After_Update Property contains any value. If it does not, the subroutine gracefully exits.&lt;/p&gt;&lt;p&gt;If the received value is the text [Event Procedure], the user-defined &lt;i&gt;Update&lt;/i&gt;&lt;i&gt;After&lt;/i&gt;&lt;i&gt;()&lt;/i&gt; is called with the sample text parameter. This event is captured in the Form Module and subsequently displays the parameter text in a MessageBox.&lt;/p&gt;
&lt;p&gt;In the scenario where the opt variable contains an expression (&lt;i&gt;Note&lt;/i&gt;: an expression starts with an &#39;=&#39; symbol), a check is made for the presence of the equal symbol as the first character. If detected, it is presumed to be a function or a valid expression. The expression is then passed to the Eval() function after removing the &#39;=&#39; symbol.&lt;/p&gt;

&lt;p&gt;If the value received in the After_Update Property doesn&#39;t satisfy any of the aforementioned criteria, it is assumed to be a macro name. Subsequently, the macro is executed using the DoCmd.RunMacro command.&lt;/p&gt;&lt;p&gt;If any Error is encountered, it shows an Error Message and exits from the Program.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Form Module Code is listed below:&lt;/h3&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;Option Compare Database
Option Explicit

Private WithEvents C1 As ClsAfterUpdateMacro

Private Sub Form_Load()
Set C1 = New ClsAfterUpdateMacro
End Sub

Private Sub cmdClose_Click()
DoCmd.Close
End Sub

Private Sub List0_Click()
    Me.Text2.Value = List0
    C1.OnAfterUpdate = Me![Text2]
End Sub

&#39;UserDefined Event Message
Private Sub &lt;b&gt;C1_UpdateAfter&lt;/b&gt;(ByVal otxt As String)
    MsgBox otxt
End Sub

&#39;This is the Normal Procedure
&#39;Executed by Access System.
Private Sub Text27_AfterUpdate()
    MsgBox &quot;AfterUpdate Event Subroutine Fired.&quot;
End Sub
&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The Form Module Code Review.&lt;/h3&gt;&lt;p&gt;The ClsAfterUpdateMac Class is declared with the Object name C1 in the Global declaration area.&lt;/p&gt;&lt;p&gt;In the Form_Load() Event Subroutine, the C1 Object is instantiated and loaded into memory.&amp;nbsp;&lt;/p&gt;&lt;p&gt;In the List0_Click() Event Procedure, the selected ListBox option is assigned to the After_Update Property through the C1.OnAfterUpdate Property Procedure.&lt;/p&gt;&lt;p&gt;The following code segment represents the subsequent subroutine that captures the AfterUpdateMac() Event when triggered from the &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html&quot; target=&quot;_blank&quot;&gt;Class Module&lt;/a&gt; using the RaiseEvent action, specifically when the option selected from the ListBox is [Event Procedure].&lt;/p&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;&#39;UserDefined Event Subroutine
Private Sub &lt;b&gt;C1_&lt;i&gt;UpdateAfter&lt;/i&gt;&lt;/b&gt;(ByVal otxt As String)&lt;br /&gt;    MsgBox otxt
End Sub&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This is used for the second part of this experiment in the Normal Form Module Coding and Event firing from the Access System.&lt;/p&gt;&lt;pre&gt;&#39;This is the Normal Procedure
&#39;Executed by Access System.
Private Sub Text27_AfterUpdate()
    MsgBox &quot;AfterUpdate Event Subroutine Fired.&quot;
End Sub
&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The Second Part of the Form.&lt;/h3&gt;&lt;p&gt;In the Second part of the Form, the same set of options is entered into a Label Control, so that when you are in the Form Design View, you can highlight and copy the required option from the Label Control and paste it into the AfterUpdate Event Property of the Text27 TextBox Control. This is easier than typing them correctly in the AfterUpdate Property, without errors.&lt;/p&gt;&lt;p&gt;Then save the Form and open it in Normal View.&lt;/p&gt;&lt;p&gt;Type at least one character in the TextBox, and press the Enter key to fire the AfterUpdate Event for the option inserted into the TextBox Text27 Property.&lt;/p&gt;&lt;p&gt;The AfterUpdate() Event Fires at this point, depending on the option in the Property, and executes the action as we saw it in our own earlier experiment.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Event Properties and their related Macros.&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6qg9YrQL5VenHWPCkw0KQ4BZaGigdOxDOBdJhVsiuTzJsX3-lNBM5VasEA9Lhx_PQxXI6xWOwoU526ZYopxE-uaKVPDpJNwBewfzAh4maycehhLeh0P5aAZbJuB_DeF_PGuZR6wLHWyP5FE8lc7Hq4308979Pl91hYhwQmcj3oc8lglKar0iUl8S4gmCC/s600/ClassCommandButton.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;539&quot; data-original-width=&quot;600&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6qg9YrQL5VenHWPCkw0KQ4BZaGigdOxDOBdJhVsiuTzJsX3-lNBM5VasEA9Lhx_PQxXI6xWOwoU526ZYopxE-uaKVPDpJNwBewfzAh4maycehhLeh0P5aAZbJuB_DeF_PGuZR6wLHWyP5FE8lc7Hq4308979Pl91hYhwQmcj3oc8lglKar0iUl8S4gmCC/s320/ClassCommandButton.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;As illustrated in the Object Browser image shown above, the left pane displays the `CommandButton` class selection, while the right pane lists its event-related properties, including the hidden ones. Notably, all event option-setting properties are prefixed with On followed by the event name, such as `OnClick`. Associated with each of these properties is another property or procedure with the same event name, suffixed with Macro, such as `OnClickMacro`. This suggests the presence of an internal routine that evaluates the option specified in the `OnClick` property and then executes the corresponding action.&lt;/p&gt;

&lt;p&gt;It is highly likely that these additional procedures associated with the event properties, identified by the Macro suffix, encapsulate logic similar to the code structure we explored in the initial section. The consistent naming convention suggests a standardized internal implementation, reinforcing the plausibility of such an underlying code structure.&lt;/p&gt;&lt;p&gt;The Demo Database is attached for your own experiments and learning.&lt;/p&gt;
&lt;!--Download Link /downloads/2024/01/0_RaiseEvent2.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1hkQWiiHvVsKefN8Nsa_cIva3eA-_tEnq/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;0_RaiseEvent2.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2024/01/0_RaiseEvent2.zip--&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/4814018468211790426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/4814018468211790426'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/4814018468211790426'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html' title='The Event Firing Mechanism in Access Objects'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKeutMvjQFAWvdx0_OImSshjdj-c4UTG4LJRS3MiP38vddUrA1YMDFt54aJxIbJV_bpNzZNP2cxPwdIcGtVY-X8D1J03yIqib1VWdR24_OIRTHD3u94Kr5aGxbbzI6v06DNGKcsBUtEOkdOFHTB2VYUCfVzgiRY_9WLjkqENMEb-tsDnBBM1pMe-fAPVhq/s72-c/Slide4Image.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-2945368769414146248</id><published>2024-01-13T23:41:00.020+05:30</published><updated>2026-07-11T19:45:43.024+05:30</updated><title type='text'>Form VBA Structured Coding Access Users-Group Europe Presentation</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;&lt;p&gt;On January 3, 2024, I presented a concise overview of the intricate topic: &quot;Streamlining Form Module Code in Standalone Class Module&quot; for the Access User Groups (Europe) Chapter.&amp;nbsp; &amp;nbsp;&lt;a href=&quot;https://www.accessusergroups.org/europe/&quot;&gt;https://accessusergroups.org/europe/&lt;/a&gt;&amp;nbsp;.&amp;nbsp;&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://youtu.be/AjvjN3h1ipY&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;768&quot; data-original-width=&quot;1358&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiCiMJMHkFvrA1SYMmENzL2-tXLy5HcUotXZYzirfF2KxiYi19NO73DkFYQLOzxTcYc0s-4ck66fT6nyxN2OL2lIDiuGE6ZOeP0dt15CfaDpJO5PIwAjPikmGETyA8fwYZfmVBqZtnwDSJR5PBHov1kUNNb5nCwXUD7ZmNGMn4fORCqMruTQG-zYgYUNtS/s320/AEUMeeting.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;center&gt;&lt;a href=&quot;https://youtu.be/AjvjN3h1ipY&quot;&gt;https://youtu.be/AjvjN3h1ipY&lt;/a&gt;&lt;/center&gt;
&lt;p&gt;The YouTube subtitles are available in eleven languages: Danish, Dutch, English, French, German, Italian, Spanish, Hindi, Malayalam, Bangla (India), and English (Auto-generated). Choose your preferred language subtitles from the Settings Menu. Experience the video, packed with technical details, all conveniently in one place. &lt;a href=&quot;https://youtu.be/AjvjN3h1ipY&quot; target=&quot;_blank&quot;&gt;YouTube.com&amp;nbsp;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;PS: The Subtitle Translation may not be accurate.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;h3&gt;Download Demo Database&lt;/h3&gt;
&lt;!--Download Link /downloads/2023/07/Streamline7.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1aKelFg1y4oSKdVqmFQk-91yQM37yCpTL/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;Streamline7.zip&lt;/a&gt;
&lt;/div&gt;
&lt;h3&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/2945368769414146248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/2945368769414146248'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/2945368769414146248'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html' title='Form VBA Structured Coding Access Users-Group Europe Presentation'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiCiMJMHkFvrA1SYMmENzL2-tXLy5HcUotXZYzirfF2KxiYi19NO73DkFYQLOzxTcYc0s-4ck66fT6nyxN2OL2lIDiuGE6ZOeP0dt15CfaDpJO5PIwAjPikmGETyA8fwYZfmVBqZtnwDSJR5PBHov1kUNNb5nCwXUD7ZmNGMn4fORCqMruTQG-zYgYUNtS/s72-c/AEUMeeting.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-1361480648516748783</id><published>2023-12-03T12:31:00.014+05:30</published><updated>2026-07-11T19:44:55.398+05:30</updated><title type='text'>Form VBA Structured Coding Numbers to Words Converter</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Numbers to Words Converter.&lt;/h3&gt;&lt;p&gt;While Microsoft Word &lt;a href=&quot;https://www.msaccesstips.com/2007/10/ms-access-and-mail-merge-3.html&quot; target=&quot;_blank&quot;&gt;Mail Merge&lt;/a&gt; provides a straightforward way to convert numbers into words, this functionality is not directly available in MS Access. To bridge this gap, we developed a versatile function that can be used wherever required—whether in a Form TextBox control, Report Summary, printed invoices, or any other context. Simply call the &lt;code data-end=&quot;461&quot; data-start=&quot;449&quot;&gt;CardText()&lt;/code&gt; function with the desired number, and it will return the corresponding words for display. It’s that simple.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;p&gt;The Main Demo Form Image is given below:&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS5HD4XHDVeHH3CpWg6EGAoAVMHelDrbjJV9Wsl-UjF14bDpnb15S2sPtZc4kjwq2aOZaMb3k61_-opzwaAciCQEDEq1XKPq7pP7NEODQ8cG1lT-BzRAyfE4qmJg7qX8VPG72Vqh37Kk_mVm2Jg7amoDmb0bKOVcRSuGCOmrdrZpFYbaA23EyXWUjfpkbe/s946/NumberToWords4.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;591&quot; data-original-width=&quot;946&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS5HD4XHDVeHH3CpWg6EGAoAVMHelDrbjJV9Wsl-UjF14bDpnb15S2sPtZc4kjwq2aOZaMb3k61_-opzwaAciCQEDEq1XKPq7pP7NEODQ8cG1lT-BzRAyfE4qmJg7qX8VPG72Vqh37Kk_mVm2Jg7amoDmb0bKOVcRSuGCOmrdrZpFYbaA23EyXWUjfpkbe/s320/NumberToWords4.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;The Demo Form in Design View.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihpB4dKXCbO7Z9ZTNvZfJFUlokf2hG9x2E3DEOy9kYdZ1zGdYRQumO110z3B54uQO8lqb_4QlSu-5eF5Qf9Srw_DFAO3Two6jUpwqsbcO2nRuMdRGE5bmvzppVo4gGWQ_iglHSR_EKvHCUOcrXkrBp9kpTwU1IUCA5IcS0DQoArq1IknFNQUycijpj_HKF/s974/CardTextDesign2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;761&quot; data-original-width=&quot;974&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihpB4dKXCbO7Z9ZTNvZfJFUlokf2hG9x2E3DEOy9kYdZ1zGdYRQumO110z3B54uQO8lqb_4QlSu-5eF5Qf9Srw_DFAO3Two6jUpwqsbcO2nRuMdRGE5bmvzppVo4gGWQ_iglHSR_EKvHCUOcrXkrBp9kpTwU1IUCA5IcS0DQoArq1IknFNQUycijpj_HKF/s320/CardTextDesign2.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;


&lt;p&gt;Sample Report Image. The Group-level Subtotal Amount is printed in Words.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3wzqtsWvVtagO8UEHYrMYb8GdD7-vO891KlrvquzBMqu0L5EcKet56CX0GZVUcDQtm4uiAVUsm42WkM00PhTaTevalbm3OTFgXLOv4SmuDWQ8-mWwZGAEaJJAcd6KAXOVMG5JfOeNoqXg8RWm3OQt1xfj2VtGL2_9TA1Zj2yN8B6VK9KrgVDFXKAAsGS5/s1229/CardText_Report.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;803&quot; data-original-width=&quot;1229&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3wzqtsWvVtagO8UEHYrMYb8GdD7-vO891KlrvquzBMqu0L5EcKet56CX0GZVUcDQtm4uiAVUsm42WkM00PhTaTevalbm3OTFgXLOv4SmuDWQ8-mWwZGAEaJJAcd6KAXOVMG5JfOeNoqXg8RWm3OQt1xfj2VtGL2_9TA1Zj2yN8B6VK9KrgVDFXKAAsGS5/s320/CardText_Report.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The CardText() Function VBA Code Listing.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Public Function CardText(ByVal inNumber As Double, Optional ByVal precision As Integer = 2) As String
&#39;------------------------------------------------------------------------
&#39;Author : a.p.r. pillai
&#39;Date   : December 2008/2023
&#39;URL    : www.msaccesstips.com
&#39;Version: 2.0
&#39;All Rights Reserved by www.msaccesstips.com
&#39;------------------------------------------------------------------------
Dim ctu, ctt, bmth
Dim strNum As String, j As Integer, k As Integer, fmt As String
Dim h As Integer, xten As Integer, yten As Integer
Dim cardseg(1 To 4) As String, txt As String, d As String, txt2 As String
Dim locn As Integer, xfract As String, xhundred As String
Dim xctu As String, xctt As String, xbmth As String

On Error GoTo CardText_Err

strNum = Trim(Str(inNumber))
locn = InStr(1, strNum, &quot;.&quot;)
&#39;Check Decimal Places and rounding
If locn &amp;gt; 0 Then
  xfract = Mid(strNum, locn + 1)
 strNum = Left(strNum, locn - 1)
    If precision &amp;gt; 0 Then
        If Len(xfract) &amp;lt; precision Then
            xfract = xfract &amp;amp; String(precision - Len(xfract), &quot;0&quot;)
        ElseIf Len(xfract) &amp;gt; precision Then
            xfract = Format(Int(Val(Left(xfract, precision + 1)) / 10 + 0.5), String(precision, &quot;0&quot;))
        End If
        xfract = IIf(Val(xfract) &amp;gt; 0, xfract &amp;amp; &quot;/&quot; &amp;amp; 10 ^ precision, &quot;&quot;)
    Else
        strNum = Val(strNum) + Int(Val(&quot;.&quot; &amp;amp; xfract) + 0.5)
        xfract = &quot;&quot;
    End If
End If

h = Len(strNum)
If h &amp;gt; 12 Then
&#39;if more than 12 digits take only 12 (max. 999 Billion)
&#39;extra value will get truncated from left.
   strNum = Right(strNum, 12)
Else
   strNum = String(12 - h, &quot;0&quot;) &amp;amp; strNum
End If

GoSub initSection

txt2 = &quot;&quot;
For j = 1 To 4
    If Val(cardseg(j)) = 0 Then
       GoTo NextStep
    End If
    txt = &quot;&quot;
    For k = 3 To 1 Step -1
      Select Case k
       Case 3
            xten = Val(Mid(cardseg(j), k - 1, 1))
            If xten = 1 Then
                txt = ctu(10 + Val(Mid(cardseg(j), k, 1)))
            Else
                txt = ctt(xten) &amp;amp; ctu(Val(Mid(cardseg(j), k, 1)))
            End If
        Case 1
            yten = Val(Mid(cardseg(j), k, 1))
            xhundred = ctu(yten) &amp;amp; IIf(yten &amp;gt; 0, bmth(1), &quot;&quot;) &amp;amp; txt
            Select Case j
                Case 2
                      d = bmth(2)
                Case 3
                    d = bmth(3)
                Case 4
                    d = bmth(4)
            End Select
            txt2 = xhundred &amp;amp; d &amp;amp; txt2
    End Select
   Next
NextStep:
Next

If Len(txt2) = 0 And Len(xfract) &amp;gt; 0 Then
    txt2 = xfract &amp;amp; &quot; only. &quot;
ElseIf Len(txt2) = 0 And Len(xfract) = 0 Then
    txt2 = &quot;&quot;
Else
  txt2 = txt2 &amp;amp; IIf(Len(xfract) &amp;gt; 0, &quot; and &quot; &amp;amp; xfract, &quot;&quot;) &amp;amp; &quot; only.&quot;
End If

CardText = txt2

CardText_Exit:
Exit Function

initSection:
&#39;Units to 19
xctu = &quot;, One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Eleven, Twelve,&quot;
xctu = xctu &amp;amp; &quot; Thirteen, Fourteen, Fifteen, Sixteen, Seventeen, Eighteen, Nineteen&quot;
ctu = Split(xctu, &quot;,&quot;)

&#39;Tens
xctt = &quot;, Ten, Twenty, Thirty, Fourty, Fifty, Sixty, Seventy, Eighty, Ninety&quot;
ctt = Split(xctt, &quot;,&quot;)

xbmth = &quot;, Hundred, Thousand, Million, Billion&quot;
bmth = Split(xbmth, &quot;,&quot;)
k = 4
For j = 1 To 10 Step 3
    cardseg(k) = Mid(strNum, j, 3)
    k = k - 1
Next
Return

CardText_Err:
CardText = &quot;&quot;
MsgBox Err.Description, , &quot;CardText()&quot;
Resume CardText_Exit
End Function

&lt;/pre&gt;
&lt;p&gt;The CardText() function, first written and &lt;a href=&quot;https://www.msaccesstips.com/2009/01/cardinal-text-format-in-access.html%20%20&quot; target=&quot;_blank&quot;&gt;published in January 2009&lt;/a&gt;, accepts two parameters. The initial parameter should be either a Decimal Number or a valid expression that resolves to a Decimal Number. The second parameter determines the precision of decimal digits. Notably, the second parameter is optional and already seeded with a default value of 2. The precision setting can be modified when invoking the CardText() function to align with specific requirements.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;How to Run the Function on the Form.&lt;/h3&gt;&lt;p&gt;Upon entering a numeric value in the first TextBox, you can execute the CardText() function by pressing the Enter key or by clicking on the Show &lt;a href=&quot;https://www.msaccesstips.com/2006/09/command-button-animation.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt;. This operation converts the entered number to words and subsequently presents it in the Label Control situated below.&lt;/p&gt;&lt;p&gt;In addition to entering a straightforward numeric value, you can compose an expression for calculation and get the result. The CardText() function processes this expression, and the resulting value is transformed into words for display. A sample expression is demonstrated below:&lt;/p&gt;
&lt;pre&gt;((625*25+0.75)*0.80)
&lt;/pre&gt;
 &lt;p&gt;There are two &lt;a href=&quot;https://www.msaccesstips.com/2008/04/colorfull-command-buttons.html&quot; target=&quot;_blank&quot;&gt;Command Buttons&lt;/a&gt;. One to run the Function and the other to close the Form. The Label Control displays the entered Number in Words.&amp;nbsp; A simple interface allows you to enter the required parameters and call the function seamlessly.&lt;/p&gt;&lt;p&gt;To illustrate the straightforward application of the CardText() function, two TextBox &lt;a href=&quot;https://www.msaccesstips.com/2007/08/edit-data-in-zoom-in-control.html &quot; target=&quot;_blank&quot;&gt;Controls&lt;/a&gt; have been incorporated beneath the Close Command Button. Specifically named &quot;Calc,&quot; the first TextBox is unbound. Users can input a numeric value into this TextBox. The adjacent TextBox, on the right side, contains the expression &quot;=CardText([Calc]).&quot; This expression uses the CardText() function to convert the value entered into the &quot;Calc&quot; TextBox, presenting it in words within the same TextBox on the right side. This intuitive setup demonstrates the seamless integration of the CardText() function, which converts the number into its textual representation.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Preparing for the Streamlining VBA Code Procedure.&lt;/h3&gt;&lt;p&gt;Only one TextBox has the AfterUpdate Event. When fired, it simply calls the &lt;a href=&quot;https://www.msaccesstips.com/2008/04/transparent-command-button.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; Click Event, validates the input value in the TextBox, and runs the CardText() Function.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Given that the form boasts a straightforward interface with minimal events to manage, the streamlining allows these uncomplicated event procedures within the intermediary class module. Consequently, there is no imperative need for wrapper classes. This simplifies the structure and enhances efficiency by consolidating the handling of basic events directly within the intermediary class module, eliminating the necessity for additional layers of abstraction. This approach streamlines the code and enables a more concise and manageable implementation.&lt;/p&gt;

&lt;p&gt;We require only a single instance of the TextBox control and two instances of the CommandButton control, each with a different name, in the intermediary class module. All three object instances are declared using the `&lt;a href=&quot;https://www.msaccesstips.com/2019/05/withevents-in-class-module-and-data.html&quot; target=&quot;_blank&quot;&gt;WithEvents&lt;/a&gt;` keyword, enabling their event procedures to be implemented within the `Card_ObjInit` class.&lt;/p&gt;

&lt;p&gt;In this particular scenario, adopting object-level wrapper classes would likely result in a larger VBA codebase for event handling. Following the recommended design guidelines would require wrapper classes, especially for the CommandButton controls. In addition, a `Collection` object would be necessary to maintain the wrapper class instances in memory, ensuring that their event procedures remain active and can be executed when the corresponding events occur.&lt;/p&gt;

&lt;p&gt;However, given the simplicity of the form interface and the limited number of events, the coding approach would introduce unnecessary complexity and resource overhead. If the streamlined implementation in the intermediary class module is sufficient to manage these events, it provides a more resource-efficient solution. The choice should therefore be based on balancing adherence to established coding practices with the optimized resource usage for the specific Form requirements.&lt;/p&gt;

&lt;p&gt;Accordingly, for this implementation, we chose to manage all event handling directly within the `Card_ObjInit` class module.&lt;/p&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;The Card_ObjInit Wrapper Class.&lt;/h3&gt;&lt;p&gt;The Card_ObjInit Class, which is a Wrapper Class, is listed below.&lt;/p&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;Option Compare Database
Option Explicit

Private WithEvents txt As Access.TextBox
Private WithEvents cmdS As Access.CommandButton
Private WithEvents cmdE As Access.CommandButton
Private frm As Access.Form

Public Property Get m_Frm() As Access.Form
    Set m_Frm = frm
End Property

Public Property Set m_Frm(ByRef vfrm As Access.Form)
    Set frm = vfrm
    
    Call Class_Init

End Property

Private Sub Class_Init()
Const EP = &quot;[Event Procedure]&quot;

Set cmdS = frm.cmdResult
    cmdS.OnClick = EP
Set cmdE = frm.cmdClose
    cmdE.OnClick = EP
Set txt = frm.Amt
    txt.AfterUpdate = EP
End Sub

Private Sub cmdE_Click()
If MsgBox(&quot;Close the Form? &quot;, vbYesNo + vbQuestion, &quot;CmdClose_Click()&quot;) = vbYes Then
    DoCmd.Close acForm, frm.Name
End If
End Sub

Private Sub txt_AfterUpdate()
 Call cmdS_Click
End Sub

Private Sub cmdS_Click()
Dim tx As Variant
Dim t As Variant
Dim ctxt As String
Dim Rounding As Integer
Dim dblResult As Double
Dim msg As String
Dim fmt As String

On Error GoTo cmdResult_Click_Err
tx = frm!Amt
t = Replace(tx, &quot;,&quot;, &quot;&quot;)
tx = t
Rounding = frm!RoundTo
fmt = &quot;#,##0.&quot; &amp;amp; String(Rounding, &quot;0&quot;)
dblResult = Eval(tx)

If dblResult &amp;gt; (10 ^ 12 - 1) Then
  msg = &quot;Value: &quot; &amp;amp; dblResult &amp;amp; &quot; Exceeds permissible limit.&quot;
  MsgBox msg, , &quot;cmdResult_Click()&quot;
Else

frm!Amt = Format(dblResult, fmt)

    ctxt = CardText(dblResult, Rounding)
    frm!Result.Caption = ctxt
End If

cmdResult_Click_Exit:
Exit Sub

cmdResult_Click_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;cmdResult_Click()&quot;
Resume cmdResult_Click_Exit
End Sub
&lt;/pre&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;The Intermediary Class Module.&lt;/h3&gt;&lt;p&gt;In the global declaration area, the TextBox instance named txt and two Command Button Control instances, cmdS&amp;nbsp;and cmdE, are also declared. Each of these instances is qualified with the &#39;WithEvents&#39; keyword, empowering them to capture events triggered on the form.&lt;/p&gt;&lt;p&gt;At the onset of the Class_Init() Subroutine, the cmdS Command Button object, labeled Show, is linked to the cmdResult Command Button through the assignment. Simultaneously, the cmdE Command Button object is associated with the cmdClose Command Button. Both of these Command Button objects have their OnClick() events enabled. Additionally, the txt object is connected to the Amt TextBox, and its AfterUpdate event is activated.&lt;/p&gt;
&lt;p&gt;The cmdE Click Event Subroutine closes the Main Form.&lt;/p&gt;
&lt;p&gt;In the cmdS Click Event Procedure, the entered value is validated, and the CardText() Function is invoked to convert the number to words. The resulting output is then displayed in the &lt;a href=&quot;https://www.msaccesstips.com/2010/05/label-animation-zoom-in-style.html&quot; target=&quot;_blank&quot;&gt;Label Control&lt;/a&gt; on the Form. If the input is an expression rather than a direct number, it is first evaluated to a number before calling the CardText() Function.&lt;/p&gt;
&lt;p&gt;The AfterUpdate () Event of the Amt TextBox calls the cmdS_Click() Event Subroutine to run the validation check, and subsequently calls the CardText() Public Function.&lt;/p&gt;

&lt;h3&gt;Demo Database Download Link. &lt;/h3&gt;
&lt;!--Download Link /downloads/2023/12/CardText V2.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1jZZVbvo41fJETovI_b0H7xjcsSk0maSW/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;CardText V2.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2023/12/CardText V2.zip--&gt;
&lt;br /&gt;
&lt;h3&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/1361480648516748783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/1361480648516748783'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/1361480648516748783'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html' title='Form VBA Structured Coding Numbers to Words Converter'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS5HD4XHDVeHH3CpWg6EGAoAVMHelDrbjJV9Wsl-UjF14bDpnb15S2sPtZc4kjwq2aOZaMb3k61_-opzwaAciCQEDEq1XKPq7pP7NEODQ8cG1lT-BzRAyfE4qmJg7qX8VPG72Vqh37Kk_mVm2Jg7amoDmb0bKOVcRSuGCOmrdrZpFYbaA23EyXWUjfpkbe/s72-c/NumberToWords4.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-9019373086800110769</id><published>2023-11-22T17:51:00.006+05:30</published><updated>2026-07-11T17:36:02.617+05:30</updated><title type='text'>Streamlining Form Module VBA RGBColor Wizard</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;RGB Color Wizard.&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Create your own RGB Color Palette for Form Design.&lt;/h3&gt;&lt;p data-end=&quot;478&quot; data-start=&quot;96&quot;&gt;This special episode focuses on streamlining Form Module code. In our RGB Color Wizard, we use an ActiveX ScrollBar control. It is important to note that ActiveX controls—such as ScrollBars, Sliders, &lt;a href=&quot;https://www.msaccesstips.com/2020/09/microsoft-treeview-control-tutorial.html&quot; target=&quot;_blank&quot;&gt;TreeView&lt;/a&gt;, and &lt;a href=&quot;https://www.msaccesstips.com/2021/11/activex-listview-control-tutorial-01.html&quot; target=&quot;_blank&quot;&gt;ListView&lt;/a&gt;—cannot be instantiated within a standalone class module. As a result, all event procedures for these controls must be written directly in the Form Module.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;760&quot; data-start=&quot;480&quot;&gt;In this example, three ScrollBar controls represent the Red, Green, and Blue color values, each ranging from 0 to 255. Together, these values generate a full RGB spectrum, thus enabling the creation of up to 16.7 million distinct colors.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The RGB Color Wizard Image is given below.&lt;/h3&gt;&lt;p&gt;Let us take a look at the Color Wizard&#39;s User Interface.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE6T91r6BFz_F6P-P4savM15hK3hWMR9y5ek2pyIrAq9d6lFDtyqfDUd97h4Lkh4REsD0_sLw5pyKal-5TerI22ZQR5k_IXPL0UCBwyjv9CPi6-Nl0p4g8gGjRBq8rICJEWN8NxbyP7YAB_vQZun6Mrwdsf4Cd8LWwKGoxClckzvlGvBP18T9e4ZjZM5sA/s765/ColorWozard1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Color Wizard&quot; border=&quot;0&quot; data-original-height=&quot;765&quot; data-original-width=&quot;631&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE6T91r6BFz_F6P-P4savM15hK3hWMR9y5ek2pyIrAq9d6lFDtyqfDUd97h4Lkh4REsD0_sLw5pyKal-5TerI22ZQR5k_IXPL0UCBwyjv9CPi6-Nl0p4g8gGjRBq8rICJEWN8NxbyP7YAB_vQZun6Mrwdsf4Cd8LWwKGoxClckzvlGvBP18T9e4ZjZM5sA/s320/ColorWozard1.png&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The Wizard Controls.&lt;/h3&gt;&lt;p data-end=&quot;386&quot; data-start=&quot;78&quot;&gt;To the left of the scrollbars, three &lt;a href=&quot;https://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins.html&quot; target=&quot;_blank&quot;&gt;TextBox&lt;/a&gt; controls are positioned. As you move the scrollbar slider left or right, the corresponding color value (ranging from 0 to 255) is displayed in the adjacent TextBox. You can also manually enter numeric values into these TextBoxes to define a specific RGB color.&lt;/p&gt;&lt;p data-end=&quot;691&quot; data-start=&quot;388&quot;&gt;On the right side of the scrollbars, three Label controls display the intensity of the individual color selected Red, Green, and Blue values, visually resembling a bar graph. The RGB() function then mixes the three values to generate the final color, which is prominently shown in the large rectangle control below.&lt;/p&gt;&lt;p&gt;

&lt;/p&gt;&lt;p data-end=&quot;1029&quot; data-start=&quot;693&quot;&gt;When you’re satisfied with the generated color, click the RGB Color rectangle to select it. Next, choose one of the 25 color boxes to save the new color—this action replaces the existing color in that box with your selection. The corresponding RGB value is also displayed in the RGBColor TextBox located beneath the color box grid.&lt;/p&gt;&lt;p data-end=&quot;370&quot; data-start=&quot;88&quot;&gt;You can store and maintain up to 25 colors at a time. To apply a saved color to a control—such as a TextBox or &lt;a href=&quot;https://www.msaccesstips.com/2010/04/label-animation-style-1.html&quot; target=&quot;_blank&quot;&gt;Label&lt;/a&gt;—for properties like &lt;em data-end=&quot;239&quot; data-start=&quot;228&quot;&gt;ForeColor&lt;/em&gt;, &lt;em data-end=&quot;252&quot; data-start=&quot;241&quot;&gt;BackColor&lt;/em&gt;, or &lt;em data-end=&quot;270&quot; data-start=&quot;257&quot;&gt;BorderColor&lt;/em&gt;, simply highlight the value in the RGB Color TextBox and copy-paste it into the desired property.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;601&quot; data-start=&quot;372&quot;&gt;For convenience, you can also copy the RGB number directly to the Clipboard by clicking the Label control labeled &lt;em data-end=&quot;507&quot; data-start=&quot;486&quot;&gt;‘Copy to Clipboard’&lt;/em&gt; beneath the RGB Color TextBox. Once copied, the RGB value can be pasted wherever needed.&lt;/p&gt;&lt;p&gt;The Form Module Code with the ActiveX Control&#39;s OnChange() Event Procedures is given below.&lt;/p&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;Option Compare Database
Option Explicit

Private CWiz As CWiz_ObjInit &#39;Intermediary Class

Const GraphFactor = (1 / 255) * 1440 &#39;The Color Graph Width is 1 inch
Dim intR As Long, intG As Long, intB As Long
Dim cdb As Database, doc As Document

Private Sub Form_Load()

Set CWiz = New CWiz_ObjInit &#39;Instantiate CWiz_ObjInit Class
Set CWiz.o_Frm = Me &#39;Assign the Form object to its Property

End Sub

Private Sub form_Unload(Cancel As Integer)
    Set CWiz = Nothing
End Sub

&#39;ActiveX Control
Private Sub Ctl_B_Change() &#39;Blue Color ScrollBar Control
Set cdb = CurrentDb
Set doc = cdb.Containers(&quot;Forms&quot;).Documents(&quot;ColorPalette&quot;)

intB = Ctl_B.Value
With Me
    ![BN] = intB
    .B.Width = GraphFactor * intB
    .B.BackColor = RGB(0, 0, intB)
    .Color.BackColor = RGB(intR, intG, intB)
    .RGBColor = .Color.BackColor

&#39;Save RGBColor and BN TextBoxes contents in Form Custom Properties
doc.Properties(&quot;RGBColor&quot;).Value = .Color.BackColor
doc.Properties(&quot;BN&quot;).Value = intB

    .Controls(&quot;Color&quot;).SpecialEffect = 0
    .CheckBox.Value = False
End With
End Sub

&#39;ActiveX Control
Private Sub Ctl_G_Change()
Set cdb = CurrentDb
Set doc = cdb.Containers(&quot;Forms&quot;).Documents(&quot;ColorPalette&quot;)

intG = Me.Ctl_G.Value

With Me
    intG = .Ctl_G.Value
    ![GN] = intG
    .G.Width = GraphFactor * intG
    .G.BackColor = RGB(0, intG, 0)
    .Color.BackColor = RGB(intR, intG, intB)
    .RGBColor = Color.BackColor

doc.Properties(&quot;RGBColor&quot;).Value = .Color.BackColor
doc.Properties(&quot;GN&quot;).Value = intG

    .Controls(&quot;Color&quot;).SpecialEffect = 0
    .CheckBox.Value = False
End With

End Sub

&#39;ActiveX Control
Private Sub Ctl_R_Change()
Set cdb = CurrentDb
Set doc = cdb.Containers(&quot;Forms&quot;).Documents(&quot;ColorPalette&quot;)

intR = Me.Ctl_R.Value
With Me
    ![RN] = intR
    .R.Width = GraphFactor * intR
    .R.BackColor = RGB(intR, 0, 0)
    .Color.BackColor = RGB(intR, intG, intB)
    .RGBColor = Color.BackColor

doc.Properties(&quot;RGBColor&quot;).Value = .Color.BackColor
doc.Properties(&quot;RN&quot;).Value = intR

    .Controls(&quot;Color&quot;).SpecialEffect = 0
    .CheckBox.Value = False
End With
End Sub

&lt;/pre&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The ScrollBar Controls.&lt;/h3&gt;&lt;p&gt;The three ScrollBars, named Ctl_R, Ctl_G, and Ctl_B, correspond to the Red, Green, and Blue colors. When the slider control on each is moved to adjust the color numbers within the range of 0 to 255, the Change Event is triggered. This event records these actions and updates other related controls, such as the &lt;a href=&quot;https://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins.html&quot; target=&quot;_blank&quot;&gt;TextBox&lt;/a&gt; content on the left side. Additionally, it increases the width of the label controls and dynamically shows the color variations based on the selected color range.&lt;/p&gt;&lt;p&gt;Additionally, the Change event dynamically updates both the RGB color shown in the large rectangular Label control and the corresponding RGB color value displayed in the TextBox beneath the Colors Grid.&lt;/p&gt;&lt;p&gt;Since we cannot create an instance of the ScrollBar ActiveX Control in the standalone Class Module, we are persuaded to write the Change Event Subroutines in the Form&#39;s Class Module.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The ColorWizard and Run-Time Data.&lt;/h3&gt;&lt;p&gt;Typically, changes to a control’s ForeColor, BackColor, or BorderColor are made in the Form’s Design View. After updating these property values and saving the Form, the modifications are preserved. The next time the Form is opened, it will display the updated colors applied during design.&lt;/p&gt;&lt;p&gt;With the RGB Color Wizard, however, we modify control properties directly in Form View. Changes made in this mode are temporary—they are not automatically saved and will be lost once the form is closed. A practical solution is to store these settings in a table, so they can be reloaded and applied the next time the form is opened.&lt;/p&gt;&lt;p&gt;Contrary to the conventional approach of using tables for everything, we&#39;re opting for a different method. In this case, we&#39;ll save the entire data within the form itself. While not a novel concept, this method is rarely employed due to its complexity. Specifically, we&#39;ll store the data in the form&#39;s custom-made properties, akin to the Tag property of a form or control. Creating these properties with VBA is possible, although the procedure is somewhat uncommon.&lt;/p&gt;&lt;p&gt;&amp;nbsp;You can see how these Custom Properties are addressed for storing/retrieving data to/from them. For an introduction to this method, visit this Link: &lt;a href=&quot;https://www.msaccesstips.com/2007/08/saving-data-on-forms-not-in-table.html&quot; target=&quot;_blank&quot;&gt;Saving Data on Forms, Not in a Table&lt;/a&gt;&amp;nbsp;to see a simple, practical usage.&amp;nbsp;&lt;/p&gt;&lt;p&gt;To preserve data from the ColorGrid, &lt;a href=&quot;https://www.msaccesstips.com/2019/10/date2text-and-text2date-functions.html&quot; target=&quot;_blank&quot;&gt;Text&lt;/a&gt; Boxes, and other controls during changes or when closing, we implemented custom properties to store this information.&lt;/p&gt;&lt;p&gt;Saving of values to all custom properties occurs when the form is closed. Upon reopening the form, these values are read from the custom properties and displayed on the corresponding controls. These two event procedures are implemented in the CWiz_ObjInit Class Module.&lt;/p&gt;&lt;p&gt;Regarding the ScrollBar Change Event Subroutine, pay attention to the subsequent lines responsible for updating custom properties and the method employed to address and store values into them:&lt;/p&gt;
&lt;pre&gt;Set cdb = CurrentDb
Set doc = cdb.Containers(&quot;Forms&quot;).Documents(&quot;ColorPalette&quot;)
.
.
.
doc.Properties(&quot;RGBColor&quot;).Value = .Color.BackColor
doc.Properties(&quot;BN&quot;).Value = intB
.
&lt;/pre&gt;
&lt;p&gt;Before saving the values into the Custom Properties, we must create the Properties on the Form.&amp;nbsp; This is a one-time exercise.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Sample Custom Property Management VBA Code.&lt;/h3&gt;&lt;p&gt;Let us see an example of creating a Custom Property to save an Employee&#39;s Name in &lt;b&gt;Form1&lt;/b&gt;. Sample VBA Code is given below:&lt;/p&gt;
&lt;pre&gt;&#39;Create a Custom Property in Form1
Private Sub CreateProperty()
Dim db As Database
Dim doc As Document
Dim prp As Property

Set db = CurrentDb
Set doc = db.Containers(&quot;Forms&quot;).Documents(&quot;Form1&quot;)

Set prp = doc.CreateProperty(&quot;EmpName&quot;, dbText, &quot;SampleText&quot;)

doc.Properties.Append prp

Set prp = Nothing
Set doc = Nothing
Set db = Nothing

End Sub

&#39;Assign a value to Custom Property in Form1
Private Sub AssignPropertyValue()

Dim db As Database
Dim doc As Document

Set db = CurrentDb
Set doc = db.Containers(&quot;Forms&quot;).Documents(&quot;Form1&quot;)
    doc.Properties(&quot;EmpName&quot;).Value = &quot;Michael Colins&quot;

Set doc = Nothing
Set db = Nothing

End Sub

&#39;Read value from Custom Property in Form1
Private Sub ReadPropertyValue()

Dim db As Database
Dim doc As Document
Dim strName As String

Set db = CurrentDb
Set doc = db.Containers(&quot;Forms&quot;).Documents(&quot;Form1&quot;)
  strName = doc.Properties(&quot;EmpName&quot;).Value
  MsgBox &quot;Name: &quot; &amp;amp; UCase(strName)

Set doc = Nothing
Set db = Nothing

End Sub

&#39;Create a Custom Property in Form1
Private Sub DeleteProperty()

Dim db As Database
Dim doc As Document

Set db = CurrentDb
Set doc = db.Containers(&quot;Forms&quot;).Documents(&quot;Form1&quot;)
    doc.Properties.Delete &quot;EmpName&quot;
    
Set doc = Nothing
Set db = Nothing
End Sub
&lt;/pre&gt;
&lt;p&gt;All the procedures for creating a custom property to save an employee&#39;s name, assigning a name to the property, reading it back, displaying it in a message box, and deleting the custom property from &lt;b&gt;Form1&lt;/b&gt; are outlined in the individual subroutines above.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The CWiz_TextBox Wrapper Class.&lt;/h3&gt;&lt;p&gt;The &lt;b&gt;CWiz_TextBox&lt;/b&gt; Wrapper Class manages the AfterUpdate() Event, allowing for direct entry of color numbers for Red, Green, and Blue into the TextBoxes named RN, GN, and BN. The subsequent changes are seamlessly reflected in the Scrollbars, the color graphs situated to the right of the Scrollbars, the new color showcased in the large rectangle label background, and the RGB color number displayed in the Textbox.&lt;/p&gt;&lt;p&gt;You may save your new Color in the Color Grid as explained earlier.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The CWiz_TextBox Wrapper Class Module Code is given below:&lt;/p&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;Option Compare Database
Option Explicit

Private WithEvents ctxt As Access.TextBox
Private cFrm As Form

Const GraphFactor = (1 / 255) * 1440
Private db As Database
Private doc As Document

Public Property Get c_Frm() As Form
    Set c_Frm = cFrm
End Property

Public Property Set c_Frm(ByRef vcFrm As Form)
    Set cFrm = vcFrm
End Property

Public Property Get c_txt() As Access.TextBox
    Set c_txt = ctxt
End Property

Public Property Set c_txt(ByRef vctxt As Access.TextBox)
    Set ctxt = vctxt
    
    Set db = CurrentDb
    Set doc = db.Containers(&quot;Forms&quot;).Documents(&quot;ColorPalette&quot;)
End Property

Private Sub ctxt_AfterUpdate()
 With cFrm
    Select Case ctxt.Name
        Case &quot;RN&quot;
            .Ctl_R.Value = cFrm![RN]
            doc.Properties(&quot;RN&quot;).Value = cFrm!RN
            .CheckBox.Value = False
        Case &quot;GN&quot;
            .Ctl_G.Value = cFrm![GN]
            doc.Properties(&quot;GN&quot;).Value = cFrm!GN
            .CheckBox.Value = False
        Case &quot;BN&quot;
            .Ctl_B.Value = cFrm![BN]
            doc.Properties(&quot;BN&quot;).Value = cFrm!BN
            .CheckBox.Value = False
    End Select
  End With
End Sub
&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The CWiz_Label Wrapper Class.&lt;/h3&gt;&lt;p&gt;The Labels in the ColorGrid, the color &lt;a href=&quot;https://www.msaccesstips.com/2007/09/ms-access-and-graph-charts2.html&quot; target=&quot;_blank&quot;&gt;graph&lt;/a&gt; Labels beside the ScrollBars, and the RGB color display Label are all managed through their Click event subroutines within the &lt;em data-end=&quot;262&quot; data-start=&quot;250&quot;&gt;CWiz_Label&lt;/em&gt; Wrapper Class.&lt;/p&gt;&lt;p&gt;The CWiz_Label Wrapper Class Module Event Procedure Code is given below:&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents clbl As Access.Label
Private sFrm As Form

Const GraphFactor = (1 / 255) * 1440
Private db As Database
Private doc As Document

Private selflag As Boolean
Private lngColor As Long

Public Property Get s_Frm() As Form
    Set s_Frm = sFrm
End Property

Public Property Set s_Frm(ByRef vsFrm As Form)
    Set sFrm = vsFrm
End Property

Public Property Get s_clbl() As Access.Label
    Set s_clbl = clbl
End Property

Public Property Set s_clbl(ByRef vclbl As Access.Label)
    Set clbl = vclbl
    
    Set db = CurrentDb
    Set doc = db.Containers(&quot;Forms&quot;).Documents(&quot;ColorPalette&quot;)
End Property

Private Sub clbl_Click()
Dim I As Integer
If Val(Mid(clbl.Name, 5)) &amp;gt; 0 Then
    I = Val(Mid(clbl.Name, 5))
End If
Select Case I
    Case 1 To 25
        Call Boxes(I) &#39;Click on Color Grid
End Select

Select Case clbl.Name
    Case &quot;Color&quot;
        Call ColorClick &#39;Click on the RGB Color Display Label
    Case &quot;Clip&quot;
       Call ClipClick   &#39;Click on this Labek to Copy RGB Color number to ClipBoard
End Select
End Sub

Private Sub ColorClick()
With sFrm
    lngColor = .Color.BackColor
    !RGBColor = .Controls(&quot;Color&quot;).BackColor
    .Controls(&quot;Color&quot;).SpecialEffect = 2
    
    &#39;Copy the created color to the grid
    !CheckBox.Value = True
End With
End Sub

Private Sub ClipClick()
    If Not IsNull(sFrm![RGBColor]) Then
        &#39; Copy the TextBox contents to the clipboard
        sFrm.RGBColor.SetFocus
        DoCmd.RunCommand acCmdCopy
        MsgBox &quot;RGB Color Number Copied to Clipboard!&quot;, vbInformation
    Else
        &#39; Display a message if the TextBox is empty
        MsgBox &quot;RGBColor is empty!&quot;, vbExclamation
    End If

End Sub

Private Sub Boxes(ByVal bx As Integer)
Dim j As Integer
Dim ctl As String
Dim Colr As Long
Dim intR As Integer
Dim intG As Integer
Dim intB As Integer

selflag = sFrm!CheckBox.Value

For j = 1 To 25
If j = bx Then
   If selflag Then
    With sFrm
      ctl = &quot;lblC&quot; &amp;amp; j
        .Controls(ctl).SpecialEffect = 2
        .Controls(ctl).BackColor = .Color.BackColor
        doc.Properties(&quot;Selected&quot;).Value = .Controls(ctl).BackColor
        !RGBColor = .Controls(ctl).BackColor
        !CheckBox.Value = False
      ctl = &quot;C&quot; &amp;amp; j
      doc.Properties(ctl).Value = .Color.BackColor
      doc.Properties(&quot;Selctl&quot;).Value = &quot;C&quot; &amp;amp; j
    End With
   Else
    With sFrm
         ctl = &quot;lblC&quot; &amp;amp; j
            !RGBColor = .Controls(ctl).BackColor
            .Controls(ctl).SpecialEffect = 2
         doc.Properties(&quot;Selected&quot;).Value = .Controls(ctl).BackColor
         doc.Properties(&quot;Selctl&quot;).Value = &quot;C&quot; &amp;amp; j
   End With
   
 Colr = sFrm!RGBColor
 &#39;Split into R,G,B
 intR = Colr Mod 256
 intG = Colr \ 256 Mod 256
 intB = Colr \ 256 \ 256 Mod 256
 
 With sFrm
    !RN = intR
    .Ctl_R.Value = sFrm!RN
    !GN = intG
    .Ctl_G.Value = sFrm!GN
    !BN = intB
    .Ctl_B.Value = sFrm!BN
 
    .R.Width = GraphFactor * intR
    .G.Width = GraphFactor * intG
    .B.Width = GraphFactor * intB

    .R.BackColor = RGB(intR, 0, 0)
    .G.BackColor = RGB(0, intG, 0)
    .B.BackColor = RGB(0, 0, intB)

    .Color.BackColor = RGB(intR, intG, intB)
  End With
  With doc
    .Properties(&quot;RGBColor&quot;).Value = sFrm.Color.BackColor
    .Properties(&quot;RN&quot;).Value = intR
    .Properties(&quot;GN&quot;).Value = intG
    .Properties(&quot;BN&quot;).Value = intB
  End With
  End If
   
Else
   ctl = &quot;lblC&quot; &amp;amp; j
   sFrm.Controls(ctl).SpecialEffect = 0
End If

Next

End Sub
&lt;/pre&gt;
&lt;p&gt;The Intermediary Class Module &lt;b&gt;CWiz_ObjInit&lt;/b&gt; VBA Code is given below:&lt;/p&gt;

&lt;pre&gt;Option Compare Database
Option Explicit

Private cw As CWiz_Label
Private txt As CWiz_TextBox
Private WithEvents cmd As CommandButton

Private WithEvents frm As Form
Private coll As New Collection

Const GraphFactor = (1 / 255) * 1440
Const MaxColor = 25
Private cdb As Database, ctr As Container, doc As Document


Public Property Get o_Frm() As Form
    Set o_Frm = frm
End Property

Public Property Set o_Frm(ByRef voFrm As Form)
    Set frm = voFrm
    
    Call Class_Init
End Property

Private Sub Class_Init()
Dim ctl As Control
Const EP = &quot;[Event Procedure]&quot;
Dim I As Integer

Call ColorPalette_Init &#39;Initialize

Set cmd = frm.cmdClose
    cmd.OnClick = EP
     
For Each ctl In frm.Controls

 I = Val(Mid(ctl.Name, 5))
 
  Select Case TypeName(ctl)
    Case &quot;Label&quot;
      Select Case I
          Case 1 To 25
            Set cw = New CWiz_Label
            Set cw.s_Frm = frm
            Set cw.s_clbl = ctl
                cw.s_clbl.OnClick = EP
            coll.Add cw
            Set cw = Nothing
      End Select
      Select Case ctl.Name
        Case &quot;Color&quot;
            Set cw = New CWiz_Label
            Set cw.s_Frm = frm
            Set cw.s_clbl = ctl
                cw.s_clbl.OnClick = EP
                
            coll.Add cw
            Set cw = Nothing
        Case &quot;Clip&quot;
            Set cw = New CWiz_Label
            Set cw.s_Frm = frm
            Set cw.s_clbl = ctl
                cw.s_clbl.OnClick = EP
            coll.Add cw
            Set cw = Nothing
        End Select
     
      Case &quot;TextBox&quot;
        Select Case ctl.Name
            Case &quot;RN&quot;, &quot;GN&quot;, &quot;BN&quot;
              Set txt = New CWiz_TextBox
              Set txt.c_Frm = frm
              Set txt.c_txt = ctl
                txt.c_txt.AfterUpdate = EP
                coll.Add txt
              Set txt = Nothing
            Case &quot;RGBColor&quot;
              Set txt = New CWiz_TextBox
              Set txt.c_Frm = frm
              Set txt.c_txt = ctl
                txt.c_txt.OnGotFocus = EP
                coll.Add txt
              Set txt = Nothing
        End Select
    End Select
Next
End Sub

Private Sub ColorPalette_Init()
Dim xRN As Integer
Dim xGN As Integer
Dim xBN As Integer
Dim xRGBColor As Long
Dim j As Integer
Dim cdb As Database
Dim ctr As Container
Dim doc As Document
Dim strctl As String

Set cdb = CurrentDb
Set ctr = cdb.Containers(&quot;Forms&quot;)
Set doc = ctr.Documents(&quot;ColorPalette&quot;)

xRN = doc.Properties(&quot;RN&quot;).Value
xGN = doc.Properties(&quot;GN&quot;).Value
xBN = doc.Properties(&quot;BN&quot;).Value
xRGBColor = doc.Properties(&quot;RGBColor&quot;).Value

With frm 
    ![RN] = xRN
    ![GN] = xGN
    ![BN] = xBN
    .R.Width = xRN * GraphFactor
    .R.BackColor = RGB(xRN, 0, 0)
    
    .G.Width = xGN * GraphFactor
    .G.BackColor = RGB(0, xGN, 0)
    
    .B.Width = xBN * GraphFactor
    .B.BackColor = RGB(0, 0, xBN)
    
.Ctl_R.Value = xRN
.Ctl_G.Value = xGN
.Ctl_B.Value = xBN

.Color.BackColor = RGB(xRN, xGN, xBN)
.RGBColor = .Color.BackColor
End With

For j = 1 To MaxColor
   strctl = &quot;lblC&quot; &amp;amp; j
   frm.Controls(strctl).BackColor = doc.Properties(&quot;C&quot; &amp;amp; j).Value
   If (&quot;C&quot; &amp;amp; j) = doc.Properties(&quot;Selctl&quot;).Value Then
      frm.Controls(strctl).SpecialEffect = 2
   End If

Next j

Form_Load_Exit:
Exit Sub

Form_Load_Err:
MsgBox Err.Description, , &quot;Form_Load&quot;
Resume Form_Load_Exit

End Sub

Private Sub cmd_Click()
Dim msg As String
Dim ctl As String, strC1 As String, j As Integer

msg = &quot;Close the Color Wizard?&quot;
If MsgBox(msg, vbYesNo + vbQuestion, &quot;cmd_Click()&quot;) = vbYes Then

    Set cdb = CurrentDb
    Set ctr = cdb.Containers(&quot;Forms&quot;)
    Set doc = ctr.Documents(&quot;ColorPalette&quot;)

For j = 1 To MaxColor
  ctl = &quot;lblC&quot; &amp;amp; j
  strC1 = &quot;C&quot; &amp;amp; j
    doc.Properties(strC1).Value = frm.Controls(ctl).BackColor
  If frm.Controls(ctl).SpecialEffect = 2 Then
      doc.Properties(&quot;Selected&quot;).Value = frm.Controls(ctl).BackColor
      doc.Properties(&quot;SelCtl&quot;).Value = strC1
  End If
Next
    doc.Properties(&quot;RGBColor&quot;).Value = Nz(frm.Controls(&quot;RGBColor&quot;).Value, 0)
    DoCmd.Close acForm, frm.Name
End If
End Sub

Private Sub Class_Terminate()
Do While coll.Count &amp;gt; 1
    coll.Remove 1
Loop
End Sub

&lt;/pre&gt;
&lt;p&gt;When the form is opened, the form object is passed to the intermediary class module, initiating the execution of the Class_Init subroutine. The first subroutine, ColorPalette_Init, is invoked from within the Class_Init subroutine. This procedure retrieves all values from the form&#39;s custom properties and assigns them to the labels, scroll bars, and text boxes.&lt;/p&gt;&lt;p&gt;This procedure is normally run in the Form_Load() Event Procedure, and the current Values on the Form Controls are saved when the &lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_blank&quot;&gt;Form&lt;/a&gt; is closed.&lt;/p&gt;&lt;p&gt;There is a single command button to close the form. A single command button object is created in the Intermediary Class Module, and its Click Event is enabled. Consequently, when the cmdClose command button is clicked, the form close event procedure is executed in the CWiz_ObjInit Module. Before closing the form, all the values of the Color Wizard form controls are saved in the form&#39;s custom properties.&lt;/p&gt;&lt;p&gt;This topic was originally &lt;a href=&quot;https://www.msaccesstips.com/2010/10/create-your-own-color-palette.html&quot; target=&quot;_blank&quot;&gt;published in October 2010&lt;/a&gt;. The initial version featured a 15-color palette, with all wizard VBA code implemented in the form module. That original wizard form is included in the demo database named&amp;nbsp;ColorPaletteOld&lt;b&gt;.&lt;/b&gt; You are encouraged to open and review its code to see how it has been refactored into a form that can now be executed from a standalone class module VBA code associated with the ActiveX ScrollBar control.&lt;/p&gt;


&lt;h3&gt;Demo Database Download Link. &lt;/h3&gt;
&lt;!--Download Link /downloads/2023/11/RGB_Colors.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1luKsL4QIUbhl9u7bhQmT5PewNMr5L6J9/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;RGB_Colors.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2023/11/RGB_Colors.zip--&gt;

&lt;h3&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/9019373086800110769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/9019373086800110769'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/9019373086800110769'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html' title='Streamlining Form Module VBA RGBColor Wizard'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE6T91r6BFz_F6P-P4savM15hK3hWMR9y5ek2pyIrAq9d6lFDtyqfDUd97h4Lkh4REsD0_sLw5pyKal-5TerI22ZQR5k_IXPL0UCBwyjv9CPi6-Nl0p4g8gGjRBq8rICJEWN8NxbyP7YAB_vQZun6Mrwdsf4Cd8LWwKGoxClckzvlGvBP18T9e4ZjZM5sA/s72-c/ColorWozard1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-4164212098819535133</id><published>2023-11-11T11:17:00.012+05:30</published><updated>2026-07-11T17:25:43.004+05:30</updated><title type='text'>Streamlining Event Procedures 3D-Text Wizard</title><content type='html'>&lt;!--Episode 18--&gt;
&lt;p&gt;The 3D Text Wizard was first introduced in a series of articles published in September 2006. I originally created this website to share practical tips and techniques, many of which I had applied in real-world projects while working for an automotive company in the Sultanate of Oman. At that time, the wizard demonstrated the QBColor version, providing a simple way to explore color effects.&lt;/p&gt;

&lt;p&gt;The updated 3D Text Wizard now supports the full RGB color spectrum, making color selection significantly more flexible. To further enhance customization, a dedicated &lt;b&gt;&lt;a href=&quot;https://www.msaccesstips.com/2010/10/colors-24-bits-and-binary-conversion.html&quot; target=&quot;_blank&quot;&gt;ColorList&lt;/a&gt;&lt;/b&gt; table has been added, allowing users to extend the available palette with their own preferred colors.&lt;/p&gt;

&lt;p&gt;This feature is particularly useful for creating three-dimensional text effects for form headings or for displaying field values, such as employee names or product names. These enhancements make the displayed text more visually appealing and easier to distinguish, especially when viewed from a distance.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;Example-1: &lt;span style=&quot;font-weight: normal;&quot;&gt;Employee Name.&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTS-L5TR7N2qcVDKPKs5MiJXhFis-KsAV0yyDF3SNoou6EtvEAepF6ygNA_uffHVHj6PyHgp_aUOywekgj7c5H58DZ-IYDnVL9wD-LrLeMzf-5lOJzQDPjjt0Xy9eRLfMuFHOMEd34YKAA-TwILnG2IT69YnaSnOL2ahDjav2XQhywne81wpRsCEP8x0aM/s840/Anne%20Hellung.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;575&quot; data-original-width=&quot;840&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTS-L5TR7N2qcVDKPKs5MiJXhFis-KsAV0yyDF3SNoou6EtvEAepF6ygNA_uffHVHj6PyHgp_aUOywekgj7c5H58DZ-IYDnVL9wD-LrLeMzf-5lOJzQDPjjt0Xy9eRLfMuFHOMEd34YKAA-TwILnG2IT69YnaSnOL2ahDjav2XQhywne81wpRsCEP8x0aM/s320/Anne%20Hellung.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open the Large Image in a New Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;Example-2:&lt;span style=&quot;font-weight: normal;&quot;&gt;Order Details Form View-2&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjGAfPGMu18gtb3PCoWGniCGGxUG84HYnm0L_9vXI9V1ZKCC2RmhzqQi3vHWA3dCenQlK3sErV-jzZFmz8cH-xY6ETMxUadar4LWK_Nax6qogSDI0fYvxqa6-NxPnrFWkcmbfTWZxeJI5CY0EkEwCO6bKPykrlzAtm3uo210lUIEKJzF67PwhQfTypKcwz/s823/Cajun%20Seasoning.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;611&quot; data-original-width=&quot;823&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjGAfPGMu18gtb3PCoWGniCGGxUG84HYnm0L_9vXI9V1ZKCC2RmhzqQi3vHWA3dCenQlK3sErV-jzZFmz8cH-xY6ETMxUadar4LWK_Nax6qogSDI0fYvxqa6-NxPnrFWkcmbfTWZxeJI5CY0EkEwCO6bKPykrlzAtm3uo210lUIEKJzF67PwhQfTypKcwz/s320/Cajun%20Seasoning.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open the Large Image in a New Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h3&gt;The 3D Text Wizard Image is given below:&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXzsh40T14X7zKqOWCurFkn5SI3YeIMqwbA1QXYQRodoK-ItsnQdEwmIMJZxRtZQ-zvr7nyvPYcKIn3nP7vP1f-Fe5bYLFoy9S454LwaUecmZd9ncOyRBD2koVJoJeISm229LxEAxWnKj1Oxz4bHvTx2-yByVUjJcR2M-ZbTFeKJDp5M489WWVtc7O58uN/s786/3DTextWizard.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;700&quot; data-original-width=&quot;786&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXzsh40T14X7zKqOWCurFkn5SI3YeIMqwbA1QXYQRodoK-ItsnQdEwmIMJZxRtZQ-zvr7nyvPYcKIn3nP7vP1f-Fe5bYLFoy9S454LwaUecmZd9ncOyRBD2koVJoJeISm229LxEAxWnKj1Oxz4bHvTx2-yByVUjJcR2M-ZbTFeKJDp5M489WWVtc7O58uN/s320/3DTextWizard.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open the Large Image in a New Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The event procedures and functions in the 3D Text Wizard have been streamlined in line with the new Event Procedure Coding Rules implemented in the standalone class module. This structured approach improves code organization and readability while making maintenance and future development more efficient.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3D Text Creation Technique.&lt;/h3&gt;&lt;p&gt;The 3D text effect is created by layering multiple Label controls or &lt;a href=&quot;https://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins.html&quot; target=&quot;_blank&quot;&gt;Text Boxes&lt;/a&gt;, each displaying the same text. Alternatively, the effect can be produced manually by placing a label or text box with an attractive foreground color on top and positioning additional layers with a darker foreground color behind it, slightly offset toward one of the four corners—top-left, top-right, bottom-left, or bottom-right. This technique creates a shadow effect that enhances the visual appearance of the text.&lt;/p&gt;

&lt;p&gt;Manually creating this effect each time can be both tedious and inefficient. As demonstrated in earlier articles, I created form headings using only two labels to achieve a simple yet effective 3D appearance.&lt;/p&gt;

&lt;p&gt;On the left side of the Text Wizard interface is a ListBox that displays a collection of colors. This &lt;a href=&quot;https://www.msaccesstips.com/2008/05/create-list-from-another-listbox.html&quot; target=&quot;_blank&quot;&gt;ListBox&lt;/a&gt; is bound to a table named Colors, allowing you to add additional color codes whenever required.&lt;/p&gt;

&lt;p&gt;To the right of the Colors List are two Option Group controls. The upper Option Group contains two choices. When the first option button is selected, the color chosen from the ListBox is displayed in the upper rectangle control and is applied to the caption of the topmost Label or to the font color of the Text Box used to create the 3D text.&lt;/p&gt;

&lt;p&gt;When the second option button is selected, the color chosen from the ListBox is applied as the border color in the first two Text Wizards—Border 2D and Border 3D.&amp;nbsp;All other Text Style Wizard options use only the ForeColor property.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The 3D Text Shadow Positions.&lt;/h3&gt;&lt;p&gt;At the top right, there is a &lt;a href=&quot;https://www.msaccesstips.com/2009/09/dynamic-listbox-combobox-contents.html&quot; target=&quot;_blank&quot;&gt;ComboBox&lt;/a&gt; with four options (0-3) to specify the light and shadow positions for the 3D Text.&lt;/p&gt;&lt;p&gt;Shadow Positions:&lt;/p&gt;&lt;p&gt;0 - Left Top Corner.&lt;/p&gt;&lt;p&gt;1 - Left Bottom Corner.&lt;/p&gt;&lt;p&gt;2 - Right Top Corner&lt;/p&gt;&lt;p&gt;3 - Right Bottom Corner&amp;nbsp;&lt;/p&gt;&lt;p&gt;The first text style, 2D, creates a white border around the text and requires no additional configuration. For both the 2D and 3D text styles, the wizard generates the effect by creating five or seven labels with the same text but with different ForeColor values. These labels are positioned beneath the top label and slightly offset to produce the desired visual effect.&lt;/p&gt;

&lt;p&gt;For the 2D border style, the underlying labels are positioned toward the four corners of the top label, creating the appearance of a border surrounding the text.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;3D Text Control Types.&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://www.msaccesstips.com/2013/12/updating-combobox-when-not-in-list-is.html&quot; target=&quot;_blank&quot;&gt;ComboBox&lt;/a&gt; positioned below the Shadow Style ComboBox offers two options and utilizes two types of controls to generate the 3D Text.&lt;/p&gt;&lt;p&gt;1 - Label&amp;nbsp;&lt;/p&gt;&lt;p&gt;2 - TextBox&lt;/p&gt;&lt;p&gt;The first option is good for creating Static Headings on Forms or Reports.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizE4iGlkXz-CRn3cZPIvgj-Php4RZHeKtgZ4pLPkv_GZUV0ecrxfhDIb6hufWuHJGgQr9VFIltr9CVCc0zw2KygIvb6K5qgx6vICrqS7dSJbwGCNqkW7HcftYVAYhlvnLz_qOiSJQEakov/s1600/report_title.jpg&quot; style=&quot;clear: left; float: center; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;285&quot; data-original-width=&quot;683&quot; height=&quot;134&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizE4iGlkXz-CRn3cZPIvgj-Php4RZHeKtgZ4pLPkv_GZUV0ecrxfhDIb6hufWuHJGgQr9VFIltr9CVCc0zw2KygIvb6K5qgx6vICrqS7dSJbwGCNqkW7HcftYVAYhlvnLz_qOiSJQEakov/s320/report_title.jpg&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open the Large Image in a New Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The second option creates 3D text using Text Box controls. This style is particularly useful for displaying data from form or report fields by using expressions, as illustrated in the examples shown at the top of this page.&lt;/p&gt;

&lt;p&gt;After selecting the desired options, click the Create 3D Text command button to generate the 3D text. The generated text is displayed in the Detail section of a new form. Beneath it, an instructional label provides guidance on modifying the text, font, font size, and font styles, such as Bold, Italic, and &lt;u&gt;Underline&lt;/u&gt;, if required. To edit the generated text, carefully select the top Label or Text Box without changing its position, and then modify the label caption or the Text Box contents as needed.&lt;/p&gt;

&lt;p&gt;After completing the modifications, select all the Label or Text Box controls by dragging a selection rectangle around them. Then copy and paste the entire group to the desired location.&lt;/p&gt;

&lt;p&gt;To display data from form fields in the Text Box controls, assign an expression—such as `=[First Name] &amp;amp; &quot; &quot; &amp;amp; [Last Name]`—to the Control Source property after selecting all the Text Box controls that make up the 3D text.&lt;/p&gt;

&lt;p&gt;After generating a text style, you can save it within the 3D Text Wizard for future use. It can then be imported into other projects and modified as required.&lt;/p&gt;&lt;p&gt;With the event procedures consolidated in a standalone intermediary class module, only a single wrapper class is required to handle all the Command Button controls on the form.&lt;/p&gt;

&lt;p&gt;The form contains only one ListBox control, and its Click event is handled by a procedure in the intermediary class module.&lt;/p&gt;

&lt;p&gt;Similarly, the form contains two Option Group controls. One is used to select the 3D text style, while the other manages the ForeColor and BackColor parameter selection. The BackColor option applies only to the first two text styles—2D and 3D Border. When either of these styles is selected, the BackColor option is enabled; otherwise, it remains disabled.&lt;/p&gt;

&lt;p&gt;Because these actions are controlled through the Text Style Option Group, a separate wrapper class for the Option Group controls is unnecessary. The ListBox and Option Group controls are declared as object instances in the intermediary class module using the WithEvents keyword, allowing their events to be handled directly within that class.&lt;/p&gt;

&lt;p&gt;The form also contains two ComboBox controls. One is used to select the required 3D text shadow option, while the other is used to choose whether the output should be created as a Label or a Text Box. These ComboBox controls do not require any event procedures.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Form Module VBA Code.&lt;/h3&gt;&lt;p&gt;Both the ListBox and the Option Group Control&#39;s Click Events are enabled in the Class_Init() subroutine, and corresponding subroutines are written in this module. First, the Form Module Code is listed below:&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private W As TWiz_Obj_Init

Private Sub Form_Load()
Set W = New TWiz_Obj_Init
Set W.w_frm = Me

End Sub

Private Sub Form_Unload(Cancel As Integer)
Set W = Nothing
End Sub

&lt;/pre&gt;
&lt;p&gt;The TWiz_Obj_Init class is declared in the Module&#39;s global area with the object name &#39;W.&#39; In the Form_Load() event procedure, the object is instantiated, and the current form object (Me) is passed to the W.w_frm()&amp;nbsp;Property Procedure. When the form is closed, the class object &#39;W&#39; is released from memory.&lt;/p&gt;
&lt;h3&gt;The TWiz_Obj_Init Class Module Code is Listed Below.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private wcmd As TWiz_CmdButton

Private WithEvents lst As Access.ListBox
Private WithEvents opt As Access.OptionGroup

Private wfrm As Access.Form
Private Coll As New Collection

Public Property Get w_frm() As Form
  Set w_frm = wfrm
End Property

Public Property Set w_frm(ByRef vfrm As Form)
Set wfrm = vfrm
DoCmd.Restore
 
Call Class_Init
End Property

Private Sub Class_Init()
Dim ctl As Control
Const EP = &quot;[Event Procedure]&quot;

Set opt = wfrm.TxtStyle &#39;3D Text Styles
    opt.OnClick = EP

Set lst = wfrm.ColorList &#39;List of Colors
    lst.OnClick = EP

For Each ctl In wfrm.Controls
    Select Case TypeName(ctl)
        Case &quot;CommandButton&quot;
          Select Case ctl.Name
            Case &quot;cmd3D&quot;, &quot;cmdClose&quot;
              Set wcmd = New TWiz_CmdButton
              Set wcmd.c_Frm = wfrm
            Set wcmd.c_cmd = ctl
                wcmd.c_cmd.OnClick = EP
                Coll.Add wcmd
            Set wcmd = Nothing
          End Select
    End Select
Next
End Sub

Private Sub lst_Click()
Dim cl As Long
cl = lst.Value
Select Case lst.Name
    Case &quot;ColorList&quot;
    If wfrm.FBack = 1 Then
        wfrm.Fore.BackColor = cl
        wfrm.CFore = cl
    Else
        wfrm.Back.BackColor = cl
        wfrm.CBack = cl
    End If

End Select
End Sub

Private Sub opt_Click()
Dim opval As Integer

Select Case opt.Name
    Case &quot;TxtStyle&quot;
        opval = opt.Value
        With wfrm.cboStyle
            If opval &amp;gt; 1 Then
                .Enabled = True
            Else
                .Enabled = False
            End If
        End With
        With wfrm.Opt2
            Select Case opval
                Case 1, 2
                    .Enabled = True
                Case Else
                    .Enabled = False
            End Select
        End With
End Select
End Sub

Private Sub Class_Terminate()
Do While Coll.Count &amp;gt; 0
    Coll.Remove 1
Loop
End Sub
&lt;/pre&gt;

&lt;p&gt;The following ListBox and OptionGroup Control declarations are placed in the Global area of the Class Module.&lt;/p&gt;
&lt;pre&gt; 
Private WithEvents lst As Access.ListBox
Private WithEvents opt As Access.OptionGroup
&lt;/pre&gt;
&lt;p&gt;The following statements in the Class_Init() Subroutine assign the &lt;a href=&quot;https://www.msaccesstips.com/2013/08/external-references-in-conditional.html&quot; target=&quot;_blank&quot;&gt;References&lt;/a&gt; from these Objects in the Form and enable their Click Events by assigning the &quot;[Event Procedure]&quot; text in their Event Properties:&lt;/p&gt;
&lt;pre&gt;Set opt = wfrm.TxtStyle &#39;3D Text Styles
    opt.OnClick = EP

Set lst = wfrm.ColorList &#39;List of Colors
    lst.OnClick = EP
&lt;/pre&gt;

&lt;p&gt;Both these objects, Sub lst_Click() and Sub opt_Click() Event Subroutines, are written below the Sub Class_Int() Procedure.&lt;/p&gt;
&lt;h3&gt;The Command Button Wrapper Class Module.&lt;/h3&gt;
&lt;p&gt;There is only one Wrapper Class for both the CommandButtons on the Form. All the Wizard Functions are called from the Command Button with the Caption Create 3D Text Click Event Procedure, depending on the 3D Text Style Option.&lt;/p&gt;&lt;p&gt;The CommandButton Wrapper Class Subroutine that calls the Wizard Functions is listed below for reference.&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents cmd As Access.CommandButton
Private cfrm As Access.Form

Public Property Get c_Frm() As Form
   Set c_Frm = cfrm
End Property

Public Property Set c_Frm(ByRef vfrm As Form)
   Set cfrm = vfrm
End Property

Public Property Get c_cmd() As CommandButton
   Set c_cmd = cmd
End Property

Public Property Set c_cmd(ByRef vcmd As CommandButton)
   Set cmd = vcmd
End Property

Private Sub cmd_Click()
Select Case cmd.Name
    Case &quot;cmd3D&quot;
        Call Create3D(cfrm) &#39;Call the 3D Text Wizard
        
    Case &quot;cmdClose&quot;
If MsgBox(&quot;Close the 3DTextWizard? &quot;, vbYesNo + vbQuestion, &quot;cmdClose_Click()&quot;) = vbYes Then
    DoCmd.Close acForm, cfrm.Name
End If
End Select

End Sub

&lt;/pre&gt;
&lt;p&gt;The Cmd3D Click Event Subroutine invokes the Create3D(cfrm) Subroutine and passes the Form Object as a Parameter. This Subroutine in the Standard Module gathers the 3D Text Wizard option settings from the Form into related variables and then calls the wizard function based on the selected text style. Each Wizard function, such as Border2D&lt;b&gt;(),&amp;nbsp;&lt;/b&gt;calls three different programs to create the 3D Text.&lt;/p&gt;&lt;p&gt;For example, the Border2D Wizard calls the following three Functions to complete the full task of creating the 3D Text:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;FormTxtLabels() &#39; Creates a Form and the Label or Text Controls&lt;/li&gt;&lt;li&gt;&lt;p&gt;Validate_Dup() &#39; Performs a Validation check.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;MsgLabel()&amp;nbsp; &#39;Creates a Label control with instructions to use the 3D Text.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Listing all the Wizard VBA codes here is not feasible due to their large volume. However, the 3DTextWizard Demo Database is attached with all the code. You can download it from the link provided at the end of this Page. All Wizard VBA codes are available in the TxtWizard Standard Module.&lt;/p&gt;&lt;p&gt;Visit the following Links to Articles published earlier for more details on the Wizard Functions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2006/09/create-3d-headings-on-forms.html&quot; target=&quot;_Blank&quot;&gt;Create 3D Headings on Form&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2006/09/border2d-heading-text.html&quot; target=&quot;_Blank&quot;&gt;Border 2D  Heading Text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2006/09/border3d-heading.html&quot; target=&quot;_Blank&quot;&gt;Border3D Heading Style&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2006/09/shadow3d-heading-style.html&quot; target=&quot;_Blank&quot;&gt;Shadow3D Heading Style&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Demo Database Download Link. &lt;/h3&gt;
&lt;!--Download Link /downloads/2023/11/3DTextWizard.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1UU2F8M_QLaX6KqyF_wo9fBMlkWXYxtPV/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;3DTextWizard.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2023/11/3DTextWizard.zip--&gt;

&lt;h3&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/4164212098819535133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/4164212098819535133'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/4164212098819535133'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html' title='Streamlining Event Procedures 3D-Text Wizard'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTS-L5TR7N2qcVDKPKs5MiJXhFis-KsAV0yyDF3SNoou6EtvEAepF6ygNA_uffHVHj6PyHgp_aUOywekgj7c5H58DZ-IYDnVL9wD-LrLeMzf-5lOJzQDPjjt0Xy9eRLfMuFHOMEd34YKAA-TwILnG2IT69YnaSnOL2ahDjav2XQhywne81wpRsCEP8x0aM/s72-c/Anne%20Hellung.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-8006973103162379109</id><published>2023-10-30T17:47:00.020+05:30</published><updated>2026-07-11T17:17:18.178+05:30</updated><title type='text'>Streamlining Form VBA External Files List HyperLinks</title><content type='html'>&lt;!--Episode 17--&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;External Files List in Hyperlink Form.&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The &#39;FileDialog&#39; Control&amp;nbsp;&lt;/h3&gt;&lt;p data-end=&quot;275&quot; data-start=&quot;96&quot;&gt;The &lt;span data-end=&quot;122&quot; data-start=&quot;100&quot;&gt;FileDialog Control&lt;/span&gt; displays files from the selected folder as hyperlinks within the form. Clicking on a &lt;a href=&quot;https://www.msaccesstips.com/2007/05/open-forms-with-hyperlinks-in-listbox.html&quot; target=&quot;_blank&quot;&gt;hyperlink&lt;/a&gt; opens the file in its native application, if installed.&lt;/p&gt;
&lt;p&gt;The control supports &lt;span data-end=&quot;322&quot; data-start=&quot;298&quot;&gt;user-defined filters&lt;/span&gt;, enabling users to narrow down the file list by category—for example, &lt;a href=&quot;https://www.msaccesstips.com/2011/04/invoke-word-mail-merge-from-access2007.html&quot; target=&quot;_blank&quot;&gt;Word documents&lt;/a&gt;, Excel worksheets, Access databases, or all files in the folder. Once the required files are selected, clicking the &lt;span data-end=&quot;544&quot; data-start=&quot;524&quot;&gt;Create File Link&lt;/span&gt; command button adds them to a table and displays them in the forms datasheet view as hyperlinks. For reference, the full file path is also shown in a separate column.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;p&gt;Files&#39; List Display Image.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg965DLUJWqwKnIrHUVhED7S3hr3NC8rIhal9Ku6SZPxJyb5Hiwi2QGH3YXsXXZQ3wzHejcQtNfMlsWfixCEsHe9LbofmOmh5z2mhhVK5bUGPGNenkPS9sScZRP08fJC1ZdXtlB8X4pBvWlq1hgWYvPeDK9CfsY5J60n7tFJ8daddzHlQy-iuauqZoENvh2/s967/FileDialog3.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;File Browser&quot; border=&quot;0&quot; data-original-height=&quot;875&quot; data-original-width=&quot;967&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg965DLUJWqwKnIrHUVhED7S3hr3NC8rIhal9Ku6SZPxJyb5Hiwi2QGH3YXsXXZQ3wzHejcQtNfMlsWfixCEsHe9LbofmOmh5z2mhhVK5bUGPGNenkPS9sScZRP08fJC1ZdXtlB8X4pBvWlq1hgWYvPeDK9CfsY5J60n7tFJ8daddzHlQy-iuauqZoENvh2/s320/FileDialog3.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;After entering the &lt;span data-end=&quot;117&quot; data-start=&quot;102&quot;&gt;file filter&lt;/span&gt; in the &lt;span data-end=&quot;137&quot; data-start=&quot;125&quot;&gt;Pathname&lt;/span&gt; text box, click the &lt;span data-end=&quot;179&quot; data-start=&quot;158&quot;&gt;Create File Links&lt;/span&gt; &lt;a href=&quot;https://www.msaccesstips.com/2006/09/command-button-animation.html&quot; target=&quot;_blank&quot;&gt;command button&lt;/a&gt;. This action opens the File Browser control, which displays the available files and folders based on the filter settings.&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUVGeDa5Khs6WTzr040YvI5fFrCA26NPj5bEa4o-ZxXVVu5VVLqlQmmEtSCc-3KSD9gvbR8erNK8snfe95OuRtJAftuYHpN7WKyS_r_hOzkRmY5ynz-v29S92D29OruOM_4HAjiQaiunt1dYfHX8cSEkrcnAeiF_RtoR9FLwe1ISecR96U_X4x7blDjEoZ/s848/FileDialog2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;File List View&quot; border=&quot;0&quot; data-original-height=&quot;579&quot; data-original-width=&quot;848&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUVGeDa5Khs6WTzr040YvI5fFrCA26NPj5bEa4o-ZxXVVu5VVLqlQmmEtSCc-3KSD9gvbR8erNK8snfe95OuRtJAftuYHpN7WKyS_r_hOzkRmY5ynz-v29S92D29OruOM_4HAjiQaiunt1dYfHX8cSEkrcnAeiF_RtoR9FLwe1ISecR96U_X4x7blDjEoZ/s320/FileDialog2.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p data-end=&quot;419&quot; data-start=&quot;95&quot;&gt;At this stage, you may navigate to and select any folder to search for files. To select multiple adjoining files, click on the first file, hold down the &lt;span data-end=&quot;257&quot; data-start=&quot;248&quot;&gt;Shift&lt;/span&gt; key, and then click on the last file. Finally, click the &lt;span data-end=&quot;323&quot; data-start=&quot;315&quot;&gt;Open&lt;/span&gt; command button. The selected files will then appear in the list, as shown in the first image.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Form Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private FD As New FLst_Object_Init

Private Sub Form_Load()
&lt;span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;Set FD.fl_Frm = Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
Set FD = Nothing
End Sub
&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;&lt;p data-end=&quot;270&quot; data-start=&quot;83&quot;&gt;In the global declaration area, an instance of the &lt;code data-end=&quot;152&quot; data-start=&quot;134&quot;&gt;FLst_Object_Init&lt;/code&gt; class module is declared with the name &lt;span data-end=&quot;198&quot; data-start=&quot;192&quot;&gt;FD&lt;/span&gt;. The keyword &lt;span data-end=&quot;219&quot; data-start=&quot;212&quot;&gt;New&lt;/span&gt; is used to create the object instance in memory.&lt;/p&gt;
&lt;p&gt;In the &lt;span data-end=&quot;294&quot; data-start=&quot;279&quot;&gt;Form_Load()&lt;/span&gt; event procedure, the current form object is passed to the &lt;span data-end=&quot;366&quot; data-start=&quot;353&quot;&gt;FD.fl_Frm&lt;/span&gt; property of the FD instance.&lt;/p&gt;&lt;p&gt;The FLst_Object_Init Class Module Code.&lt;/p&gt;&lt;p&gt;The FLst_Object_Init with the Class_Init()&amp;nbsp;Subroutine VBA Code is given below:&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private cmd As FLst_CmdButton
Private frm As Access.Form
Private Coll As New Collection

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;Disk Directory Listing in Hyperlinks
&#39;Author: a.p.r. pillai
&#39;Date  : 25/10/2023
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

Public Property Get fl_Frm() As Access.Form
    Set fl_Frm = frm.m_cFrm
End Property

Public Property Set fl_Frm(ByRef pNewValue As Access.Form)
    Set frm = pNewValue
    
    Call Class_Init
End Property

Private Sub Class_Init()
Dim ctl As Control
Dim listcount As Long
Const EP = &quot;[Event Procedure]&quot;

&lt;span style=&quot;color: red;&quot;&gt;&#39;=============================&lt;/span&gt;
&#39;Calling the Public Function ButtonStatus() From &lt;span style=&quot;color: red;&quot;&gt;FLst_CmdButton&lt;/span&gt; Class
&#39;from the &lt;b&gt;Flst_CmdButton&lt;/b&gt; Class directly,
&lt;span style=&quot;color: red;&quot;&gt;Set cmd = New FLst_CmdButton &lt;/span&gt;&#39;Create a separate instance&lt;span style=&quot;color: red;&quot;&gt;
Set cmd.cmd_Frm = frm &lt;/span&gt;&#39;Pass the Form Object to the Property&lt;span style=&quot;color: red;&quot;&gt;

Call cmd.ButtonStatus &lt;/span&gt;&#39;Call the Public Function, with Param, if any&lt;span style=&quot;color: red;&quot;&gt;
Set cmd = Nothing &lt;/span&gt;&#39;Remove the instance
&lt;span style=&quot;color: red;&quot;&gt;&#39;=============================
&lt;/span&gt;
For Each ctl In frm.Controls
Select Case TypeName(ctl)
      Case &quot;CommandButton&quot;
        Select Case ctl.Name
            Case &quot;cmdHelp&quot;, &quot;cmdFileDialog&quot;, _
            &quot;cmdDelLink&quot;, &quot;cmdDelFile&quot;, _
            &quot;cmdClose&quot;, &quot;cmdDelAll&quot;
            
                Set cmd = New FLst_CmdButton
                Set cmd.cmd_Frm = frm
                Set cmd.c_cmd = ctl
        
                    cmd.c_cmd.OnClick = EP
                Coll.Add cmd
                Set cmd = Nothing
        End Select
End Select
Next

End Sub

Private Sub Class_Terminate()
Do While Coll.Count &amp;gt; 0
    Coll.Remove 1
Loop
End Sub

&lt;/pre&gt;
&lt;p&gt;The following two Subroutines, if present in the Class Module, run automatically.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Class_Initialize()&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Class_Terminate()&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Assuming we have both the above Subroutines in ClassA.&lt;/p&gt;&lt;p data-end=&quot;162&quot; data-start=&quot;87&quot;&gt;When you create an instance of &lt;span data-end=&quot;128&quot; data-start=&quot;118&quot;&gt;ClassA&lt;/span&gt; inside &lt;span data-end=&quot;146&quot; data-start=&quot;136&quot;&gt;ClassB&lt;/span&gt;, for example:&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;213&quot; data-start=&quot;164&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-vba&quot;&gt;Dim A As ClassA  
Set A = New ClassA
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;374&quot; data-start=&quot;215&quot;&gt;The &lt;span data-end=&quot;241&quot; data-start=&quot;219&quot;&gt;Class_Initialize()&lt;/span&gt; subroutine of &lt;em data-end=&quot;264&quot; data-start=&quot;256&quot;&gt;ClassA&lt;/em&gt; runs automatically (if it exists). You can place any initialization code here to prepare the class for use.&lt;/p&gt;&lt;p data-end=&quot;644&quot; data-start=&quot;376&quot;&gt;When the statement &lt;code data-end=&quot;412&quot; data-start=&quot;395&quot;&gt;Set A = Nothing&lt;/code&gt; is executed, or when the &lt;span data-end=&quot;448&quot; data-start=&quot;438&quot;&gt;ClassB&lt;/span&gt; object itself is unloaded, the &lt;span data-end=&quot;501&quot; data-start=&quot;480&quot;&gt;Class_Terminate()&lt;/span&gt; subroutine in &lt;em data-end=&quot;524&quot; data-start=&quot;516&quot;&gt;ClassA&lt;/em&gt; executes. This is where you can perform clean-up tasks, such as&amp;nbsp;&lt;code data-end=&quot;608&quot; data-start=&quot;589&quot;&gt;Set Obj = Nothing&amp;nbsp;&lt;/code&gt;releasing memory and resources.&lt;/p&gt;&lt;p data-end=&quot;824&quot; data-start=&quot;646&quot;&gt;This mechanism is especially useful when your class contains other objects—such as a &lt;span data-end=&quot;742&quot; data-start=&quot;728&quot;&gt;&lt;a href=&quot;https://www.msaccesstips.com/2018/12/ms-access-and-collection-object-basics.html&quot; target=&quot;_blank&quot;&gt;Collection&lt;/a&gt;&lt;/span&gt;, &lt;span data-end=&quot;758&quot; data-start=&quot;744&quot;&gt;Dictionary&lt;/span&gt;, or additional class instances—that must be explicitly cleared.&lt;/p&gt;&lt;p&gt;




&lt;/p&gt;&lt;p data-end=&quot;899&quot; data-start=&quot;826&quot;&gt;The following &lt;span data-end=&quot;850&quot; data-start=&quot;840&quot;&gt;Class1&lt;/span&gt; module is instantiated within the form module.&lt;/p&gt;
&lt;pre&gt;&#39;Class1
Dim DT As ClsDateTime

Private Sub Class_Initialize()
  Set DT = New ClsDateTime
  Forms(&quot;Form2&quot;).Text2 = DT.DateTime
End Sub

Private Sub Class_Terminate()
 Set DT = Nothing

End Sub
&lt;/pre&gt;
&lt;p data-end=&quot;551&quot; data-start=&quot;86&quot;&gt;The &lt;span data-end=&quot;112&quot; data-start=&quot;90&quot;&gt;Class_Initialize()&lt;/span&gt; subroutine, if defined in a class module, executes automatically when the class object is instantiated. However, in our streamlined VBA coding approach, we are unable to leverage this feature. The reason is that the class requires the &lt;span data-end=&quot;373&quot; data-start=&quot;348&quot;&gt;Form object reference&lt;/span&gt; to be available before the initialization routine can run. Since the Form object is not yet available at the moment of instantiation, we cannot rely on &lt;span data-end=&quot;548&quot; data-start=&quot;526&quot;&gt;Class_Initialize()&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;820&quot; data-start=&quot;553&quot;&gt;Instead, we explicitly call the &lt;span data-end=&quot;601&quot; data-start=&quot;585&quot;&gt;Class_Init()&lt;/span&gt; subroutine immediately after acquiring the Form object reference within the class module’s Set&amp;nbsp;&lt;span data-end=&quot;709&quot; data-start=&quot;693&quot;&gt;Property &lt;/span&gt;procedure. This ensures that initialization takes place only after the required Form reference is available.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;1164&quot; data-start=&quot;488&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p data-end=&quot;486&quot; data-start=&quot;135&quot;&gt;That doesn’t mean the &lt;span data-end=&quot;179&quot; data-start=&quot;157&quot;&gt;Class_Initialize()&lt;/span&gt; subroutine is unusable in this context. We can still use it to instantiate supporting objects, such as a &lt;span data-end=&quot;313&quot; data-start=&quot;299&quot;&gt;Collection&lt;/span&gt; or &lt;span data-end=&quot;331&quot; data-start=&quot;317&quot;&gt;Dictionary&lt;/span&gt;, or any other objects that do not depend on the Form reference. For instance, you might use it to create and prepare a Collection object as shown below:&lt;/p&gt;
&lt;pre&gt;Private Sub Class_Initialize()
	Set Coll = New Collection
End Sub
&lt;/pre&gt;
&lt;p data-end=&quot;409&quot; data-start=&quot;87&quot;&gt;The &lt;span data-end=&quot;112&quot; data-start=&quot;91&quot;&gt;Collection object&lt;/span&gt; is declared in the global declaration area of the Class Module. Since we used the &lt;span data-end=&quot;202&quot; data-start=&quot;195&quot;&gt;New&lt;/span&gt; keyword in the declaration statement, explicit initialization code inside the &lt;span data-end=&quot;303&quot; data-start=&quot;281&quot;&gt;Class_Initialize()&lt;/span&gt; subroutine is not required—the object is automatically created when the class instance is instantiated.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;685&quot; data-start=&quot;411&quot;&gt;The &lt;span data-end=&quot;436&quot; data-start=&quot;415&quot;&gt;Class_Terminate()&lt;/span&gt; subroutine, on the other hand, is very useful for memory management. It acts much like the &lt;span data-end=&quot;545&quot; data-start=&quot;528&quot;&gt;Form_Unload()&lt;/span&gt; event procedure, providing a place to release object references and perform any necessary cleanup before the class instance is destroyed.&lt;/p&gt;
&lt;pre&gt;Private Sub Class_Terminate()
Do While Coll.Count &amp;gt; 0
    Coll.Remove 1
Loop
End Sub

&lt;/pre&gt;
&lt;p data-end=&quot;185&quot; data-start=&quot;55&quot;&gt;The above code ensures that the &lt;span data-end=&quot;108&quot; data-start=&quot;87&quot;&gt;Collection object&lt;/span&gt; is cleared when the &lt;span data-end=&quot;149&quot; data-start=&quot;129&quot;&gt;FLst_Object_Init&lt;/span&gt; Class Module unloads from memory.&lt;/p&gt;&lt;p data-end=&quot;251&quot; data-start=&quot;187&quot;&gt;For this project, only two &lt;a href=&quot;https://www.msaccesstips.com/2018/12/ms-access-and-collection-object-basics.html&quot;&gt;Wrapper Class&lt;/a&gt; Modules are required:&lt;/p&gt;&lt;ol data-end=&quot;410&quot; data-start=&quot;252&quot;&gt;
&lt;li data-end=&quot;327&quot; data-start=&quot;252&quot;&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;255&quot;&gt;&lt;span data-end=&quot;275&quot; data-start=&quot;255&quot;&gt;FLst_Object_Init&lt;/span&gt; — which contains the &lt;span data-end=&quot;313&quot; data-start=&quot;297&quot;&gt;Class_Init()&lt;/span&gt; subroutine.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;410&quot; data-start=&quot;328&quot;&gt;
&lt;p data-end=&quot;410&quot; data-start=&quot;331&quot;&gt;&lt;span data-end=&quot;349&quot; data-start=&quot;331&quot;&gt;FLst_CmdButton&lt;/span&gt; — which handles all Command Button operations on the form.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;


&lt;/p&gt;&lt;p data-end=&quot;778&quot; data-start=&quot;412&quot;&gt;The &lt;span data-end=&quot;434&quot; data-start=&quot;416&quot;&gt;FLst_CmdButton&lt;/span&gt; class contains several subroutines. For clarity and better organization, each Command Button’s &lt;span data-end=&quot;545&quot; data-start=&quot;530&quot;&gt;Click Event&lt;/span&gt; procedure calls its Subroutine from this class rather than placing the entire block of code directly under the Command Button event in Form. This approach makes the code more modular, easier to read, and simpler to maintain.&lt;/p&gt;
&lt;h3&gt;The FLst_CmdButton Class Module Code.&lt;/h3&gt;
&lt;pre&gt;&#39;The Click Event Subroutines
Private Sub cmd_Click()
Select Case cmd.Name
  Case &quot;cmdClose&quot;
    If MsgBox(&quot;Close this Form?&quot;, vbOKCancel + vbQuestion, &quot;cmd_Click&quot;) = vbOK Then
        DoCmd.Close acForm, cmdfrm.Name
        Exit Sub
    End If

    Case &quot;cmdFileDialog&quot;
        Call cmdFileDialog &#39;Display selected Path &amp;amp; files
        
    Case &quot;cmdDelLink&quot;
        Call cmdDelLink &#39;Delete Selected Link from list
    
    Case &quot;cmdDelAll&quot;
        Call cmdDelAll &#39;Delete All Links from list
    
    Case &quot;cmdDelFile&quot;
        Call cmdDelFile &#39;Delete Link and File from Disk
        
    Case &quot;cmdHelp&quot;
        DoCmd.OpenForm &quot;Help&quot;, acNormal &#39;Show help Form
End Select
End Sub
&lt;/pre&gt;
&lt;h4 id=&quot;FileBrowser&quot;&gt;The cmdFileDialog() Subroutine.&lt;/h4&gt;
&lt;p&gt;This Subroutine is run by clicking&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;the Command Button with the Caption&amp;nbsp;&quot;Create File Links&quot;&lt;/span&gt;.&lt;/p&gt;
&lt;pre&gt;Private Sub cmdFileDialog()
On Error GoTo cmdFileDialog_Click_Err

&#39;Requires reference to Microsoft Office 12.0 Object Library.
Dim fDialog As office.FileDialog
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim defPath As String
Dim varFile As Variant
Dim strfiles As String

   &#39;Set up the File Dialog.
   Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
   With fDialog
      &#39;Allow user to make multiple selections of disk files.
      .AllowMultiSelect = True
      .InitialFileName = Dir(strPath)
      .InitialView = msoFileDialogViewDetails
      &#39;Set the title of the dialog box.
      .Title = &quot;Please select one or more files&quot;

      &#39;Clear out the current filters, and add our own.
      .Filters.Clear
      .Filters.Add &quot;Access Databases&quot;, &quot;*.mdb; *.accdb&quot;
      .Filters.Add &quot;Excel WorkBooks&quot;, &quot;*.xlsx; *.xlsm; *.xls; *.csv&quot;
      .Filters.Add &quot;Word Documents&quot;, &quot;*.docx; *.doc&quot;
      .Filters.Add &quot;Access Projects&quot;, &quot;*.adp&quot;
      .Filters.Add &quot;All Files&quot;, &quot;*.*&quot;
      .FilterIndex = 1
      &#39;.Execute
      &#39;Show the dialog box. If the .Show method returns True, the
      &#39;user picked at least one file. If the .Show method returns
      &#39;False, the user clicked Cancel.
    If .Show = True Then
        Set db = CurrentDb
        Set rst = db.OpenRecordset(&quot;DirectoryList&quot;, dbOpenDynaset)
        &#39;Add all selected files to the DirectoryList Table
        defPath = &quot;&quot;
      For Each varFile In .SelectedItems
         If defPath = &quot;&quot; Then
            defPath = Left(varFile, InStrRev(varFile, &quot;\&quot;))
            defPath = defPath &amp;amp; &quot;*.*&quot;
            cmdfrm.PathName = defPath
            cmdfrm.PathName.Requery
            strPath = defPath
         End If
            rst.AddNew
            &#39;Create Hyperlink in 4 segments
            &#39;1st segment: only the File Name
            strfiles = Mid(varFile, InStrRev(varFile, &quot;\&quot;) + 1)
            &#39;2nd segment:Full File PathName,3rd Empty,4th TipText
            strfiles = strfiles &amp;amp; &quot;#&quot; &amp;amp; varFile &amp;amp; &quot;##Click&quot;
            rst![FileLinks] = strfiles
            rst![Path] = varFile
            rst.Update
    Next
        
    Call ButtonStatus

        Else
            MsgBox &quot;You clicked Cancel in the file dialog box.&quot;
        End If
      
   End With

cmdFileDialog_Click_Exit:
Exit Sub

cmdFileDialog_Click_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;cmdFileDialog_Click()&quot;
Resume cmdFileDialog_Click_Exit
End Sub
&lt;/pre&gt;
&lt;p data-end=&quot;138&quot; data-start=&quot;123&quot;&gt;The statement&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;214&quot; data-start=&quot;140&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-vba&quot;&gt;Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;452&quot; data-start=&quot;216&quot;&gt;opens the &lt;span data-end=&quot;257&quot; data-start=&quot;226&quot;&gt;File Browser Dialog Control&lt;/span&gt; and initializes its various properties. Within this control, file-type filters can be defined, allowing users to select specific file categories when browsing from the default path.&lt;/p&gt;&lt;p data-end=&quot;725&quot; data-start=&quot;454&quot;&gt;If users are unsure about the file selection process, they can click on the &lt;span data-end=&quot;553&quot; data-start=&quot;530&quot;&gt;Help Command Button&lt;/span&gt; located at the top right of the form. This button provides detailed information on the purpose of each command button and explains the different ways files can be selected.&lt;/p&gt;&lt;p data-end=&quot;1028&quot; data-start=&quot;727&quot;&gt;A table named &lt;span data-end=&quot;758&quot; data-start=&quot;741&quot;&gt;DirectoryList&lt;/span&gt; is designed to store the selected files. The first column takes the files in &lt;span data-end=&quot;856&quot; data-start=&quot;836&quot;&gt;hyperlink format&lt;/span&gt;, while the second column records the &lt;span data-end=&quot;912&quot; data-start=&quot;894&quot;&gt;full file path&lt;/span&gt; for reference. Clicking the hyperlink will open the file in its native application (e.g., MS Word, Excel, others, if available in the system).&lt;/p&gt;&lt;p data-end=&quot;1045&quot; data-start=&quot;1030&quot;&gt;The statement&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;1079&quot; data-start=&quot;1047&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-vba&quot;&gt;Call ButtonStatus()
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;1480&quot; data-start=&quot;1081&quot;&gt;invokes the &lt;span data-end=&quot;1111&quot; data-start=&quot;1093&quot;&gt;ButtonStatus()&lt;/span&gt; subroutine, which checks whether the &lt;span data-end=&quot;1166&quot; data-start=&quot;1149&quot;&gt;DirectoryList&lt;/span&gt; table contains any records. If the table is empty, all command buttons (except &lt;em data-end=&quot;1265&quot; data-start=&quot;1246&quot;&gt;Create File Links&lt;/em&gt; and &lt;em data-end=&quot;1276&quot; data-start=&quot;1270&quot;&gt;Help&lt;/em&gt;) are disabled. This subroutine is also called from other procedures and from the &lt;span data-end=&quot;1385&quot; data-start=&quot;1365&quot;&gt;FLst_Object_Init&lt;/span&gt; class module (refer to the red-highlighted code inside the &lt;code data-end=&quot;1459&quot; data-start=&quot;1445&quot;&gt;Class_Init()&lt;/code&gt; subroutine above).&lt;/p&gt;&lt;p data-end=&quot;1757&quot; data-start=&quot;1482&quot;&gt;Another important point: if you create a &lt;span data-end=&quot;1542&quot; data-start=&quot;1523&quot;&gt;Public function&lt;/span&gt; inside a stand-alone class module, it becomes accessible across other class modules or standard modules within the application. This means such a function can be called and reused from outside its defining class.&lt;/p&gt;&lt;p data-end=&quot;1854&quot; data-start=&quot;1759&quot;&gt;In the next step, we will conduct some &lt;span data-end=&quot;1812&quot; data-start=&quot;1798&quot;&gt;trial runs&lt;/span&gt; to explore how to call a function from:&lt;/p&gt;&lt;p&gt;









&lt;/p&gt;&lt;ul data-end=&quot;1938&quot; data-start=&quot;1855&quot;&gt;
&lt;li data-end=&quot;1884&quot; data-start=&quot;1855&quot;&gt;
&lt;p data-end=&quot;1884&quot; data-start=&quot;1857&quot;&gt;another &lt;strong data-end=&quot;1881&quot; data-start=&quot;1865&quot;&gt;Class Module&lt;/strong&gt;,&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1915&quot; data-start=&quot;1885&quot;&gt;
&lt;p data-end=&quot;1915&quot; data-start=&quot;1887&quot;&gt;a &lt;strong data-end=&quot;1908&quot; data-start=&quot;1889&quot;&gt;Standard Module&lt;/strong&gt;, and&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1938&quot; data-start=&quot;1916&quot;&gt;
&lt;p data-end=&quot;1938&quot; data-start=&quot;1918&quot;&gt;a &lt;strong data-end=&quot;1935&quot; data-start=&quot;1920&quot;&gt;Form Module&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h4&gt;The cmdDelLink Subroutine.&lt;/h4&gt;
&lt;p data-end=&quot;427&quot; data-start=&quot;97&quot;&gt;To &lt;span data-end=&quot;119&quot; data-start=&quot;100&quot;&gt;delete a record&lt;/span&gt; from the hyperlink list, first click on the &lt;span data-end=&quot;190&quot; data-start=&quot;164&quot;&gt;Record Selector button&lt;/span&gt; to highlight the desired record. Then click the &lt;span data-end=&quot;254&quot; data-start=&quot;239&quot;&gt;Delete Link&lt;/span&gt; command button. Before the record is permanently removed, a &lt;span data-end=&quot;339&quot; data-start=&quot;315&quot;&gt;confirmation message&lt;/span&gt; will appear, giving you the option to proceed with the deletion or cancel the action.&lt;/p&gt;
&lt;pre&gt;&#39;Delete the Link From the List
Private Sub cmdDelLink()
On Error GoTo cmdDelLink_Click_Err
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strFile As String
Dim msg As String

&#39;Read the current record Pathname
strFile = cmdfrm.DirectoryList.Form!Path
Set db = CurrentDb
Set rst = db.OpenRecordset(&quot;DirectoryList&quot;, dbOpenDynaset)
rst.FindFirst &quot;Path = &#39;&quot; &amp;amp; strFile &amp;amp; &quot;&#39;&quot;
If Not rst.NoMatch Then
    msg = UCase(&quot;Link: &quot; &amp;amp; strFile &amp;amp; vbCr &amp;amp; &quot;DELETE from above List?&quot;)
    
If MsgBox(msg, vbQuestion + vbYesNo, &quot;cmddelLink_Click()&quot;) = vbYes Then
    rst.Delete
    rst.Requery
    cmdfrm.DirectoryList.Form.Requery
    MsgBox UCase(&quot;File Link: &quot; &amp;amp; strFile &amp;amp; &quot; Deleted.&quot;)
End If
Else
    MsgBox UCase(&quot;Link: &quot; &amp;amp; strFile &amp;amp; &quot; Not Found!!&quot;)
End If

Call ButtonStatus

rst.Close
Set rst = Nothing
Set db = Nothing

cmdDelLink_Click_Exit:
Exit Sub

cmdDelLink_Click_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;cmdDelLink_Click()&quot;
Resume cmdDelLink_Click_Exit
End Sub
&lt;/pre&gt;
&lt;h4&gt;The cmdDelAll() Subroutine.&lt;/h4&gt;
&lt;p data-end=&quot;349&quot; data-start=&quot;88&quot;&gt;This subroutine deletes &lt;span data-end=&quot;127&quot; data-start=&quot;112&quot;&gt;all records&lt;/span&gt; from the &lt;em data-end=&quot;152&quot; data-start=&quot;137&quot;&gt;DirectoryList&lt;/em&gt; table. Once the deletion is complete, all three command buttons associated with delete actions are &lt;span data-end=&quot;264&quot; data-start=&quot;252&quot;&gt;disabled&lt;/span&gt;. They remain disabled until at least one file is added back to the hyperlink list.&lt;/p&gt;
&lt;pre&gt;Private Sub cmdDelAll()
Dim msg As String
Dim yn As Integer
Dim listcount As Long

On Error GoTo cmdDelAll_Click_Err
listcount = DCount(&quot;*&quot;, &quot;DirectoryList&quot;)
If listcount = 0 Then
    cmdfrm.cmdDelAll.Enabled = False
    Exit Sub
Else
    cmdfrm.cmdDelAll.Enabled = True
End If

msg = &quot;All File Links in the List will be Deleted!&quot;
msg = msg &amp;amp; vbCr &amp;amp; &quot;Are You sure?&quot;
If MsgBox(msg, vbYesNo + vbCritical, &quot;cmdDelAll()&quot;) = vbYes Then
    If MsgBox(&quot;Deleting All File Links?&quot;, vbOKCancel + vbInformation, &quot;cmdDelAll()&quot;) = vbOK Then
        DoCmd.SetWarnings False
        DoCmd.OpenQuery &quot;DeleteAll_LinksQ&quot;, acViewNormal
        DoCmd.SetWarnings True
        cmdfrm.DirectoryList.Form.Requery
        cmdfrm.cmdDelAll.Enabled = False
    End If
End If

Call ButtonStatus

cmdDelAll_Click_Exit:
Exit Sub

cmdDelAll_Click_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;cmdDelAll_Click()&quot;
Resume cmdDelAll_Click_Exit
End Sub
&lt;/pre&gt;

&lt;h4&gt;The cmdDelFile() Subroutine.&lt;/h4&gt;
&lt;h3&gt;Caution:&lt;/h3&gt;
&lt;p data-end=&quot;338&quot; data-start=&quot;79&quot;&gt;Be cautious when using this command button. Clicking it will permanently &lt;span data-end=&quot;185&quot; data-start=&quot;152&quot;&gt;&lt;i&gt;delete the file from disk&lt;/i&gt;&lt;/span&gt; and remove its hyperlink from the list. Use this option &lt;span data-end=&quot;299&quot; data-start=&quot;249&quot;&gt;only when you are sure to delete the actual file&lt;/span&gt; from your system, not just the link in Microsoft Access.&lt;/p&gt;
&lt;pre&gt;&#39;Caution: Deletes the File from Disk
&#39;1. Delete the File from Disk
&#39;2. Remove selected link from List
Private Sub cmdDelFile()
On Error GoTo cmdDelFile_Click_Err
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strFile As String
Dim msg As String

&#39;Read selected Record Pathinfo
strFile = cmdfrm.DirectoryList.Form!Path
Set db = CurrentDb
Set rst = db.OpenRecordset(&quot;DirectoryList&quot;, dbOpenDynaset)
rst.FindFirst &quot;Path = &#39;&quot; &amp;amp; strFile &amp;amp; &quot;&#39;&quot;
If Not rst.NoMatch Then
    msg = UCase(&quot;File: &quot; &amp;amp; strFile &amp;amp; vbCr &amp;amp; &quot;DELETE from Disk?&quot;)
If MsgBox(msg, vbQuestion + vbYesNo, &quot;cmdDelFile_Click&quot;) = vbYes Then
    
   If MsgBox(UCase(&quot;Are you sure you want to Delete&quot;) &amp;amp; vbCr _
   &amp;amp; UCase(rst!Path &amp;amp; &quot; File from DISK?&quot;), vbCritical + vbYesNo, &quot;cmdDelFile_Click()&quot;) = vbNo Then
    GoTo cmdDelFile_Click_Exit
   End If
   &#39;Delete record entry from Table DirectoryList
    rst.Delete
    rst.Requery
    
Call ButtonStatus

    &#39;Delete file from Disk
    If Len(Dir(strFile)) &amp;gt; 0 Then
        Kill strFile
        MsgBox &quot;File: &quot; &amp;amp; strFile &amp;amp; &quot; Deleted.&quot;
    Else
        MsgBox &quot;File: &quot; &amp;amp; strFile &amp;amp; vbCr &amp;amp; &quot;Not Found on Disk!&quot;
    End If
  End If
Else
    MsgBox &quot;File: &quot; &amp;amp; strFile &amp;amp; &quot; Not Found!!&quot;
End If

cmdDelFile_Click_Exit:
    rst.Close
    Set rst = Nothing
    Set db = Nothing
Exit Sub

cmdDelFile_Click_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;cmdDelFile_Click()&quot;
Resume cmdDelFile_Click_Exit
End Sub
&lt;/pre&gt;
&lt;h4&gt;The ButtonStatus()&lt;/h4&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;103&quot;&gt;All three delete subroutines in the &lt;span data-end=&quot;157&quot; data-start=&quot;139&quot;&gt;FLst_CmdButton&lt;/span&gt; class, as well as those in the &lt;span data-end=&quot;209&quot; data-start=&quot;189&quot;&gt;FLst_Object_Init&lt;/span&gt; class, invoke the public subroutine &lt;span data-end=&quot;264&quot; data-start=&quot;246&quot;&gt;ButtonStatus()&lt;/span&gt;. This subroutine ensures that the command buttons remain disabled whenever the &lt;span data-end=&quot;361&quot; data-start=&quot;344&quot;&gt;DirectoryList&lt;/span&gt; table is empty.&lt;/p&gt;
&lt;pre&gt;Public Sub ButtonStatus()
Dim listcount As Long

On Error GoTo ButtonsStatus_Err:

listcount = DCount(&quot;*&quot;, &quot;DirectoryList&quot;)
cmdfrm.DirectoryList.Form.Requery

If listcount = 0 Then
    cmdfrm.cmdDelLink.Enabled = False
    cmdfrm.cmdDelAll.Enabled = False
    cmdfrm.cmdDelFile.Enabled = False
Else
    cmdfrm.cmdDelLink.Enabled = True
    cmdfrm.cmdDelAll.Enabled = True
    cmdfrm.cmdDelFile.Enabled = True
End If

ButtonsStatus_Exit:
Exit Sub

ButtonsStatus_Err:
MsgBox Err &amp;amp; &quot; : &quot; &amp;amp; Err.Description, , &quot;ButtonsStatus()&quot;
Resume ButtonsStatus_Exit
End Sub
&lt;/pre&gt;
&lt;h3&gt;Calling a Public Function from a Class Module.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a Class Module named ClsDateTime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy and Paste the following Function Code into the Class Module:&lt;/p&gt;
 &lt;pre&gt;Option Compare Database
Option Explicit

Public Function DateTime() As String
Dim fmt As String

fmt = &quot;dd/mm/yyyy hh:nn:ss&quot;
DateTime = &quot;DateTime: &quot; &amp;amp; Format(Now(), fmt)

End Function

 &lt;/pre&gt;
&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Save the Class Module.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p&gt;Create a New Form named Form1 or any other name you prefer, and open it in Design View.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a TextBox Control on the Form and make sure the TextBox Name is Text0.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Display the Form Property Sheet and select the Property Sheet&#39;s&amp;nbsp;&lt;i&gt;Other&lt;/i&gt; Tab.&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;Set the Has Module Property value to Yes&amp;nbsp;to add a Class Module to the Form.&lt;/li&gt;&lt;li&gt;&lt;p&gt;Display the Form1 Code Module, Copy and Paste the following Code in the Form Module, Save and Close the Form:&lt;/p&gt;
&lt;pre&gt;Private Sub Form_Load()
Dim DT As New ClsDateTime

Me.Text0 = DT.DateTime

End Sub
&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Open Form1 in Normal View. The current Date and Time will appear in the TextBox.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;ol&gt;&lt;li&gt;&lt;p data-end=&quot;492&quot; data-start=&quot;133&quot;&gt;In the &lt;span data-end=&quot;155&quot; data-start=&quot;140&quot;&gt;Form_Load()&lt;/span&gt; event procedure, create an instance named DT of the &lt;span data-end=&quot;214&quot; data-start=&quot;199&quot;&gt;ClsDateTime&lt;/span&gt; Class Module.&amp;nbsp;When you type&amp;nbsp;&lt;code data-end=&quot;276&quot; data-start=&quot;271&quot;&gt;DT.&lt;/code&gt;&amp;nbsp;, the &lt;span data-end=&quot;296&quot; data-start=&quot;282&quot;&gt;DateTime()&lt;/span&gt; function will automatically appear in the IntelliSense list. Simply select and call the function, and when the form opens, the current date and time will be displayed in the designated TextBox.&lt;/p&gt;
&lt;p data-end=&quot;660&quot; data-start=&quot;494&quot;&gt;This same procedure can also be applied between two class modules—allowing you to call a Function of one Class Module from another, besides from the &lt;a href=&quot;https://www.msaccesstips.com/2007/08/saving-data-on-forms-not-in-table.html&quot;&gt;form&lt;/a&gt; module.&lt;/p&gt;
&lt;p data-end=&quot;769&quot; data-start=&quot;662&quot;&gt;In our streamlined, structured VBA coding approach, we typically work with three levels of class modules:&lt;/p&gt;
&lt;ol data-end=&quot;923&quot; data-start=&quot;771&quot;&gt;
&lt;li data-end=&quot;795&quot; data-start=&quot;771&quot;&gt;
&lt;p data-end=&quot;795&quot; data-start=&quot;774&quot;&gt;The &lt;span data-end=&quot;793&quot; data-start=&quot;778&quot;&gt;Form Module&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;833&quot; data-start=&quot;796&quot;&gt;
&lt;p data-end=&quot;833&quot; data-start=&quot;799&quot;&gt;An &lt;span data-end=&quot;831&quot; data-start=&quot;802&quot;&gt;Intermediary Class Module&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;923&quot; data-start=&quot;834&quot;&gt;
&lt;p data-end=&quot;923&quot; data-start=&quot;837&quot;&gt;The &lt;span data-end=&quot;857&quot; data-start=&quot;841&quot;&gt;Class Module&lt;/span&gt; containing the required function (in this case, &lt;span data-end=&quot;920&quot; data-start=&quot;906&quot;&gt;DateTime()&lt;/span&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let us now test this function in such a three-tier setup, where the form module communicates with the intermediary class, which in turn calls the function in the dedicated class module.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Make a Copy of Form1 and name it Form2. &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Rename the TextBox Name to Text2. &lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Display its Class Module, then copy and paste the following two Lines of Code, overwriting the existing lines.&lt;/p&gt;
&lt;pre&gt;Option Compare Database

Private test As New Class1

&lt;/pre&gt;
  &lt;/li&gt;&lt;li&gt;&lt;p&gt;Create a Class Module Named Class1.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Copy and paste the Following Code into the Class1 Module:&lt;/p&gt;
&lt;pre&gt;Option Compare Database

Private D  As New ClsDateTime

Private Sub Class_initialize()
  Forms(&quot;Form2&quot;).Text2 = D.DateTime
End Sub
&lt;/pre&gt;
  &lt;/li&gt;&lt;li&gt;&lt;p&gt;Select Save from the File Menu to save all the Files.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Open Form2 in Normal View. The DateTime value should appear in the Text2 TextBox on the Form. &lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p data-end=&quot;370&quot; data-start=&quot;118&quot;&gt;Since class modules cannot load themselves into memory, we used the &lt;span data-end=&quot;195&quot; data-start=&quot;186&quot;&gt;Form2&lt;/span&gt; module to create an instance of the &lt;span data-end=&quot;242&quot; data-start=&quot;232&quot;&gt;Class1&lt;/span&gt; module. Once the &lt;span data-end=&quot;270&quot; data-start=&quot;260&quot;&gt;Class1&lt;/span&gt; class module is instantiated, it in turn creates an instance of the &lt;span data-end=&quot;354&quot; data-start=&quot;339&quot;&gt;ClsDateTime&lt;/span&gt; class module.&lt;/p&gt;&lt;p data-end=&quot;639&quot; data-start=&quot;372&quot;&gt;At this point, the &lt;span data-end=&quot;413&quot; data-start=&quot;391&quot;&gt;Class_Initialize()&lt;/span&gt; subroutine in &lt;span data-end=&quot;443&quot; data-start=&quot;428&quot;&gt;ClsDateTime&lt;/span&gt; runs automatically. From within this subroutine, the &lt;span data-end=&quot;511&quot; data-start=&quot;497&quot;&gt;DateTime()&lt;/span&gt; public function is called. The result returned by the function is then passed back and displayed in the TextBox on &lt;span data-end=&quot;636&quot; data-start=&quot;627&quot;&gt;Form2&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;



&lt;/p&gt;&lt;p data-end=&quot;891&quot; data-is-last-node=&quot;&quot; data-is-only-node=&quot;&quot; data-start=&quot;779&quot;&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p data-end=&quot;777&quot; data-start=&quot;646&quot;&gt;This keeps the workflow very clear:&lt;br data-end=&quot;686&quot; data-start=&quot;683&quot; /&gt;
&lt;span data-end=&quot;775&quot; data-start=&quot;686&quot;&gt;&lt;i&gt;Form2 → Class1 → ClsDateTime (Initialize → DateTime() → Return value → Form2.TextBox)&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Hope you understand how it works now.&lt;/p&gt;&lt;p&gt;Try Calling the DateTime() Function from the Standard Module in a Test() Function.&lt;/p&gt;
&lt;h3&gt;Demo Database Download Link. &lt;/h3&gt;
&lt;!--Download Link /downloads/2023/10/DirListing2K1.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1cCSPECL-EDkSKr9veP_MnjRDaeKHgp_r/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;DirListing2K1.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2023/10/DirListing2K1.zip--&gt;

&lt;br /&gt;
&lt;h4&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
&lt;/li&gt;&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/8006973103162379109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/8006973103162379109'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/8006973103162379109'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html' title='Streamlining Form VBA External Files List HyperLinks'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg965DLUJWqwKnIrHUVhED7S3hr3NC8rIhal9Ku6SZPxJyb5Hiwi2QGH3YXsXXZQ3wzHejcQtNfMlsWfixCEsHe9LbofmOmh5z2mhhVK5bUGPGNenkPS9sScZRP08fJC1ZdXtlB8X4pBvWlq1hgWYvPeDK9CfsY5J60n7tFJ8daddzHlQy-iuauqZoENvh2/s72-c/FileDialog3.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-1898596109883545524</id><published>2023-10-18T08:16:00.011+05:30</published><updated>2026-07-11T16:40:00.915+05:30</updated><title type='text'>New Custom-Made Report Wizard - Part 16</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlining Custom-Made Reports Wizard Form Module VBA Code.&lt;/h3&gt;&lt;p data-end=&quot;367&quot; data-start=&quot;99&quot;&gt;I hope you enjoyed exploring last week’s &lt;strong data-end=&quot;162&quot; data-start=&quot;140&quot;&gt;Custom Form Wizard&lt;/strong&gt;, which organized its VBA code into a few standalone &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html&quot; target=&quot;_blank&quot;&gt;Class Modules&lt;/a&gt;. This approach allows you to access, review, and study the code directly without interfering with the Form Design or its embedded Form Module.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;720&quot; data-start=&quot;369&quot;&gt;The &lt;span data-end=&quot;397&quot; data-start=&quot;373&quot;&gt;Custom Report Wizard&lt;/span&gt; shares the same user interface design as the &lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_blank&quot;&gt;Form Wizard.&lt;/a&gt; It was originally published in December 2008 under Access 2003. In this updated version, however, the Report Wizard’s Form Module VBA code has been refactored to run from standalone Class Modules, making it easier to maintain.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;

&lt;p data-end=&quot;326&quot; data-start=&quot;297&quot;&gt;&lt;span data-end=&quot;324&quot; data-start=&quot;297&quot;&gt;The &lt;span data-end=&quot;91&quot; data-start=&quot;74&quot;&gt;Report Wizard&lt;/span&gt; is designed with a &lt;span data-end=&quot;125&quot; data-start=&quot;111&quot;&gt;TabControl&lt;/span&gt; containing two pages. On the first TabPage, a &lt;span data-end=&quot;183&quot; data-start=&quot;172&quot;&gt;ListBox&lt;/span&gt; provides two key options, while a &lt;span data-end=&quot;230&quot; data-start=&quot;218&quot;&gt;ComboBox&lt;/span&gt; allows you to select a &lt;span data-end=&quot;263&quot; data-start=&quot;254&quot;&gt;Table&lt;/span&gt; or &lt;span data-end=&quot;276&quot; data-start=&quot;267&quot;&gt;Query&lt;/span&gt; as the data source.&lt;/span&gt;&lt;/p&gt;&lt;ol data-end=&quot;360&quot; data-start=&quot;294&quot;&gt;&lt;li data-end=&quot;326&quot; data-start=&quot;294&quot;&gt;&lt;p data-end=&quot;326&quot; data-start=&quot;297&quot;&gt;&lt;span data-end=&quot;324&quot; data-start=&quot;297&quot;&gt;Report in Column Format&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li data-end=&quot;360&quot; data-start=&quot;327&quot;&gt;
&lt;p data-end=&quot;360&quot; data-start=&quot;330&quot;&gt;&lt;span data-end=&quot;358&quot; data-start=&quot;330&quot;&gt;Report in Tabular Format&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p data-end=&quot;578&quot; data-start=&quot;362&quot;&gt;These two options are provided as a &lt;span data-end=&quot;412&quot; data-start=&quot;398&quot;&gt;Value List&lt;/span&gt; in the &lt;span data-end=&quot;433&quot; data-start=&quot;420&quot;&gt;RowSource&lt;/span&gt; property. To ensure that the first option is selected automatically, the &lt;span data-end=&quot;539&quot; data-start=&quot;522&quot;&gt;Default Value&lt;/span&gt; property is set with the expression:&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;611&quot; data-start=&quot;580&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre!&quot;&gt;&lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;WizList&lt;/span&gt;&lt;span class=&quot;hljs-operator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;Column&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-operator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;



&lt;/p&gt;&lt;p data-end=&quot;699&quot; data-start=&quot;613&quot;&gt;This ListBox has the first item pre-selected when the Wizard opens.&lt;/p&gt;&lt;p data-end=&quot;356&quot; data-start=&quot;83&quot;&gt;The &lt;span data-end=&quot;107&quot; data-start=&quot;87&quot;&gt;ComboBox &lt;a href=&quot;https://www.msaccesstips.com/2007/08/edit-data-in-zoom-in-control.html&quot; target=&quot;_blank&quot;&gt;Control&lt;/a&gt;&lt;/span&gt; displays a list of tables and select queries, filtered from the &lt;span data-end=&quot;187&quot; data-start=&quot;172&quot;&gt;MSysObjects&lt;/span&gt; system table. Its &lt;span data-end=&quot;223&quot; data-start=&quot;206&quot;&gt;Default Value&lt;/span&gt; property is set to the expression:&amp;nbsp;&lt;code data-end=&quot;282&quot; data-start=&quot;258&quot;&gt;=FilesList.Column(0,0)&lt;/code&gt;, which automatically selects the first item in the list as the default.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The SQL of the File Selection Query.&lt;/h3&gt;
&lt;pre&gt;SELECT MSysObjects.Name
FROM MSysObjects
WHERE (((MSysObjects.Type)=1 Or (MSysObjects.Type)=5) AND ((Left([Name],4))&amp;lt;&amp;gt;&#39;WizQ&#39;) AND ((Left([Name],1))&amp;lt;&amp;gt;&#39;~&#39;) AND ((MSysObjects.Flags)=0))
ORDER BY MSysObjects.Type, MSysObjects.Name;
&lt;/pre&gt;
&lt;p&gt;
The TabControl first page image is given below:
&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX9o4TKvhqttg_Q72ZSo6qm3h-1yKfDpYgwwnMYhU_NBya0yB7l83o7qYUwtymrvrKs1rEw51Ric_yi7fhl7Zzw1w7zUbsTZvPQcmeN7f2Y9ot_dyttqyZJwy2fFy48DHm81_33QfmJwuxEhI_PW9DguDpPX7_MQwnWIxR1Z8G-KSa4DyhBC2hKUMbbWit/s707/ReportWizard1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Report Wizard Page1&quot; border=&quot;0&quot; data-original-height=&quot;707&quot; data-original-width=&quot;691&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX9o4TKvhqttg_Q72ZSo6qm3h-1yKfDpYgwwnMYhU_NBya0yB7l83o7qYUwtymrvrKs1rEw51Ric_yi7fhl7Zzw1w7zUbsTZvPQcmeN7f2Y9ot_dyttqyZJwy2fFy48DHm81_33QfmJwuxEhI_PW9DguDpPX7_MQwnWIxR1Z8G-KSa4DyhBC2hKUMbbWit/s320/ReportWizard1.png&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Report Wizard Page2 Image:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj23v7leG6A7xsjffb06Nzt17YrgETceaLsMkISWWDgfNUz_Ks7In9EJhZPyzR6h7mNfMbvYW0tye7_h2WlUUI3l2ukNmFMmpbRkUiXo_VnOdCcykpqX1m7s_Q4eJp3lsTepYx-ar116XJHMOMhIf0z40z_Y_lVy7kPjC_KELvcyHt-hyhf8E5cV_Y8DBYP/s708/ReportWizard2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Report Wizard Page2&quot; border=&quot;0&quot; data-original-height=&quot;708&quot; data-original-width=&quot;692&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj23v7leG6A7xsjffb06Nzt17YrgETceaLsMkISWWDgfNUz_Ks7In9EJhZPyzR6h7mNfMbvYW0tye7_h2WlUUI3l2ukNmFMmpbRkUiXo_VnOdCcykpqX1m7s_Q4eJp3lsTepYx-ar116XJHMOMhIf0z40z_Y_lVy7kPjC_KELvcyHt-hyhf8E5cV_Y8DBYP/s320/ReportWizard2.png&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The following lines of the VBA Code are only needed in the Form&#39;s Class Module. All other Events, Subroutines, and Functions are placed in the Standalone Class Modules.&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private obj As New RWizObject_Init

Private Sub Form_Load()
    Set obj.fm_fom = Me
End Sub
&lt;/pre&gt;
&lt;p data-end=&quot;413&quot; data-start=&quot;101&quot;&gt;The &lt;span data-end=&quot;150&quot; data-start=&quot;105&quot;&gt;RWizObject_Init intermediary Class Module&lt;/span&gt; is instantiated with the object name &lt;span data-end=&quot;195&quot; data-start=&quot;188&quot;&gt;obj&lt;/span&gt; in the global declaration section of the Form Module. During the &lt;span data-end=&quot;276&quot; data-start=&quot;261&quot;&gt;Form_Load()&lt;/span&gt; event procedure, the form object reference is passed to the &lt;span data-end=&quot;356&quot; data-start=&quot;337&quot;&gt;RWizObject_Init&lt;/span&gt; class module’s property procedure using the statement:&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;445&quot; data-start=&quot;415&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-vba&quot;&gt;Set obj.fm_fom = Me
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;h3&gt;The RWizObject_Init Class.&lt;/h3&gt;
&lt;p&gt;The RWizObject_Init&amp;nbsp;VBA Code is listed below. All the Report creation functions are placed within this Class Module.&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private fom As Access.Form

Private cmdb As RWiz_CmdButton
Private lstb As RWiz_ListBox
Private comb As RWiz_Combo

Private tb As RWiz_TabCtl
Private Coll As New Collection

&#39;Wizard Functions Running Command Button Instance&#39;
&#39;Functions are placed in this Module
Private WithEvents cmdFinish As Access.CommandButton
Dim DarkBlue As Long, twips As Long, xtyp As Integer, strFile As String

Public Property Get fm_fom() As Form
  Set fm_fom = fom
End Property

Public Property Set fm_fom(ByRef mfom As Form)
  Set fom = mfom
    
  Call Class_Init
End Property

Private Sub Class_Init()
Dim Ctl As Control
Const EP = &quot;[Event Procedure]&quot;

&#39;Filter Table/Select Query Names for ComboBox
Call Create_FilesList

For Each Ctl In fom.Controls
    Select Case Ctl.ControlType
        Case acTabCtl
            Set tb = New RWiz_TabCtl
            Set tb.Tb_Frm = fom
            Set tb.Tb_Tab = Ctl
              tb.Tb_Tab.OnChange = EP
              
              Coll.Add tb
            Set tb = Nothing
        
        Case acCommandButton
            Select Case Ctl.Name
                Case &quot;cmdReport&quot;
                    &#39;Not to add in the Collection object
                    &#39;The Click Event Runs the Wizard Functions
                    &#39;from this Class Module, not from the
                    &#39;Wrapper Class - FWiz_CmdButton
                    
                    Set cmdFinish = fom.cmdReport
                    cmdFinish.OnClick = EP
                Case Else
            
            Set cmdb = New RWiz_CmdButton
            Set cmdb.w_Frm = fom
            Set cmdb.w_cmd = Ctl
                cmdb.w_cmd.OnClick = EP
                
              Coll.Add cmdb
            Set cmdb = Nothing
         End Select
            
        Case acComboBox
            Set comb = New RWiz_Combo
            Set comb.cbo_Frm = fom
            Set comb.c_cbo = Ctl
                comb.c_cbo.OnGotFocus = EP
                comb.c_cbo.OnLostFocus = EP
            
        Case acListBox
            Set lstb = New RWiz_ListBox
            Set lstb.lst_Frm = fom
            Set lstb.m_lst = Ctl
                lstb.m_lst.OnGotFocus = EP
                lstb.m_lst.OnLostFocus = EP
                
                Coll.Add lstb
            Set lstb = Nothing
    End Select
Next
            
End Sub

Private Sub cmdFinish_Click()
        xtyp = fom!WizList
        strFile = fom!FilesList
        If xtyp = 1 Then
            Columns strFile
        Else
            Tabular strFile
        End If
          DoCmd.Close acForm, fom.Name
End Sub&lt;/pre&gt;
&lt;h3&gt;Create_FilesList() Subroutine Code.&lt;/h3&gt;
&lt;p&gt;The Subroutine that creates the Files List for the ComboBox on the first page of the Wizard.&lt;/p&gt;
&lt;pre&gt;&#39;Create Tables/Queries List for
Private Sub Create_FilesList()
Dim strSQL1 As String
Dim cdb As DAO.Database
Dim Qry As DAO.QueryDef
Dim FList As ComboBox

On Error GoTo Create_FilesList_Err
DoCmd.Restore

strSQL1 = &quot;SELECT MSysObjects.Name &quot; _
&amp;amp; &quot;FROM MSysObjects &quot; _
&amp;amp; &quot;WHERE (((MSysObjects.Type)=1 Or (MSysObjects.Type)=5) &quot; _
&amp;amp; &quot;AND ((Left([Name],4))&amp;lt;&amp;gt;&#39;WizQ&#39;) AND ((Left([Name],1))&amp;lt;&amp;gt;&#39;~&#39;) &quot; _
&amp;amp; &quot;AND ((MSysObjects.Flags)=0)) &quot; _
&amp;amp; &quot;ORDER BY MSysObjects.Type, MSysObjects.Name;&quot;

DarkBlue = 8388608
twips = 1440

Set cdb = CurrentDb
Set Qry = cdb.QueryDefs(&quot;WizQuery&quot;)
If Err = 3265 Then
  Set Qry = cdb.CreateQueryDef(&quot;WizQuery&quot;)
  Qry.SQL = strSQL1
  cdb.QueryDefs.Append Qry
  cdb.QueryDefs.Refresh
  Err.Clear
End If

With Forms(&quot;ReportWizard&quot;)
Set FList = .FilesList
    .FilesList.RowSource = &quot;WizQuery&quot;
    .FilesList.Requery
End With

Create_FilesList_Exit:
Exit Sub

Create_FilesList_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;Create_FilesList()&quot;
Resume Create_FilesList_Exit
End Sub
&lt;/pre&gt;
&lt;h3&gt;The Function that Creates the Report in Column Format.&lt;/h3&gt;
&lt;pre&gt;Public Function Columns(ByVal DataSource As String)

Dim cdb As Database
Dim FldList() As String
Dim Ctrl As Control
Dim Rpt As Report
Dim PgSection As Section
Dim DetSection As Section
Dim HdSection As Section

Dim lngTxtLeft As Long
Dim lngTxtTop As Long
Dim lngTxtHeight As Long
Dim lngtxtwidth As Long

Dim lngLblLeft As Long
Dim lngLblTop As Long
Dim lngLblHeight As Long
Dim lngLblWidth As Long

Dim FldCheck As Boolean
Dim strTblQry As String
Dim intflds As Integer
Dim lstcount As Long
Dim RptFields As ListBox
Dim j As Integer


&#39;Create Report with Selected Fields

On Error Resume Next

strFile = DataSource
Set RptFields = fom.SelList
lstcount = RptFields.listcount

If lstcount = 0 Then
   MsgBox &quot;Fields Not Selected for Report!&quot;
   Exit Function
Else
   lstcount = lstcount - 1
End If

ReDim FldList(0 To lstcount) As String

Set cdb = CurrentDb
Set Rpt = CreateReport

Set HdSection = Rpt.Section(acPageHeader)
    HdSection.Height = 0.6667 * twips

Set DetSection = Rpt.Section(acDetail)
    DetSection.Height = 0.166 * twips

For j = 0 To lstcount
  FldList(j) = RptFields.ItemData(j)
Next

With Rpt
    .Caption = strFile
    .RecordSource = strFile
    lngtxtwidth = 1.5 * twips
    lngTxtLeft = 1.1 * twips
    lngTxtTop = 0.0417 * twips
    lngTxtHeight = 0.2181 * twips

    lngLblWidth = lngtxtwidth
    lngLblLeft = 0.073 * twips
    lngLblTop = 0.0417 * twips
    lngLblHeight = 0.2181 * twips
End With

For j = 0 To lstcount

   Set Ctrl = CreateReportControl(Rpt.Name, acTextBox, acDetail, , FldList(j), lngTxtLeft, lngTxtTop, lngtxtwidth, lngTxtHeight)
    With Ctrl
       .ControlSource = FldList(j)
       .FontName = &quot;Comic Sans MS&quot;
       .FontSize = 8
       .FontWeight = 700
       .ForeColor = DarkBlue
       .BorderColor = DarkBlue
       .Name = FldList(j)
       .BackColor = RGB(255, 255, 255)
       .BorderStyle = 1
       .SpecialEffect = 0
     Select Case (j / 9)
     	Case 1,2,3
        	lngTxtTop = (0.0417 * twips)
        	lngTxtLeft = lngTxtLeft + (2.7084 * twips)
        Case Else
        	lngTxtTop = lngTxtTop + .Height + (0.1 * twips)
     End Select
    End With

   Set Ctrl = CreateReportControl(Rpt.Name, acLabel, acDetail, FldList(j), FldList(j), lngLblLeft, lngLblTop, lngLblWidth, lngLblHeight)
    With Ctrl
       .Caption = FldList(j)
       .Height = (0.2181 * twips)
       .Name = FldList(j) &amp;amp; &quot; Label&quot;
       .Width = twips
       .ForeColor = 0
       .BorderStyle = 0
       .FontWeight = 400
       Select Case (j/9)
       		Case 1,2,3
              lngLblTop = (0.0417 * twips)
        	  lngLblLeft = lngLblLeft + (2.7083 * twips)
       		Case Else
        	  lngLblTop = lngLblTop + .Height + (0.1 * twips)
       End Select
    End With
Next

lngLblWidth = 4.5 * twips
lngLblLeft = 0.073 * twips
lngLblTop = 0.0521 * twips
lngLblHeight = 0.323 &amp;amp; twips
lngLblWidth = 4.5 &amp;amp; twips
 Set Ctrl = CreateReportControl(Rpt.Name, acLabel, acPageHeader, , &quot;Head1&quot;, lngLblLeft, lngLblTop, lngLblWidth, lngLblHeight)
   With Ctrl
        .Caption = strFile
        .TextAlign = 2
        .Width = 4.5 * twips
        .Height = 0.38 * twips
        .ForeColor = DarkBlue
        .BorderStyle = 0
        .BorderColor = DarkBlue
        .FontName = &quot;Times New Roman&quot;
        .FontSize = 20
        .FontWeight = 700 &#39; Bold
        .FontItalic = True
        .FontUnderline = True
   End With

Page_Footer Rpt

DoCmd.OpenReport Rpt.Name, acViewPreview

Columns_Exit:
Exit Function

Columns_Err:
MsgBox Err.Description, , &quot;Columns&quot;
Resume Columns_Exit
End Function
&lt;/pre&gt;
&lt;h3&gt;The Tabular Type Report Creation Function.&lt;/h3&gt;
&lt;p data-end=&quot;472&quot; data-start=&quot;122&quot;&gt;In both Wizards, the majority of the VBA code consists of &lt;span data-end=&quot;205&quot; data-start=&quot;180&quot;&gt;variable declarations&lt;/span&gt;&amp;nbsp;that define the &lt;span data-end=&quot;245&quot; data-start=&quot;225&quot;&gt;TextBox controls&lt;/span&gt; and their associated &lt;span data-end=&quot;291&quot; data-start=&quot;267&quot;&gt;child Label controls&lt;/span&gt;, along with their dimension values. Additional properties—such as &lt;span data-end=&quot;393&quot; data-start=&quot;358&quot;&gt;Font name, Font size, ForeColor&lt;/span&gt;, and other formatting attributes—are applied after the controls are created.&lt;/p&gt;
&lt;p data-end=&quot;259&quot; data-start=&quot;127&quot;&gt;The statement &lt;code data-end=&quot;175&quot; data-start=&quot;141&quot;&gt;Set Ctrl = CreateReportControl()&lt;/code&gt; requires several &lt;a href=&quot;https://www.msaccesstips.com/2018/07/function-parameter-array-passing.html&quot; target=&quot;_blank&quot;&gt;parameters&lt;/a&gt; to be defined before it can be executed. For example:&lt;/p&gt;&lt;pre class=&quot;overflow-visible!&quot; data-end=&quot;403&quot; data-start=&quot;261&quot;&gt;&lt;div class=&quot;contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary&quot;&gt;&lt;div class=&quot;sticky top-9&quot;&gt;&lt;div class=&quot;absolute end-0 bottom-0 flex h-9 items-center pe-2&quot;&gt;&lt;div class=&quot;bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;overflow-y-auto p-4&quot; dir=&quot;ltr&quot;&gt;&lt;code class=&quot;whitespace-pre! language-vba&quot;&gt;Set Ctrl = CreateReportControl(Rpt.Name, acTextBox, _
    acDetail, , FldList(j), lngTxtLeft, lngTxtTop, lngTxtWidth, lngTxtHeight)
&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p data-end=&quot;442&quot; data-start=&quot;405&quot;&gt;Each parameter has a specific role:&lt;/p&gt;&lt;ol data-end=&quot;1072&quot; data-start=&quot;444&quot;&gt;
&lt;li data-end=&quot;521&quot; data-start=&quot;444&quot;&gt;
&lt;p data-end=&quot;521&quot; data-start=&quot;447&quot;&gt;&lt;strong data-end=&quot;459&quot; data-start=&quot;447&quot;&gt;Rpt.Name&lt;/strong&gt; – The name of the &lt;a href=&quot;https://www.msaccesstips.com/2007/08/highlighting-reports.html&quot; target=&quot;_blank&quot;&gt;Report&lt;/a&gt; where the control will be created.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;599&quot; data-start=&quot;522&quot;&gt;
&lt;p data-end=&quot;599&quot; data-start=&quot;525&quot;&gt;&lt;strong data-end=&quot;538&quot; data-start=&quot;525&quot;&gt;acTextBox&lt;/strong&gt; – The type of control to create (in this case, a TextBox).&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;706&quot; data-start=&quot;600&quot;&gt;
&lt;p data-end=&quot;706&quot; data-start=&quot;603&quot;&gt;&lt;strong data-end=&quot;615&quot; data-start=&quot;603&quot;&gt;acDetail&lt;/strong&gt; – The section of the Report where the control will be placed (the Detail section).&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;794&quot; data-start=&quot;707&quot;&gt;
&lt;p data-end=&quot;794&quot; data-start=&quot;710&quot;&gt;&lt;strong data-end=&quot;720&quot; data-start=&quot;710&quot;&gt;Parent&lt;/strong&gt; – Used if the control belongs to a SubReport (omitted in this example).&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;862&quot; data-start=&quot;795&quot;&gt;
&lt;p data-end=&quot;862&quot; data-start=&quot;798&quot;&gt;&lt;strong data-end=&quot;812&quot; data-start=&quot;798&quot;&gt;FldList(j)&lt;/strong&gt; – The name of the field to bind to the TextBox.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;918&quot; data-start=&quot;863&quot;&gt;
&lt;p data-end=&quot;918&quot; data-start=&quot;866&quot;&gt;&lt;strong data-end=&quot;880&quot; data-start=&quot;866&quot;&gt;lngTxtLeft&lt;/strong&gt; – The Left position of the control.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;972&quot; data-start=&quot;919&quot;&gt;
&lt;p data-end=&quot;972&quot; data-start=&quot;922&quot;&gt;&lt;strong data-end=&quot;935&quot; data-start=&quot;922&quot;&gt;lngTxtTop&lt;/strong&gt; – The Top position of the control.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1021&quot; data-start=&quot;973&quot;&gt;
&lt;p data-end=&quot;1021&quot; data-start=&quot;976&quot;&gt;&lt;strong data-end=&quot;991&quot; data-start=&quot;976&quot;&gt;lngTxtWidth&lt;/strong&gt; – The Width of the control.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1072&quot; data-start=&quot;1022&quot;&gt;
&lt;p data-end=&quot;1072&quot; data-start=&quot;1025&quot;&gt;&lt;strong data-end=&quot;1041&quot; data-start=&quot;1025&quot;&gt;lngTxtHeight&lt;/strong&gt; – The Height of the control.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;



&lt;/p&gt;&lt;p data-end=&quot;1225&quot; data-start=&quot;1074&quot;&gt;All these values must be predefined before calling the &lt;code data-end=&quot;1152&quot; data-start=&quot;1129&quot;&gt;CreateReportControl()&lt;/code&gt; function to ensure the control is created with the correct properties.&lt;/p&gt;&lt;p data-end=&quot;268&quot; data-start=&quot;115&quot;&gt;After the TextBox control is created, its &lt;span data-end=&quot;186&quot; data-start=&quot;157&quot;&gt;Font and Color attributes&lt;/span&gt; (such as &lt;code data-end=&quot;206&quot; data-start=&quot;196&quot;&gt;FontName&lt;/code&gt;, &lt;code data-end=&quot;218&quot; data-start=&quot;208&quot;&gt;FontSize&lt;/code&gt;, and &lt;code data-end=&quot;235&quot; data-start=&quot;224&quot;&gt;ForeColor&lt;/code&gt;) are applied programmatically.&lt;/p&gt;&lt;p data-end=&quot;372&quot; data-start=&quot;270&quot;&gt;Next, the TextBox’s &lt;span data-end=&quot;313&quot; data-start=&quot;290&quot;&gt;child Label control&lt;/span&gt; is created in the Report&amp;nbsp;&lt;span data-end=&quot;355&quot; data-start=&quot;332&quot;&gt;Page Header section.&lt;/span&gt;&lt;/p&gt;&lt;ul data-end=&quot;650&quot; data-start=&quot;374&quot;&gt;
&lt;li data-end=&quot;521&quot; data-start=&quot;374&quot;&gt;
&lt;p data-end=&quot;521&quot; data-start=&quot;376&quot;&gt;In a &lt;span data-end=&quot;405&quot; data-start=&quot;381&quot;&gt;Column-Format Report&lt;/span&gt;, however, the Label control is placed in the &lt;span data-end=&quot;469&quot; data-start=&quot;451&quot;&gt;Detail section&lt;/span&gt;, positioned to the &lt;span data-end=&quot;502&quot; data-start=&quot;489&quot;&gt;left side&lt;/span&gt; of each TextBox.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;650&quot; data-start=&quot;522&quot;&gt;
&lt;p data-end=&quot;650&quot; data-start=&quot;524&quot;&gt;While creating the TextBox in this layout, enough horizontal space is reserved on the left to accommodate the Label control.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;


&lt;/p&gt;&lt;p data-end=&quot;798&quot; data-start=&quot;652&quot;&gt;This ensures that field names (labels) and their corresponding values (Textboxes) are neatly aligned and visually clear in the generated Report.&lt;/p&gt;
&lt;pre&gt;Public Function Tabular(ByVal DataSource As String)

Dim cdb As Database
Dim FldList() As String
Dim Ctrl As Control
Dim Rpt As Report
Dim PgSection As Section
Dim DetSection As Section

Dim lngTxtLeft As Long
Dim lngTxtTop As Long
Dim lngTxtHeight As Long
Dim lngtxtwidth As Long

Dim lngLblLeft As Long
Dim lngLblTop As Long
Dim lngLblHeight As Long
Dim lngLblWidth As Long

Dim FldCheck As Boolean
Dim strTblQry As String
Dim intflds As Integer
Dim lstcount As Long
Dim RptFields As ListBox
Dim j As Integer

&#39;Create Report with Selected Fields

On Error Resume Next
strFile = DataSource

Set RptFields = fom.SelList
lstcount = RptFields.listcount

If lstcount = 0 Then
   MsgBox &quot;Fields Not Selected for Report!&quot;
   Exit Function
Else
   lstcount = lstcount - 1
End If

ReDim FldList(0 To lstcount) As String

Set cdb = CurrentDb&lt;/pre&gt;&lt;pre&gt;&#39;Create Report Object
Set Rpt = CreateReport
Set PgSection = Rpt.Section(acPageHeader)
    PgSection.Height = 0.6667 * twips

Set DetSection = Rpt.Section(acDetail)
    DetSection.Height = 0.1667 * twips

For j = 0 To lstcount
  FldList(j) = RptFields.ItemData(j)
Next

With Rpt
    .Caption = strFile
    .RecordSource = strFile
    
    lngtxtwidth = 0.5 * twips
    lngTxtLeft = 0.073 * twips
    lngTxtTop = 0
    lngTxtHeight = 0.1668 * twips

    lngLblWidth = lngtxtwidth
    lngLblLeft = lngTxtLeft
    lngLblTop = 0.5 * twips
    lngLblHeight = lngTxtHeight
End With

For j = 0 To lstcount
   Set Ctrl = CreateReportControl(Rpt.Name, acTextBox, _
   acDetail, , FldList(j), lngTxtLeft, lngTxtTop, lngtxtwidth, lngTxtHeight)
    With Ctrl
       .ControlSource = FldList(j)
       .ForeColor = DarkBlue
       .BorderColor = DarkBlue
       .BorderStyle = 1
       .Name = FldList(j)
       lngTxtLeft = lngTxtLeft + (0.5 * twips)
    End With
   
   Set Ctrl = CreateReportControl(Rpt.Name, acLabel, _
   acPageHeader, , FldList(j), lngLblLeft, lngLblTop, lngLblWidth, lngLblHeight)
   
    With Ctrl
       .Caption = FldList(j)
       .Name = FldList(j) &amp;amp; &quot; Label&quot;
       .Width = (0.5 * twips)
       .ForeColor = DarkBlue
       .BorderColor = DarkBlue
       .BorderColor = 0
       .BorderStyle = 1
       .FontWeight = 700 &#39; Bold
       lngLblLeft = lngLblLeft + (0.5 * twips)
    End With
Next

lngLblWidth = 4.5 * twips
lngLblLeft = 0.073 * twips
lngLblTop = 0.0521 * twips
lngLblHeight = 0.323 &amp;amp; twips
lngLblWidth = 4.5 &amp;amp; twips
 Set Ctrl = CreateReportControl(Rpt.Name, acLabel, acPageHeader, , &quot;Head1&quot;, lngLblLeft, lngLblTop, lngLblWidth, lngLblHeight)
   With Ctrl
        .Caption = strFile
        .TextAlign = 2
        .Width = 4.5 * twips
        .Height = 0.38 * twips
        .ForeColor = DarkBlue
        .BorderStyle = 0
        .BorderColor = DarkBlue
        .FontName = &quot;Times New Roman&quot;
        .FontSize = 16
        .FontWeight = 700 &#39; Bold
        .FontItalic = True
        .FontUnderline = True
   End With
On Error GoTo Tabular_Err

Page_Footer Rpt

DoCmd.OpenReport Rpt.Name, acViewPreview

Tabular_Exit:
Exit Function

Tabular_Err:
MsgBox Err.Description, , &quot;Tabular&quot;
Resume Tabular_Exit
End Function
&lt;/pre&gt;
&lt;h3&gt;The Page_Footer() Function Code.&lt;/h3&gt;
&lt;p&gt;This Function is called by both the Column and Tabular Wizards to create the Date and Page Numbers in the Report PageFooter Section. &lt;/p&gt;
&lt;pre&gt;Public Function Page_Footer(ByRef obj)
Dim lngWidth As Long, ctrwidth As Long, ctrlCount As Long
Dim j As Long, cdb As Database
Dim lngleft As Long, lngtop As Long, LineCtrl As Control, Ctrl As Control
Dim rptSection As Section, leftmost As Long, lngheight As Long
Dim rightmost As Long, RightIndx As Integer
&#39;
&#39;Note : The Controls appearing in Detail Section from left to Right
&#39;       is not indexed 0 to nn in the order of placing,
&#39;       instead 1st control placed in the Section has index value 0
&#39;       irrespective of its current position.
&#39;
On Error GoTo Page_Footer_Err

Set cdb = CurrentDb
Set rptSection = obj.Section(acDetail)

ctrlCount = rptSection.Controls.Count - 1

lngleft = rptSection.Controls(0).Left
rightmost = rptSection.Controls(0).Left

&#39;indexed 0 control may not be the leftmost control on the Form/Report
&#39;so find the leftmost control&#39;s left value
For j = 0 To ctrlCount
 leftmost = rptSection.Controls(j).Left
 
 If leftmost &amp;lt; lngleft Then
   lngleft = leftmost
 End If
 If leftmost &amp;gt; rightmost Then
   rightmost = leftmost
   RightIndx = j
 End If
Next
 
lngtop = 0.0208 * 1440
lngWidth = 0: ctrwidth = 0

   lngWidth = rightmost + rptSection.Controls(RightIndx).Width
   lngWidth = lngWidth - lngleft
   
  Set LineCtrl = CreateReportControl(obj.Name, acLine, acPageFooter, &quot;&quot;, &quot;&quot;, lngleft, lngtop, lngWidth, 0)
  Set Ctrl = LineCtrl
  LineCtrl.BorderColor = 12632256
  LineCtrl.BorderWidth = 2
  LineCtrl.Name = &quot;ULINE&quot;
  
lngtop = 0.0418 * 1440
lngleft = LineCtrl.Left
lngWidth = 2 * 1440
lngheight = 0.229 * 1440

&#39;draw Page No control at the Report footer
Set LineCtrl = CreateReportControl(obj.Name, acTextBox, acPageFooter, &quot;&quot;, &quot;&quot;, lngleft, lngtop, lngWidth, lngheight)
With LineCtrl
   .ControlSource = &quot;=&#39;Page : &#39; &amp;amp; [page] &amp;amp; &#39; / &#39; &amp;amp; [pages]&quot;
   .Name = &quot;PageNo&quot;
   .FontName = &quot;Arial&quot;
   .FontSize = 10
   .FontWeight = 700
   .TextAlign = 1
End With
&#39;draw Date Control at the right edge of the Line Control
&#39;calculate left position of Date control

lngleft = (LineCtrl.Left + Ctrl.Width) - lngWidth
Set LineCtrl = CreateReportControl(obj.Name, acTextBox, acPageFooter, &quot;&quot;, &quot;&quot;, lngleft, lngtop, lngWidth, lngheight)
With LineCtrl
   .ControlSource = &quot;=&#39;Date : &#39; &amp;amp; Format(Date(),&#39;dd/mm/yyyy&#39;)&quot;
   .Name = &quot;Dated&quot;
   .FontName = &quot;Arial&quot;
   .FontSize = 10
   .FontWeight = 700
   .TextAlign = 3
End With

Page_Footer_Exit:
Exit Function

Page_Footer_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, &quot;Page_Footer()&quot;
Resume Page_Footer_Exit
End Function
&lt;/pre&gt;
&lt;p data-end=&quot;241&quot; data-start=&quot;79&quot;&gt;Several &lt;span data-end=&quot;106&quot; data-start=&quot;87&quot;&gt;Command Buttons&lt;/span&gt; are placed on both pages of the TabControl, and all their event subroutines are handled within the &lt;span data-end=&quot;224&quot; data-start=&quot;206&quot;&gt;RWiz_CmdButton&lt;/span&gt; Wrapper Class.&lt;/p&gt;&lt;p data-end=&quot;576&quot; data-start=&quot;243&quot;&gt;On the second page, there is a &lt;span data-end=&quot;284&quot; data-start=&quot;274&quot;&gt;Finish&lt;/span&gt; button (&lt;code data-end=&quot;304&quot; data-start=&quot;293&quot;&gt;cmdReport&lt;/code&gt;) that triggers the Report Wizard’s main functions. Since all Wizard-related functions reside in the &lt;span data-end=&quot;423&quot; data-start=&quot;405&quot;&gt;WizObject_Init&lt;/span&gt; Class Module, a &lt;span data-end=&quot;476&quot; data-start=&quot;440&quot;&gt;separate Command Button instance&lt;/span&gt; (&lt;code data-end=&quot;489&quot; data-start=&quot;478&quot;&gt;cmdFinish&lt;/code&gt;) is explicitly defined in that module to handle the &lt;code data-end=&quot;553&quot; data-start=&quot;542&quot;&gt;cmdReport&lt;/code&gt; button’s operations.&lt;/p&gt;&lt;p&gt;

&lt;/p&gt;&lt;p data-end=&quot;848&quot; data-start=&quot;578&quot;&gt;Unlike the other &lt;a href=&quot;https://www.msaccesstips.com/2008/03/double-action-command-button.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; instances, the &lt;code data-end=&quot;636&quot; data-start=&quot;625&quot;&gt;cmdFinish&lt;/code&gt; instance is &lt;span data-end=&quot;687&quot; data-start=&quot;649&quot;&gt;not added to the Collection object&lt;/span&gt; after its &lt;code data-end=&quot;707&quot; data-start=&quot;698&quot;&gt;OnClick&lt;/code&gt; event is enabled. This ensures that its functionality remains isolated and directly tied to the Report Wizard’s core procedures.&lt;/p&gt;&lt;p&gt;The &lt;span data-end=&quot;147&quot; data-start=&quot;121&quot;&gt;Click event subroutine&lt;/span&gt; for this Command Button is implemented in the &lt;span data-end=&quot;212&quot; data-start=&quot;194&quot;&gt;WizObject_Init&lt;/span&gt; Class Module, allowing the Report Wizard functions to be called directly from within the module.&lt;/p&gt;
&lt;p data-end=&quot;621&quot; data-start=&quot;313&quot;&gt;At the start of the &lt;span data-end=&quot;349&quot; data-start=&quot;333&quot;&gt;Class_Init()&lt;/span&gt; subroutine, the &lt;span data-end=&quot;388&quot; data-start=&quot;366&quot;&gt;Create_FilesList()&lt;/span&gt; function is executed to generate the ComboBox’s source list of tables and select queries. This is followed by creating the ListBox and Command Button instances, enabling their events, and adding them to the &lt;a href=&quot;https://www.msaccesstips.com/2018/12/ms-access-and-collection-object-basics.html&quot; target=&quot;_blank&quot;&gt;Collection&lt;/a&gt; object.&lt;/p&gt;
&lt;p data-end=&quot;841&quot; data-start=&quot;623&quot;&gt;When the &lt;span data-end=&quot;645&quot; data-start=&quot;632&quot;&gt;cmdReport&lt;/span&gt; button is clicked, it calls the &lt;span data-end=&quot;706&quot; data-start=&quot;678&quot;&gt;Report Creation Function&lt;/span&gt;. Although the &lt;span data-end=&quot;745&quot; data-start=&quot;721&quot;&gt;Column Format Report&lt;/span&gt; is less commonly used, it remains useful for specialized purposes such as &lt;span data-end=&quot;838&quot; data-start=&quot;820&quot;&gt;label printing&lt;/span&gt;.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The RWiz_CmdButton Class Module.&lt;/h3&gt;&lt;p&gt;This Wrapper Class Module of CommandButton Object contains the following Command Button Click Event Subroutines.&lt;/p&gt;&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents cmd As CommandButton
Private frm As Form
Dim DarkBlue As Long, twips As Long, xtyp As Integer, strFile As String

Public Property Get w_Frm() As Form
    Set w_Frm = frm
End Property

Public Property Set w_Frm(ByRef wFrm As Form)
    Set frm = wFrm
End Property

Public Property Get w_cmd() As CommandButton
    Set w_cmd = cmd
End Property

Public Property Set w_cmd(ByRef wcmd As CommandButton)
    Set cmd = wcmd
End Property

Private Sub cmd_Click()
Dim lblInfo As String

  Select Case cmd.Name

    Case &quot;cmdCancel2&quot;
        DoCmd.Close acForm, frm.Name
               
    Case &quot;cmdNext&quot;
    If frm.SelList.listcount = 0 Then
        frm.cmdReport.Enabled = False
    Else
        frm.cmdReport.Enabled = True
    End If
    
  &#39;Display the Wizard selection along with
  &#39;the Table/Query selected in a Label Control
  &#39;In the 2nd Page when the User Clicks
  &#39;the cmdNext Command Button to display
  &#39;the 2nd Page of the Wizard.
    lblInfo = &quot;Table/Query: &quot; &amp;amp; frm!FilesList
    If frm!WizList = 1 Then
        lblInfo = lblInfo &amp;amp; &quot; - Column Report.&quot;
    Else
        lblInfo = lblInfo &amp;amp; &quot; - Tabular Report.&quot;
    End If
    frm!info.Caption = lblInfo
    
 &#39;Create the field List of the selected Table
 &#39;and display them in the 1st ListBox on the
 &#39;2nd Page of the Report Wizard.
       Call SelectTable
       
    Case &quot;cmdCancel&quot;
        DoCmd.Close acForm, frm.Name
        
    Case &quot;cmdRight&quot;
&#39;Move the selected field to the Right=side ListBox.
&#39;Multiselect option not given
        RightAll 1

    Case &quot;cmdRightAll&quot;
&#39;Option Number Moves all the fields from
&#39;Left side ListBox to the Right-side ListBox
        RightAll 2

    Case &quot;cmdLeft&quot;
        LeftAll 1
        
    Case &quot;cmdLeftAll&quot;
        LeftAll 2
    
    Case &quot;cmdBack&quot;
    &#39;Go back to first Page. cancels the 2nd Page selections.
        frm.SelList.RowSource = &quot;&quot; &#39;Empty Selected field list
        frm.FilesList.RowSource = &quot;WizQuery&quot;
        frm.Page1.Visible = True
        frm.Page1.SetFocus
        frm.Page2.Visible = False
               
End Select
End Sub

Private Sub SelectTable()
Dim vizlist As ListBox
Dim lcount As Integer
Dim chkflag As Boolean
Dim FildList As ListBox
Dim strName As String
Dim strRSource As String
Dim cdb As DAO.Database
Dim doc As Document
Dim Tbl As DAO.TableDef
Dim Qry As DAO.QueryDef
Dim QryTyp As Integer
Dim FieldCount As Integer
Dim flag As Byte
Dim j As Integer

Set vizlist = frm.WizList
lcount = vizlist.listcount - 1

chkflag = False
For j = 0 To lcount
  If vizlist.Selected(j) = True Then
    xtyp = j + 1
    chkflag = True
  End If
Next

If IsNull(frm![FilesList]) = True Then
   MsgBox &quot;Select a File from Table/Query List.&quot;, vbOKOnly + vbExclamation, &quot;cmdNext&quot;
   frm.WizList.Selected(0) = True
Else
   strFile = frm.FilesList
   frm.Page2.Visible = True
   frm.Page2.SetFocus
   frm.Page1.Visible = False
   
Set cdb = CurrentDb
flag = 0
For Each Tbl In cdb.TableDefs
    If Tbl.Name = strFile Then
       flag = 1
    End If
Next
For Each Qry In cdb.QueryDefs
    If Qry.Name = strFile Then
       flag = 2
    End If
Next
If flag = 1 Then
    Set Tbl = cdb.TableDefs(strFile)
    Set FildList = frm.FldList
    strRSource = &quot;&quot;
    FieldCount = Tbl.Fields.Count - 1
    For j = 0 To FieldCount
        If Len(strRSource) = 0 Then
            strRSource = Tbl.Fields(j).Name
        Else
            strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; Tbl.Fields(j).Name
        End If
    Next
ElseIf flag = 2 Then
    Set Qry = cdb.QueryDefs(strFile)
    strRSource = &quot;&quot;
    FieldCount = Qry.Fields.Count - 1
    For j = 0 To FieldCount
        If Len(strRSource) = 0 Then
            strRSource = Qry.Fields(j).Name
        Else
            strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; Qry.Fields(j).Name
        End If
    Next
End If

frm.FldList.RowSource = strRSource
frm.FldList.Requery
End If

End Sub

Private Function RightAll(ByVal SelectionType As Integer)
Dim FldList As ListBox, SelctList As ListBox, strRSource As String
Dim listcount As Long, j As Long, strRS2 As String

&#39;On Error GoTo RightAll_Err
If SelectionType = 0 Then
   Exit Function
End If
Set FldList = Forms(&quot;ReportWizard&quot;).FldList
Set SelctList = Forms(&quot;ReportWizard&quot;).SelList

listcount = FldList.listcount - 1
strRSource = SelctList.RowSource: strRS2 = &quot;&quot;

Select Case SelectionType
    Case 1
        For j = 0 To listcount
            If FldList.Selected(j) = True Then
                If Len(strRSource) = 0 Then
                    strRSource = FldList.ItemData(j)
                Else
                    strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; FldList.ItemData(j)
                End If
            Else
                If Len(strRS2) = 0 Then
                    strRS2 = FldList.ItemData(j)
                Else
                    strRS2 = strRS2 &amp;amp; &quot;;&quot; &amp;amp; FldList.ItemData(j)
                End If
            End If
        Next
        SelctList.RowSource = strRSource
        FldList.RowSource = strRS2
        SelctList.Requery
        FldList.Requery
    frm.cmdReport.Enabled = True
    Case 2

        For j = 0 To listcount
            If Len(strRSource) = 0 Then
                strRSource = FldList.ItemData(j)
            Else
                strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; FldList.ItemData(j)
            End If
        Next
        SelctList.RowSource = strRSource
        FldList.RowSource = &quot;&quot;
        SelctList.Requery
        FldList.Requery
        frm.cmdCancel2.SetFocus
    If SelctList.listcount = 0 Then
        frm.cmdReport.Enabled = False
    End If
End Select
frm.cmdReport.Enabled = True

RightAll_Exit:
Exit Function

RightAll_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;RightAll&quot;
Resume RightAll_Exit
End Function

Private Function LeftAll(ByVal SelectionType As Integer)
Dim FldList As ListBox, SelctList As ListBox, strRSource As String
Dim listcount As Long, j As Long, strRS2 As String

On Error GoTo LeftAll_Err

If SelectionType = 0 Then
   Exit Function
   
End If

Set FldList = Forms(&quot;ReportWizard&quot;).FldList
Set SelctList = Forms(&quot;ReportWizard&quot;).SelList

listcount = SelctList.listcount - 1
strRSource = FldList.RowSource: strRS2 = &quot;&quot;

Select Case SelectionType
    Case 1
        For j = 0 To listcount
            If SelctList.Selected(j) = True Then
                If Len(strRSource) = 0 Then
                    strRSource = SelctList.ItemData(j)
                Else
                    strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; SelctList.ItemData(j)
                End If
            Else
                If Len(strRS2) = 0 Then
                    strRS2 = SelctList.ItemData(j)
                Else
                    strRS2 = strRS2 &amp;amp; &quot;;&quot; &amp;amp; SelctList.ItemData(j)
                End If
            End If
        Next
        SelctList.RowSource = strRS2
        FldList.RowSource = strRSource
        SelctList.Requery
        FldList.Requery
    If SelctList.listcount = 0 Then
        frm.cmdReport.Enabled = False
    End If
    Case 2
        For j = 0 To listcount
            If Len(strRSource) = 0 Then
                strRSource = SelctList.ItemData(j)
            Else
                strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; SelctList.ItemData(j)
            End If
        Next
        SelctList.RowSource = &quot;&quot;
        FldList.RowSource = strRSource
        SelctList.Requery
        FldList.Requery
    If SelctList.listcount = 0 Then
        frm.cmdReport.Enabled = False
    End If
End Select
LeftAll_Exit:
Exit Function

LeftAll_Err:
MsgBox Err.Description, , &quot;LeftAll&quot;
Resume LeftAll_Exit

End Function

&lt;/pre&gt;
&lt;p data-end=&quot;294&quot; data-start=&quot;127&quot;&gt;On the &lt;span data-end=&quot;170&quot; data-start=&quot;134&quot;&gt;second page of the Report Wizard&lt;/span&gt;, a set of &lt;span data-end=&quot;205&quot; data-start=&quot;181&quot;&gt;four Command Buttons&lt;/span&gt;&amp;nbsp;is positioned between the two ListBox controls for the field selection and removal process:&lt;/p&gt;&lt;ol data-end=&quot;810&quot; data-start=&quot;296&quot;&gt;
&lt;li data-end=&quot;433&quot; data-start=&quot;296&quot;&gt;
&lt;p data-end=&quot;433&quot; data-start=&quot;299&quot;&gt;&lt;strong data-end=&quot;326&quot; data-start=&quot;299&quot;&gt;Single Field Move ( &amp;gt; )&lt;/strong&gt; – Moves the currently selected field from the first ListBox to the second ListBox (one field at a time).&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;556&quot; data-start=&quot;434&quot;&gt;
&lt;p data-end=&quot;556&quot; data-start=&quot;437&quot;&gt;&lt;strong data-end=&quot;463&quot; data-start=&quot;437&quot;&gt;Move All Fields ( &amp;gt;&amp;gt; )&lt;/strong&gt; – Transfers all fields from the first ListBox to the second ListBox in a single operation.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;685&quot; data-start=&quot;557&quot;&gt;
&lt;p data-end=&quot;685&quot; data-start=&quot;560&quot;&gt;&lt;strong data-end=&quot;589&quot; data-start=&quot;560&quot;&gt;Remove Single Field ( &amp;lt; )&lt;/strong&gt; – Removes the selected field from the second ListBox and places it back in the first ListBox.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;810&quot; data-start=&quot;686&quot;&gt;
&lt;p data-end=&quot;810&quot; data-start=&quot;689&quot;&gt;&lt;strong data-end=&quot;717&quot; data-start=&quot;689&quot;&gt;Remove All Fields ( &amp;lt;&amp;lt; )&lt;/strong&gt; – Clears all items from the second ListBox and restores them back to the first ListBox at once.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;

&lt;/p&gt;&lt;p data-end=&quot;960&quot; data-start=&quot;812&quot;&gt;Additionally, the &lt;span data-end=&quot;853&quot; data-start=&quot;830&quot;&gt;Back Command Button&lt;/span&gt; clears all fields from the second ListBox and navigates back to the &lt;span data-end=&quot;957&quot; data-start=&quot;922&quot;&gt;first page of the Report Wizard&lt;/span&gt;.&lt;/p&gt;
&lt;h3&gt;The RWiz_Combo Class Module Code &lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private cbofrm As Access.Form
Private WithEvents cbo As Access.ComboBox &#39;ComboBox object

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;ComboBox Wrapper Class
&#39;Author: a.p.r. pillai
&#39;Date  : 20/10/2023
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

&#39;Form&#39;s Property GET/SET Procedures
Public Property Get cbo_Frm() As Form
    Set cbo_Frm = cbofrm
End Property

Public Property Set cbo_Frm(ByRef cfrm As Form)
    Set cbofrm = cfrm
End Property

&#39;TextBox Property GET/SET Procedures
Public Property Get c_cbo() As ComboBox
    Set c_cbo = cbo
End Property

Public Property Set c_cbo(ByRef pcbo As ComboBox)
    Set cbo = pcbo
End Property

Private Sub cbo_Click()
        cbofrm!FileList = Null

        cbofrm.TabCtl0.Pages(0).Visible = True
        cbofrm.TabCtl0.Pages(0).SetFocus
        cbofrm.TabCtl0.Pages(1).Visible = False
        cbofrm.TabCtl0.Pages(1).SetFocus
End Sub

Private Sub cbo_GotFocus()
    GFColor cbofrm, cbo
End Sub

Private Sub cbo_LostFocus()
    LFColor cbofrm, cbo
End Sub
&lt;/pre&gt;
&lt;h3&gt;The RWiz_ListBox Class Module Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private lstfrm As Access.Form
Private WithEvents lst As Access.ListBox

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;ListBox Wrapper Class
&#39;Author: a.p.r. pillai
&#39;Date  : 20/10/2023
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

&#39;Form&#39;s Property GET/SET Procedures
Public Property Get lst_Frm() As Form
    Set lst_Frm = lstfrm
End Property

Public Property Set lst_Frm(ByRef mFrm As Form)
    Set lstfrm = mFrm
End Property

&#39;TextBox Property GET/SET Procedures
Public Property Get m_lst() As ListBox
    Set m_lst = lst
End Property

Public Property Set m_lst(ByRef mLst As ListBox)
    Set lst = mLst
End Property

Private Sub lst_Click()
Dim i As Integer

Select Case lst.Name
    Case &quot;WizList&quot;
        &#39;Code
    Case &quot;FldList&quot;
        &#39;Code
    Case &quot;SelList&quot;
        &#39;Code
End Select

End Sub

Private Sub lst_GotFocus()
    GFColor lstfrm, lst
End Sub

Private Sub lst_LostFocus()
    LFColor lstfrm, lst
End Sub
&lt;/pre&gt;
&lt;p&gt;The ListBox and ComboBox Class Module Subroutine Code highlights the Control, when these controls receive Focus.&lt;/p&gt;
&lt;h3&gt;The RWiz_TabCtl Class Module Code. &lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private tbFrm As Form
Private WithEvents tb As TabControl

&#39;------------------------------------------------------
&#39;Streamlining Form Module Code
&#39;in Stand-alone Class Modules
&#39;------------------------------------------------------
&#39;Tab Control Events
&#39;Author: a.p.r. pillai
&#39;Date  : 20/10/2023
&#39;Rights: All Rights(c) Reserved by www.msaccesstips.com
&#39;------------------------------------------------------

Public Property Get Tb_Frm() As Form
    Set Tb_Frm = tbFrm
End Property

Public Property Set Tb_Frm(ByRef mFrm As Form)
    Set tbFrm = mFrm
End Property

Public Property Get Tb_Tab() As TabControl
    Set Tb_Tab = tb
End Property

Public Property Set Tb_Tab(ByRef mTab As TabControl)
    Set tb = mTab
End Property

Private Sub tb_Change()
Select Case tb.Value
    Case 0
        &#39;MsgBox &quot;Change Event: TabCtl.Page(0)&quot;
    Case 1
        &#39;MsgBox &quot;Change Event: TabCtl.Page(1)&quot;
End Select
        
End Sub
&lt;/pre&gt;
&lt;p data-end=&quot;271&quot; data-start=&quot;64&quot;&gt;The &lt;span data-end=&quot;92&quot; data-start=&quot;68&quot;&gt;Wrapper Class Module&lt;/span&gt; also includes the &lt;code data-end=&quot;129&quot; data-start=&quot;111&quot;&gt;TabPage_Change()&lt;/code&gt; Event. This was added primarily for completeness, but in the current implementation, it is &lt;span data-end=&quot;268&quot; data-start=&quot;221&quot;&gt;not utilized for any specific functionality&lt;/span&gt;.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Download the Demo Database from the Link given below.&lt;/h3&gt;
&lt;!--Download Link /downloads/2023/10/ReportWizard.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1J4hsQXrXZp50AEzklxLSVN2z3yJrdHnz/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;ReportWizard.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2023/10/ReportWizard.zip--&gt;

&lt;br /&gt;
&lt;h3&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/1898596109883545524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/1898596109883545524'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/1898596109883545524'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html' title='New Custom-Made Report Wizard - Part 16'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX9o4TKvhqttg_Q72ZSo6qm3h-1yKfDpYgwwnMYhU_NBya0yB7l83o7qYUwtymrvrKs1rEw51Ric_yi7fhl7Zzw1w7zUbsTZvPQcmeN7f2Y9ot_dyttqyZJwy2fFy48DHm81_33QfmJwuxEhI_PW9DguDpPX7_MQwnWIxR1Z8G-KSa4DyhBC2hKUMbbWit/s72-c/ReportWizard1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-7189331229920223403</id><published>2023-10-09T14:52:00.012+05:30</published><updated>2026-07-10T22:42:42.019+05:30</updated><title type='text'>New Custom Made Form Wizard VBA - Part 15</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Streamlined Custom-Made Form Wizard.&lt;/h3&gt;&lt;p data-end=&quot;245&quot; data-start=&quot;53&quot;&gt;This blog post was originally &lt;a href=&quot;https://www.msaccesstips.com/2008/12/custom-made-form-wizard.html&quot; target=&quot;_blank&quot;&gt;published in &lt;span data-end=&quot;113&quot; data-start=&quot;96&quot;&gt;December 2008&lt;/span&gt;&lt;/a&gt; under &lt;span data-end=&quot;135&quot; data-start=&quot;120&quot;&gt;Access 2003&lt;/span&gt; and has now been updated to demonstrate the streamlined VBA coding approach using standalone Class Modules.&lt;/p&gt;&lt;p data-end=&quot;452&quot; data-start=&quot;247&quot;&gt;The Form Wizard in Access can generate two types of forms: &lt;span data-end=&quot;323&quot; data-start=&quot;306&quot;&gt;Column Format&lt;/span&gt; and &lt;span data-end=&quot;346&quot; data-start=&quot;328&quot;&gt;Tabular Format&lt;/span&gt;. But why create a &lt;span data-end=&quot;387&quot; data-start=&quot;365&quot;&gt;custom Form Wizard&lt;/span&gt; when Access already includes built-in Form and Report Wizards?&lt;/p&gt;&lt;p data-end=&quot;749&quot; data-start=&quot;454&quot;&gt;My curiosity was sparked by the techniques employed in the built-in Form/Report Wizards. Moreover,&amp;nbsp;&lt;span style=&quot;box-sizing: border-box; margin: 0px; padding: 0px;&quot;&gt;the ability to create&amp;nbsp;tabular forms with fixed-length fields&amp;nbsp;is&amp;nbsp;&lt;/span&gt;handy for customization, particularly when working with a wide range of columns in an Access form or report.&lt;/p&gt;&lt;p&gt;


&lt;/p&gt;&lt;p data-end=&quot;842&quot; data-start=&quot;751&quot;&gt;The custom Form Wizard itself is designed with a &lt;span data-end=&quot;814&quot; data-start=&quot;800&quot;&gt;TabControl&lt;/span&gt; containing &lt;span data-end=&quot;839&quot; data-start=&quot;826&quot;&gt;two pages&lt;/span&gt;.&lt;/p&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The First Page of the Wizard.&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYb7rWqv41TI2zOps5jk8Fs7f9M3bbjn1w8FOLV1rKi8eTPx2YjJXIXmu-lj7xZ7W03Eh7lHs7psrlO-11ubeIKij6YAbG-huUeea-pxYsSjNqZ83QL5pV7rReq3YdnKdUE3Rq_1lh51PwAqvYFXh2ybTU7sltiyjNftKGwFLx27oBkdXNyFCJA9JV8qk0/s693/FormWizard1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;689&quot; data-original-width=&quot;693&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYb7rWqv41TI2zOps5jk8Fs7f9M3bbjn1w8FOLV1rKi8eTPx2YjJXIXmu-lj7xZ7W03Eh7lHs7psrlO-11ubeIKij6YAbG-huUeea-pxYsSjNqZ83QL5pV7rReq3YdnKdUE3Rq_1lh51PwAqvYFXh2ybTU7sltiyjNftKGwFLx27oBkdXNyFCJA9JV8qk0/s320/FormWizard1.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p data-end=&quot;218&quot; data-start=&quot;83&quot;&gt;At the top of the Form Wizard, a &lt;span data-end=&quot;127&quot; data-start=&quot;116&quot;&gt;ListBox&lt;/span&gt; allows you to select the &lt;span data-end=&quot;168&quot; data-start=&quot;153&quot;&gt;Wizard Type&lt;/span&gt;—either &lt;span data-end=&quot;193&quot; data-start=&quot;176&quot;&gt;Column Format&lt;/span&gt; or &lt;span data-end=&quot;215&quot; data-start=&quot;197&quot;&gt;Tabular Format&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;452&quot; data-start=&quot;220&quot;&gt;Just below it, a &lt;span data-end=&quot;249&quot; data-start=&quot;237&quot;&gt;&lt;a href=&quot;https://www.msaccesstips.com/2009/09/dynamic-listbox-combobox-contents.html&quot; target=&quot;_blank&quot;&gt;ComboBox&lt;/a&gt;&lt;/span&gt; displays a list of available &lt;span data-end=&quot;289&quot; data-start=&quot;279&quot;&gt;Tables&lt;/span&gt; and &lt;span data-end=&quot;305&quot; data-start=&quot;294&quot;&gt;Queries&lt;/span&gt;, retrieved from the database system tables through a query. These names are then added to the ComboBox as the &lt;span data-end=&quot;414&quot; data-start=&quot;400&quot;&gt;Row Source.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The Query SQL is given below.&lt;/p&gt;&lt;pre&gt;SELECT MSysObjects.Name
FROM MSysObjects
WHERE (((MSysObjects.Type)=1 Or (MSysObjects.Type)=5) AND ((Left([Name],4))&amp;lt;&amp;gt;&#39;WizQ&#39;) AND ((Left([Name],1))&amp;lt;&amp;gt;&#39;~&#39;) AND ((MSysObjects.Flags)=0))
ORDER BY MSysObjects.Type, MSysObjects.Name;
&amp;nbsp;&lt;/pre&gt;&lt;p&gt;The options shown as selected in both the &lt;span data-end=&quot;132&quot; data-start=&quot;121&quot;&gt;ListBox&lt;/span&gt; and &lt;span data-end=&quot;149&quot; data-start=&quot;137&quot;&gt;ComboBox&lt;/span&gt; are set as defaults. However, you can change these selections before moving to the next step by clicking the &lt;span data-end=&quot;267&quot; data-start=&quot;259&quot;&gt;Next&lt;/span&gt; &lt;a href=&quot;https://www.msaccesstips.com/2011/06/creating-animated-command-button-with.html&quot; target=&quot;_blank&quot;&gt;command button&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The Second Wizard Page Image.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicfqWimjs7fir8xqRm9cwiUOVPRltgA8G7oyrjGsnTHz4E1-WIUL9JUgVHB-prylBztd7aTs0jTkzGd2bhpiA2-E2o0Nk_Ao5Ed_DBKZviwANKineftvjzE9Ujk6ZNx9FBkaBlTdO4Gc5w4XKBokTy4wr4TIAcp5VvyhkhdRN9l-pX9J2QfQMVCe5qSon4/s690/FormWizard2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;685&quot; data-original-width=&quot;690&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicfqWimjs7fir8xqRm9cwiUOVPRltgA8G7oyrjGsnTHz4E1-WIUL9JUgVHB-prylBztd7aTs0jTkzGd2bhpiA2-E2o0Nk_Ao5Ed_DBKZviwANKineftvjzE9Ujk6ZNx9FBkaBlTdO4Gc5w4XKBokTy4wr4TIAcp5VvyhkhdRN9l-pX9J2QfQMVCe5qSon4/s320/FormWizard2.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p data-end=&quot;328&quot; data-start=&quot;83&quot;&gt;The fields from the selected Table or &lt;a href=&quot;https://www.msaccesstips.com/2008/02/union-query.html&quot; target=&quot;_blank&quot;&gt;Query&lt;/a&gt; will be listed in the &lt;span data-end=&quot;170&quot; data-start=&quot;149&quot;&gt;left-side ListBox&lt;/span&gt; control. You can add fields individually by selecting a field and clicking the &lt;span data-end=&quot;255&quot; data-start=&quot;250&quot;&gt;&amp;gt;&lt;/span&gt; button. To include all fields at once, simply click the &lt;span data-end=&quot;318&quot; data-start=&quot;312&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; button.&lt;/p&gt;&lt;p data-end=&quot;321&quot; data-start=&quot;66&quot;&gt;Similarly, you can remove unwanted fields from the selected list by using the left-pointing &lt;span data-end=&quot;163&quot; data-start=&quot;158&quot;&gt;&amp;lt;&lt;/span&gt; button to remove them one by one, or the &lt;span data-end=&quot;211&quot; data-start=&quot;205&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; button to remove all fields at once. If no fields are selected, the &lt;span data-end=&quot;290&quot; data-start=&quot;280&quot;&gt;Finish&lt;/span&gt; button will remain disabled.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;442&quot; data-start=&quot;323&quot;&gt;Once the required fields are chosen, click the &lt;span data-end=&quot;380&quot; data-start=&quot;370&quot;&gt;Finish&lt;/span&gt; button to generate the Form and open it in &lt;span data-end=&quot;439&quot; data-start=&quot;424&quot;&gt;Normal View&lt;/span&gt;.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The FormWizard Form Module VBA Code.&lt;/h3&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private obj As New FWizObject_Init

Private Sub Form_Load()
    Set obj.fm_fom = Me
End Sub
&lt;/pre&gt;
&lt;p&gt;The &lt;span data-end=&quot;105&quot; data-start=&quot;86&quot;&gt;FWizObject_Init&lt;/span&gt; Class Module contains the list of object-level wrapper classes. The VBA code for the &lt;span data-end=&quot;210&quot; data-start=&quot;191&quot;&gt;FWizObject_Init&lt;/span&gt; Class Module is provided below.&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private fom As Access.Form

Private cmdb As FWiz_CmdButton
Private lstb As FWiz_ListBox
Private comb As FWiz_Combo

Private tb As FWiz_TabCtl
Private Coll As New Collection

&#39;Wizard Functions Running Command Button Instance&#39;
&#39;Functions are placed in this Module
&lt;b&gt;Private WithEvents cmdFinish As Access.CommandButton&lt;/b&gt;
Dim DarkBlue As Long, twips As Long, xtyp As Integer, strFile As String

Public Property Get fm_fom() As Form
  Set fm_fom = fom
End Property

Public Property Set fm_fom(ByRef mfom As Form)
  Set fom = mfom
    
  Call Class_Init
End Property

Private Sub Class_Init()
Dim Ctl As Control
Const EP = &quot;[Event Procedure]&quot;

&#39;Filter Table/Select Query Names for ComboBox
Call Create_FilesList

For Each Ctl In fom.Controls
    Select Case Ctl.ControlType
        Case acTabCtl
            Set tb = New FWiz_TabCtl
            Set tb.Tb_Frm = fom
            Set tb.Tb_Tab = Ctl
              tb.Tb_Tab.OnChange = EP
              
              Coll.Add tb
            Set tb = Nothing
        
        Case acCommandButton
            Select Case Ctl.Name
                Case &quot;cmdForm&quot;
                    &#39;Not to add in the Collection object
                    &#39;The Click Event Runs the Wizard Functions
                    &#39;from this Class Module, not from the
                    &#39;Wrapper Class - FWiz_CmdButton
                    
                    Set cmdFinish = fom.cmdForm
                    cmdFinish.OnClick = EP
                Case Else
            
            Set cmdb = New FWiz_CmdButton
            Set cmdb.w_Frm = fom
            Set cmdb.w_cmd = Ctl
                cmdb.w_cmd.OnClick = EP
                
              Coll.Add cmdb
            Set cmdb = Nothing
         End Select
            
        Case acComboBox
            Set comb = New FWiz_Combo
            Set comb.cbo_Frm = fom
            Set comb.c_cbo = Ctl
                comb.c_cbo.OnGotFocus = EP
                comb.c_cbo.OnLostFocus = EP
            
        Case acListBox
            Set lstb = New FWiz_ListBox
            Set lstb.lst_Frm = fom
            Set lstb.m_lst = Ctl
                lstb.m_lst.OnGotFocus = EP
                lstb.m_lst.OnLostFocus = EP
                
                Coll.Add lstb
            Set lstb = Nothing
    End Select
Next
            
End Sub

Private Sub cmdFinish_Click()
        xtyp = fom!WizList
        strFile = fom!FilesList
        If xtyp = 1 Then
            Columns strFile
        Else
            Tabular strFile
        End If
          DoCmd.Close acForm, fom.Name
End Sub

&#39;Create Tables/Queries List for
Private Sub Create_FilesList()
Dim strSQL1 As String
Dim cdb As DAO.Database
Dim Qry As DAO.QueryDef
Dim FList As ComboBox

On Error GoTo Create_FilesList_Err
DoCmd.Restore

strSQL1 = &quot;SELECT MSysObjects.Name &quot; _
&amp;amp; &quot;FROM MSysObjects &quot; _
&amp;amp; &quot;WHERE (((MSysObjects.Type)=1 Or (MSysObjects.Type)=5) &quot; _
&amp;amp; &quot;AND ((Left([Name],4))&amp;lt;&amp;gt;&#39;WizQ&#39;) AND ((Left([Name],1))&amp;lt;&amp;gt;&#39;~&#39;) &quot; _
&amp;amp; &quot;AND ((MSysObjects.Flags)=0)) &quot; _
&amp;amp; &quot;ORDER BY MSysObjects.Type, MSysObjects.Name;&quot;

DarkBlue = 8388608
twips = 1440

Set cdb = CurrentDb
Set Qry = cdb.QueryDefs(&quot;WizQuery&quot;)
If Err = 3265 Then
  Set Qry = cdb.CreateQueryDef(&quot;WizQuery&quot;)
  Qry.SQL = strSQL1
  cdb.QueryDefs.Append Qry
  cdb.QueryDefs.Refresh
  Err.Clear
End If

With Forms(&quot;FormWizard&quot;)
Set FList = .FilesList
    .FilesList.RowSource = &quot;WizQuery&quot;
    .FilesList.Requery
End With

Create_FilesList_Exit:
Exit Sub

Create_FilesList_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;Create_FilesList()&quot;
Resume Create_FilesList_Exit
End Sub

&#39;Wizard Functions
Private Function Columns(ByVal DataSource As String)
&#39;-------------------------------------------------------------------
&#39;Author : a.p.r. pillai
&#39;Date   : Sept-2000
&#39;URL    : www.msaccesstips.com
&#39;All Rights Reserved by www.msaccesstips.com
&#39;-------------------------------------------------------------------
Dim cdb As Database
Dim FldList() As String
Dim Ctrl As Control
Dim frm As Form
Dim HdSection As Section
Dim DetSection As Section
Dim FrmFields As ListBox

Dim lngTxtLeft As Long
Dim lngTxtTop As Long
Dim lngTxtHeight As Long
Dim lngtxtwidth As Long

Dim lngLblLeft As Long
Dim lngLblTop As Long
Dim lngLblHeight As Long
Dim lngLblWidth As Long

Dim FldCheck As Boolean
Dim strTblQry As String
Dim intflds As Integer
Dim lstcount As Long
Dim j As Integer

&#39;Create Form with Selected Fields
On Error GoTo Columns_Err

strFile = DataSource

Set FrmFields = Forms(&quot;FormWizard&quot;).SelList
lstcount = FrmFields.listcount

If lstcount = 0 Then
   MsgBox &quot;Fields Not Selected for Form&quot;, , &quot;FormWizard&quot;
   Exit Function
Else
   lstcount = lstcount - 1
End If

ReDim FldList(0 To lstcount) As String

Set cdb = CurrentDb
Set frm = CreateForm
Application.RunCommand acCmdFormHdrFtr
With frm
    .DefaultView = 0
    .ViewsAllowed = 0
    .DividingLines = False
    .Section(acFooter).Visible = True
    .Section(acFooter).Height = 0.1667 * twips &#39;0.1667 Inches
    .Section(acHeader).DisplayWhen = 0
    .Section(acHeader).Height = 0.5 * twips &#39;0.5 Inches
End With

Set HdSection = frm.Section(acHeader)
    HdSection.Height = 0.6667 * twips

Set DetSection = frm.Section(acDetail)
    DetSection.Height = 0.166 * twips


For j = 0 To lstcount
  FldList(j) = FrmFields.ItemData(j)
Next

With frm
    .RecordSource = strFile
    .Caption = strFile

    lngtxtwidth = 1.25 * twips
    lngTxtLeft = 1.6694 * twips
    lngTxtTop = 0
    lngTxtHeight = 0.21 * twips

    lngLblLeft = 0.073 * twips
    lngLblTop = 0 &#39;0.5 * twips
    lngLblWidth = 1.5208 * twips
    lngLblHeight = lngTxtHeight
End With

For j = 0 To lstcount

&#39;Create Field Child Label
   Set Ctrl = CreateControl(frm.Name, acLabel, acDetail, _
   FldList(j), FldList(j), lngLblLeft, lngLblTop, lngLblWidth, lngLblHeight)
    With Ctrl
       .Caption = FldList(j)
       .Name = FldList(j) &amp;amp; &quot; Label&quot;
       .Width = 1.5208 * twips
       .ForeColor = 0
       .BorderColor = 0
       .BorderStyle = 0
       .FontWeight = 400 &#39; Normal 700 &#39; Bold
       Select Case (1 / 9)
            Case 1, 2, 3
                lngLblTop = 0
                lngLblLeft = lngLblLeft + (2.7083 * twips)
            Case Else
                lngLblTop = lngLblTop + .Height + (0.1 * 1440)
       End Select
    End With

&#39;Create Field TextBox
   Set Ctrl = CreateControl(frm.Name, acTextBox, acDetail, , _
   FldList(j), lngTxtLeft, lngTxtTop, lngtxtwidth, lngTxtHeight)
    With Ctrl
       .ControlSource = FldList(j)
       .FontName = &quot;Arial&quot;
       .FontSize = 10
       .Name = FldList(j)
       .BackColor = RGB(255, 255, 255)
       .ForeColor = 0
       .BorderColor = 9868950
       .BorderStyle = 1
       .SpecialEffect = 2
       
       Select Case (j / 9)
            Case 1, 2, 3
                lngTxtTop = 0
                lngTxtLeft = lngTxtLeft + (3.7084 * twips)
       Case Else
                lngTxtTop = lngTxtTop + .Height + (0.1 * twips)
       End Select
    End With

Next

&#39;Create Heading Label
Call CreateHeading(frm)

Columns_Exit:
Exit Function

Columns_Err:
MsgBox Err.Description, , &quot;Columns()&quot;
Resume Columns_Exit
End Function


Private Function Tabular(ByVal DataSource As String)
&#39;-------------------------------------------------------------------
&#39;Author : a.p.r. pillai
&#39;Date   : Sept-2000
&#39;URL    : www.msaccesstips.com
&#39;All Rights Reserved by www.msaccesstips.com
&#39;-------------------------------------------------------------------
Dim cdb As Database
Dim FldList() As String
Dim Ctrl As Control
Dim frm As Form
Dim HdSection As Section
Dim DetSection As Section

Dim lngTxtLeft As Long
Dim lngTxtTop As Long
Dim lngTxtHeight As Long
Dim lngtxtwidth As Long

Dim lngLblLeft As Long
Dim lngLblTop As Long
Dim lngLblHeight As Long
Dim lngLblWidth As Long

Dim FldCheck As Boolean
Dim strTblQry As String
Dim intflds As Integer
Dim lstcount As Long
Dim FrmFields As ListBox
Dim j As Integer

&#39;Create Form with Selected Fields
strFile = DataSource
On Error GoTo Tabular_Err

Set FrmFields = Forms(&quot;FormWizard&quot;).SelList
lstcount = FrmFields.listcount

If lstcount = 0 Then
   MsgBox &quot;Fields Not Selected for the Form&quot;
   Exit Function
Else
   lstcount = lstcount - 1
End If

ReDim FldList(0 To lstcount) As String

Set cdb = CurrentDb
Set frm = CreateForm
Application.RunCommand acCmdFormHdrFtr

With frm
    .DefaultView = 1
    .ViewsAllowed = 0
    .DividingLines = False
    .Section(acFooter).Visible = True
    .Section(acHeader).DisplayWhen = 0
    .Section(acHeader).Height = 0.5 * 1440
    .Section(acFooter).Height = 0.1667 * 1440
End With

Set HdSection = frm.Section(acHeader)
    HdSection.Height = 0.6667 * twips

Set DetSection = frm.Section(acDetail)
    DetSection.Height = 0.166 * twips


For j = 0 To lstcount
  FldList(j) = FrmFields.ItemData(j)
Next

With frm
    .Caption = strFile
    .RecordSource = strFile
    lngtxtwidth = 0.5 * twips &#39;Inches
    lngTxtLeft = 0.073 * twips
    lngTxtTop = 0
    lngTxtHeight = 0.166 * twips

    lngLblWidth = lngtxtwidth
    lngLblLeft = lngTxtLeft
    lngLblTop = 0.5 * twips
    lngLblHeight = lngTxtHeight
End With

For j = 0 To lstcount
 
&#39;Create Fields in the Detail Section
   Set Ctrl = CreateControl(frm.Name, acTextBox, acDetail, , _
   FldList(j), lngTxtLeft, lngTxtTop, lngtxtwidth, lngTxtHeight)
    
    With Ctrl
       .ControlSource = FldList(j)
       .Name = FldList(j)
       .FontName = &quot;Verdana&quot;
       .Width = (0.5 * twips) &#39;Inches
       .FontSize = 8
       .ForeColor = 0
       .BorderColor = 12632256
       .BackColor = 16777215
       .BorderStyle = 1
       .SpecialEffect = 0
       lngTxtLeft = lngTxtLeft + (0.5 * twips)
    End With
   
&#39;Field Heading Labels
   Set Ctrl = CreateControl(frm.Name, acLabel, acHeader, , _
   FldList(j), lngLblLeft, lngLblTop, lngLblWidth, lngLblHeight)
    
    With Ctrl
       .Caption = FldList(j)
       .Name = FldList(j) &amp;amp; &quot; Label&quot;
       .Width = (0.5 * twips)
       .ForeColor = DarkBlue
       .BorderColor = DarkBlue
       .BorderStyle = 1
       .FontWeight = 700 &#39; Bold
       lngLblLeft = lngLblLeft + (0.5 * twips)
    End With
Next

&#39;Heading Label
Call CreateHeading(frm)

Tabular_Exit:
Exit Function

Tabular_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;Tabular()&quot;
Resume Tabular_Exit
End Function

Private Function CreateHeading(ByRef hFrm As Form)
Dim Ctl As Control
Dim lngLblLeft As Long
Dim lngLblTop As Long
Dim lngLblWidth As Long
Dim lngLblHeight As Long

On Error GoTo CreateHeading_Err

lngLblLeft = 0.073 * twips
lngLblTop = 0.0521 * twips
lngLblWidth = 1.5208 * twips
lngLblHeight = 0.323 &amp;amp; twips

&#39;Create Heading Label
 Set Ctl = CreateControl(hFrm.Name, acLabel, acHeader, , _
 &quot;Head1&quot;, lngLblLeft, lngLblTop, lngLblWidth, lngLblHeight)
   
   With Ctl
        .Caption = strFile
        .TextAlign = 2
        .Width = 4.5 * twips
        .Height = 0.38 * twips
        
        .ForeColor = DarkBlue
        .BorderStyle = 0
        .BorderColor = DarkBlue
        
        .FontName = &quot;Arial&quot;
        .FontSize = 18
        .FontWeight = 700 &#39; Bold
        .FontItalic = True
        .FontUnderline = True
   End With
   
DoCmd.OpenForm hFrm.Name, acNormal

CreateHeading_Exit:
Exit Function

CreateHeading_Err:
MsgBox Err &amp;amp; &quot;: &quot; &amp;amp; Err.Description, , &quot;CreateHeading()&quot;
Resume CreateHeading_Exit

End Function
&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;A separate &lt;a href=&quot;https://www.msaccesstips.com/2006/09/command-button-animation.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; instance named &lt;span data-end=&quot;138&quot; data-start=&quot;125&quot;&gt;cmdFinish&lt;/span&gt; is created in the intermediate Class Module &lt;span data-end=&quot;202&quot; data-start=&quot;183&quot;&gt;FWizObject_Init&lt;/span&gt; to execute all the Wizard-related functions defined in the main Class Module. The &lt;span data-end=&quot;306&quot; data-start=&quot;285&quot;&gt;cmdFinish_Click()&lt;/span&gt; event procedure serves as the entry point for running these Wizard functions.Private Sub cmdFinish_Click()&lt;/p&gt;&lt;pre&gt;        xtyp = fom!WizList
        strFile = fom!FilesList
        If xtyp = 1 Then
            Columns strFile
        Else
            Tabular strFile
        End If
          DoCmd.Close acForm, fom.Name &#39;Closes the Wizard Form.
End Sub
&lt;/pre&gt;
&lt;p&gt;Sample Form Images, both Column and Tabular Forms, are created using the Categories Table given below.&lt;/p&gt;
&lt;h4&gt;Wizard-Created Form in Column Format.&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNmRsViqVg7JRtaD_fSPHUKimtrTDInUFh0AcJ5Abp31cHWK72ivP_pylxFSIlQwpHf3ooVLKvgsozzAplfhem9JgtjWzbAWieOj5hGt8kLsIofVpDfJ0e8jQQVJI3WNZfyoRXkj3wHW80M28h-zmuzsGy4UhgX0N6I24QZOn6bLueTVe12SYOeoSgC-j8/s744/CategoriesColumns.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;416&quot; data-original-width=&quot;744&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNmRsViqVg7JRtaD_fSPHUKimtrTDInUFh0AcJ5Abp31cHWK72ivP_pylxFSIlQwpHf3ooVLKvgsozzAplfhem9JgtjWzbAWieOj5hGt8kLsIofVpDfJ0e8jQQVJI3WNZfyoRXkj3wHW80M28h-zmuzsGy4UhgX0N6I24QZOn6bLueTVe12SYOeoSgC-j8/s320/CategoriesColumns.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Wizard Form in Tabular Format with Categories Table.&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxrrW67GeqmW69b3lLbWj8skMmhaMv_jw55O_bpXC6M2YdMfPAySTBiWvq4_MTiBYzH_HcJQ3oRzB2PTYRNVFHmLHLcoShbrwfKXGzSni6XN3HhIHA807u1OO3W2-lhL_XNcRqlNpUsRsX3yX_uRC5RZygnHstlA3kdTU3tJzXx4gSQIq703yT0tEzR6xL/s772/CategoriesTabular.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;442&quot; data-original-width=&quot;772&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxrrW67GeqmW69b3lLbWj8skMmhaMv_jw55O_bpXC6M2YdMfPAySTBiWvq4_MTiBYzH_HcJQ3oRzB2PTYRNVFHmLHLcoShbrwfKXGzSni6XN3HhIHA807u1OO3W2-lhL_XNcRqlNpUsRsX3yX_uRC5RZygnHstlA3kdTU3tJzXx4gSQIq703yT0tEzR6xL/s320/CategoriesTabular.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;
&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The Tabular Form is created with fixed-width Fields and needs to be modified with the required width of each Field.&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Command Buttons Wrapper Class: FWiz_CmdButton VBA Code.&lt;/h3&gt;&lt;p data-end=&quot;455&quot; data-start=&quot;131&quot;&gt;The &lt;span data-end=&quot;153&quot; data-start=&quot;135&quot;&gt;FWiz_CmdButton&lt;/span&gt; Class Module contains the &lt;a href=&quot;https://www.msaccesstips.com/2009/01/command-button-animation-2.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; wrapper code and is provided below for your reference. Other related wrapper classes include only a few lines of event procedure code. You may open these Class Modules directly in the attached demo database to review and study their implementation in detail.&lt;/p&gt;
&lt;pre&gt;Option Compare Database
Option Explicit

Private WithEvents cmd As CommandButton
Private frm As Form
Dim DarkBlue As Long, twips As Long, xtyp As Integer, strFile As String

Public Property Get w_Frm() As Form
    Set w_Frm = frm
End Property

Public Property Set w_Frm(ByRef wFrm As Form)
    Set frm = wFrm
End Property

Public Property Get w_cmd() As CommandButton
    Set w_cmd = cmd
End Property

Public Property Set w_cmd(ByRef wcmd As CommandButton)
    Set cmd = wcmd
End Property

Private Sub cmd_Click()
Dim lblInfo As String

  Select Case cmd.Name

    Case &quot;cmdCancel2&quot;
        DoCmd.Close acForm, frm.Name
               
    Case &quot;cmdNext&quot;
    If frm.SelList.listcount = 0 Then
        frm.cmdForm.Enabled = False
    Else
        frm.cmdForm.Enabled = True
    End If
    
    lblInfo = &quot;Table/Query: &quot; &amp;amp; frm!FilesList
    If frm!WizList = 1 Then
        lblInfo = lblInfo &amp;amp; &quot; - Columnar Form.&quot;
    Else
        lblInfo = lblInfo &amp;amp; &quot; - Tabular Form.&quot;
    End If
    frm!info.Caption = lblInfo
       Call SelectTable
       
    Case &quot;cmdCancel&quot;
        DoCmd.Close acForm, frm.Name
        
    Case &quot;cmdRight&quot;
        RightAll 1

    Case &quot;cmdRightAll&quot;
        RightAll 2

    Case &quot;cmdLeft&quot;
        LeftAll 1
        
    Case &quot;cmdLeftAll&quot;
        LeftAll 2
    
    Case &quot;cmdBack&quot;
        frm.FilesList.RowSource = &quot;WizQuery&quot;
        frm.Page1.Visible = True
        frm.Page1.SetFocus
        frm.Page2.Visible = False
               
End Select
End Sub

Private Sub SelectTable()
Dim vizlist As ListBox, lcount As Integer, chkflag As Boolean
Dim FildList As ListBox, strName As String, strRSource As String
Dim cdb As Database, doc As Document
Dim Tbl As TableDef, Qry As QueryDef, QryTyp As Integer
Dim flag As Byte, FieldCount As Integer, j As Integer

Set vizlist = frm.WizList
lcount = vizlist.listcount - 1

chkflag = False
For j = 0 To lcount
  If vizlist.Selected(j) = True Then
    xtyp = j + 1
    chkflag = True
  End If
Next

If IsNull(frm![FilesList]) = True Then
   MsgBox &quot;Select a File from Table/Query List.&quot;, vbOKOnly + vbExclamation, &quot;cmdNext&quot;
   frm.WizList.Selected(0) = True
Else
   strFile = frm.FilesList
   frm.Page2.Visible = True
   frm.Page2.SetFocus
   frm.Page1.Visible = False
   
Set cdb = CurrentDb
flag = 0
For Each Tbl In cdb.TableDefs
    If Tbl.Name = strFile Then
       flag = 1
    End If
Next
For Each Qry In cdb.QueryDefs
    If Qry.Name = strFile Then
       flag = 2
    End If
Next
If flag = 1 Then
    Set Tbl = cdb.TableDefs(strFile)
    Set FildList = frm.FldList
    strRSource = &quot;&quot;
    FieldCount = Tbl.Fields.Count - 1
    For j = 0 To FieldCount
        If Len(strRSource) = 0 Then
            strRSource = Tbl.Fields(j).Name
        Else
            strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; Tbl.Fields(j).Name
        End If
    Next
ElseIf flag = 2 Then
    Set Qry = cdb.QueryDefs(strFile)
    strRSource = &quot;&quot;
    FieldCount = Qry.Fields.Count - 1
    For j = 0 To FieldCount
        If Len(strRSource) = 0 Then
            strRSource = Qry.Fields(j).Name
        Else
            strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; Qry.Fields(j).Name
        End If
    Next
End If

frm.FldList.RowSource = strRSource
frm.FldList.Requery
End If

End Sub

Private Function RightAll(ByVal SelectionType As Integer)
Dim FldList As ListBox, SelctList As ListBox, strRSource As String
Dim listcount As Long, j As Long, strRS2 As String

On Error GoTo RightAll_Err
If SelectionType = 0 Then
   Exit Function
End If
Set FldList = Forms(&quot;FormWizard&quot;).FldList
Set SelctList = Forms(&quot;FormWizard&quot;).SelList

listcount = FldList.listcount - 1
strRSource = SelctList.RowSource: strRS2 = &quot;&quot;

Select Case SelectionType
    Case 1
        For j = 0 To listcount
            If FldList.Selected(j) = True Then
                If Len(strRSource) = 0 Then
                    strRSource = FldList.ItemData(j)
                Else
                    strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; FldList.ItemData(j)
                End If
            Else
                If Len(strRS2) = 0 Then
                    strRS2 = FldList.ItemData(j)
                Else
                    strRS2 = strRS2 &amp;amp; &quot;;&quot; &amp;amp; FldList.ItemData(j)
                End If
            End If
        Next
        SelctList.RowSource = strRSource
        FldList.RowSource = strRS2
        SelctList.Requery
        FldList.Requery
    frm.cmdForm.Enabled = True
    Case 2

        For j = 0 To listcount
            If Len(strRSource) = 0 Then
                strRSource = FldList.ItemData(j)
            Else
                strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; FldList.ItemData(j)
            End If
        Next
        SelctList.RowSource = strRSource
        FldList.RowSource = &quot;&quot;
        SelctList.Requery
        FldList.Requery
    frm.cmdForm.Enabled = False
End Select
frm.cmdForm.Enabled = True

RightAll_Exit:
Exit Function

RightAll_Err:
MsgBox Err.Description, , &quot;RightAll&quot;
Resume RightAll_Exit
End Function

Private Function LeftAll(ByVal SelectionType As Integer)
Dim FldList As ListBox, SelctList As ListBox, strRSource As String
Dim listcount As Long, j As Long, strRS2 As String

On Error GoTo LeftAll_Err

If SelectionType = 0 Then
   Exit Function
   
End If

Set FldList = Forms(&quot;FormWizard&quot;).FldList
Set SelctList = Forms(&quot;FormWizard&quot;).SelList

listcount = SelctList.listcount - 1
strRSource = FldList.RowSource: strRS2 = &quot;&quot;

Select Case SelectionType
    Case 1
        For j = 0 To listcount
            If SelctList.Selected(j) = True Then
                If Len(strRSource) = 0 Then
                    strRSource = SelctList.ItemData(j)
                Else
                    strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; SelctList.ItemData(j)
                End If
            Else
                If Len(strRS2) = 0 Then
                    strRS2 = SelctList.ItemData(j)
                Else
                    strRS2 = strRS2 &amp;amp; &quot;;&quot; &amp;amp; SelctList.ItemData(j)
                End If
            End If
        Next
        SelctList.RowSource = strRS2
        FldList.RowSource = strRSource
        SelctList.Requery
        FldList.Requery
    If SelctList.listcount = 0 Then
        frm.cmdForm.Enabled = False
    End If
    Case 2
        For j = 0 To listcount
            If Len(strRSource) = 0 Then
                strRSource = SelctList.ItemData(j)
            Else
                strRSource = strRSource &amp;amp; &quot;;&quot; &amp;amp; SelctList.ItemData(j)
            End If
        Next
        SelctList.RowSource = &quot;&quot;
        FldList.RowSource = strRSource
        SelctList.Requery
        FldList.Requery
    If SelctList.listcount = 0 Then
        frm.cmdForm.Enabled = False
    End If
End Select
LeftAll_Exit:
Exit Function

LeftAll_Err:
MsgBox Err.Description, , &quot;LeftAll&quot;
Resume LeftAll_Exit

End Function

&lt;/pre&gt;
&lt;h3&gt;Demo Database Download Link:&lt;/h3&gt;
&lt;!--Download Link /downloads/2023/10/FormWizard1.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1bD0oPeGDuPP3PXdWoUfil8fPGdMvyhpA/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;FormWizard1.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2023/10/FormWizard1.zip--&gt;
&lt;br /&gt;
&lt;h3&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/7189331229920223403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/7189331229920223403'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/7189331229920223403'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html' title='New Custom Made Form Wizard VBA - Part 15'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYb7rWqv41TI2zOps5jk8Fs7f9M3bbjn1w8FOLV1rKi8eTPx2YjJXIXmu-lj7xZ7W03Eh7lHs7psrlO-11ubeIKij6YAbG-huUeea-pxYsSjNqZ83QL5pV7rReq3YdnKdUE3Rq_1lh51PwAqvYFXh2ybTU7sltiyjNftKGwFLx27oBkdXNyFCJA9JV8qk0/s72-c/FormWizard1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7457417942281874810.post-3111012847067704305</id><published>2023-09-30T21:17:00.020+05:30</published><updated>2026-07-10T22:40:51.352+05:30</updated><title type='text'>Form and Report Detail Sections Event Handling - Part 14</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;All Frequently Used Controls on a Form.&lt;/h3&gt;&lt;p&gt;We have learned how to capture events fired by Form or Report controls and handle them through Event Subroutines in their respective Wrapper Classes. The TextBox and other objects&#39; Wrapper Classes are enabled with the actual references of the controls on the Form, allowing us to interact with them seamlessly. Beyond event handling, any other control on the Form can also be accessed from the Wrapper Class to read or update its values. This flexibility opens the door to creative features such as running animations, simulating a digital clock on the Form, implementing a countdown timer before the Form is closed, and much more.&amp;nbsp;&lt;/p&gt;&lt;p data-end=&quot;772&quot; data-start=&quot;117&quot;&gt;For such activities, every Wrapper Class includes a Form object instance, to which the active Form’s reference is assigned. This allows the Wrapper Class to interact directly with the Form. When you need to handle events such as the &lt;span data-end=&quot;366&quot; data-start=&quot;350&quot;&gt;Form_Timer()&lt;/span&gt; Event or the &lt;span data-end=&quot;393&quot; data-start=&quot;380&quot;&gt;MouseMove&lt;/span&gt; Event on the Form’s Detail Section, the Form instance must be declared with the &lt;span data-end=&quot;488&quot; data-start=&quot;474&quot;&gt;WithEvents&lt;/span&gt; keyword inside the Wrapper Class. Since the Form instance is always included in a Wrapper Class, any of the above-mentioned features can be triggered from within any control’s Wrapper Class. However, if the Form-level events are not handled in the Class Module, then the form object can have a simple declaration like:&amp;nbsp;&lt;i&gt;Private frm as Form.&lt;/i&gt;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Form Detail Section declaration,&lt;/h3&gt;
&lt;!--Google In-Article Ads start--&gt;
&lt;script async=&quot;&quot; src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; data-ad-client=&quot;ca-pub-2376623373770548&quot; data-ad-format=&quot;fluid&quot; data-ad-layout=&quot;in-article&quot; data-ad-slot=&quot;6147807460&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;!--Google In-Article Ads END--&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;Private frm as Access.Form
Private WithEvents SecDetail As Access.Section

Set SecDetail = frm.Section(acDetail)
	SecDetail.OnMouseMove = &quot;[Event Procedure]&quot;

&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;Report Detail Section Declaration.&lt;/h3&gt;
&lt;pre&gt;Private WithEvents Rpt as Access.Report
Private WithEvents RptSec as Access.[_SectionInReport]

Set RptSec = Rpt.Section(acDetail)

&lt;/pre&gt;
&lt;p&gt;By moving Event Subroutine VBA Code out of the Form and Report modules and Coding in standalone Class Modules, we can work with the code independently. The &lt;span data-end=&quot;296&quot; data-start=&quot;282&quot;&gt;Collection&lt;/span&gt; object plays a key role here, as it allows multiple instances of the same control type (such as &lt;a href=&quot;https://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins.html&quot; target=&quot;_blank&quot;&gt;TextBox&lt;/a&gt; controls on a Form) to remain in memory, each enabled with the required Events. This approach keeps the Form design process separate from the coding task, making both development and maintenance more efficient.&lt;/p&gt;&lt;p data-end=&quot;820&quot; data-start=&quot;125&quot;&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_blank&quot;&gt;Episode Seven&lt;/a&gt; is a classic example that demonstrates the strength of this new approach—shifting Form/Report module code into standalone Class Modules. With this method, repetitive manual coding is greatly reduced. For instance, a single pair of &lt;span data-end=&quot;384&quot; data-start=&quot;370&quot;&gt;GotFocus()&lt;/span&gt; and &lt;span data-end=&quot;404&quot; data-start=&quot;389&quot;&gt;LostFocus()&lt;/span&gt; routines can manage any number of TextBoxes on a Form, without writing separate Subroutines for each one. Likewise, if ten TextBoxes require &lt;span data-end=&quot;556&quot; data-start=&quot;539&quot;&gt;AfterUpdate()&lt;/span&gt; Event Subroutines, each with different validation rules, all the Code can be organized within a single &lt;span data-end=&quot;674&quot; data-start=&quot;657&quot;&gt;AfterUpdate()&lt;/span&gt; procedure in the standalone Class Module. This method of coding is not limited to TextBoxes—it applies uniformly to all types of controls on the Form.&lt;/p&gt;&lt;p data-end=&quot;244&quot; data-start=&quot;82&quot;&gt;Event Procedure code becomes better organized when placed in Wrapper Classes, making it easier to maintain and debug independently—without interfering with the Form’s design.&lt;/p&gt;
&lt;pre&gt;Private Sub Txt_AfterUpdate()
  Select Case Txt.Name
  	 Case &quot;Quantity&quot;
     	&#39;Code
     Case &quot;UnitPrice&quot;
     	&#39;Code
     Case &quot;TaxRate&quot;
     	&#39;Code
     Case . . .
     
  End Select
End Sub
&lt;/pre&gt;
&lt;p data-end=&quot;695&quot; data-start=&quot;87&quot;&gt;If any TextBox’s &lt;span data-end=&quot;119&quot; data-start=&quot;104&quot;&gt;AfterUpdate&lt;/span&gt; event code needs modification, or if a new TextBox requires an &lt;span data-end=&quot;198&quot; data-start=&quot;183&quot;&gt;AfterUpdate&lt;/span&gt; event subroutine, there is no need to open the Form in &lt;span data-end=&quot;269&quot; data-start=&quot;254&quot;&gt;Design View&lt;/span&gt;, locate the TextBox control, open the &lt;span data-end=&quot;326&quot; data-start=&quot;308&quot;&gt;Property Sheet&lt;/span&gt;, find the event &lt;a href=&quot;https://www.msaccesstips.com/2008/09/source-connect-str-property-and-odbc.html&quot; target=&quot;_blank&quot;&gt;property&lt;/a&gt;, and then click the &lt;span data-end=&quot;382&quot; data-start=&quot;372&quot;&gt;Build…&lt;/span&gt; button to access the event procedure. Instead, we can simply open the Class Module directly and make the necessary changes. Compare this with the traditional approach, where developers often waste considerable time repeating the same steps for each control event, sometimes multiple times for the same control.&lt;/p&gt;&lt;p data-end=&quot;331&quot; data-start=&quot;53&quot;&gt;I am confident you will recognize the difference once you adopt this new coding approach. While it may take a little time to become familiar with the concept—especially if you are new to VBA development—the benefits in efficiency and maintainability are well worth the effort.&lt;/p&gt;
&lt;p&gt;The Form shown below incorporates several controls designed in earlier episodes, with their corresponding Wrapper Class Modules imported to handle the control event procedures. In addition, animations such as scrolling text, a digital clock, and a countdown timer (displayed before the form closes) have been implemented within the Class Module to run seamlessly on the Form.&lt;/p&gt;&lt;p data-end=&quot;447&quot; data-start=&quot;53&quot;&gt;Everything you can do in a Form Module can also be achieved from a standalone Class Module. The real advantage comes when you shift your mindset to this approach—working differently, more effortlessly, and in a well-organized manner, with the added benefit of reusing your VBA code across projects, often with little or no modification. Once you experience this, the difference becomes clear.&lt;/p&gt;&lt;p data-end=&quot;520&quot; data-start=&quot;106&quot;&gt;Anything attempted for the first time feels difficult—that’s how most of us began our journey with VBA coding, spending countless minutes or even hours solving problems through trial and error. I retired from service 13 years ago, yet I continue to learn new things every day and share my experiences with others. Learning never truly stops; in fact, it becomes even more meaningful when we pass it on to others.&lt;/p&gt;&lt;p data-end=&quot;469&quot; data-start=&quot;68&quot;&gt;
&lt;/p&gt;&lt;p data-end=&quot;798&quot; data-start=&quot;522&quot;&gt;Technology is advancing at an incredible pace, and it is inspiring to see children as young as 10 to 15 years old already practicing coding and building apps. What once took us years to discover, they now explore at such an early age—truly fortunate learners of this generation!&lt;/p&gt;&lt;p data-end=&quot;488&quot; data-start=&quot;112&quot;&gt;I was first introduced to computer-related automation at the age of 27, during my service in the Indian Navy Defence Establishment. My initial exposure came through the Key Punch Machine, where I worked on panel wiring to automate tasks such as skipping or duplicating specific columns of an 80-column punch card—the standard input medium for programs and data at that time.&lt;/p&gt;
&lt;p&gt;The mainframe system we used was an &lt;span data-end=&quot;538&quot; data-start=&quot;526&quot;&gt;ICL 1901&lt;/span&gt;, equipped with disk drives, and the programming languages of choice were &lt;span data-end=&quot;621&quot; data-start=&quot;612&quot;&gt;COBOL&lt;/span&gt; and &lt;span data-end=&quot;637&quot; data-start=&quot;626&quot;&gt;FORTRAN&lt;/span&gt;. I even managed to learn a bit of COBOL back then, in 1975, which became my earliest step into the world of programming.&amp;nbsp;&lt;/p&gt;&lt;p&gt;If you need some beginner lessons on Class Modules, they are available starting with this Link: &lt;a href=&quot;https://www.msaccesstips.com/2018/10/ms-access-class-module-and-vba.html&quot; target=&quot;_blank&quot;&gt;MS-Access Class&amp;nbsp;Modules and VBA&lt;/a&gt;&amp;nbsp;series of a few Articles.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Demo Database With All Frequently Used Controls.&lt;/h3&gt;&lt;p&gt;The attached sample Demo Database contains the following Form. The download link is available at the end of this page, and the main Form (frmControls_All) Image is given below.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizIVywqhfzoizcEIh_banRi273XyTD6qiaOwaUHkyS7f6ANpjas8lNOXMwUwMtuTthf2PQEbEANVWNgg4D8wOZBAqi41PIXfr5UQqcNEsbAeKUWIP2aq-SANmHiua_mNXI1k95xGsD7zm7D3CrKXsdPhH_hc1UCYvPSzFNk0cme6cETBk4TZwodz7tX62s/s1015/StremlineAllForm.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;831&quot; data-original-width=&quot;1015&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizIVywqhfzoizcEIh_banRi273XyTD6qiaOwaUHkyS7f6ANpjas8lNOXMwUwMtuTthf2PQEbEANVWNgg4D8wOZBAqi41PIXfr5UQqcNEsbAeKUWIP2aq-SANmHiua_mNXI1k95xGsD7zm7D3CrKXsdPhH_hc1UCYvPSzFNk0cme6cETBk4TZwodz7tX62s/s320/StremlineAllForm.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open the large image in a new Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;On the top-left side, the form features a &lt;span data-end=&quot;149&quot; data-start=&quot;124&quot;&gt;TabControl-based menu&lt;/span&gt;&amp;nbsp;with three layers of options, each hosted on separate Tab Pages. To achieve a clean interface, the &lt;span data-end=&quot;286&quot; data-start=&quot;258&quot;&gt;Tab Page style is hidden&lt;/span&gt;&lt;strong data-end=&quot;286&quot; data-start=&quot;258&quot;&gt;&amp;nbsp;&lt;/strong&gt;by setting its property to &lt;em data-end=&quot;320&quot; data-start=&quot;314&quot;&gt;None&lt;/em&gt;. Navigation between these menu pages is handled by dedicated &lt;a href=&quot;https://www.msaccesstips.com/2008/04/transparent-command-button.html&quot; target=&quot;_blank&quot;&gt;command button&lt;/a&gt; clicks. Each button triggers a &lt;span data-end=&quot;457&quot; data-start=&quot;433&quot;&gt;TabPage Change event&lt;/span&gt;, which in turn displays a message corresponding to the Page Index number.&lt;/p&gt;&lt;p&gt;The three available menus are &lt;span data-end=&quot;147&quot; data-start=&quot;117&quot;&gt;Tables, Forms, and Reports&lt;/span&gt;. The TabControl, along with its associated menu selection command buttons, was copied from the earlier episode’s form and pasted into this one. Some menu options were modified to replace them with other Forms and Reports introduced in previous episodes. The corresponding &lt;span data-end=&quot;456&quot; data-start=&quot;420&quot;&gt;Class Modules were also imported&lt;/span&gt; into this database to ensure proper execution of these features.&lt;/p&gt;&lt;p&gt;Imported Class Modules, TabControl, and the Menu changing Command Buttons.&lt;/p&gt;
&lt;p&gt;The following Class Modules were imported into this Database, from an earlier episode to run the Menu options with a few changes:&lt;/p&gt;
&lt;pre&gt;TabLst_Object_Init
TabLst_CmdButton
TabLst_ListBox
TabLst_TabCtl

&lt;/pre&gt;
&lt;p&gt;The Tab Page TABLES has three options: Employees, Orders, and Customer Tables. Double-click on an Item to open it. Before opening the Table, a Female Voice will announce the Table Name before it appears on the Screen.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Employees and Orders Form.&lt;/h3&gt;&lt;p data-end=&quot;580&quot; data-start=&quot;73&quot;&gt;On the &lt;span data-end=&quot;89&quot; data-start=&quot;80&quot;&gt;FORMS&lt;/span&gt; TabPage, the first option is the &lt;span data-end=&quot;141&quot; data-start=&quot;123&quot;&gt;Employees Form,&lt;/span&gt;&amp;nbsp;with an embedded &lt;span data-end=&quot;177&quot; data-start=&quot;159&quot;&gt;Orders SubForm&lt;/span&gt;. In the footer section of the Employees Form, you will find a &lt;span data-end=&quot;267&quot; data-start=&quot;240&quot;&gt;Search and Find TextBox&lt;/span&gt; that allows you to look up records using the &lt;span data-end=&quot;327&quot; data-start=&quot;313&quot;&gt;EmployeeID&lt;/span&gt; as the search key. When a search is performed, a label will briefly flash for a few seconds to indicate whether the search was successful. For testing, try entering an &lt;span data-end=&quot;532&quot; data-start=&quot;503&quot;&gt;EmployeeID greater than 9&lt;/span&gt;—this will demonstrate the “not found” result.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsWzzCeERosZpMx23U3LOOcmlP6isgTxN8zCE2c1kI4seGTtyGG0s2p-slxp03ozLxfSAsLVnmTV2f8CyWh3_ApsF8btnv9chOlLkEGwq0gwsJBIgJXRnQiNAzz3UWbkMymGLFHp-GTkEV2LduTDKpSS38NK1lWP7irbmjTRxzniXy9_PpCp-73LlMlrmo/s722/EmployeeOrders1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;629&quot; data-original-width=&quot;722&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsWzzCeERosZpMx23U3LOOcmlP6isgTxN8zCE2c1kI4seGTtyGG0s2p-slxp03ozLxfSAsLVnmTV2f8CyWh3_ApsF8btnv9chOlLkEGwq0gwsJBIgJXRnQiNAzz3UWbkMymGLFHp-GTkEV2LduTDKpSS38NK1lWP7irbmjTRxzniXy9_PpCp-73LlMlrmo/s320/EmployeeOrders1.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;T&lt;i&gt;ry to implement the Female Voice to announce the success or failure of the search operation.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;The above Form and its VBA Codes are running from the following Class Modules, with the &lt;b&gt;Emp&lt;/b&gt;&amp;nbsp;Prefixes:&lt;/p&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;EmpObject_Init
EmpCmdButton
EmpTextBox
EmpCombo
&lt;/pre&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;The Employee-wise Orders Freight Sales Analysis.&lt;/h3&gt;&lt;p data-end=&quot;341&quot; data-start=&quot;90&quot;&gt;The second option on the &lt;span data-end=&quot;129&quot; data-start=&quot;115&quot;&gt;Forms Menu&lt;/span&gt; is the &lt;span data-end=&quot;189&quot; data-start=&quot;137&quot;&gt;Employee-wise Orders Freight-Sales Analysis Form&lt;/span&gt; (&lt;em data-end=&quot;209&quot; data-start=&quot;191&quot;&gt;frm_OptionGroup2&lt;/em&gt;), which includes a Graph Chart for quick view. This form features an &lt;span data-end=&quot;308&quot; data-start=&quot;284&quot;&gt;Option Group Control&lt;/span&gt; with three selectable options:&lt;/p&gt;&lt;ol data-end=&quot;437&quot; data-start=&quot;342&quot;&gt;
&lt;li data-end=&quot;374&quot; data-start=&quot;342&quot;&gt;
&lt;p data-end=&quot;374&quot; data-start=&quot;345&quot;&gt;Highest Freight Sales Value&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;406&quot; data-start=&quot;375&quot;&gt;
&lt;p data-end=&quot;406&quot; data-start=&quot;378&quot;&gt;Lowest Freight Sales Value&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;437&quot; data-start=&quot;407&quot;&gt;
&lt;p data-end=&quot;437&quot; data-start=&quot;410&quot;&gt;Total Freight Sales Value&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;

&lt;/p&gt;&lt;p data-end=&quot;643&quot; data-start=&quot;439&quot;&gt;Based on the selected option, the corresponding result is displayed in a &lt;span data-end=&quot;523&quot; data-start=&quot;512&quot;&gt;TextBox&lt;/span&gt;, accompanied by an &lt;span data-end=&quot;569&quot; data-start=&quot;543&quot;&gt;animated label caption&lt;/span&gt;—text that moves from right to left for added visual effect.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1hS1Vd7ZZnSevBzG2qSBiyS-HIu-mKOlqL6pVIMNda-ael-5R96YbsX_M8qXOWrDttqufgeRTIXFwvUh7t_snsofyLbbYqmvV2gNwtyDT95LYJtD48aTmtGANRgaIT-6wUwtA4LxvWjPfcgcHgkCdZKWNXEaAJn7_ttXg2xBnSYt-HxMETtMzrTRgrNCf/s928/OptionGrpFrm.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;661&quot; data-original-width=&quot;928&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1hS1Vd7ZZnSevBzG2qSBiyS-HIu-mKOlqL6pVIMNda-ael-5R96YbsX_M8qXOWrDttqufgeRTIXFwvUh7t_snsofyLbbYqmvV2gNwtyDT95LYJtD48aTmtGANRgaIT-6wUwtA4LxvWjPfcgcHgkCdZKWNXEaAJn7_ttXg2xBnSYt-HxMETtMzrTRgrNCf/s320/OptionGrpFrm.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p data-end=&quot;271&quot; data-start=&quot;94&quot;&gt;The above form is powered by two standalone &lt;span data-end=&quot;155&quot; data-start=&quot;138&quot;&gt;Class Modules&lt;/span&gt;, as shown below. Both the &lt;span data-end=&quot;190&quot; data-start=&quot;182&quot;&gt;Form&lt;/span&gt; and the &lt;span data-end=&quot;216&quot; data-start=&quot;199&quot;&gt;Class Modules&lt;/span&gt; have been imported from an earlier episode.&lt;/p&gt;
&lt;pre&gt;Opt_Object_Init
Opt_Frame2&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;p&gt;The Option Group Subroutine VBA code is executed from the &lt;span data-end=&quot;154&quot; data-start=&quot;140&quot;&gt;Opt_Frame2&lt;/span&gt; Class Module. The &lt;span data-end=&quot;194&quot; data-start=&quot;173&quot;&gt;Employee &lt;a href=&quot;https://www.msaccesstips.com/2008/03/refresh-dependant-combo-box-contents.html&quot; target=&quot;_blank&quot;&gt;ComboBox&lt;/a&gt;&lt;/span&gt;, the &lt;span data-end=&quot;233&quot; data-start=&quot;200&quot;&gt;Freight Value display TextBox&lt;/span&gt;, and the &lt;span data-end=&quot;285&quot; data-start=&quot;243&quot;&gt;&lt;a href=&quot;https://www.msaccesstips.com/2006/09/command-button-animation.html&quot; target=&quot;_blank&quot;&gt;Command Button&lt;/a&gt; Click Event Subroutines&lt;/span&gt; are handled through the &lt;span data-end=&quot;329&quot; data-start=&quot;310&quot;&gt;Opt_Object_Init&lt;/span&gt; Class Module. Since each of these controls has only a single instance on the form, separate Wrapper Classes were not created for them. The Graph Chart on the Form.&lt;/p&gt;&lt;p data-end=&quot;641&quot; data-start=&quot;91&quot;&gt;The Graph Chart’s source data comes from the &lt;span data-end=&quot;154&quot; data-start=&quot;136&quot;&gt;OrderSummaryQ2&lt;/span&gt; query, which in turn is based on the &lt;span data-end=&quot;209&quot; data-start=&quot;192&quot;&gt;OrderDetailQ2&lt;/span&gt; query. The &lt;span data-end=&quot;238&quot; data-start=&quot;221&quot;&gt;OrderDetailQ2&lt;/span&gt; query filters data from the &lt;span data-end=&quot;277&quot; data-start=&quot;267&quot;&gt;Orders&lt;/span&gt; table using the &lt;span data-end=&quot;308&quot; data-start=&quot;294&quot;&gt;EmployeeID&lt;/span&gt; selected in the &lt;span data-end=&quot;335&quot; data-start=&quot;325&quot;&gt;cboEmp&lt;/span&gt; ComboBox. A hidden TextBox named &lt;span data-end=&quot;376&quot; data-start=&quot;369&quot;&gt;EID&lt;/span&gt; contains the expression&lt;code data-end=&quot;412&quot; data-start=&quot;401&quot;&gt;=[cboEmp]&lt;/code&gt;, which copies the EmployeeID selected in &lt;span data-end=&quot;464&quot; data-start=&quot;454&quot;&gt;cboEmp&lt;/span&gt;. This value is then used in the &lt;span data-end=&quot;518&quot; data-start=&quot;497&quot;&gt;Link Master Field&lt;/span&gt; property of the Graph Chart to dynamically update the chart whenever a different EmployeeID is chosen from the ComboBox.&lt;/p&gt;&lt;p data-end=&quot;149&quot; data-start=&quot;87&quot;&gt;The &lt;span data-end=&quot;116&quot; data-start=&quot;91&quot;&gt;third TabControl page&lt;/span&gt; contains three report options:&lt;/p&gt;&lt;ol data-end=&quot;290&quot; data-start=&quot;150&quot;&gt;
&lt;li data-end=&quot;175&quot; data-start=&quot;150&quot;&gt;
&lt;p data-end=&quot;175&quot; data-start=&quot;153&quot;&gt;&lt;span data-end=&quot;173&quot; data-start=&quot;153&quot;&gt;Employee Records&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li data-end=&quot;227&quot; data-start=&quot;176&quot;&gt;
&lt;p data-end=&quot;227&quot; data-start=&quot;179&quot;&gt;&lt;span data-end=&quot;265&quot; data-start=&quot;231&quot;&gt;Students Passed/Failed Listing&lt;/span&gt; (from the same report)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;

&lt;/p&gt;&lt;p data-end=&quot;518&quot; data-start=&quot;292&quot;&gt;The last two reports, along with their corresponding Class Modules, have been imported into this &lt;a href=&quot;https://www.msaccesstips.com/2008/05/database-daily-backup.html&quot; target=&quot;_blank&quot;&gt;database &lt;/a&gt;from earlier episodes. The following stand-alone Class Modules handle the Event Subroutine VBA code for these reports:&lt;/p&gt;
&lt;pre&gt;ClsStudentHighlight0
ClsStudentsList
&lt;/pre&gt;
&lt;p&gt;The &lt;i&gt;ClsStudentHighlight0&lt;/i&gt;&amp;nbsp;Class Module runs the Detail_Print &lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_blank&quot;&gt;Event&lt;/a&gt; Subroutine Code for the Report StudentsHighlight_Class0.&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;b&gt;The Report Image is given below:&lt;/b&gt;&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlwlWH-lFSeJej8ENULRimEw0izU__pTV-VU_sbuY293w7H2iTi4H_brs0ogPInjyM9u5EBLak4H0QcRt7DsMWQVqUcrYVPhUmICeXRDtFmnVYAXfzSV83GjnQo6cEmeM87OSrb6uF8DnwB7kumobHR5xdVEAknxdh5R-Itd6CtEsNUG6Svwg6tvhc4_Gj/s973/StreamReport1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;Streamline Report Image&quot; border=&quot;0&quot; data-original-height=&quot;765&quot; data-original-width=&quot;973&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlwlWH-lFSeJej8ENULRimEw0izU__pTV-VU_sbuY293w7H2iTi4H_brs0ogPInjyM9u5EBLak4H0QcRt7DsMWQVqUcrYVPhUmICeXRDtFmnVYAXfzSV83GjnQo6cEmeM87OSrb6uF8DnwB7kumobHR5xdVEAknxdh5R-Itd6CtEsNUG6Svwg6tvhc4_Gj/s320/StreamReport1.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The &lt;span data-end=&quot;133&quot; data-start=&quot;101&quot;&gt;ClsStudentsList Class Module&lt;/span&gt; runs the &lt;code data-end=&quot;160&quot; data-start=&quot;143&quot;&gt;Detail_Format()&lt;/code&gt; and &lt;code data-end=&quot;180&quot; data-start=&quot;165&quot;&gt;Report_Page()&lt;/code&gt; event subroutines. Additionally, the &lt;code data-end=&quot;232&quot; data-start=&quot;218&quot;&gt;PageBorder()&lt;/code&gt; function is called from the Standard Module to draw two border lines on each page of the report. An ellipse is also drawn around the TextBox in the &lt;code data-end=&quot;397&quot; data-start=&quot;381&quot;&gt;Detail_Print()&lt;/code&gt; event of the report.&lt;/p&gt;&lt;p&gt;The Students Exam Passed List Image is given below.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8XVz8gFuou28QyOqdXNTxd_DTYFkTfVKOpYKCh4xvRr0ND-zroGDOYSrys24yUfTKklUuaDlH_4jCCcuxsC2MxodA2IcVfQZ71y4KXEFaBHxRhJt-ig97TAsDVpQSoOr4HreAIBl27j4YVws6XDnz51sCLxACjDhBhlby_bbfo-aeFUs430EGufBci7l9/s936/ReportFormat.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;644&quot; data-original-width=&quot;936&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8XVz8gFuou28QyOqdXNTxd_DTYFkTfVKOpYKCh4xvRr0ND-zroGDOYSrys24yUfTKklUuaDlH_4jCCcuxsC2MxodA2IcVfQZ71y4KXEFaBHxRhJt-ig97TAsDVpQSoOr4HreAIBl27j4YVws6XDnz51sCLxACjDhBhlby_bbfo-aeFUs430EGufBci7l9/s320/ReportFormat.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p data-end=&quot;317&quot; data-start=&quot;84&quot;&gt;The &lt;span data-end=&quot;117&quot; data-start=&quot;88&quot;&gt;Exam Failed Cases Listing&lt;/span&gt; is generated from the same report. Both listings are created by hiding the Report Detail section for records that do not meet the specified criteria, controlled through the &lt;code data-end=&quot;308&quot; data-start=&quot;291&quot;&gt;Detail_Format()&lt;/code&gt; event.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxmILD3Vwein6HFKXk0VY6krYVmCin8v8HF28vKLClJbuXCnLXx1XiFjGiDQv7G9F61qyrBsPm4fbhD3m482wc6CQ5dBnfl_GgBQ0nVdTVrqKaYNJNnD4g8wWKlbLWZXHVwLs7EMQiiqAzeMaRgChgBF8iR2F0BwuD204TgVDAVOb8tbqh3pOiQ4yxdZbH/s928/ReportFormat2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;688&quot; data-original-width=&quot;928&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxmILD3Vwein6HFKXk0VY6krYVmCin8v8HF28vKLClJbuXCnLXx1XiFjGiDQv7G9F61qyrBsPm4fbhD3m482wc6CQ5dBnfl_GgBQ0nVdTVrqKaYNJNnD4g8wWKlbLWZXHVwLs7EMQiiqAzeMaRgChgBF8iR2F0BwuD204TgVDAVOb8tbqh3pOiQ4yxdZbH/s320/ReportFormat2.png&quot; width=&quot;320&quot; /&gt;&lt;p&gt;Right-click to open Large Image in New Tab/Window.&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;

&lt;h3 style=&quot;text-align: left;&quot;&gt;The SubForm on the Main Form.&lt;/h3&gt;&lt;p&gt;Next, a SubForm contains&amp;nbsp;three TextBoxes. The &lt;span data-end=&quot;157&quot; data-start=&quot;145&quot;&gt;Quantity&lt;/span&gt; TextBox accepts values only in the range of &lt;span data-end=&quot;213&quot; data-start=&quot;202&quot;&gt;1 to 10&lt;/span&gt;, while the &lt;span data-end=&quot;239&quot; data-start=&quot;225&quot;&gt;Unit Price&lt;/span&gt; TextBox must contain a non-zero value. These entries are validated in the &lt;code data-end=&quot;324&quot; data-start=&quot;314&quot;&gt;OnExit()&lt;/code&gt; event subroutine of the &lt;span data-end=&quot;360&quot; data-start=&quot;349&quot;&gt;ClsText&lt;/span&gt; Class Module before being accepted. The &lt;span data-end=&quot;415&quot; data-start=&quot;401&quot;&gt;TotalPrice&lt;/span&gt; TextBox uses its &lt;code data-end=&quot;447&quot; data-start=&quot;433&quot;&gt;OnGotFocus()&lt;/code&gt; event subroutine to calculate the total price (&lt;code data-end=&quot;517&quot; data-start=&quot;495&quot;&gt;Quantity * UnitPrice&lt;/code&gt;) and populate the result into the TextBox. This calculated value is also displayed in the Label control positioned above the SubForm.&lt;/p&gt;&lt;p data-end=&quot;365&quot; data-start=&quot;82&quot;&gt;The &lt;span data-end=&quot;97&quot; data-start=&quot;86&quot;&gt;SubForm&lt;/span&gt; is introduced here to demonstrate how to scan its controls and enable the required events within the &lt;code data-end=&quot;213&quot; data-start=&quot;199&quot;&gt;Class_Init()&lt;/code&gt; subroutine of the &lt;span data-end=&quot;251&quot; data-start=&quot;232&quot;&gt;ClsControls_All&lt;/span&gt; Class Module. This process is handled through two &lt;code data-end=&quot;314&quot; data-start=&quot;302&quot;&gt;For...Next&lt;/code&gt; loops. The first loop begins with the statement:&lt;/p&gt;
&lt;pre&gt;For Each ctl In &lt;b&gt;fom&lt;/b&gt;.&lt;b&gt;mySubForm.Form&lt;/b&gt;.Controls
&lt;/pre&gt;
&lt;p&gt;For the SubForm scanning, and the other starts with:&lt;/p&gt;
&lt;pre&gt;For Each ctl In &lt;b&gt;fom&lt;/b&gt;.Controls&lt;/pre&gt;
&lt;p&gt;to scan for the required controls and enable their Event Procedures.&amp;nbsp;&lt;/p&gt;&lt;p data-end=&quot;293&quot; data-start=&quot;89&quot;&gt;&lt;strong data-end=&quot;98&quot; data-start=&quot;89&quot;&gt;Note:&lt;/strong&gt; If you place any TextBox on the TabControl pages, they are still treated as part of the main Form. Ensure that their names do not conflict with other TextBox names already present on the Form.&lt;/p&gt;&lt;p data-end=&quot;409&quot; data-start=&quot;53&quot;&gt;The Form contains a ComboBox with a list of country names. When a country is selected, its list index number is used to automatically select the corresponding capital city in the ListBox. Additionally, clicking an item in the ListBox displays the selected value in a message box, confirming that the Click event is being captured in the Class Module.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Option Group Control.&lt;/h3&gt;&lt;p&gt;The Option Group control is not linked to any specific function. However, when a radio button is clicked, the index number of the selected option is displayed. This serves as confirmation that the event has been fired and successfully captured in the Option Group Class Module &lt;span data-end=&quot;341&quot; data-start=&quot;328&quot;&gt;ClsOption&lt;/span&gt;.&lt;/p&gt;&lt;p data-end=&quot;287&quot; data-start=&quot;53&quot;&gt;The &lt;span data-end=&quot;76&quot; data-start=&quot;57&quot;&gt;Employee Orders&lt;/span&gt; &lt;a href=&quot;https://www.msaccesstips.com/2012/05/deleting-folders-with-dos-command.html&quot; target=&quot;_blank&quot;&gt;command button&lt;/a&gt; opens the form with the Graph Chart (included in the TabControl menu). The Next Command Button, labeled &lt;span data-end=&quot;220&quot; data-start=&quot;203&quot;&gt;Heading Color&lt;/span&gt;, changes the &lt;span data-end=&quot;247&quot; data-start=&quot;234&quot;&gt;ForeColor&lt;/span&gt; property of the form’s heading label.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;469&quot; data-start=&quot;289&quot;&gt;The &lt;span data-end=&quot;302&quot; data-start=&quot;293&quot;&gt;Close&lt;/span&gt; button triggers a 10-second countdown on the label positioned above the SubForm. Once the countdown reaches zero, the form &lt;span data-end=&quot;445&quot; data-start=&quot;426&quot;&gt;&lt;i&gt;frmControls_All&lt;/i&gt;&lt;/span&gt;&amp;nbsp;closes.&lt;/p&gt;&lt;p data-end=&quot;141&quot; data-start=&quot;47&quot;&gt;The Class Modules associated with the main form controls are named with the prefix &lt;span data-end=&quot;138&quot; data-start=&quot;130&quot;&gt;Cls….&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p data-end=&quot;270&quot; data-start=&quot;143&quot;&gt;You can view the complete list of these Class Modules in the &lt;span data-end=&quot;227&quot; data-start=&quot;204&quot;&gt;declaration section&lt;/span&gt; of the &lt;span data-end=&quot;254&quot; data-start=&quot;235&quot;&gt;ClsControls_All&lt;/span&gt; Class Module.&lt;/p&gt;
&lt;pre&gt;Private tx As ClsText
Private cmd As ClsCmdButton
Private cbo As Clscombo
Private Lst As ClsListBox
Private Opt As ClsOption
&lt;/pre&gt;
&lt;h4&gt;Demo Database Download Link:&lt;/h4&gt;
&lt;!--Download Link /downloads/2023/09/MixAllControls.zip.zip--&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://drive.google.com/file/d/1HX-CdfeRtgjMRRN2Zl8VbzGSdduMaWFg/view?usp=sharing&quot;&gt;
&lt;img border=&quot;0&quot; data-original-height=&quot;29&quot; data-original-width=&quot;22&quot; height=&quot;29&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFE4uDLH9dk3S6pEcfTkT6GW6r11XqBI4HQnLnhQFZMKFeeQt5ABV_NqvLHM68J7RacISsvbUEl0PlAq6V7i0t0mQF3iesrBuqGuvrf5CJV72OzrGZ7rdMxkxzw8FYlz-qniNySoqtqUN4/s320/zip.gif&quot; width=&quot;22&quot; /&gt;MixAllControls.zip&lt;/a&gt;
&lt;/div&gt;
&lt;!--Download Link /downloads/2023/09/MixAllControls.zip--&gt;
&lt;br /&gt;
&lt;h3&gt;Streamlining Form Module Code in Standalone Class Module.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/reusing-form-module-vba-code-for-new.html&quot; target=&quot;_Blank&quot;&gt;Re-using Form Module VBA Coding for New Projects.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/04/streamlining-form-module-code-part-two.html&quot; target=&quot;_Blank&quot;&gt;Defining Custom Events in Microsoft Access Part Two&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/05/streamlining-form-module-code-part-three.html&quot; target=&quot;_Blank&quot;&gt;Objects and Their Built-in Events Part 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Standalone Class Module and Events - Part Four&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/06/streamlining-form-module-code-part-four.html&quot; target=&quot;_Blank&quot;&gt;Several TextBoxes and Event Capturing Part Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-six.html?m=1&quot; target=&quot;_Blank&quot;&gt;&amp;nbsp;Class Objects and Wrapper Classes - Part Six&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-seven.html&quot; target=&quot;_Blank&quot;&gt;Form Module vs. Reusable Class Module Coding Demo - Part Seven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/07/streamlining-form-module-code-part-eight.html&quot; target=&quot;_Blank&quot;&gt;Collection Object replaces Class Object Array - Part Eight&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-nine.html&quot; target=&quot;_Blank&quot;&gt;Reusability of Streamlined VBA Code - Part Nine&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part-Ten.html&quot; target=&quot;_Blank&quot;&gt;Organizing Wrapper Classes for Different Forms - Part Ten&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/08/streamlining-form-module-code-part.html&quot; target=&quot;_Blank&quot;&gt;ComboBox and Option-Group Wrapper Classes - Part Eleven&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-code-in.html?m=1&quot; target=&quot;_Blank&quot;&gt;Report Module Code in Class Module - Part Twelve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-report-module-in-class.html&quot; target=&quot;_Blank&quot;&gt;Hiding Report Lines Conditionally - Part 13&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html&quot; target=&quot;_Blank&quot;&gt;Form Report Detail Sections Event Handling - Part 14&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-custom-made-form-wizard.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Form Wizard VBA - Part 15&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-custom-report.html&quot; target=&quot;_Blank&quot;&gt;New Custom-Made Report Wizard - Part 16&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/10/streamlining-form-vba-external-files.html&quot; target=&quot;_Blank&quot;&gt;Streamlining VBA External Files List in Hyperlinks-17&lt;/a&gt;&lt;/li&gt; 
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Event Procedures 3D-Text Wizard-18&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/11/streamlining-event-procedures-rgbcolor.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Form Module VBA RGBColor Wizard-19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2023/12/streamlining-numbers-to-words-converter.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Numbers to Words Converter-20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/streamlining-form-module-code.html&quot; target=&quot;_Blank&quot;&gt;Form VBA Structured Coding Access Users-Group Europe Presentation-21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/01/the-event-firing-mechanism-in-access.html&quot; target=&quot;_Blank&quot;&gt;The Event Firing Mechanism in Access Objects-22&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/one-textbox-and-three-wrapper-class.html&quot; target=&quot;_Blank&quot;&gt;One TextBox and Three Wrapper Class Instances-23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-synchronized-forms.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Synchronized Floating Popup Form-24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/02/streamlining-code-database-compacting.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Compacting/Repair Database-25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamlining-code-reminder-popup-form.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Remainder Popup Form-26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/03/streamline-zoom-in-control-data-editing.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Editing Data in Zoom-in Control-27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/streamline-filter-by-character-sort.html&quot; target=&quot;_Blank&quot;&gt;Streamlining Code Filter By Character and Sort-28&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/04/table-query-records-in-collection-object.html&quot; target=&quot;_Blank&quot;&gt;Table Query Records in Collection Object-29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/class-for-all-data-entry-editing-forms.html&quot; target=&quot;_Blank&quot;&gt;Class for All Data Entry Editing Forms-30&lt;/a&gt;&lt;/li&gt;  
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/05/wrapper-class-module-creation-wizard.html&quot; target=&quot;_Blank&quot;&gt;Wrapper Class Module Creation Wizard-31&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.msaccesstips.com/2024/06/wrapper-class-template-wizard-v2.html&quot; target=&quot;_Blank&quot;&gt;wrapper-class-template-wizard-v2&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='https://www.msaccesstips.com/feeds/3111012847067704305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/3111012847067704305'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/7457417942281874810/posts/default/3111012847067704305'/><link rel='alternate' type='text/html' href='https://www.msaccesstips.com/2023/09/streamlining-form-module-code-part-14.html' title='Form and Report Detail Sections Event Handling - Part 14'/><author><name>a.p.r. pillai</name><uri>http://www.blogger.com/profile/02627590161919120214</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjmyGG0mY3t2AE2UuIV7ccZMZgLmKRmNptVqOsdJwBOgdW__2ne4jAYN2LNM7yHlpP4CkJ5b_xiOZplsKZ7PLoN7hVsPQkVU_T1kV6RnhUT-o_tknEBInX7AKmXRto6ntyPJWSOxvgi-gC7He4Ie2YQvblA3CrAMhKCao42U5s1xjLd5A/s1600/IMG_1373.PNG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizIVywqhfzoizcEIh_banRi273XyTD6qiaOwaUHkyS7f6ANpjas8lNOXMwUwMtuTthf2PQEbEANVWNgg4D8wOZBAqi41PIXfr5UQqcNEsbAeKUWIP2aq-SANmHiua_mNXI1k95xGsD7zm7D3CrKXsdPhH_hc1UCYvPSzFNk0cme6cETBk4TZwodz7tX62s/s72-c/StremlineAllForm.png" height="72" width="72"/><thr:total>2</thr:total></entry></feed>