I have a program that reads/interprets user text; then uses the info to do other stuff.
text (XL sheet) --> interpret routine --> UDT(s) (parameters(list) what the user text is saying)
The routine for interpreting text is vastly complicated and slow.
I want to save/load the interpreter UDT(s) results, so the program can attempt to skip the interpret routine when executed.
Re: Passing UDT as variant, for saving/loading UDTs
You have to declare your UDT in a TypeLib. You can create TypeLibs with VB6, but, when done that way, you have to distribute the TypeLib. Alternatively, you can learn about these TypeLibs and compile them with the MIDL compiler. Done that way, they don't have to be distributed with your EXE.
And, once your UDT is declared in your TypeLib (as opposed to within your VB6 source code), you can place them into Variant variables.
(I'd supply references, but I've got to go in a few.)
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: Passing UDT as variant, for saving/loading UDTs
Also, just to say it, be sure to declare all procedures in your forms and CLS modules as Friend (rather than Public). If you've got a public UDT, you can pass it around to Friend procedures without a problem, although the argument must be declared with the UDT's declaration name (and not passed as a Variant). Only way to get a UDT into a Variant is to use a TypeLib.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: Passing UDT as variant, for saving/loading UDTs
I got something. It was painful.
I spent a while trying to figure out a work around. There is nothing.
VB can't do reflections
VB can't do overloads
VB can't do GOTO labels outside of scope
I made Class that has Save/Load functions. And Get/Let Properties with the same name(s) as the user-type...
I made it as copy/paste-able as possible, for adding/removing user-types to class code.
Here's the thing, I'm actually doing this in EXCEL-VBA. I posted it here because that is were the Save/Load UDT array Post was. I thought it made more sense to keep the post here because it had nothing to do with the Office App it was being run from.
With VBA you can programmatically create code. According to the internet you can do the same in VB.
So I made a Class that automatically creates the UDT SAVE/LOAD Class with functions for all the custom user-types. That way you don't have to manually edit UDT-SAVE/LOAD Class every time you add or remove a user-type.
Attached is the code.
For VB I think you just need to replace ThisWorkbook with Application in the makeUDTTool Class and it should run.
makeUDTtool.cls : Class for creating UDT save/load class
Module_demo_4_UDTtool.bas : routines for creating and using UDT save/load class
new1_UDTTools.cls : for reference, should not need to import
new2_UDTTools.cls : for reference, should not need to import
Import the makeUDTTool class
Import the Module_demo_4_UDTtool module
Run the udtTool_maker_demo routine
newX_UDTTools Class(s) should be created
Run the udtTool_SaveLoad_demo routine
Shows how the newly created new2_UDTTools Class is used.
Re: Passing UDT as variant, for saving/loading UDTs
Tony, I'm sorry but I didn't look at your code. But yeah, you can wrap a UDT in an object (instantiated from a class), and then get that "wrapped" UDT into a variant. But, it's a pain. Once it's in a typelib, it's much easier to do.
But yeah, you can wrap the UDT in a class, and do it.
For example, here's some code for a BAS module:
Code:
Option Explicit
Public Type MyUDT
a As Long
b As Long
End Type
And code for a Class1 CLS module:
Code:
Option Explicit
Dim InternalUdt As MyUDT
Friend Property Get TheUdt() As MyUDT
TheUdt = InternalUdt
End Property
Friend Property Let TheUdt(udt As MyUDT)
InternalUdt = udt
End Property
And finally, some test code for a Form1 FRM module:
Code:
Option Explicit
Private Sub Form_Load()
Dim c1 As New Class1 ' Our instantiated class used as a UDT wrapper.
Dim u1 As MyUDT ' A test UDT.
u1.a = 5 ' Give it some non-zero values.
u1.b = 6
c1.TheUdt = u1 ' Copy it in the class wrapper.
Dim u2 As MyUDT ' Another test UDT.
u2 = c1.TheUdt ' Get UDT out of wrapper (as a copy).
Debug.Print u2.a ' Check: Yep, it prints 5.
Dim v As Variant ' Variant for putting class into.
Set v = c1 ' Stick our wrapper class into the variant (as a reference).
Dim c2 As Class1 ' Another class variable for another reference of our class.
Set c2 = v ' Pull wrapper class out of variant (creating yet another reference to it).
Dim u3 As MyUDT ' Another UDT for testing.
u3 = c2.TheUdt ' Copy our UDT out of this new class reference.
Debug.Print u3.a ' Check and see if it's a good copy. Yep, it prints 5.
End Sub
---------
And just FYI, you can reference TypeLibs in the VBA:
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: Passing UDT as variant, for saving/loading UDTs
you can wrap a UDT in an object (instantiated from a class), and then get that "wrapped" UDT into a variant. But, it's a pain. Once it's in a typelib, it's much easier to do.
Re: Passing UDT as variant, for saving/loading UDTs
Nvm, that is what I did... Just a more complete version...
That is not what I did...
I made these containers a Type and not a Class for a reason; I wanted them to behave like a value-type.
I have Types inside Types inside an array in other Types and so on...
%99.9 of the time I do NOT want the equal sign '=' to be setting things by reference.
If they were classes I would have to make and update clone routines for every container created, and have nested clone procedures... And used Clone instead of '=', for hundreds times in the code
Cloning is slow and makes the code hard to follow. Any small changed made to a container would also require changing X number of clone routines.
I have a universal clone routine in .NET but it uses reflections, which VB does not have.
If something is accidently set byref it can be a nightmare trying to figure out what and where the error is.
Also, I would have to deal with initializing every container created.
--------------------------------------
I don't want to make a TypeLib because I cannot/will not use additional reference in any of my EXCEL-VBA programs.
My programs are run by everyone, some of which no nothing of programming or how to add missing dlls, or have the privileges to do so.
Programs need to run on various Windows Versions and Excel versions and 32b, and be update immune. A seemingly small extra step of adding a missing TypeLib to someone's computer can turn into a major hassle... I did it before, never again.
--------------------------------------
The code attached creates a class with Save/Load capabilities for every UDT used... Creates generic properties names so the operation is self explanatory.
Look at Sub udtTool_SaveLoad_demo()
Code:
'________ some user-defined types for code demonstration _________________________________
'
' !Types CANNOT conatain Objects or enumerations for UDT SAVE/LOAD tool to work
'
' -Must be Public
' -Name Does NOT matter
' *if the name(s) are changed, the UDT-Tool Class must be re-made using 'makeUDTtool'
Public Type myTYPE1
num1 As Double
str1 As String
End Type
Public Type myTYPE2
type1_arr() As myTYPE1
num2 As Integer
num_arr2() As Integer
End Type
Public Type myTYPE3
type2_arr() As myTYPE2
str3 As String
End Type
'_______________________________________________________________________________
'_____ UDT SAVE/LOAD Tool CLass Maker ___________________________________
'
' only need to be called once
' will only make code if Class does Not exist yet
'
' Creates a Class that has functions for Saveing/Load UDT arrays from file
'
' myUDTmakerTool.makeClass [name of new-Class], [exact name of User-Type], [exact name of User-Type], ...
'
' After this is run, the 'udtTool_SaveLoad_demo' can run
'
'myTYPE1
'myTYPE2
'myTYPE3
Sub udtTool_maker_demo()
Dim myUDTmakerTool As New makeUDTtool
' *attempt to make UDT tool with no type-names passed
'
' *need UDT names, won't make anything
'
myUDTmakerTool.makeClass "new1_UDTTools"
'- make UDTtool named 'new1_UDTTools' with only 'myTYPE1' functions/properties
'
myUDTmakerTool.makeClass "new1_UDTTools", "myTYPE1"
'SUCCESS
' *attempt make UDTtool for 'myTYPE2' using the SAME NAME
' - will NOT do anything!
'
' code will not overwrite existing Classes
' must delete Class manually to remake
'
myUDTmakerTool.makeClass "new1_UDTTools", "myTYPE2"
' make UDTtool named 'new2_UDTTools' with all user-type functions
'
myUDTmakerTool.makeClass "new2_UDTTools", "myTYPE1", "myTYPE2", "myTYPE3"
'SUCCESS
' now Classes 'new1_UDTTools' & 'new2_UDTTools' are available
'
' They'll have save/load functions for {myTYPE1} & {myTYPE1,myTYPE2,myTYPE3} (respectivly)
'
End Sub
'myTYPE1
'myTYPE2
'myTYPE3
Sub udtTool_SaveLoad_demo()
Dim demo_type1() As myTYPE1
Dim demo_type2() As myTYPE2
Dim demo_type3() As myTYPE3
Dim check_type1() As myTYPE1
Dim check_type2() As myTYPE2
Dim check_type3() As myTYPE3
Dim myUDTtool As New new2_UDTTools '<-- made in the above code
'-- populate UDTs with crap
Call populate_demo_types(demo_type1, demo_type2, demo_type3)
'-- retain values (for program validation)
check_type1 = demo_type1
check_type2 = demo_type2
check_type3 = demo_type3
'____ Program will SAVE UDT arrays to file(s) _____________________________
'STEP (1)
'-- add UDT arrays to TOOL (type1&3)
myUDTtool.myTYPE1 = demo_type1
myUDTtool.myTYPE3 = demo_type3
'STEP (2)
'-- save to computer
'
' saves both 'demo_type1', 'demo_type3'
'
' !! 'demo_type2' is NOT saved
' it was not added to the udtTOOL @ STEP (1)
'
' default filename is:
' "udt_array_[UDTname].txt"
'
myUDTtool.SaveUDT
'STEP (3)
'-- now add 'demo_type2'
myUDTtool.myTYPE2 = demo_type2
'STEP (4)
'-- save all 3 to 'myFavoriteFile_[UDTname].txt'
'
' "myFavoriteFile_myTYPE1.txt"
' "myFavoriteFile_myTYPE2.txt"
' "myFavoriteFile_myTYPE3.txt"
'
myUDTtool.SaveUDT "myFavoriteFile"
'STEP (5)
'-- save only demo_type2 to 'myThirdFile_[UDTname].txt'
'
' "myThirdFile_myTYPE2.txt"
'
' function will recongnize "myTYPE2" in 'FileName' argument
' and only save that type
'
myUDTtool.SaveUDT "myThirdFile" & "myTYPE2"
'_______ This is what is Should be saved at this Point ________________________
'
'* in the same directory as the WorkBook ...
'
' "udt_array_[UDTname].txt"
' -type1 & type3 saved there @ STEP (2)
' udt_array_myTYPE1.txt
' udt_array_myTYPE2.txt
'
' "myFavoriteFile_[UDTname].txt"
' -type1 & type2 & type3 saved there @ STEP (4)
' myFavoriteFile_myTYPE1.txt
' myFavoriteFile_myTYPE2.txt
' myFavoriteFile_myTYPE3.txt
'
' "myThirdFile_[UDTname].txt"
' -type2 saved there @ STEP (4)
' myThirdFile_myTYPE2.txt
'_______________________________________________________________________________
'____ Now, Program will LOAD UDT arrays from file(s) ___________________________
'STEP (6)
'-- load files saved with filename "udt_array_[UDTname].txt"
'
' *remember, only type1&3 were save here @ STEP (2)
'
'
Erase demo_type1 '<-- erase local arrays
Erase demo_type2
Erase demo_type3
myUDTtool.LoadUDT "udt_array"
demo_type1 = myUDTtool.myTYPE1
demo_type3 = myUDTtool.myTYPE3
demo_type2 = myUDTtool.myTYPE2 '<-- this will work, !!BUT it is NOT from the "udt_array" file
' It is from the file set @ STEP (3)
' Class still retains the type2 array that was set
'STEP (7)
'-- repeat STEP (6) but also set data in 'myUDTtool' to Nothing
'
'
Erase demo_type1 '<-- erase local arrays
Erase demo_type2
Erase demo_type3
myUDTtool.myTYPE1 = demo_type1 '< *Also reset arrays in Class
myUDTtool.myTYPE2 = demo_type2
myUDTtool.myTYPE3 = demo_type3
myUDTtool.LoadUDT "udt_array"
demo_type1 = myUDTtool.myTYPE1
demo_type3 = myUDTtool.myTYPE3
demo_type2 = myUDTtool.myTYPE2 '<-- !Now this will NOT work, unlike STEP (6)
' because the arrays were also reset in the Class
' -type2 was NOT save @ "udt_array...txt", so it is still set to NOTHING
'STEP (8)
'-- get ALL UDT arrays saved in "myFavoriteFile_[UDTname].txt"
'
'
Erase demo_type1 '<-- erase local arrays
Erase demo_type2
Erase demo_type3
myUDTtool.myTYPE1 = demo_type1 '< *Also reset arrays in Class
myUDTtool.myTYPE2 = demo_type2
myUDTtool.myTYPE3 = demo_type3
myUDTtool.LoadUDT "myFavoriteFile"
demo_type1 = myUDTtool.myTYPE1
demo_type2 = myUDTtool.myTYPE2
demo_type3 = myUDTtool.myTYPE3
'STEP (9)
'
' (A) get ONlY type1 from "udt_array_[UDTname].txt"
'
' (B) get ONLY type2 from "myThirdFile_[UDTname].txt"
' * type2 is the only one saved there @ STEP (5)
'
' (C) get ONLY type3 from "myFavoriteFile_[UDTname].txt"
'
'
Erase demo_type1 '<-- erase local arrays
Erase demo_type2
Erase demo_type3
myUDTtool.myTYPE1 = demo_type1 '< *Also reset arrays in Class
myUDTtool.myTYPE2 = demo_type2
myUDTtool.myTYPE3 = demo_type3
'____(A)____________________________________________________________
myUDTtool.LoadUDT "udt_array" & "myTYPE1" '<-- load only type1 from "udt_array...txt"
Erase demo_type1 '<-- erase local arrays
Erase demo_type2
Erase demo_type3
'-------------------------
demo_type1 = myUDTtool.myTYPE1 '<-- should work
demo_type2 = myUDTtool.myTYPE2 '<-- !should NOT work
demo_type3 = myUDTtool.myTYPE3 '<-- !should NOT work
'____(B)____________________________________________________________
myUDTtool.LoadUDT "myThirdFile" '<-- load only type2 from "myThirdFile...txt"
' *remember only type2 was saved there @ STEP (5)
' therefore, 'myTYPE2' does NOT need to be specified in the argument
Erase demo_type1 '<-- erase local arrays
Erase demo_type2
Erase demo_type3
'-------------------------
demo_type1 = myUDTtool.myTYPE1 '<-- should work, Class still holds UDT array loaded from "udt_array...txt" (above)
demo_type2 = myUDTtool.myTYPE2 '<-- should work, Newly loaded from "myThirdFile...txt"
demo_type3 = myUDTtool.myTYPE3 '<-- !should NOT work
'____(C)____________________________________________________________
myUDTtool.LoadUDT "myFavoriteFile" & "myTYPE3" '<-- load only type3 from "myFavoriteFile...txt"
' *remember, all types were saved there @ STEP (4)
Erase demo_type1 '<-- erase local arrays
Erase demo_type2
Erase demo_type3
'-------------------------
demo_type1 = myUDTtool.myTYPE1 '<-- should work, Class still holds UDT array loaded from "udt_array...txt" (above)
demo_type2 = myUDTtool.myTYPE2 '<-- should work, Class still holds UDT array loaded from "myThirdFile...txt" (above)
demo_type3 = myUDTtool.myTYPE3 '<-- should work, Newly loaded from "myThirdFile...txt"
End Sub
Sub populate_demo_types(ByRef demo_type1() As myTYPE1, _
ByRef demo_type2() As myTYPE2, _
ByRef demo_type3() As myTYPE3)
Dim i, j As Integer
Dim str As String
ReDim demo_type1(9)
For i = 0 To UBound(demo_type1)
With demo_type1(i)
.num1 = i
.str1 = CStr(i)
End With
Next
ReDim demo_type2(9)
For i = 0 To UBound(demo_type2)
With demo_type2(i)
.type1_arr = demo_type1
For j = 0 To UBound(.type1_arr)
With .type1_arr(j)
.num1 = .num1 + i * 10
.str1 = CStr(.num1)
End With
Next
.num2 = i * 10
ReDim .num_arr2(5)
For j = 0 To UBound(.num_arr2)
.num_arr2(j) = .num2 + j
Next
End With
Next
ReDim demo_type3(7)
For i = 0 To UBound(demo_type3)
With demo_type3(i)
.type2_arr = demo_type2
For j = 0 To UBound(.type2_arr)
With .type2_arr(j)
.num2 = .num2 * 10
End With
Next
.str3 = CStr(i * 100)
End With
Next
End Sub
Last edited by tonyd5; Oct 26th, 2021 at 08:58 AM.
Re: Passing UDT as variant, for saving/loading UDTs
Glad you got it going.
And yeah, I "get" it with respect to "needing dependencies (like typelibs) registered" on target computers. It can be a problem.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: Passing UDT as variant, for saving/loading UDTs
Tony, I'm not sure what you're trying to do, but this thread might help you. It shows you how to "serialize" a UDT by using a Windows pipe. Then, if you like, you can write that serialized data to wherever you want. Olaf also has the de-serializing code there as well in case you want to put the byte-string back into a UDT.
But yeah, UDTs have all kinds of difficult internal spacing, as well as many things that are "referenced" (like strings and objects). By the way, I doubt that serialization will work if you have any objects in your UDT, but I doubt you do.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: Passing UDT as variant, for saving/loading UDTs
Kind of a specialty case but maybe useful, you can use something like a memory structure class to generically
hold the different types in one configurable container which can be serialized/deserialized at any time.
Downside you do not get intellisense on the field element names. More designed for dealing with file formats,
and extracting structs from raw memory, files, packet buffers etc
Re: Passing UDT as variant, for saving/loading UDTs
Originally Posted by Elroy
Tony, I'm not sure what you're trying to do, but this thread might help you. It shows you how to "serialize" a UDT by using a Windows pipe. Then, if you like, you can write that serialized data to wherever you want. Olaf also has the de-serializing code there as well in case you want to put the byte-string back into a UDT.
But yeah, UDTs have all kinds of difficult internal spacing, as well as many things that are "referenced" (like strings and objects). By the way, I doubt that serialization will work if you have any objects in your UDT, but I doubt you do.
I also looked into that briefly, that is very cool.
The goal is for me or anyone to make Types like normal and be able to use a universal Save/Load function without doing anything extra what so ever.
I believe I accomplished that. I can save/load ANY udt with 2 lines of code in the calling routine; 3 if you count the Class declaration.
Just look:
Code:
' UDTTools (CLass) '< ! this gets made automatically with Let/Get properties for all UDTs
'----------------------------------------------------------------------------------------
' LET: myUDTtool.[Name of UDT](input() as [Name of UDT])
' GET: myUDTtool.[Name of UDT]() as [Name of UDT]
'
' myUDTtool.[SaveUDT|LoadUDT](Optional [Filename & Optional [Name of UDT]] as String)
' myUDTtool.[SaveUDT|LoadUDT]() '<-- [save|load] all UDT arrays [to|from] 'udt_array_[Name of UDT].txt' (for each type)
' myUDTtool.[SaveUDT|LoadUDT]("myfile") '<-- [save|load] all UDT arrays [to|from] 'myfile_[Name of UDT].txt' (for each type)
' myUDTtool.[SaveUDT|LoadUDT]("myfile" & "myTYPE1") '<-- [save|load] only 'myTYPE1()' [to|from] 'myfile_myTYPE1.txt'
'
'
Dim Xvar1() As myTYPE1
Dim Yvar1() As myTYPE1
'
Dim Xvar2() As myTYPE2
Dim Yvar2() As myTYPE2
'
Dim myUDTtool As New UDTTools
'
'add whatever to 'Xvar()[1,2]'
'
'- Save Xvar[1,2] to file
myUDTtool.myTYPE1 = Xvar1
myUDTtool.myTYPE2 = Xvar2
myUDTtool.SaveUDT
'- Load Yvar[1,2] from file
myUDTtool.LoadUDT
Yvar1=myUDTtool.myTYPE1
Yvar2=myUDTtool.myTYPE2
Re: Passing UDT as variant, for saving/loading UDTs
You know? It dawns on me that we could easily put these serialized UDTs into a Variant. Variants can trivially hold Byte arrays, which is what the serialized UDT becomes. And then, when we were ready to use it, just de-serialize it.
Also, personally, I'd take Olaf's work out of that CLS module, and just make them straight-up procedure calls in a BAS module. But that's just me. I use CLS modules often, but I do think people go overboard with their use. However, after examination, his approach does have the advantage of being able to raise an event for the caller.
Last edited by Elroy; Oct 28th, 2021 at 11:44 AM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: Passing UDT as variant, for saving/loading UDTs
The serialization of UDTs is very power.
Its basically a UDT --> Variant converter. Opens up a lot of options.
I can add this feature to the existing solution I did without too much work.
UDT--> Byte() solution still has 2 problems with it.
Wrapping UDT-->Byte() routine in to universal call:
myBYTarr=UDT_2_ByteArr(AnyUDT)
My existing solution already has the ability to work around this problem.
Determining which UDT type the byte array is serializing:
i.e. Which UDT to deserialize to.
This is more tricky.
You could manually specifying which UDT the byte array is supposed to be in code, but this could be a big limitation.
Maybe the name of the UDT can also be stored in the serialized Byte()...
Code:
' used after the input arg is serialized to Byte array
Sub DoDifferent_StuFF(any_ser_UDT() As Byte)
Dim loc_Type1 As SomeUDT
Dim loc_Type2 As AnotherUDT
'!!**!! Which Type is it??
[loc_Type1|loc_Type2] = Derserialize_2_UDT(any_ser_UDT)
' do different operations depending on the input type
Select Case [which_type]
Case which_type = SomeUDT
'
' do stuff
'
Case which_type = AnotherUDT
'
' do different stuff
'
End Select
End Sub
Re: Passing UDT as variant, for saving/loading UDTs
Originally Posted by Elroy
However, after examination, his approach does have the advantage of being able to raise an event for the caller.
Yep... and the two Events are, what makes the routines within the Class-Code generically usable (in a way).
The built-in VB6-serialization we make use of there,
will always want the concrete UDT-Type(Symbol) in the VB6 Put- or Get statements -
there's no way around that really (when you want to avoid "hacking" and much larger code-sources).
So the two Events offer a simple way, to "isolate and move" the Put- and Get-calls into a specific "consumer"-Form or Class-
where one can adjust to a specific UDT-Symbol in just a single extra-code-line (leaving the rest of the Code in the Helper-Class).
And of course - a direct generic conversion-function would be nicer...
but the Event-based approach requires only one single implementation line (a Put or Get call) -
in addition to the Load- or Save- trigger calls on the Class-instance.
Re: Passing UDT as variant, for saving/loading UDTs
Put/Get on UDT must perform a lot of codegen underneath to execute actual [de]serialization.
And that's probably the reason why this feature is still delayed in TwinBasic -- volumes of codegen for all (nested) data-types and edge cases *and* has to be compatible with VB6 undocumented format.
Nowadays I would always go for JSON earlier on feature design phase, which means restricting interchanged data to nested Collections of primitive data-types.
Re: Passing UDT as variant, for saving/loading UDTs
loading and saving UDT is quite slow.
comparing to parse the UDT, its many times slower.
I remember using a loading/saving UDT method and eventually when the UDT was above 5MB it was taking 10 seconds to load/save.
with the parsing method, it takes me under 1 second to load now and the UDT is at this moment 13MB.
the parsing is quite easy to do but it can be quite long.
I use something like: (example)
Code:
With MyUDT
.exp = GetByte
.Speed = GetInteger
.Money = GetDecimal
.ms = GetSingle
.Name = GetString
End With
and each one is a call to a function, like:
Code:
Private Function GetDecimal() As Variant
CopyMemory GetDecimal, data(Size), 16
Size = Size + 16
End Function
and of course to "save" I do the reverse.
example of my "decimal" set
Code:
Private Sub AddDecimal(SourceDecimal As Variant)
CopyMemory data(Size), SourceDecimal, 16
Size = Size + 16
End Sub
when data is all filled up, I simply save the entire array.