Skip to content

GregYannes/SOb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SOb

The SOb framework lets you simulate "objects" in VBA.

With a full suite of features at your fingertips — including pretty printing — your simulated object ("SOb") mimics an object or UDT without the frustrating downsides. No matter how many SObs you need, or where you need them, this framework supports them within your existing code. No imports are needed!

Tip

See here for the latest (pre)release.

The SOb Story

I first encountered this use case when developing GitHelp, which simulates a fielded "library" of documentation. It demanded an innovative approach, and as seasoned developers chimed in, this took on a life of its own!

Like me, you might desire several such data structures, where some fields are accessible (or not) to outside users. These structures (like UDTs) are self-contained within your module, yet (like objects) they can be used by object classes and modules alike. Ideally these other modules should still compile in the absence of yours, which should be easy for lay users to (re)install.

Unfortunately, neither objects nor UDTs achieve this outcome! For every object you include, your users must install an additional class module. And if objects "are a pain", then "UDTs are notoriously problematic".

Advantages

The SOb framework addresses all these shortcomings. It builds your SOb atop a Collection, which is native to VBA across platforms (Windows and Mac). And unlike classes, your SObs carry no baggage whatsoever—you can easily set them all up within your existing module!

Feature Description SOb Object UDT
Painless Is it quick and easy for you to code? 1
Installable Is it quick and easy for lay users to install your code? 2
Native Is it native to VBA?
Portable Does it work across all platforms?
Independent Is it free of external dependencies? 3
Global Can it be used seamlessly across other modules and classes? 4 5
Compilation Can its dependents compile in its absence? 6 7
Instantiation Can you dynamically declare new instances after design time? 8 9
Placeholder Can it be passed to a generic Variant or Object? 10 7
Collectible Can it be included within a Collection (or Dictionary)? 11 7
Identity Is its type identifiable by name, so you can distinguish it? 12 13
Methods Does it support procedures that operate on it? 14 15 16
Printing Does it support pretty printing for visualization? 17
Validation Can it validate values before they are assigned to fields? 18 19 20
Private Can you hide certain fields (and "methods") from your user? 21 21
Secure Are its fields secure against unauthorized editing? 22 23

Setup

Setup is quick and painless with handy templates. Simply fill out the TODOs and paste the result in your module! See here for detailed instructions.

Usage

Using an SOb is analogous to using an object. The SOb framework provides a backend, which lets you implement your frontend for your actual SOb.

Simply enumerate its fields (like "Bar") in the template, and you may manipulate your SOb ("Foo") as illustrated below.

Private Enum Foo__Fields
	Bar
	' ...
End Enum

See documentation for further details and concrete examples.

Action Frontend Backend Object UDT
Declaration Dim x As Object Dim x As Object Dim x As Foo Dim x As Foo
Instantiation Set x = New_Foo() Set x = New_Obj("Foo") Set x = New Foo
Reading Foo_Bar(x) Obj_Field(x, Bar) x.Bar x.Bar
Writing Foo_Bar(x) = 1 Obj_Field(x, Bar) = 1 x.Bar = 1 x.Bar = 1
Invocation Foo_Fun(x, …) x.Fun(…)

API

Here are all the features provided by SOb for developers. To avoid confusing your users, the SOb module hides its own functions from Excel, via Option Private.

Metadata

Describe the SOb module itself.

Creation

"Declare" a new SOb.

Typology

Ascertain the "type" of an SOb…

  • Obj_Class(): Retrieve the simulated "class" (String) of an SOb.
  • IsObj(): Test (Boolean) if something is an SOb.

…and manipulate that type.

  • AsObj(): Cast something as an SOb (Object).

Fields

Access simulated "fields" in an SOb…

…along with metadata about such fields.

Validation

Validate SObs within advanced implementations of Is*().

  • Obj_Check(): Call your accessors without assignment, merely to test (say) their type integrity.
  • Obj_CheckError(): Test (Boolean) if certain errors (like type) invalidate the check, but propagate any other errors.

Visualization

Textually visualize the entire SOb…

…or specifically its fields in detail.

Utilities

Perform broadly useful (Public) tasks via the SOb module

…along with further (Private) tasks via an SOb snippet in your own module.

Footnotes

  1. "Classes are a pain" to develop.

  2. To avoid burdening users with prohibitive setup, developers have often resorted to dubious hacks!

  3. For every object you include, your users must install an additional class module.

  4. A class module may call procedures from standard modules, like your own module or even the SOb module.

  5. UDTs are restrictively siloed between classes and modules.

    There is only one exception7.

  6. Their absence can derail compilation, unless other modules inefficiently resort to late-binding.

  7. Not unless you reference the UDT in a type library. 2 3 4

  8. You may declare new instances of objects at runtime, using the New keyword…

  9. …but you may not declare new instances of UDTs.

  10. You cannot pass them to placeholders like Variant or Object

  11. …nor can you include them within a Collection or (on Windows) a Dictionary.

  12. Via Obj_Class() and IsObj().

  13. Via the TypeName() function or the TypeOf operator.

  14. Technically these "methods" are simply modular procedures of the form SOb_Method(sob, …), where the sob is passed by reference. 2

  15. Objects support methods for performing actions…

  16. …but UDTs do not support methods and "cannot carry out actions".

    Technically, you could imitate an SOb and implement "methods"14 of the form UDT_Method(udt, …), where the udt is passed by reference.

  17. Unlike .NET and other languages, VBA does not implement a prototypical .ToString() method for objects.

  18. The accessors for your SOb are Property procedures, in which you may validate input19 before assigning it to the field.

  19. Objects use Property procedures to validate values for fields… 2

  20. …but UDTs have no mechanism for validation.

  21. Via the Private keyword for properties (and procedures). 2

  22. Its fields are "encrypted" against the more insidious tampering. Others cannot typically overwrite the value of a "private" field in your SOb—though they can remove the field, which effectively resets it to an uninitialized state.

    However, if you outsource the framework from your module to the SOb module, then others can overwrite it via SOb.Obj_Field().

  23. Their fields are still vulnerable to editing.

About

Simulate objects in VBA.

Resources

Stars

Watchers

Forks

Languages