From: Webbiz on
On Mon, 8 Mar 2010 11:37:03 -0500, "Nobody" <nobody(a)nobody.com> wrote:

>Like others suggested, you can use a Dictionary object, but if you need to
>do more, you would have to make some workaround like using a separator
>character, but implementing your own would give you more control. Here is a
>class version of the code that I posted earlier:
>
>Output:
>
>Symbols Count = 5
>Item4 is at 4
>'D' is at 4
>ChartName for 'C' is Item3
>Symbol for chart name 'Item3' is C
>Symbols Count = 4
>Item4 is at 0
>'D' is at 0
>
>' Form1 code
>
>Option Explicit
>
>Private oSymbols As New CSymbols
>
>Private Sub Form_Load()
> oSymbols.Add "Item1", "A"
> oSymbols.Add "Item2", "B"
> oSymbols.Add "Item3", "C"
> oSymbols.Add "Item4", "D"
> oSymbols.Add "Item5", "E"
>
> Debug.Print "Symbols Count = " & oSymbols.Count
>
> Debug.Print "Item4 is at " & oSymbols.FindChartName("Item4")
> Debug.Print "'D' is at " & oSymbols.FindSymbol("D")
>
> Debug.Print "ChartName for 'C' is " & oSymbols.GetChartName("C")
> Debug.Print "Symbol for chart name 'Item3' is " & _
> oSymbols.GetSymbol("Item3")
>
> oSymbols.Remove 4
>
> Debug.Print "Symbols Count = " & oSymbols.Count
>
> Debug.Print "Item4 is at " & oSymbols.FindChartName("Item4")
> Debug.Print "'D' is at " & oSymbols.FindSymbol("D")
>
>End Sub
>
>
>
>' CSymbols Class module code
>
>Option Explicit
>
>Private Type TSymbols
> ChartName As String
> Symbol As String
>End Type
>
>Private m_Symbols() As TSymbols
>Private m_SymbolsCount As Long
>
>' Returns True when item successfully added, False when out of memory
>Public Function Add(ByRef ChartName As String, _
> ByRef Symbol As String) As Boolean
>
> Dim i As Long
>
> On Error Resume Next
>
> i = UBound(m_Symbols)
> If Err.Number <> 0 Then
> ' Not Redimmed before
> Err.Clear
> ReDim Preserve m_Symbols(1 To 100)
> If Err.Number <> 0 Then
> ' Out of memory
> Add = False
> Exit Function
> End If
> End If
>
> If m_SymbolsCount = UBound(m_Symbols) Then
> ' Time to increase array size
> ReDim Preserve m_Symbols(1 To UBound(m_Symbols) + 100)
> If Err.Number <> 0 Then
> ' Out of memory
> Add = False
> Exit Function
> End If
> End If
>
> ' Add item to the array
> m_SymbolsCount = m_SymbolsCount + 1
> m_Symbols(m_SymbolsCount).ChartName = ChartName
> m_Symbols(m_SymbolsCount).Symbol = Symbol
>
> Add = True ' Success
>
>End Function
>
>Public Sub Remove(ByVal Start As Long)
> Dim i As Long
>
> If Start >= 1 And Start <= m_SymbolsCount Then
> For i = Start To m_SymbolsCount - 1
> m_Symbols(i) = m_Symbols(i + 1)
> Next
> m_SymbolsCount = m_SymbolsCount - 1
> End If
>End Sub
>
>Public Property Get Count() As Long
> Count = m_SymbolsCount
>End Property
>
>' Returns the index in m_Symbols() array, 0 if not found
>Public Function FindChartName(ByRef ChartName As String) As Long
> Dim i As Long
>
> For i = 1 To m_SymbolsCount
> If m_Symbols(i).ChartName = ChartName Then
> FindChartName = i
> Exit Function
> End If
> Next
>
>End Function
>
>' Returns the index in m_Symbols() array, 0 if not found
>Public Function FindSymbol(ByRef Symbol As String) As Long
> Dim i As Long
>
> For i = 1 To m_SymbolsCount
> If m_Symbols(i).Symbol = Symbol Then
> FindSymbol = i
> Exit Function
> End If
> Next
>
>End Function
>
>' Returns the corrosponding Symbol name, empty string if not found
>Public Function GetSymbol(ByRef ChartName As String) As String
> Dim i As Long
>
> For i = 1 To m_SymbolsCount
> If m_Symbols(i).ChartName = ChartName Then
> GetSymbol = m_Symbols(i).Symbol
> Exit Function
> End If
> Next
>
>End Function
>
>' Returns the corrosponding ChartName, empty string if not found
>Public Function GetChartName(ByRef Symbol As String) As String
> Dim i As Long
>
> For i = 1 To m_SymbolsCount
> If m_Symbols(i).Symbol = Symbol Then
> GetChartName = m_Symbols(i).ChartName
> Exit Function
> End If
> Next
>
>End Function
>
>Private Sub Class_Terminate()
> Erase m_Symbols
>End Sub
>


Thanks for taking the time to write this code example NOBODY. Much
appreciated.

