Chris Leah
Chris Leah

Reputation: 79

Reduce amount of if code VB.NET

I am creating a Solar PV Calculator using ASP Web Forms and VB backend. I just looked at my code and being a novice VB.NET developer, I just wanted to know if there is a way to do something differently, reduce the amount of lines of code or something similar. Here's a cumbersome part of y code:

Dim SR As Integer
    'Store radiation value
    If drpDwnRoofFacing.Text = "South" And drpAngleOfRoof.Text = "Horizontal" Then
        SR = 933
    ElseIf drpDwnRoofFacing.Text = "SE/SW" And drpAngleOfRoof.Text = "Horizontal" Then
        SR = 933
    ElseIf drpDwnRoofFacing.Text = "E/W" And drpAngleOfRoof.Text = "Horizontal" Then
        SR = 933
    ElseIf drpDwnRoofFacing.Text = "NE/NW" And drpAngleOfRoof.Text = "Horizontal" Then
        SR = 933
    ElseIf drpDwnRoofFacing.Text = "North" And drpAngleOfRoof.Text = "Horizontal" Then
        SR = 933
    ElseIf drpDwnRoofFacing.Text = "South" And drpAngleOfRoof.Text = "30 Degrees" Then
        SR = 1042
    ElseIf drpDwnRoofFacing.Text = "SE/SW" And drpAngleOfRoof.Text = "30 Degrees" Then
        SR = 997
    ElseIf drpDwnRoofFacing.Text = "E/W" And drpAngleOfRoof.Text = "30 Degrees" Then
        SR = 886
    ElseIf drpDwnRoofFacing.Text = "NE/NW" And drpAngleOfRoof.Text = "30 Degrees" Then
        SR = 762
    ElseIf drpDwnRoofFacing.Text = "North" And drpAngleOfRoof.Text = "30 Degrees" Then
        SR = 709
    ElseIf drpDwnRoofFacing.Text = "South" And drpAngleOfRoof.Text = "45 Degrees" Then
        SR = 1023
    ElseIf drpDwnRoofFacing.Text = "SE/SW" And drpAngleOfRoof.Text = "45 Degrees" Then
        SR = 968
    ElseIf drpDwnRoofFacing.Text = "E/W" And drpAngleOfRoof.Text = "45 Degrees" Then
        SR = 829
    ElseIf drpDwnRoofFacing.Text = "NE/NW" And drpAngleOfRoof.Text = "45 Degrees" Then
        SR = 666
    ElseIf drpDwnRoofFacing.Text = "North" And drpAngleOfRoof.Text = "45 Degrees" Then
        SR = 621
    ElseIf drpDwnRoofFacing.Text = "South" And drpAngleOfRoof.Text = "60 Degrees" Then
        SR = 960
    ElseIf drpDwnRoofFacing.Text = "SE/SW" And drpAngleOfRoof.Text = "60 Degrees" Then
        SR = 900
    ElseIf drpDwnRoofFacing.Text = "E/W" And drpAngleOfRoof.Text = "60 Degrees" Then
        SR = 753
    ElseIf drpDwnRoofFacing.Text = "NE/NW" And drpAngleOfRoof.Text = "60 Degrees" Then
        SR = 580
    ElseIf drpDwnRoofFacing.Text = "North" And drpAngleOfRoof.Text = "60 Degrees" Then
        SR = 485
    ElseIf drpDwnRoofFacing.Text = "South" And drpAngleOfRoof.Text = "Vertical" Then
        SR = 724
    ElseIf drpDwnRoofFacing.Text = "SE/SW" And drpAngleOfRoof.Text = "Vertical" Then
        SR = 684
    ElseIf drpDwnRoofFacing.Text = "E/W" And drpAngleOfRoof.Text = "Vertical" Then
        SR = 565
    ElseIf drpDwnRoofFacing.Text = "NE/NW" And drpAngleOfRoof.Text = "Vertical" Then
        SR = 427
    ElseIf drpDwnRoofFacing.Text = "North" And drpAngleOfRoof.Text = "Vertical" Then
        SR = 360
    End If

Upvotes: 2

Views: 209

Answers (4)

Steven Doggart
Steven Doggart

Reputation: 43743

I would recommend storing this data outside of the application code, such as in a database, or if that's unnecessary, an XML file. However, even if you are going to hard-code the transformation rules in your code, it would still be better to separate out the hard-coding of the rules from the logic that processes and applies the rules. For instance, you could create a class that contained a rule, like this:

Public Class MyRule
    Public Sub New(roofFacing As String, angleOfRoof As String, SR As Integer)
        _roofFacing = roofFacing
        _angleOfRoof = angleOfRoof
        _SR = sr
    End New

    Public ReadOnly Property RoofFacing() As String
        Get
            Return _roofFacing
        End Get
    End Property
    Private _roofFacing As String

    Public ReadOnly Property AngleOfRoof() As String
        Get
            Return _angleOfRoof
        End Get
    End Property
    Private _angleOfRoofAs String

    Public ReadOnly Property SR() As String
        Get
            Return _SR
        End Get
    End Property
    Private _SR String
