Git Product home page Git Product logo

vba-idictionary's Introduction

VBA-IDictionary v2.2 (February 05, 2023)

VBA dictionary alternative to the Scripting.Dictionary which is Mac compatible which implements a IScriptingDictionary interface to allow for various dictionary implementations.

Classes Required:

Optional Reference Addin: Microsoft Scripting Runtime Scripting scrrun.dll

Usage

Creating an IScriptingDictionary

Creating a IScriptingDictionary with Dictionary.Create()

The Dictionary.cls is an IScriptingDictionary factory class. It returns an available IScriptingDictionary implementation, according to the compiler constants and/or the implementation specified. I.e. If the Scripting.Dictionary is specified and not available the DictionaryKeyValuePair will be returned. Cannot use New and must use the Dictionary.Create method to create a IScriptingDictionary object.

The Dictionary.Create has three optional parameters:

  • dictionaryType : Specifies which IScriptingDictionary implementation to create. i.e. ScriptingDictionary or DictionaryKeyValuePairs. Default is the IScriptingDictionaryType.isdtScriptingDictionary.

  • compareMethod : Specifies how string keys are handled either case sensitive or ignore case. Default value is vbBinaryCompare.

  • encodingMethod : Specifies which encoding method to use on case sensitive string keys i.e. Unicode or ASCII. It is only applicable to the DictionaryKeyValuePair class for improved performance, and the option TextEncodingMethod.temAscii should only be used where string keys are ASCII compatible. Default value is TextEncodingMethod.temUnicode.

Examples:

Dim myDictionary As IScriptingDictionary

Set myDictionary = Dictionary.Create

Set myDictionary = Dictionary.Create(IScriptingDictionaryType.isdtScriptingDictionary, VBA.vbTextCompare)

Set myDictionary = Dictionary.Create(IScriptingDictionaryType.isdtDictionaryKeyValuePair, VBA.vbBinaryCompare, TextEncodingMethod.temAscii)

Creating using directly a IScriptingDictionary implementation provided

Two IScriptingDictionary implementations have been provided, DictionaryKeyValuePair and ScriptingDictionary, they can be created using New or the Create method.

The ScriptingDictionary.Create() has one optional parameter:

  • compareMethod : Specifies how string keys are handled either case sensitive or ignore case. Default value is vbBinaryCompare.

Example

Dim myDictionary As IScriptingDictionary 'or could use As ScriptingDictionary

Set myDictionary = ScriptingDictionary.Create(VBA.vbTextCompare)

The DictionaryKeyValuePair.Create() has the two optional parameters:

  • compareMethod : Specifies how string keys are handled either case sensitive or ignore case. Default value is vbBinaryCompare.

  • encodingMethod : Specifies which encoding text method to use on case sensitive string keys i.e. Unicode or ASCII. This parameter provides performance improvement for ASCII compatibile string keys. The default value is TextEncodingMethod.temUnicode

    Dim myDictionary As IScriptingDictionary 'or could use As DictionaryKeyValuePair

Set myDictionary = DictionaryKeyValuePair.Create(VBA.vbTextCompare, TextEncodingMethod.temAscii)

Add, CompareMode, Count, Exists, Item, Key, Items, Keys, Remove, RemoveAll

The same behaviour as the Scripting.Dictionary object

Compiler Constants

Note the compiler constants in the Dictionary.cls and ScriptingDictionary.cls

These compiler constants may require updating to True or False according to the availablity of the Scripting.Dictionary reference and platform.

For Mac:

#Const SCRIPTING_REFERENCE = False

#Const SCRIPTING_LATEBINDING = False

For Windows:

If the Microsoft Scripting Runtime Scripting is referenced:

#Const SCRIPTING_REFERENCE = True

If the Microsoft Scripting Runtime Scripting not referenced but wish to use it late bound:

#Const SCRIPTING_REFERENCE = False

#Const SCRIPTING_LATEBINDING = True

For Mac as the Scripting.Dictionary isn't available the Dictionary.Create uses the DictionaryKeyValuePair as a compatible alternative.

On Windows if both compiler constants are set to False the Dictionary.Create uses the DictionaryKeyValuePair as an alternative.

Advantages

The VBA-IDictionary provides interfaces for the dictionary implementations provided, allowing for the easy transition when switching between dictionary implementations. i.e. It allows for programming to an interface instead to a particular implementation which can be advantageous for unit testing etc.

Added support for keys of LongLong data type which is only availablue using the DictionaryKeyVluePair.cls IScriptingDictionary implementation and compatibile with VBA 7. This also allows using LongPtr as keys as they are converted to the LongLong or Long data type for VB6.

Significant performance compared to other VBA dictionary implementations, and in some scenerios provides a significant performance over the MS Runtime Scripting.Dictionary.

Performance

Great consideration has been given to provide as good as possible performance while using the underlying VBA.Collection.

