static resizeable arrays? 
Author Message
 static resizeable arrays?

OK, here's my next stupid question.  First, bear in mind that this is a
quick-and-dirty utility that will be used in-house for a few months, not
a widely distributed application so it's OK if I get sloppy.

I'm reading data in from a bunch of text files and using the raw incoming
data to produce summaries in CSV files.  Among other things, each text
file will contain accounting activity for a given month, and from one
source file to the next I need to remember a list of account numbers and
their previous balances.  I will not know in advance how many accounts
will come in, so the array must be dynamic to be resized.  On the other
hand, any function I write to record new values and return old values
must retain the stored amounts over the life of the program.

In Clipper, my native language, it would be a snap to write a function
that uses a static variable which retains its values as you enter and
exit the function, but is still dynamically resizable.  From what I have
read so far, it appears that VB will not allow this - a function with a
locally scoped array cannot have that array both dynamic in size and
static in content.

So, what's my best bet here?  I could take the cheater's way out and use
a global (or at least module-wide) dynamic array, or I could store the
info to a temporary file that gets reloaded and resaved each time the
function starts and exits, or I could give up on outsourcing the work of
manipulating the array to a separate function and just store the array
and all usage of it in the main program body... or I could
"assume" (har!) that there will never be more than N records and give
myself a static array of N*2 just to be doubly sure.

Each of those has a taint of poor programming practice... I was brought
up to believe that a specific task should be in a separate function, not
smack in the middle of your main body of code.  A fixed size would be at
best inefficient (hey, on my Commodore PET those bytes *mattered*) and at
worst risks overflowing when there's more data than I was expecting.

Since this is just a quick-n-dirty project I'll probably go with the
module-wide global array, but I'm curious what y'all real programmers
would consider the best solution.

--
Peter B. Steiger
Cheyenne, WY
If you must reply by email, you can reach me by placing
zeroes where you see stars: wypbs.**1 at gmail.com



Sun, 19 Jun 2011 02:21:34 GMT  
 static resizeable arrays?
Look into ReDim Preserve...

--
Randem Systems
Your Installation Specialist
The Top Inno Setup Script Generator
http://www.randem.com/innoscript.html
http://www.randem.com/installerproblems.html
http://www.randem.com/vistainstalls.html
http://www.financialtrainingservices.org



Quote:
> OK, here's my next stupid question.  First, bear in mind that this is a
> quick-and-dirty utility that will be used in-house for a few months, not
> a widely distributed application so it's OK if I get sloppy.

> I'm reading data in from a bunch of text files and using the raw incoming
> data to produce summaries in CSV files.  Among other things, each text
> file will contain accounting activity for a given month, and from one
> source file to the next I need to remember a list of account numbers and
> their previous balances.  I will not know in advance how many accounts
> will come in, so the array must be dynamic to be resized.  On the other
> hand, any function I write to record new values and return old values
> must retain the stored amounts over the life of the program.

> In Clipper, my native language, it would be a snap to write a function
> that uses a static variable which retains its values as you enter and
> exit the function, but is still dynamically resizable.  From what I have
> read so far, it appears that VB will not allow this - a function with a
> locally scoped array cannot have that array both dynamic in size and
> static in content.

> So, what's my best bet here?  I could take the cheater's way out and use
> a global (or at least module-wide) dynamic array, or I could store the
> info to a temporary file that gets reloaded and resaved each time the
> function starts and exits, or I could give up on outsourcing the work of
> manipulating the array to a separate function and just store the array
> and all usage of it in the main program body... or I could
> "assume" (har!) that there will never be more than N records and give
> myself a static array of N*2 just to be doubly sure.

> Each of those has a taint of poor programming practice... I was brought
> up to believe that a specific task should be in a separate function, not
> smack in the middle of your main body of code.  A fixed size would be at
> best inefficient (hey, on my Commodore PET those bytes *mattered*) and at
> worst risks overflowing when there's more data than I was expecting.

