Solved

Best way of comparing values from multiple instances of the same object

Posted on 2006-11-09
5
182 Views
Last Modified: 2010-04-23
Hi,

I'm trying to figure out the best way of doing this...  

On the business side, the application tracks budget information for Clients.  Each client can have 0..many Groups.  For a Client that has Groups, budgets can exist at just the Client level or the Client level and the Group level.

On the programming side...  I have an object, call it Budget, whose properties are populated with values from a stored proc when it's instantiated.  It can either take the form of a ClientBudget or a PolicyGroupBudget.  

If a Budget is being viewed for a Group, for each field on a form I want to set the value as follows.  If the field has a non-null/blank value at the Group level, then use that.  If not, then use the Client level value if it is non-null/blank.  Otherwise, make the field blank.

I tried to do something like this:

objClient = New BusinessObjects.Budget(Me.ClientID)
objGroup = New BusinessObjects.Budget(Me. GroupID)

MyField.Value = GetObjectValue(objGroup, objClient, FieldName)

And the function would look something like this:

Private Function GetObjectValue(ByVal objGroup As BusinessObjects.Budget, ByVal objClient As BusinessObjects.Budget, ByVal FieldName As String) As Object
        Try
            If mblnFormIsAClientBudget Then
                GetObjectValue = objClient.Fieldname
          (More code here…)

            End If
        Catch ex As Exception

        End Try
    End Function

The problem is, it won’t let me do the objClient.FieldName b/c of course, FieldName is a string holding the name of the field to pull.  

Does anyone know how to make this work?  If not, is there a better way of doing this?  I tried doing it right in the original Sub using Iif’s but it got messy.

Thanks so much for the help!
0
Comment
Question by:MrDeveloper
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
5 Comments
 
LVL 5

Expert Comment

by:xersoft
ID: 17914552
Actually you *could* access the field name from just a string name kind of as you are doing using the following function. There are some situations where this will not work.

The function takes the object you wish to access and the property/field/method you wish to return a value from. It uses reflection to go and get the value and then returns it. If it can’t find a property/field/method with the given name or proper parameter configuration it will return nothing.

Make sure you check the return from this function before you use the value.

I tested the function on a simple object that had public fields, properties and methods that returned values (functions)

The functions and properties MUST not have parameters or they can not be used with this function.


    Public Function GetValue(ByVal Obj As Object, ByVal Name As String) As Object
        'use reflection to get the property or field name from the object
        Dim Members() As Reflection.MemberInfo = Obj.GetType.GetMember(Name, Reflection.MemberTypes.Field Or Reflection.MemberTypes.Property Or Reflection.MemberTypes.Method, Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public)
        If Members.Length < 1 Then Return Nothing

        Dim areturn As Object = Nothing

        'look at the members we found
        For Each member As Reflection.MemberInfo In Members

            If member.MemberType = Reflection.MemberTypes.Field Then
                'get the value of the field
                areturn = DirectCast(member, Reflection.FieldInfo).GetValue(Obj)

            ElseIf member.MemberType = Reflection.MemberTypes.Property Then
                'ensure we can read and then get the value of the property
                'only use properties that have no parameters
                Dim prop As Reflection.PropertyInfo = DirectCast(member, Reflection.PropertyInfo)
                If prop.CanRead AndAlso prop.GetIndexParameters.Length = 0 Then
                    areturn = prop.GetValue(Obj, Nothing)
                End If

            ElseIf member.MemberType = Reflection.MemberTypes.Method Then
                'ensure there is a return value and then call the function to get the value
                Dim method As Reflection.MethodInfo = DirectCast(member, Reflection.MethodInfo)
                If Not method.ReturnType Is Nothing AndAlso method.GetParameters.Length = 0 Then
                    areturn = method.Invoke(Obj, New Object() {})
                End If

            End If

            'if we found a value then drop out of loop
            If Not areturn Is Nothing Then Exit For
        Next


        Return areturn
    End Function
0
 
LVL 5

Assisted Solution

by:xersoft
xersoft earned 250 total points
ID: 17914572
Using the code above you could write your function like this:

   Private Function GetObjectValue(ByVal objGroup As BusinessObjects.Budget, ByVal objClient As BusinessObjects.Budget, ByVal FieldName As String) As Object
        Try
            Dim itm1 As Object = GetValue(objClient, FieldName)
            If Not itm1 Is Nothing Then Return itm1
            Dim itm2 As Object = GetValue(objGroup, FieldName)
            Return itm2
        Catch ex As Exception
            Throw New ApplicationException("Can not find a property, field or function with the name: " & FieldName & " that contains a valid value.")
        End Try
    End Function
0
 
LVL 24

Accepted Solution

by:
Jeff Certain earned 250 total points
ID: 17915839
A better OO approach might be to have GroupBudget.GetValue(), which calls GroupBudget.ClientBudget.GetValue if the value is null. Then your code just looks like this pseudo-code:

Class Group
Function GetValue
if _value is nothing then
  return Client.GetValue
else
  return _value
end if

Class Client
Function GetValue
Return _value
0
 
LVL 5

Expert Comment

by:xersoft
ID: 17916233
I agree with Chaosian, that would be a better way to do it. You'd have to set it up in each property but once it was done you'd be good to go.

Plus using reflection, although neat, is not always the best way to go due to speed concerns and other typing issues.
0
 

Author Comment

by:MrDeveloper
ID: 17916472
thanks so much guys.  Those are both really good solutions.  I'm going to use the GetValue (really cool...) but I'm splitting the points.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial
This video shows how to use Hyena, from SystemTools Software, to update 100 user accounts from an external text file. View in 1080p for best video quality.

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question