End Class

Then, you could hard-code the creation of the list of rules, as if they were coming in from a database, like this:

Dim rules As New List(Of MyRule)()
rules.Add(New MyRule("South", "Horizontal", 933))
rules.Add(New MyRule("South", "SE/SW", 933))
' ...
rules.Add(New MyRule("South", Nothing, 933))

Then, instead of a gigantic If statement, you can just have a simple loop to apply the rules, like this:

Dim SR As Integer
For Each rule As MyRule In rules
    If _
    ( _
        (rule.RoofFacing Is Nothing) OrEsle _
        (rule.RoofFacing = drpDwnRoofFacing.Text) _
    ) AndAlso _
    ( _
        (rule.AngleOfRoof Is Nothing) OrEsle _
        (rule.AngleOfRoof = drpAngleOfRoof.Text) _
    ) Then
        SR = rule.SR
        Exit For
    End If
Next

As you can see, once you design it this way, it will be much easier to modify the rules or add additional rules in the future. However, rather than strings, you should really be using enumerations for those values. For instance:

Public Enum RoofFacings
    Any
    North
    South
    EastOrWest
    ' ...
End Enum

Public Enum AnglesOfRoof
    Any
    Horizontal
    Degrees30
    Degrees45
    ' ...
    Vertical
End Enum

Upvotes: 5

Dom Sinclair
Dom Sinclair

Reputation: 2528

What about using a select statement instead. You'll cut your initial choice to the value of drpAngleOfRoof, and then you only need to worry about the value of drpDownRoofFacing. Something like this:

Select Case drpAngleOfRoof.Text
Case "Horizontal"
    Return 933
Case "30 Degrees"
    Select Case drpDwnRoofFacing.Text
        Case "South"
            Return 1042
        Case "SE/SW"
            Return 997
        Case "E/W"
            Return 886
        Case "NE/NW"
            Return 762
        Case "North"
            Return 709
    End Select
Case "45 Degrees"
    Select Case drpDwnRoofFacing.Text
        Case "South"
            Return 1023
        Case "SE/SW"
            Return 968
        Case "E/W"
            Return 829
        Case "NE/NW"
            Return 666
        Case "North"
            Return 621
    End Select
Case "60 Degrees"
    Select Case drpDwnRoofFacing.Text
        Case "South"
            Return 960
        Case "SE/SW"
            Return 900
        Case "E/W"
            Return 753
        Case "NE/NW"
            Return 580
        Case "North"
            Return 485
    End Select
Case "Vertical"
    Select Case drpDwnRoofFacing.Text
        Case "South"
            Return 724
        Case "SE/SW"
            Return 684
        Case "E/W"
            Return 565
        Case "NE/NW"
            Return 427
        Case "North"
            Return 360
    End Select
End Select

Upvotes: -1

SysDragon
SysDragon

Reputation: 9888

Select Case drpAngleOfRoof.Text
        Case "Horizontal"
            Select Case drpDwnRoofFacing.Text
                Case "South" : SR = 933
                Case "SE/SW" : SR = 933
                Case "E/W" : SR = 933
                Case "NE/NW" : SR = 933
                Case "North" : SR = 933
            End Select
        Case "30 Degrees"
            Select Case drpDwnRoofFacing.Text
                Case "South" : SR = 933
                Case "SE/SW" : SR = 933
                Case "E/W" : SR = 933
                Case "NE/NW" : SR = 933
                Case "North" : SR = 933
            End Select
        Case "45 Degrees"
            Select Case drpDwnRoofFacing.Text
                Case "South" : SR = 933
                Case "SE/SW" : SR = 933
                Case "E/W" : SR = 933
                Case "NE/NW" : SR = 933
                Case "North" : SR = 933
            End Select
        Case "60 Degrees"
            Select Case drpDwnRoofFacing.Text
                Case "South" : SR = 933
                Case "SE/SW" : SR = 933
                Case "E/W" : SR = 933
                Case "NE/NW" : SR = 933
                Case "North" : SR = 933
            End Select
        Case "Vertical"
            Select Case drpDwnRoofFacing.Text
                Case "South" : SR = 933
                Case "SE/SW" : SR = 933
                Case "E/W" : SR = 933
                Case "NE/NW" : SR = 933
                Case "North" : SR = 933
            End Select
    End Select

Upvotes: 3

DaveRead
DaveRead

Reputation: 3413

You can nest the IF statements, i.e.

If drpAngleOfRoof.Text = "Horizontal" Then

    If drpDwnRoofFacing.Text = "South" Then

         SR = 933

    End If

End If

to group all the statements related to each angle position together, for example.

Or you could use a Select...Case statement, as an alternative.

http://msdn.microsoft.com/en-us/library/cy37t14y(v=vs.71).aspx

Upvotes: 2

Related Questions