> Since this is just a quick-n-dirty project I'll probably go with the
> module-wide global array, but I'm curious what y'all real programmers
> would consider the best solution.

> --
> Peter B. Steiger
> Cheyenne, WY
> If you must reply by email, you can reach me by placing
> zeroes where you see stars: wypbs.**1 at gmail.com



Sun, 19 Jun 2011 03:36:25 GMT  
 static resizeable arrays?
I would use a class, it makes your code organized, and helps in
compartmentalization and segregating the functionality of your program. This
helps and making the code reusable in other projects, but classes may have
small performance overhead, mainly because public variables in classes are
treated internally as properties(function calls).

Regardless of what you choose, you can make a function that auto expand a
dynamic array as needed, and use a variable as a count of the actual
elements. Example:

Public Type TAccountData
    sAccountName As String
    dValue  As Double
End Type

Public AccountData() As TAccountData
Public AccountDataCount As Long

To auto expand the array, use EnlargeArrayIfNeededUDF1() which is posted
here:

http://groups.google.com/group/microsoft.public.vb.com/msg/76f3ea96a3...

You need to change "As UDF1" to "As TAccountData". The function auto expands
the array by 100 element at a time if it's not large enough. Use
AccountDataCount to keep track of the number of elements, not UBound.

Finally, see ParseCSV01 below to parse CSV files quickly:

http://www.xbeat.net/vbspeed/c_ParseCSV.php



Sun, 19 Jun 2011 03:55:46 GMT  
 static resizeable arrays?


Quote:
> So, what's my best bet here?  I could take the cheater's way out and use
> a global (or at least module-wide) dynamic array, or I could store the
> info to a temporary file that gets reloaded and resaved each time the
> function starts and exits, or I could give up on outsourcing the work of
> manipulating the array to a separate function and just store the array
> and all usage of it in the main program body... or I could
> "assume" (har!) that there will never be more than N records and give
> myself a static array of N*2 just to be doubly sure.

> Each of those has a taint of poor programming practice... I was brought
> up to believe that a specific task should be in a separate function, not
> smack in the middle of your main body of code.  A fixed size would be at
> best inefficient (hey, on my Commodore PET those bytes *mattered*) and at
> worst risks overflowing when there's more data than I was expecting.

> Since this is just a quick-n-dirty project I'll probably go with the
> module-wide global array, but I'm curious what y'all real programmers
> would consider the best solution.

The best solution is usually the one that allows for ease-of-use by the
rest of your code.

In otherwords, your main code would like to add an account, change
the balance on an account, or read the account balance, all without
having to concern itself with resizing or reallocating some dynamic
array.

For small lists (under 5000) a Collection would do well.  For larger
lists a dynamic array is the better choice.  The collection can be
added to without need to reallocate size, but its performance degrads
at larger sizes.  The array does well at all sizes, but requires extra
code to manage size.

In either case, it would help to wrap the dynamics up into procedures
so that your main code can just call on the functions it needs without
need of management details.

Here is one such method using a collection.  With added effort, the
same could be done using a dynamic 2D array (Name/Value type array)

In a standard module, paste the following code:

' --- Standard Module code ---
Option Explicit
Private Balances As New Collection  ' Better to create this (New) at startup ...

Public Property Let Balance(Account As String, Value As Currency)
  On Error Resume Next
  Balances.Remove Account
  Balances.Add Array(Value, Account), Account
  If Err.Number Then Err.Clear
End Property

Public Property Get Balance(Account As String) As Currency
Dim act
  On Error Resume Next
  act = Balances(Account)
  If Err.Number Then
    Balance = 0
    Err.Clear
  Else
    Balance = act(0)
  End If
End Property

Public Function AccountsList() As String
Dim itm
  For Each itm In Balances
    AccountsList = AccountsList & itm(1) & vbCrLf
  Next
End Function

Public Function AccountBalances() As String
Dim itm
  For Each itm In Balances
    AccountBalances = AccountBalances & itm(1) & ", " & itm(0) & vbCrLf
  Next
End Function