I like the idea of using ADD and REMOVE methods as part of a class.
Seems to be a 'clean' solution that is also portable if I have to do
this again in another project.

When it comes to Classes, I'm still a bit slow in catching on. I'm
going to babble on here on what this is doing. If I'm off base, please
let me know.

The Form_Load() is where the object will be instantiated and data
loaded into it. I can put this anywhere I want in the app, but for my
purposes, the Form_Load() would fit just fine in triggering the
'SYMBOL OBJ INITIALISING' procedure. Within this procedure, I would
have to load the data from a datafile to restore all the previously
entered data.

Q: Might be a dumb question, but is it possible to save a class object
with its data to a file in one easy dump and load it as such to
restore it, or do I have to loop through all the records within the
class object when saving to and loading from disk?

Q. Would it be wise/unwise to have the data load (from file) as part
of the Class, perhaps as the Class Constructor triggered when an
object is created from it? And then, to have all the data saved back
to the file as part of the Class Destructor (Terminate?) ?


Q. I find it interesting this technique of deliberately causing an
error in order to branch to a different routine, such as the initial
Redim of m_Symbols. Is this common practice?


I'm thinking that my class won't need the Remove, FindChartName,
FindSymbol and GetChartName routines. The GetChartName routine, if I
were to keep it, would have to be modified anyway as it is possible to
have more than one chart with the same symbol (although not the other
way around).

The only thing that needs to be returned from the object is the Symbol
based on the Chartname supplied. Once I know the Symbol that was
assigned to a chart, I can run the methods specific to that symbol
elsewhere in code.

This class will need a different type of 'Remove' routine though. I'll
add this where the item is deleted and filled in with the last item
(as suggested by another) since the order is not important within the
array.

Thanks!

Webbiz
From: Webbiz on
On Mon, 8 Mar 2010 12:17:11 -0600, "Larry Serflaten"
<serflaten(a)usinternet.com> wrote:

>
>"Webbiz" <nospam(a)noway.com> wrote
>
>> In this particular lookup, it's the long-winded description string
>> that gets searched on and the two-char string that is returned.
>
>So would a Collection be the suitable vehicle?
>
> Set Symbols = New Collection
> Symbols.Add "CT", "May Cotton 2010"
> Symbols.Add "CT", "Cotton May 2010"
> Symbols.Add "CT", "My Cotton Chart 0510"
> Symbols.Add "S", "Soybeans"
> Symbols.Add "LC", "Apr Live Cattle 2009"
> ... etc...
>
> Such that you get the symbols back when you know the long name:
>
> sym = Symbols("Soybeans")
>
>???
>LFS
>


Don't laugh, but I'll have to read on 'Collections' as I've never used
it personally.

The user of the program can name his charts whatever he wants. But in
order to retrieve information specific to the data loaded into the
chart, the symbol needs to be associated with it.

Each week, I will have a text file that can be downloaded which
contains these symbols and some important data associated with it.
There are 20 symbols.

I have no idea how the user named his charts, so I have to leave it up
to the user to assign the correct symbol to the respective chart.

The app, noting there is a symbol file on the drive, will load this
file into the app.

When the user is viewing a chart that has been assigned to a symbol,
the user can select the additional data be displayed on his chart by
way of keypress, mouse click, menu or whatever. The app will load the
text file that was downloaded so as to have the symbols and the
associated data. The app will match the symbol assigned to the chart
to the symbol in this file to get the correct additional data. This
data is then applied to the chart in some way.

Right now, the users already may have 10, 20 or more charts created
from use over the previous months/years. When this feature is added,
the user will have to update the app of course. Then the user will
need to start assigning the symbols to the charts.

Naturally, when the user exists the program the symbol assignments
need to be saved so that the next time the app is run it will remember
the assignments. If a chart is ever deleted, I will need to remove the
chartname ->> symbol reference. If the user, for whatever reason,
wants more than one chart to be assigned to the same symbol, this is
to be allowed. Of course one cannot assign more than one symbol to a
single chart though.

That's it in a rather large nutshell. Can collections deal with this?

I'm currently toying with NOBODY's Class suggestion and code.

Thanks.

Webbiz

From: Nobody on
"Webbiz" <nospam(a)noway.com> wrote in message
news:gkbap59vi85c1gpmfcb21lmsj4tv5unnrh(a)4ax.com...
> Thanks for taking the time to write this code example NOBODY. Much
> appreciated.
>
> I like the idea of using ADD and REMOVE methods as part of a class.
> Seems to be a 'clean' solution that is also portable if I have to do
> this again in another project.
>
> When it comes to Classes, I'm still a bit slow in catching on. I'm
> going to babble on here on what this is doing. If I'm off base, please
> let me know.
>
> The Form_Load() is where the object will be instantiated and data
> loaded into it. I can put this anywhere I want in the app, but for my
> purposes, the Form_Load() would fit just fine in triggering the
> 'SYMBOL OBJ INITIALISING' procedure. Within this procedure, I would
> have to load the data from a datafile to restore all the previously
> entered data.
>
> Q: Might be a dumb question, but is it possible to save a class object
> with its data to a file in one easy dump and load it as such to
> restore it, or do I have to loop through all the records within the
> class object when saving to and loading from disk?