See the Excel VBA-IDictionaryPerformance spreadhsheet for a performance comparisions of the ScriptingDictionary, DictionaryKeyValuePair and other VBA dictionary implementations. Performance results displayed in the graphs can be filtered to compare various IScriptingDictionary implementations, for the various key and item data types and string key encoding options provided.

Performance testing can be performed using the modules in the MS Access database provided, TestPerformanceKeyValuePairAdd.bas and TestPeformanceKeyValuePairItem.bas and results are displayed in the immediate window. The results are currently manually copied into the peformance Excel spreadsheet using the Text Import Wizard. Those modules are still under development.

The DictionaryKeyValuePairs compared to other VBA dictionary implementations its significant performance improvement, especially when adding items, is likely due to not constantly maintaining an array of Items and Keys, and only populating them when requested. On future requests for Items and Keys they are only repopulated if changes have been made to the dictionary keys, and/or items. This tradeoff results in the first iteration of Items and Keys to be fractionally slower and any subsequent requests without changes are at similar performance as not repopulated.

For Adding items, compared to the MS Scripting.Dictionary for datasets at approximately 350,000 items it starts to outperform.

For the scenerio for string keys and the compare mode is vbTextCompare at approximately 100,000 items it starts to outperform.

Overall the performance of the DictionaryKeyValuePair has significant improvements over other VBA dictionary implementations at approximately twice the performance for small datasets, and numerous times for large ones. It appears to have a gradual linear degraduation in performance the larger the dataset.

I haven't recently got around to pushing it limitations, thou should be reasonably capable of handling datasets of two million items within a reasonable timeframe. The Scripting.Dictionary noticeably degrades in performance for datasets over 500,000+ items.

For datasets continaing key and/or items that are objects whatever the data structure used, VBA's appears slow at dereferening of objects and destroying them as it is single threaded. For this requirement it's best to keep datasets under 300,000 items as it takes considerable time to clean up. The only other work around is when have large datasets containing objects to give them global scope or keep alive and push the cleaning up process to when the application closes.

As always it's a matter of selecting the appropriate data structure for your requirements and not one suits all purposes.

Testing

Unit testing can be found in TestModuleDictionaryKeyValuePair.bas within the Ms Access database provided. The VBA Addin Rubberduck is required to run the unit testing.

Only tested on the Windows platform VBA 7 and would be appreciated if anyone can test it on the Mac platform and for VB6. I don't anticipate any compatiblity issues if the compiler constants are appropriately set.

Notes

Support for keys of LongLong data type which is only availablue under VBA 7 using the DictionaryKeyValuePair.

Untested on Mac and VBA 6.

Version 2.1 Modifications

For performance improvements removed the use of a managed variant containing an Integer array to use a managed Integer Array. Overall result was a slight performance improvement of approximately 5% for processing case-sensitive string keys.

Updated TextEncoderUnicode ToHexString function to use a managed Char array which is manually freed when the class goes out of scope.

Added ManagedCharSafeArray.cls

Added TypeSafeArray.bas

Version 2.1 Modifications September 05, 2019

MangedCharSafeArray was restructured to more appropriately associate a managed Char array with its SafeArray descriptor allocated. This was to ensure that the SafeArray descriptor is allocated to only one managed Char array at a time.

  • Updated to predeclared class and added a Create method.

    Public Function Create(ByRef outCharsArray() As Integer) As ManagedCharSafeArray

  • The Get Property was removed and a replace with the method:

    Public Sub SafeArrayAllocateToCharArray(ByRef outManagedChars() As Integer)

Version 2.2 Modifications February 05, 2023

  • Updated: Mac 32 CopyAnyToMemory was incorrectly named CopyMemoryByPtr

Future Modifications

From the initial release have improved the performance of processing case-senstive string keys by appropriately 20% and there are now limited opportunities for future performance improvements. Any suggestions for performance improvements or issues are highly welcomed.

Also testing is required on the Mac platform and VB 6 which I'm unable to test.

In a separate project will aim to extend the VBA-IDictionary project with an IList and/or ICollection interface.

vba-idictionary's People

Contributors

markjohnstonegithub avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

vba-idictionary's Issues

Add unit tests

Hi,

In the readme, you mention unit tests for Rubberduck, but they don't appear to be in the repo. Are they still to be added?

I have VB6 installed, and would be happy to test.

Thanks,
Andy

Do you have community or documentation?

Is your feature request related to a problem? Please describe.
Do you have a tutorial how to use it? With VB6 etc how I can contact you?
I want to create com object and use it in VBA,VB6

Testing required for Mac and VBA 6

Unable to test on Mac and for VBA 6.

Possibly there could be issues with the TextEncodingUnicode for case-sensitive string keys when using memory functions, thou have used what should be Mac and VBA 6 compatible options.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.