Object Model Problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Iain Bishop

    Object Model Problem

    I'm trying to model objects for the following problem:

    A building site contains assemblies, each of which can contain other
    assemblies and/or materials.

    I have modelled this using a Site class, Assembly class, and Material class
    as follows...

    Site Class (clsSite):
    Option Explicit
    'General Details
    Public ProjectNumber As String
    Public SiteWBSCode As String
    Public SiteType As String
    Public LastUpdateFirst Name As String
    Public LastUpdateSurna me As String
    Public LastUpdateDate As Date
    Public TotalPriceOfAll Materials As Double
    Public GeneralNotes As String
    'Contents of Site
    Public SiteAssemblies As clsAssemblies 'a collection class of clsAssembly
    Public SiteMaterials As clsMaterials 'a collection class of clsMaterial

    Assembly Class (clsAssembly):
    Option Explicit
    'General Details
    Public ID As Long
    Public QuantityRequest ed As Integer
    Public QuantityIssued As Integer
    'Contents
    Public AssemblyAssembl ies As clsAssemblies 'a collection class of
    clsAssembly
    Public AssemblyMateria ls As clsMaterials 'a collection class of clsMaterial

    Material Class (clsMaterial)
    Option Explicit
    'General Details
    Public InventoryCode As String
    Public Rate As Double
    Public QuantityRequest ed As Integer
    Public QuantityIssued As Integer
    Public TotalPrice As Double
    Public DateAmended As Date

    My questions are:
    1. Have I modelled the problem correctly?
    2. There is the potential for an infinite hierarchy of Assemblies - is this
    ok?
    3. If so, I am having problems imagining how I would iterate through say all
    the materials to update their 'Rate' for example.
    4. I'm also having problems imagining how I would go and find a material if
    its 'Quantity Requested' has changed, given that it could be any number of
    levels down.

    I've spent hours without making much progress. Please help if you know the
    answer to any of these questions.

    Many Thanks
    Iain


  • Dikkie Dik

    #2
    Re: Object Model Problem

    You did quite well, I think. The fact that assemblies contain
    assemblies, and therefore do not have a defined ending level is true,
    and not a problem.
    Do not search. Let the object model itself do the search for you. For
    instance: the TotalPriceOfAll Materials could easily be a property of
    both the materials collection and the assemblies collection. As an
    assembly is only made up of subassemblies and materials, You just add
    the totals form both collections. The collections are then responsible
    to get the totals from all their members. This "drills down" to every
    level automatically (this technique is called the Propagation Pattern).
    If you are searching for something, just pass down an empty results list
    and let the collections fill it.
    This may seem a bit performance-heavy, but it isn't. Especially if the
    number of possible hits is limited (like searching for an ID), a
    collection can stop searching when the limit is reached, thereby
    preventing other collections to start an unnecessary search.

    There is no risk for an infinite number of assemblies, unless a
    subassembly can have a "parent" assembly as one of its own subassemblies
    (or even itself as a subassembly). Like a tree, it can grow as many
    twigs as it has the chance to, but it will remain finite.
    [color=blue]
    > 4. I'm also having problems imagining how I would go and find a
    > material if its 'Quantity Requested' has changed, given that it
    > could be any number of levels down.[/color]

    Good question. I think the answer does not lie in your object model yet,
    but in the real world. Who changes the 'Quantity Requested' property?
    And how does he know about it? Materials may be part of the
    assembly-structure, but also part of, say, a bill of materials. If the
    same instances are used, updating them in the bill of materials
    automatically updates them in the assembly structure.

    This may also be an alternative answer to the update question; if the
    materials are also in a list, it may be easier to update them there.

    Do not be afraid to start with an object model that is not perfect. You
    can always refine as you work on it. Speaking from my own experience, it
    is better to improve a simple scheme than to try to do a "Big Design
    Upfront". Just keep asking what responsibility should lie in what class
    and you can solve most questions.

    Best regards


    Iain Bishop wrote:[color=blue]
    > I'm trying to model objects for the following problem:
    >
    > A building site contains assemblies, each of which can contain other
    > assemblies and/or materials.
    >
    > I have modelled this using a Site class, Assembly class, and Material class
    > as follows...
    >
    > Site Class (clsSite):
    > Option Explicit
    > 'General Details
    > Public ProjectNumber As String
    > Public SiteWBSCode As String
    > Public SiteType As String
    > Public LastUpdateFirst Name As String
    > Public LastUpdateSurna me As String
    > Public LastUpdateDate As Date
    > Public TotalPriceOfAll Materials As Double
    > Public GeneralNotes As String
    > 'Contents of Site
    > Public SiteAssemblies As clsAssemblies 'a collection class of clsAssembly
    > Public SiteMaterials As clsMaterials 'a collection class of clsMaterial
    >
    > Assembly Class (clsAssembly):
    > Option Explicit
    > 'General Details
    > Public ID As Long
    > Public QuantityRequest ed As Integer
    > Public QuantityIssued As Integer
    > 'Contents
    > Public AssemblyAssembl ies As clsAssemblies 'a collection class of
    > clsAssembly
    > Public AssemblyMateria ls As clsMaterials 'a collection class of clsMaterial
    >
    > Material Class (clsMaterial)
    > Option Explicit
    > 'General Details
    > Public InventoryCode As String
    > Public Rate As Double
    > Public QuantityRequest ed As Integer
    > Public QuantityIssued As Integer
    > Public TotalPrice As Double
    > Public DateAmended As Date
    >
    > My questions are:
    > 1. Have I modelled the problem correctly?
    > 2. There is the potential for an infinite hierarchy of Assemblies - is this
    > ok?
    > 3. If so, I am having problems imagining how I would iterate through say all
    > the materials to update their 'Rate' for example.
    > 4. I'm also having problems imagining how I would go and find a material if
    > its 'Quantity Requested' has changed, given that it could be any number of
    > levels down.
    >
    > I've spent hours without making much progress. Please help if you know the
    > answer to any of these questions.
    >
    > Many Thanks
    > Iain
    >
    >[/color]

    Comment

    • Steve Gerrard

      #3
      Re: Object Model Problem

      Some general comments and ideas to consider:
      ---
      Something like TotalPriceOfAll Materials should probably be a method, not a
      variable. Unless you have a serious performance problem, it will be cleaner to
      actually add up all the material costs each time, rather than storing it and
      trying to make sure it stays updated.
      ---
      If you are familiar with Interfaces, or willing to become so, they could make
      your model easier. If you had an interface called IMaterial, for instance, then
      the Assembly class and Material class could both implement it. This would allow
      you to have a single collection that was a mixture of Assembly and Material
      objects. I can explain more about it if you are interested - it is not difficult
      to do.
      ---
      Your Site class does not need to repeat the structure of an Asssembly - it can
      simply contain one. So you could have

      'Contents of Site
      Public SiteAsm As clsAssembly

      which would give you
      SiteAsm.Assembl yAssemblies
      and
      SiteAsm.Assembl yMaterials

      and avoid duplication of code.

      Remember that your user does not have to know that the entire material structure
      of a site is being treated as a single assembly; it is just a programming
      convenience. Object design should serve the programmer's purposes, not the end
      user's. You could then put TotalPriceOfAll Materials in the Assembly class, as
      described in the post from Dikkie Dik.
      ---
      There is nothing wrong with adding an object reference to two collections (you
      only need to make sure that you don't create a cross reference, where two
      objects have references to each other).

      So, if you are adding a clsMaterial object to some assembly, you can also add it
      to a separate MasterList:
      Dim MasterList As clsMaterials
      Dim Site As clsSite
      Dim Mat As clsMaterial

      Set Mat = New clsMaterial
      Site.SiteAssemb lies(2).Assembl yAssemblies(4). AssemblyMateria ls.Add Mat
      MasterList.Add Mat

      This means you can find a material by drilling down through the Site structure,
      or by looking in the MasterList. Both collections contain a reference to the
      same object, so any changes to it would be seen from either vantage point. You
      could even make MasterList a property of the Site class.
      ---

      "Iain Bishop" <iebishop@yahoo .co.uk> wrote in message
      news:lKyde.956$ 31.558@news-server.bigpond. net.au...[color=blue]
      > I'm trying to model objects for the following problem:
      >
      > A building site contains assemblies, each of which can contain other
      > assemblies and/or materials.
      >
      > I have modelled this using a Site class, Assembly class, and Material class
      > as follows...
      >
      > Site Class (clsSite):
      > Option Explicit
      > 'General Details
      > Public ProjectNumber As String
      > Public SiteWBSCode As String
      > Public SiteType As String
      > Public LastUpdateFirst Name As String
      > Public LastUpdateSurna me As String
      > Public LastUpdateDate As Date
      > Public TotalPriceOfAll Materials As Double
      > Public GeneralNotes As String
      > 'Contents of Site
      > Public SiteAssemblies As clsAssemblies 'a collection class of clsAssembly
      > Public SiteMaterials As clsMaterials 'a collection class of clsMaterial
      >
      > Assembly Class (clsAssembly):
      > Option Explicit
      > 'General Details
      > Public ID As Long
      > Public QuantityRequest ed As Integer
      > Public QuantityIssued As Integer
      > 'Contents
      > Public AssemblyAssembl ies As clsAssemblies 'a collection class of
      > clsAssembly
      > Public AssemblyMateria ls As clsMaterials 'a collection class of clsMaterial
      >
      > Material Class (clsMaterial)
      > Option Explicit
      > 'General Details
      > Public InventoryCode As String
      > Public Rate As Double
      > Public QuantityRequest ed As Integer
      > Public QuantityIssued As Integer
      > Public TotalPrice As Double
      > Public DateAmended As Date
      >
      > My questions are:
      > 1. Have I modelled the problem correctly?
      > 2. There is the potential for an infinite hierarchy of Assemblies - is this
      > ok?
      > 3. If so, I am having problems imagining how I would iterate through say all
      > the materials to update their 'Rate' for example.
      > 4. I'm also having problems imagining how I would go and find a material if
      > its 'Quantity Requested' has changed, given that it could be any number of
      > levels down.
      >
      > I've spent hours without making much progress. Please help if you know the
      > answer to any of these questions.
      >
      > Many Thanks
      > Iain
      >
      >[/color]


      Comment

      • Iain Bishop

        #4
        Re: Object Model Problem

        Thanks a lot Dikkie and Steve for your responses. Its very much appreciated.
        I'm beginning to get an idea of what I need to do now.

        Steve, you mentioned interfaces. I know of them but have never used them, so
        am not familiar with them or how they could help. Would you mind explaining
        how I could use them?

        Thanks
        Iain


        "Steve Gerrard" <mynamehere@com cast.net> wrote in message
        news:bIydndr-47elFerfRVn-1Q@comcast.com. ..[color=blue]
        > Some general comments and ideas to consider:
        > ---
        > Something like TotalPriceOfAll Materials should probably be a method, not a
        > variable. Unless you have a serious performance problem, it will be[/color]
        cleaner to[color=blue]
        > actually add up all the material costs each time, rather than storing it[/color]
        and[color=blue]
        > trying to make sure it stays updated.
        > ---
        > If you are familiar with Interfaces, or willing to become so, they could[/color]
        make[color=blue]
        > your model easier. If you had an interface called IMaterial, for instance,[/color]
        then[color=blue]
        > the Assembly class and Material class could both implement it. This would[/color]
        allow[color=blue]
        > you to have a single collection that was a mixture of Assembly and[/color]
        Material[color=blue]
        > objects. I can explain more about it if you are interested - it is not[/color]
        difficult[color=blue]
        > to do.
        > ---
        > Your Site class does not need to repeat the structure of an Asssembly - it[/color]
        can[color=blue]
        > simply contain one. So you could have
        >
        > 'Contents of Site
        > Public SiteAsm As clsAssembly
        >
        > which would give you
        > SiteAsm.Assembl yAssemblies
        > and
        > SiteAsm.Assembl yMaterials
        >
        > and avoid duplication of code.
        >
        > Remember that your user does not have to know that the entire material[/color]
        structure[color=blue]
        > of a site is being treated as a single assembly; it is just a programming
        > convenience. Object design should serve the programmer's purposes, not the[/color]
        end[color=blue]
        > user's. You could then put TotalPriceOfAll Materials in the Assembly class,[/color]
        as[color=blue]
        > described in the post from Dikkie Dik.
        > ---
        > There is nothing wrong with adding an object reference to two collections[/color]
        (you[color=blue]
        > only need to make sure that you don't create a cross reference, where two
        > objects have references to each other).
        >
        > So, if you are adding a clsMaterial object to some assembly, you can also[/color]
        add it[color=blue]
        > to a separate MasterList:
        > Dim MasterList As clsMaterials
        > Dim Site As clsSite
        > Dim Mat As clsMaterial
        >
        > Set Mat = New clsMaterial
        > Site.SiteAssemb lies(2).Assembl yAssemblies(4). AssemblyMateria ls.Add Mat
        > MasterList.Add Mat
        >
        > This means you can find a material by drilling down through the Site[/color]
        structure,[color=blue]
        > or by looking in the MasterList. Both collections contain a reference to[/color]
        the[color=blue]
        > same object, so any changes to it would be seen from either vantage point.[/color]
        You[color=blue]
        > could even make MasterList a property of the Site class.
        > ---
        >
        > "Iain Bishop" <iebishop@yahoo .co.uk> wrote in message
        > news:lKyde.956$ 31.558@news-server.bigpond. net.au...[color=green]
        > > I'm trying to model objects for the following problem:
        > >
        > > A building site contains assemblies, each of which can contain other
        > > assemblies and/or materials.
        > >
        > > I have modelled this using a Site class, Assembly class, and Material[/color][/color]
        class[color=blue][color=green]
        > > as follows...
        > >
        > > Site Class (clsSite):
        > > Option Explicit
        > > 'General Details
        > > Public ProjectNumber As String
        > > Public SiteWBSCode As String
        > > Public SiteType As String
        > > Public LastUpdateFirst Name As String
        > > Public LastUpdateSurna me As String
        > > Public LastUpdateDate As Date
        > > Public TotalPriceOfAll Materials As Double
        > > Public GeneralNotes As String
        > > 'Contents of Site
        > > Public SiteAssemblies As clsAssemblies 'a collection class of[/color][/color]
        clsAssembly[color=blue][color=green]
        > > Public SiteMaterials As clsMaterials 'a collection class of clsMaterial
        > >
        > > Assembly Class (clsAssembly):
        > > Option Explicit
        > > 'General Details
        > > Public ID As Long
        > > Public QuantityRequest ed As Integer
        > > Public QuantityIssued As Integer
        > > 'Contents
        > > Public AssemblyAssembl ies As clsAssemblies 'a collection class of
        > > clsAssembly
        > > Public AssemblyMateria ls As clsMaterials 'a collection class of[/color][/color]
        clsMaterial[color=blue][color=green]
        > >
        > > Material Class (clsMaterial)
        > > Option Explicit
        > > 'General Details
        > > Public InventoryCode As String
        > > Public Rate As Double
        > > Public QuantityRequest ed As Integer
        > > Public QuantityIssued As Integer
        > > Public TotalPrice As Double
        > > Public DateAmended As Date
        > >
        > > My questions are:
        > > 1. Have I modelled the problem correctly?
        > > 2. There is the potential for an infinite hierarchy of Assemblies - is[/color][/color]
        this[color=blue][color=green]
        > > ok?
        > > 3. If so, I am having problems imagining how I would iterate through say[/color][/color]
        all[color=blue][color=green]
        > > the materials to update their 'Rate' for example.
        > > 4. I'm also having problems imagining how I would go and find a material[/color][/color]
        if[color=blue][color=green]
        > > its 'Quantity Requested' has changed, given that it could be any number[/color][/color]
        of[color=blue][color=green]
        > > levels down.
        > >
        > > I've spent hours without making much progress. Please help if you know[/color][/color]
        the[color=blue][color=green]
        > > answer to any of these questions.
        > >
        > > Many Thanks
        > > Iain
        > >
        > >[/color]
        >
        >[/color]


        Comment

        • Steve Gerrard

          #5
          Re: Object Model Problem


          "Iain Bishop" <iebishop@yahoo .co.uk> wrote in message
          news:CtSde.1925 $31.14@news-server.bigpond. net.au...[color=blue]
          > Thanks a lot Dikkie and Steve for your responses. Its very much appreciated.
          > I'm beginning to get an idea of what I need to do now.
          >
          > Steve, you mentioned interfaces. I know of them but have never used them, so
          > am not familiar with them or how they could help. Would you mind explaining
          > how I could use them?
          >
          > Thanks
          > Iain
          >[/color]

          I have to admit, I was kind of hoping you would ask :)

          Here is a demo, which hopefully illustrates the concept. I have tried to keep it
          as brief as possible, there are lots of things you might want to add if you
          decided to pursue it.

          You need one form with a command button, and three classes, named as given.
          Paste the code into each one, then run it and click the button. You may want to
          trace the execution to see what is happening, especially the GetTotal call at
          the end of the button click. Note that clicking the button again will add more
          stuff.

          '----
          ' first, the interface, a class called IMaterial

          Public Property Get MaterialTotal() As Double
          End Property

          '----
          ' that was easy enough. Now the first instance class.
          ' this is CMaterial, for an individual material item.
          ' Instead of the usual property Get/Let, I just initialize to
          ' random values to keep it short.

          Implements IMaterial

          Private mQuantity As Double
          Private mCostPer As Double

          ' class
          Private Sub Class_Initializ e()
          mQuantity = Fix(Rnd * 10)
          mCostPer = Fix(Rnd * 100)
          End Sub

          ' IMaterial implementation
          Private Property Get IMaterial_Mater ialTotal() As Double
          IMaterial_Mater ialTotal = mQuantity * mCostPer
          End Property

          '---
          ' This is the other instance class, called CAssembly.
          ' It contains a collection of IMaterial items.

          Implements IMaterial

          Private mCol As Collection

          ' class
          Private Sub Class_Initializ e()
          Set mCol = New Collection
          End Sub

          ' public methods
          Public Function Add(Item As IMaterial) As IMaterial
          mCol.Add Item
          ' return Item, so New can be used in the call...
          Set Add = Item
          End Function

          Public Function GetTotal() As Double
          Dim dSum As Double
          Dim iMat As IMaterial


          ' Note how the GetTotal function just retrieves the
          ' MaterialTotal of each item, regardless of whether
          ' it is a material or another assembly...

          For Each iMat In mCol
          dSum = dSum + iMat.MaterialTo tal
          Next iMat

          GetTotal = dSum

          End Function

          ' IMaterial implementation
          Private Property Get IMaterial_Mater ialTotal() As Double
          IMaterial_Mater ialTotal = GetTotal()
          End Property

          '---
          ' And last, a Form to test it.

          Private mSite As CAssembly

          Private Sub Form_Load()
          Set mSite = New CAssembly
          End Sub

          Private Sub Command1_Click( )
          Dim oAsm As CAssembly
          Dim oMat As CMaterial
          Dim oAsm2 As CAssembly

          ' oMat is not actually used here, but you
          ' would need it to set other properties

          'add a mat to the site
          Set oMat = mSite.Add(New CMaterial)

          'add an assembly to the site
          Set oAsm = mSite.Add(New CAssembly)
          'add some mats to the assembly
          Set oMat = oAsm.Add(New CMaterial)
          Set oMat = oAsm.Add(New CMaterial)

          'add an assembly to the assembly
          Set oAsm2 = oAsm.Add(New CAssembly)
          'add some mats to the nested assembly
          Set oMat = oAsm2.Add(New CMaterial)
          Set oMat = oAsm2.Add(New CMaterial)

          'see what we've got
          MsgBox "Total is " & mSite.GetTotal

          End Sub


          Comment

          • Iain Bishop

            #6
            Re: Object Model Problem

            Thanks for that Steve.
            I don't think I will use an IMaterial interface for this because I had
            already coded up some of the Data Services Layer which assumes an assembly
            contains two collections - one for other assemblies and one for materials.
            I'll consider it next time though!

            Iain

            "Steve Gerrard" <mynamehere@com cast.net> wrote in message
            news:85WdnXo_or vOr-XfRVn-2w@comcast.com. ..[color=blue]
            >
            > "Iain Bishop" <iebishop@yahoo .co.uk> wrote in message
            > news:CtSde.1925 $31.14@news-server.bigpond. net.au...[color=green]
            > > Thanks a lot Dikkie and Steve for your responses. Its very much[/color][/color]
            appreciated.[color=blue][color=green]
            > > I'm beginning to get an idea of what I need to do now.
            > >
            > > Steve, you mentioned interfaces. I know of them but have never used[/color][/color]
            them, so[color=blue][color=green]
            > > am not familiar with them or how they could help. Would you mind[/color][/color]
            explaining[color=blue][color=green]
            > > how I could use them?
            > >
            > > Thanks
            > > Iain
            > >[/color]
            >
            > I have to admit, I was kind of hoping you would ask :)
            >
            > Here is a demo, which hopefully illustrates the concept. I have tried to[/color]
            keep it[color=blue]
            > as brief as possible, there are lots of things you might want to add if[/color]
            you[color=blue]
            > decided to pursue it.
            >
            > You need one form with a command button, and three classes, named as[/color]
            given.[color=blue]
            > Paste the code into each one, then run it and click the button. You may[/color]
            want to[color=blue]
            > trace the execution to see what is happening, especially the GetTotal call[/color]
            at[color=blue]
            > the end of the button click. Note that clicking the button again will add[/color]
            more[color=blue]
            > stuff.
            >
            > '----
            > ' first, the interface, a class called IMaterial
            >
            > Public Property Get MaterialTotal() As Double
            > End Property
            >
            > '----
            > ' that was easy enough. Now the first instance class.
            > ' this is CMaterial, for an individual material item.
            > ' Instead of the usual property Get/Let, I just initialize to
            > ' random values to keep it short.
            >
            > Implements IMaterial
            >
            > Private mQuantity As Double
            > Private mCostPer As Double
            >
            > ' class
            > Private Sub Class_Initializ e()
            > mQuantity = Fix(Rnd * 10)
            > mCostPer = Fix(Rnd * 100)
            > End Sub
            >
            > ' IMaterial implementation
            > Private Property Get IMaterial_Mater ialTotal() As Double
            > IMaterial_Mater ialTotal = mQuantity * mCostPer
            > End Property
            >
            > '---
            > ' This is the other instance class, called CAssembly.
            > ' It contains a collection of IMaterial items.
            >
            > Implements IMaterial
            >
            > Private mCol As Collection
            >
            > ' class
            > Private Sub Class_Initializ e()
            > Set mCol = New Collection
            > End Sub
            >
            > ' public methods
            > Public Function Add(Item As IMaterial) As IMaterial
            > mCol.Add Item
            > ' return Item, so New can be used in the call...
            > Set Add = Item
            > End Function
            >
            > Public Function GetTotal() As Double
            > Dim dSum As Double
            > Dim iMat As IMaterial
            >
            >
            > ' Note how the GetTotal function just retrieves the
            > ' MaterialTotal of each item, regardless of whether
            > ' it is a material or another assembly...
            >
            > For Each iMat In mCol
            > dSum = dSum + iMat.MaterialTo tal
            > Next iMat
            >
            > GetTotal = dSum
            >
            > End Function
            >
            > ' IMaterial implementation
            > Private Property Get IMaterial_Mater ialTotal() As Double
            > IMaterial_Mater ialTotal = GetTotal()
            > End Property
            >
            > '---
            > ' And last, a Form to test it.
            >
            > Private mSite As CAssembly
            >
            > Private Sub Form_Load()
            > Set mSite = New CAssembly
            > End Sub
            >
            > Private Sub Command1_Click( )
            > Dim oAsm As CAssembly
            > Dim oMat As CMaterial
            > Dim oAsm2 As CAssembly
            >
            > ' oMat is not actually used here, but you
            > ' would need it to set other properties
            >
            > 'add a mat to the site
            > Set oMat = mSite.Add(New CMaterial)
            >
            > 'add an assembly to the site
            > Set oAsm = mSite.Add(New CAssembly)
            > 'add some mats to the assembly
            > Set oMat = oAsm.Add(New CMaterial)
            > Set oMat = oAsm.Add(New CMaterial)
            >
            > 'add an assembly to the assembly
            > Set oAsm2 = oAsm.Add(New CAssembly)
            > 'add some mats to the nested assembly
            > Set oMat = oAsm2.Add(New CMaterial)
            > Set oMat = oAsm2.Add(New CMaterial)
            >
            > 'see what we've got
            > MsgBox "Total is " & mSite.GetTotal
            >
            > End Sub
            >
            >[/color]


            Comment

            • Jew

              #7
              Re: Object Model Problem

              On Mon, 02 May 2005 23:30:25 GMT, "Iain Bishop" <iebishop@yahoo .co.uk> wrote:
              [color=blue]
              >I'm trying to model objects for the following problem:
              >
              >A building site contains assemblies, each of which can contain other
              >assemblies and/or materials.
              >
              >I have modelled this using a Site class, Assembly class, and Material class
              >as follows...
              >
              >Site Class (clsSite):
              >Option Explicit
              >'General Details
              >Public ProjectNumber As String
              >Public SiteWBSCode As String
              >Public SiteType As String
              >Public LastUpdateFirst Name As String
              >Public LastUpdateSurna me As String
              >Public LastUpdateDate As Date
              >Public TotalPriceOfAll Materials As Double
              >Public GeneralNotes As String
              >'Contents of Site
              >Public SiteAssemblies As clsAssemblies 'a collection class of clsAssembly
              >Public SiteMaterials As clsMaterials 'a collection class of clsMaterial
              >
              >Assembly Class (clsAssembly):
              >Option Explicit
              >'General Details
              >Public ID As Long
              >Public QuantityRequest ed As Integer
              >Public QuantityIssued As Integer
              >'Contents
              >Public AssemblyAssembl ies As clsAssemblies 'a collection class of
              >clsAssembly
              >Public AssemblyMateria ls As clsMaterials 'a collection class of clsMaterial
              >
              >Material Class (clsMaterial)
              >Option Explicit
              >'General Details
              >Public InventoryCode As String
              >Public Rate As Double
              >Public QuantityRequest ed As Integer
              >Public QuantityIssued As Integer
              >Public TotalPrice As Double
              >Public DateAmended As Date
              >
              >My questions are:
              >1. Have I modelled the problem correctly?[/color]

              The replies you receievd so far sound very good. An exploded Bill
              Of Material / Product Structure generally has the financial standard
              costs and labor hours regenerated at the end of every month, so I
              see no reason why you cannot save some CPU time by *NOT* making your
              subtotals methods instead of properties: the End Of Month Closing
              routines will perform all the necessary calculations and update the
              properties.

              For example: the PRMS mid-frame application that runs on the AS/400
              has standard labor, standard labor costs, material costs, and the
              like as properties (values). At the end of every financial month the
              Month End Close / Cost Build programs are run, and new values for
              components and sub-assemblies are generated. This generally means
              the financial module includes in the database the next/future costing
              values, and historical values. The database also contains actual labor
              hours, actual labor costs, actual material costs, etc., so that one
              may forecast future costs.
              [color=blue]
              > 2. There is the potential for an infinite hierarchy of Assemblies -
              > is this ok?[/color]

              Infinite is bad; finite is good. :-)

              You must add a check that looks to see if an assembly's newly-added
              component part is not the assembly itself, and (if the component
              is a sub-assembly) check to see if any of the newly-added component
              parts include the parent part. This is actually very easy to do.

              A section of code from my Product Structure modual (changing my
              news reader's word-wrap to 700 characters):

              Private Sub txtParent_LostF ocus()
              Dim FindPN As String, sSQL As String, nodX As Node, TheDesc As String, TheUM As String

              FindPN = UCase$(Trim(txt Parent.Text))
              txtParent.Text = FindPN: ' A fuction that looks at the Product Master to see if a part number exists

              If FindPN = "" Then Exit Sub

              MousePointer = 11
              DoEvents

              Dim de As Boolean
              If ServerLocation = "" Then
              de = DoesPNExist(Fin dPN, TheDesc, TheUM)
              Else
              de = DF.DoesPNExist( FindPN, TheDesc, TheUM): ' Internet server, use Business Object
              End If

              If de = True Then
              lblDesc.Caption = TheDesc

              TreeView1.Nodes .Clear
              Set nodX = TreeView1.Nodes .Add()
              nodX.Expanded = True
              nodX.Text = FindPN
              nodX.Image = 1
              nodX.SelectedIm age = 3
              nodX.Key = FindPN
              nodX.Tag = 0
              List1.AddItem nodX.Text
              List2.AddItem nodX.Text

              If ServerLocation = "" Then
              Set Adodc1.Recordse t = GetSMP("SELECT * FROM ProductStructur e WHERE Parent = '" & FindPN & "';")
              Else
              Set Adodc1.Recordse t = DF.GetSMP("SELE CT * FROM ProductStructur e WHERE Parent = '" & FindPN & "';"): ' database is on web server
              End If

              Do Until Adodc1.Recordse t.EOF
              Set nodX = TreeView1.Nodes .Add(1, tvwChild)
              nodX.Text = Adodc1.Recordse t!Child
              nodX.Image = 2
              nodX.Key = Adodc1.Recordse t!Child
              nodX.Parent = Adodc1.Recordse t!Parent
              nodX.SelectedIm age = 3
              nodX.Tag = 1
              List1.AddItem " " & nodX.Text
              List2.AddItem "SELECT * FROM ProductStructur e WHERE Parent = '" & FindPN & "' AND Child = '" & nodX.Text & "';"
              Adodc1.Recordse t.MoveNext
              Loop
              DoEvents
              PopulateSubAsse mblies
              Else
              lblDesc.Caption = "The parent assembly does not exist in the product master."
              End If
              MousePointer = 0
              DoEvents
              End Sub

              Private Sub PopulateSubAsse mblies()
              Dim nodX As Node, Child As String, Parent As String, Level As Long
              Dim LookIndex As Long, LastKey As String, tl As Long, i As Long
              Dim lBox As Long

              LookIndex = 1

              Do
              LookIndex = LookIndex + 1
              Parent = TreeView1.Nodes (LookIndex).Tex t
              Level = TreeView1.Nodes (LookIndex).Tag
              For i = 0 To List1.ListCount - 1
              If Trim(List1.List (i)) = Parent Then
              lBox = i
              Exit For
              End If
              Next

              If ServerLocation = "" Then
              Set Adodc1.Recordse t = GetSMP("SELECT * FROM ProductStructur e WHERE Parent = '" & Parent & "' ORDER BY Child;")
              Else
              Set Adodc1.Recordse t = DF.GetSMP("SELE CT * FROM ProductStructur e WHERE Parent = '" & Parent & "' ORDER BY Child;"): ' SMPBO
              End If

              If Adodc1.Recordse t.EOF = False Then

              TreeView1.Nodes (LookIndex).Ima ge = 1
              TreeView1.Nodes (LookIndex).Exp anded = True

              Adodc1.Recordse t.MoveFirst

              Do While Adodc1.Recordse t.EOF = False
              Child = Adodc1.Recordse t!Child
              Set nodX = TreeView1.Nodes .Add(Parent, tvwChild, , Child, 2, 3)
              nodX.Tag = Level + 1
              List1.AddItem String$((Level + 1) * 3, " ") & nodX.Text, lBox + 1
              List2.AddItem "SELECT * FROM ProductStructur e WHERE Parent = '" & Parent & "' AND Child = '" & nodX.Text & "';", lBox + 1

              Adodc1.Recordse t.MoveNext
              Loop
              End If
              If LookIndex = TreeView1.Nodes .Count Then Exit Do
              Loop
              btnReport.Enabl ed = True
              End Sub

              What my program does is first check to see if the database is
              local, or if it is on a web server. It then checks to see if
              the part number is in the Product Master; if it is, it checks
              to see if it is an assembly: if it is not in the Product Structure,
              it is assumed to be a component and not an assembly.

              If the part number is in the Product Structure, it is an assembly.
              Every component of that assembly is filled into the TreeView, and
              then the TreeView is stepped through. No matter how many new
              assemblies are added, the TreeView is filled in below what ever
              assembly and component it is currently examining, so one can make
              a exploded Bill of Material as large as one's computer has RAM.
              [color=blue]
              > 3. If so, I am having problems imagining how I would iterate through
              > say all the materials to update their 'Rate' for example.[/color]

              What I did was to step through each sub-assembly and build a list
              of SQL statements that will later retrieve the Product Structures
              for those sub-assemblies. If a sub-assembly has sub-assemblies
              within them, I just create new SQL statements and add them to
              the end of my list (in my program I used a list box, but an
              array would also work).
              [color=blue]
              >4. I'm also having problems imagining how I would go and find a material if
              >its 'Quantity Requested' has changed, given that it could be any number of
              >levels down.[/color]

              The quantity required would be the sum of each unique component in an
              exploded Bill Of Material. You may have an assembly with fifty
              sub-assemblies, and a dozen of those sub-assemblies may have
              sub-sub-assemblies. To print a "Pick Sheet" you have to iterate
              through the assembly and sub-assemblies and sub-sub-assemblies and
              sum up each unique component. This is very easy to do.
              [color=blue]
              > I've spent hours without making much progress. Please help if you
              > know the answer to any of these questions.[/color]

              Shall I post on a web page a PKZip example for you?
              [color=blue]
              >Many Thanks
              >Iain[/color]

              Comment

              Working...