I haven't used this, so I don't know the details, but check the help for
"PropertyBag object". You will find a topic called "Persisting a Component's
Data". It probably doesn't apply to Standard EXE projects. Other than that,
you can provide your own Load/Save functions that take a file name and save
the information there. You can call these functions from
Initialize/Terminate events, but these events don't return error codes, so
it's best to call Load/Save methods explicitly. You can show a MsgBox, but I
tend to avoid GUI code in classes and return an error code, and let the
calling form show a MsgBox. This is just in case I use that class in a
non-GUI app later, such as a command line only tool, or ActiveX in a web
server, or as a service, which cannot show a GUI.

> Q. Would it be wise/unwise to have the data load (from file) as part
> of the Class, perhaps as the Class Constructor triggered when an
> object is created from it? And then, to have all the data saved back
> to the file as part of the Class Destructor (Terminate?) ?

That's fine. See the above.

> Q. I find it interesting this technique of deliberately causing an
> error in order to branch to a different routine, such as the initial
> Redim of m_Symbols. Is this common practice?

That's very common and perfectly fine, especially when ReDim'ing arrays for
the first time.


From: Webbiz on
On Sun, 7 Mar 2010 20:09:27 -0500, "Jim Mack" <jmack(a)mdxi.nospam.com>
wrote:


>With fewer than 100 symbols, practically anything you do will feel
>instantaneous.
>
>Since you're carrying the Symbol field in the array, the actual array
>order doesn't matter and a deletion can just mean swapping the deleted
>element with the last element, then ReDim Preserve the array one
>element smaller. No shuffling needed.


How does this look in doing that? This is a method in my CSymbol
Class.

Public Sub Delete(ByRef ChartName As String)

Dim i As Long, j As Long
Dim bResize As Boolean

On Error Resume Next

i = UBound(m_Symbols)

If Err.number <> 0 Then
Exit Sub
Else

If m_Symbols(i).ChartName = ChartName Then 'delete last record
by resizing only
bResize = True
Else
For j = 0 To i
If m_Symbols(j).ChartName = ChartName Then 'match
m_Symbols(j) = m_Symbols(i) 'Transfer last record
over one to remove
bResize = True
Exit For
End If
Next j
End If

End If

If bResize Then 'Resize to remove last element
If i > 0 Then
ReDim Preserve m_Symbols(i - 1)
Else
Erase m_Symbols
End If
End If

End Sub
From: Webbiz on
On Mon, 08 Mar 2010 17:27:02 -0600, Webbiz <nospam(a)noway.com> wrote:

>On Sun, 7 Mar 2010 20:09:27 -0500, "Jim Mack" <jmack(a)mdxi.nospam.com>
>wrote:
>
>
>>With fewer than 100 symbols, practically anything you do will feel
>>instantaneous.
>>
>>Since you're carrying the Symbol field in the array, the actual array
>>order doesn't matter and a deletion can just mean swapping the deleted
>>element with the last element, then ReDim Preserve the array one
>>element smaller. No shuffling needed.
>
>
>How does this look in doing that? This is a method in my CSymbol
>Class.
>
>Public Sub Delete(ByRef ChartName As String)
>
>Dim i As Long, j As Long
>Dim bResize As Boolean
>
> On Error Resume Next
>
> i = UBound(m_Symbols)
>
> If Err.number <> 0 Then
> Exit Sub
> Else
>
> If m_Symbols(i).ChartName = ChartName Then 'delete last record
>by resizing only
> bResize = True
> Else
> For j = 0 To i
> If m_Symbols(j).ChartName = ChartName Then 'match
> m_Symbols(j) = m_Symbols(i) 'Transfer last record
>over one to remove
> bResize = True
> Exit For
> End If
> Next j
> End If
>
> End If
>
> If bResize Then 'Resize to remove last element
> If i > 0 Then
> ReDim Preserve m_Symbols(i - 1)
> Else
> Erase m_Symbols
> End If
> End If
>
>End Sub



I think maybe this one is better?


Public Sub Delete(ByRef ChartName As String)

Dim i As Long, j As Long
Dim bResize As Boolean


If m_SymbolsCount > 0 Then

If m_Symbols(m_SymbolsCount).ChartName = ChartName Then
'delete last record by resizing only
If m_SymbolsCount = 1 Then
Erase m_Symbols
mSymbolsCount = 0
Exit Sub
End If
Else
For j = 1 To m_SymbolsCount
If m_Symbols(j).ChartName = ChartName Then 'match
m_Symbols(j) = m_Symbols(m_SymbolsCount) 'Transfer
last record over one to remove
ReDim Preserve m_Symbols(m_SymbolsCount - 1)
mSymbolsCount = mSymbolsCount - 1
Exit Sub
End If
Next j
End If

End If

End Sub


Webbiz
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5
Prev: Datagrid problem
Next: Virtual memory increasing.