Then anywhere in your code you can just call on these methods.  For
example, from a Form_Load event:

Private Sub Form_Load()

  ' Create / Assign
  Balance("A001") = 100.01
  Balance("A002") = 200.02
  Balance("A003") = 300.03

  ' Read
  Debug.Print "Account #A002:", Balance("A002")
  ' Error recovery (no such account)
  Debug.Print "Account #B001:", Balance("B001")

  ' Lists (add functions to suit your needs)
  Debug.Print
  Debug.Print "Accounts:"
  Debug.Print AccountsList

  Debug.Print "Balances:"
  Debug.Print AccountBalances

End Sub



Sun, 19 Jun 2011 06:24:32 GMT  
 static resizeable arrays?

OK, here's my next stupid question.  First, bear in mind that this is a
quick-and-dirty utility that will be used in-house for a few months, not
a widely distributed application so it's OK if I get sloppy.

I'm reading data in from a bunch of text files and using the raw incoming
data to produce summaries in CSV files.  Among other things, each text
file will contain accounting activity for a given month, and from one
source file to the next I need to remember a list of account numbers and
their previous balances.  I will not know in advance how many accounts
will come in, so the array must be dynamic to be resized.  On the other
hand, any function I write to record new values and return old values
must retain the stored amounts over the life of the program.

In Clipper, my native language, it would be a snap to write a function
that uses a static variable which retains its values as you enter and
exit the function, but is still dynamically resizable.  From what I have
read so far, it appears that VB will not allow this - a function with a
locally scoped array cannot have that array both dynamic in size and
static in content.

So, what's my best bet here?  I could take the cheater's way out and use
a global (or at least module-wide) dynamic array, or I could store the
info to a temporary file that gets reloaded and resaved each time the
function starts and exits, or I could give up on outsourcing the work of
manipulating the array to a separate function and just store the array
and all usage of it in the main program body... or I could
"assume" (har!) that there will never be more than N records and give
myself a static array of N*2 just to be doubly sure.

Each of those has a taint of poor programming practice... I was brought
up to believe that a specific task should be in a separate function, not
smack in the middle of your main body of code.  A fixed size would be at
best inefficient (hey, on my Commodore PET those bytes *mattered*) and at
worst risks overflowing when there's more data than I was expecting.

Since this is just a quick-n-dirty project I'll probably go with the
module-wide global array, but I'm curious what y'all real programmers
would consider the best solution.

If the format of your input files is structured in some way (such as a CSV) you could use ADO and
query the data directly into a Recordset object. You can also create a Recordset on the fly and add
the data as you read it from the input files.

I can provide an example if this fits into your scenario.

Paul
~~~~
Microsoft MVP (Visual Basic)



Sun, 19 Jun 2011 21:07:59 GMT  
 static resizeable arrays?
On Wed, 31 Dec 2008 07:07:59 -0600, Paul Clement sez:

Quote:
> If the format of your input files is structured in some way (such as a
> CSV) you could use ADO and query the data directly into a Recordset
> object. You can also create a Recordset on the fly and add the data as
> you read it from the input files.

> I can provide an example if this fits into your scenario.

Actually I'm going the other way - reading (somewhat) unformatted input
and producing a CSV.  Specifically, the client is supplying PDF reports,
and my job is to convert to ASCII (hooray for the open source PDF2TEXT)
and then parse each line looking for identifying information in the page
headers plus rows of data to stuff into the final CSV.

For now, I went with a module-wide global and a separate function that
handles resizing the account totals array, stores new values, and reports
old values.  I like the idea of using classes... I'm not much of an OOP
fan, but classes make perfect sense when you're manipulating a record
with multiple types of data (character and double).

--
Peter B. Steiger
Cheyenne, WY
If you must reply by email, you can reach me by placing
zeroes where you see stars: wypbs.**1 at gmail.com



Mon, 20 Jun 2011 01:18:45 GMT  
 static resizeable arrays?


Quote:
> I'm reading data in from a bunch of text files and using the raw incoming
> data to produce summaries in CSV files.  Among other things, each text
> file will contain accounting activity for a given month, and from one
> source file to the next I need to remember a list of account numbers and
> their previous balances.  I will not know in advance how many accounts
> will come in, so the array must be dynamic to be resized.  On the other
> hand, any function I write to record new values and return old values
> must retain the stored amounts over the life of the program.

This sounds like a job for a Collection, not an array at all.  If each entry
is multvalued there are two obvious choices:

One would be to created a multivalued Class and store instances of it in the
Collection.

The other would be a fabricated ADO Recordset, which offers you a lot of
extra power via its Find, Sort, and Filter functionality.  Another advantage
is you can even persist these to disk in one method call if required (Save
method).  With almost no work you can create CSV output from them as well
(GetString method).

For anything quick and dirty that doesn't have extremely tight performance
requirements I just can't see fooling with arrays and writing the code to
manage them when power tools are available out of the box.  Recordsets can
even be hierarchical, giving you a 3rd or even 4th dimension to work with
where required.  They are also actually quite efficient, a ton of effort has
gone into making them so.



Mon, 20 Jun 2011 01:36:38 GMT  
 static resizeable arrays?
On Wed, 31 Dec 2008 12:36:38 -0500, Bob Riemersma sez:

Quote:
> For anything quick and dirty that doesn't have extremely tight
> performance requirements I just can't see fooling with arrays and
> writing the code to manage them when power tools are available out of
> the box.

Well, the difference is that since about 1978 I *know* how to do a clumsy
iterative do-while-my-condition-not-met walk through an array, so I could
throw that together in 15 minutes.

That said, now that a working version has been delivered on time I like
the ADO recordsets you described. I'm definitely gonna learn how to do
that before the boss wants me to pretty it up or add functionality.
Thanks!

--
Peter B. Steiger
Cheyenne, WY
If you must reply by email, you can reach me by placing
zeroes where you see stars: wypbs.**1 at gmail.com



Mon, 20 Jun 2011 08:34:46 GMT  
 static resizeable arrays?


Quote:
> That said, now that a working version has been delivered on time I like
> the ADO recordsets you described.

See "Open Text" heading in this article:

HOW TO: Use Jet OLE DB Provider 4.0 to Connect to ISAM Databases
http://support.microsoft.com/default.aspx?scid=kb;en-us;326548



Mon, 20 Jun 2011 08:46:34 GMT  
 static resizeable arrays?


Quote:
> On Wed, 31 Dec 2008 12:36:38 -0500, Bob Riemersma sez:
> That said, now that a working version has been delivered on time I like
> the ADO recordsets you described. I'm definitely gonna learn how to do
> that before the boss wants me to pretty it up or add functionality.
> Thanks!

When you do this, don't overlook:

Optimize Property-Dynamic (ADO)
http://msdn.microsoft.com/en-us/library/ms677521(VS.85).aspx

This can be used to improve the performance of Sort, Find, etc.

Actually in most cases the benefits are so great that it is almost never
sensible to store data in an array if it will need sorting.  By the time you
get a fast sort on an array debugged you'd have long been done using a
Recordset.  This is doubly true if you later find you need to sort on
multiple columns:

rs.Sort = "LastName ASC, FirstName ASC"

It helps a lot if you choose to use a Recordset instead of an array in the
first place.  Using an array as your primary data structure and then copying
things into and out of a Recordset as you work reduces the benefits quite a
bit.



Tue, 21 Jun 2011 00:06:13 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. Better method of detecting static array initialized?

2. Initialize a Static Array

3. Static Array?

4. static array, i'm sure it's possible

5. Assigning a string to a static Byte array

6. Static variable not static enough ???

7. Programmatically add resizeable labels to windows form at runtime

8. Can't launch a 2nd resizeable web window

9. Flag resizeable=yes not working in window.open with IE4

10. resizeable frames in form

11. Making a form not resizeable?

12. Can't launch a 2nd resizeable web window

 

 
Powered by phpBB® Forum Software