views:

124

answers:

4

i have :

vb code:

    Private Sub Calculation()

     Dim txt1 As Decimal
            txt1 = (CS_Incoms_done.Text / CS_Incoms_target.Text) * 100
            CS_Incom_Result.Text = "%" + FormatNumber(txt, 2, TriState.False)

            Dim txt2 As Decimal
            txt2 = (CS_GovernmentService_done.Text / CS_GovernmentService_target.Text) * 100
            CS_GovernmentService_Result.Text = "%" + FormatNumber(txt2, 2, TriState.False)

            Dim txt3 As Decimal
            txt3 = (CS_RentBox_done.Text / CS_RentBox_target.Text) * 100
            CS_RentBox_Result.Text = "%" + FormatNumber(txt3, 2, TriState.False)

Dim txt4 As Decimal
            txt4 = (CS_ServiceAdvertising_done.Text / CS_ServiceAdvertising_target.Text) * 100
            CS_ServiceAdvertising_Result.Text = "%" + FormatNumber(txt4, 2, TriState.False)

  Dim txt5 As Decimal
            txt5 = (CS_ServiceCatogray_done.Text / CS_ServiceCatogray_target.Text) * 100
            CS_ServiceCatogray_Result.Text = "%" + FormatNumber(txt5, 2, TriState.False)
    End Sub

i just show you 5 textbox's of 100 textbox's .... and don't want to complete all the textbox's like this ... i want a simple code to do it..

... as you notice , every three textbox's are look a like on the first two parts of their id's..~

for example --> CS_ServiceCatogray _Result.Text, CS_ServiceCatogray _done.Text and CS_ServiceCatogray _target.Text...

~..and the last part is the same in all textbox's for geving the Result ..> _Result.Text , _done.Text and _target.Text

So... i had an idea to take the id and put the Similar two parts in an array... and use For Each something like:

Dim allItems As Array
        For Each item As Control In panel4.Controls
            Select Case item.[GetType]().Name
                Case "TextBox"

                    'here just be sure that this item is not saved in the allItems array ,if it is not  do >>'
                    allItems[Last_Item_Saved_Index+1] = DirectCast(item, TextBox).ID ',  i want  to save just the two Similar parts of the textboxs ids'


'i am not sure if this completely correct, but i wanted to do something like it['
                    Dim partOFtxt As String = allItems[Last_Item_Saved_Index]

                    Dim txt As Decimal = (partOFtxt + "_done.Text") / (partOFtxt + "_target.Text")

                    (partOFtxt + "_Result.Text") = "%" + FormatNumber(txt, 2, TriState.False)  ']'
                    'end condition'

                    Exit Select
                Case Else
        Exit Select
            End Select
        Next

i hope that you get the idea..

if you have a better idea ... it would be nice..

Thanks in advance..

+2  A: 

Edit: Removed part of the answer to make the rest clearer.

Or if you want to make it easy to loop through them, you could do something like this:

In your initialization code you link each textbox with the textboxes used to calculate it's value as:

CS_Incom_Result.Tag = New KeyValuePair(Of TextBox, TextBox)(CS_Incoms_done, CS_Incoms_target)

Then you create a method as:

Public sub UpdateTextBox(t as TextBox) 
    Dim kvp as KeyValuePair(Of TextBox, TextBox) = CType(t.Tag, KeyValuePair(Of TextBox, TextBox))
    Dim txt as Decimal = (decimal.Parse(kvp.Key.Text) / decimal.Parse(kvp.Value.Text)) * 100
    t.Text = "%" & FormatNumber(txt, 2, TriState.False)
End Function

And then you could update them all in a loop as:

For Each ctrl As Control In panel4.Controls
    If Typeof ctrl is TextBox Then
        UpdateTextBox(Ctype(ctrl, TextBox)
    Endif
Next
ho1
your way is even longer than mine ... and i have to deal with 100 'textboxs' not just one...!!!
jjj
I never said that the above was only for 1 textbox, just that I only showed one in the sample... I don't really understand your complaint about longer either, since the second version in my code above is one 3 line method and a 5 line loop. You would have the first line about 33 times (one for each result box) which isn't great, but I'd be reluctant to have controls being linked to each other via their name since it would be easy to introduce bugs during maintenance.
ho1
i know that you showed me one ... what if i want to do the same code for the 100 `textboxs` .. it will be a mess...!!!
jjj
If you have 100 textboxes you already have a mess, there's no way of avoiding that. There might be some case where that would be a suitable design, but I'm doubtful. However, if you read the lower half of my answer, starting from the line beginning with "Or if..." I think that option is a possible way of handling a bad situation. But just to make that clear, I'll remove the top half of my answer completely since I think maybe it's a bit messy with 2 suggestions.
ho1
Thinking about the 100 textboxes... Can't you replace them with a `DataGridView` instead, for example with one readonly Name column, one readonly result column and then the two other columns where the user can enter the values. Would of course look different from your current design but since many users have used Excel it might a be reasonably alternative.
ho1
thanks any way ...
jjj
+1  A: 

i got it...^_^ :

Private Sub Calculation()
        Dim decZeroResult As Decimal = 1.1
        Dim strCommonID As String
        For Each item As Control In panel4.Controls
            Select Case item.[GetType]().Name
                Case "TextBox"
                    If InStr(item.ID.ToUpper, "_Done".ToUpper) Then
                        strCommonID = Mid(item.ID, 1, InStr(item.ID.ToUpper, "_Done".ToUpper) - 1)
                        Dim MyTxt1 As TextBox
                        Dim MyTxt2 As TextBox
                        MyTxt1 = CType(item, TextBox)
                        For Each item2 As Control In panel4.Controls
                            Select Case item2.[GetType]().Name
                                Case "TextBox"
                                    If item2.ID.ToUpper = strCommonID.ToUpper & "_target".ToUpper Then
                                        MyTxt2 = CType(item2, TextBox)
                                        If CType(item2, TextBox).Text = 0 Then
                                            If CType(item, TextBox).Text = 0 Then
                                                decZeroResult = 0
                                            ElseIf CType(item, TextBox).Text > 0 Then
                                                decZeroResult = 100
                                            End If
                                        ElseIf CType(item2, TextBox).Text > 0 Then
                                            If CType(item, TextBox).Text > 0 Then
                                                decZeroResult = FormatNumber(((MyTxt1.Text / MyTxt2.Text) * 100), 1, TriState.False)
                                            Else
                                                decZeroResult = 0
                                            End If
                                        End If
                                        For Each item3 As Control In panel4.Controls
                                            Select Case item3.[GetType]().Name
                                                Case "Label"
                                                    If item3.ID.ToUpper = strCommonID.ToUpper & "_Result".ToUpper Then

                                                        CType(item3, Label).Text = decZeroResult & " %"

                                                        Exit For
                                                    End If
                                            End Select
                                        Next
                                        Exit For
                                    End If
                            End Select
                        Next
                    End If
            End Select
        Next

        For Each item As Control In panel1.Controls
            Select Case item.[GetType]().Name
                Case "TextBox"
                    If InStr(item.ID.ToUpper, "_Done".ToUpper) Then
                        strCommonID = Mid(item.ID, 1, InStr(item.ID.ToUpper, "_Done".ToUpper) - 1)
                        Dim MyTxt1 As TextBox
                        Dim MyTxt2 As TextBox
                        MyTxt1 = CType(item, TextBox)
                        For Each item2 As Control In panel1.Controls
                            Select Case item2.[GetType]().Name
                                Case "TextBox"
                                    If item2.ID.ToUpper = strCommonID.ToUpper & "_target".ToUpper Then
                                        MyTxt2 = CType(item2, TextBox)
                                        If CType(item2, TextBox).Text = 0 Then
                                            If CType(item, TextBox).Text = 0 Then
                                                decZeroResult = 0
                                            ElseIf CType(item, TextBox).Text > 0 Then
                                                decZeroResult = 100
                                            End If
                                        ElseIf CType(item2, TextBox).Text > 0 Then
                                            If CType(item, TextBox).Text > 0 Then
                                                decZeroResult = FormatNumber(((MyTxt1.Text / MyTxt2.Text) * 100), 1, TriState.False)
                                            Else
                                                decZeroResult = 0
                                            End If
                                        End If
                                        For Each item3 As Control In panel1.Controls
                                            Select Case item3.[GetType]().Name
                                                Case "Label"
                                                    If item3.ID.ToUpper = strCommonID.ToUpper & "_Result".ToUpper Then

                                                        CType(item3, Label).Text = decZeroResult & " %"

                                                        Exit For
                                                    End If
                                            End Select
                                        Next
                                        Exit For
                                    End If
                            End Select
                        Next
                    End If
            End Select
        Next

        For Each item As Control In panel2.Controls
            Select Case item.[GetType]().Name
                Case "TextBox"
                    If InStr(item.ID.ToUpper, "_Done".ToUpper) Then
                        strCommonID = Mid(item.ID, 1, InStr(item.ID.ToUpper, "_Done".ToUpper) - 1)
                        Dim MyTxt1 As TextBox
                        Dim MyTxt2 As TextBox
                        MyTxt1 = CType(item, TextBox)
                        For Each item2 As Control In panel2.Controls
                            Select Case item2.[GetType]().Name
                                Case "TextBox"
                                    If item2.ID.ToUpper = strCommonID.ToUpper & "_target".ToUpper Then
                                        MyTxt2 = CType(item2, TextBox)
                                        If CType(item2, TextBox).Text = 0 Then
                                            If CType(item, TextBox).Text = 0 Then
                                                decZeroResult = 0
                                            ElseIf CType(item, TextBox).Text > 0 Then
                                                decZeroResult = 100
                                            End If
                                        ElseIf CType(item2, TextBox).Text > 0 Then
                                            If CType(item, TextBox).Text > 0 Then
                                                decZeroResult = FormatNumber(((MyTxt1.Text / MyTxt2.Text) * 100), 1, TriState.False)
                                            Else
                                                decZeroResult = 0
                                            End If
                                        End If
                                        For Each item3 As Control In panel2.Controls
                                            Select Case item3.[GetType]().Name
                                                Case "Label"
                                                    If item3.ID.ToUpper = strCommonID.ToUpper & "_Result".ToUpper Then

                                                        CType(item3, Label).Text = decZeroResult & " %"

                                                        Exit For
                                                    End If
                                            End Select
                                        Next
                                        Exit For
                                    End If
                            End Select
                        Next
                    End If
            End Select
        Next

        For Each item As Control In panel3.Controls
            Select Case item.[GetType]().Name
                Case "TextBox"
                    If InStr(item.ID.ToUpper, "_Done".ToUpper) Then
                        strCommonID = Mid(item.ID, 1, InStr(item.ID.ToUpper, "_Done".ToUpper) - 1)
                        Dim MyTxt1 As TextBox
                        Dim MyTxt2 As TextBox
                        MyTxt1 = CType(item, TextBox)
                        For Each item2 As Control In panel3.Controls
                            Select Case item2.[GetType]().Name
                                Case "TextBox"
                                    If item2.ID.ToUpper = strCommonID.ToUpper & "_target".ToUpper Then
                                        MyTxt2 = CType(item2, TextBox)
                                        If CType(item2, TextBox).Text = 0 Then
                                            If CType(item, TextBox).Text = 0 Then
                                                decZeroResult = 0
                                            ElseIf CType(item, TextBox).Text > 0 Then
                                                decZeroResult = 100
                                            End If
                                        ElseIf CType(item2, TextBox).Text > 0 Then
                                            If CType(item, TextBox).Text > 0 Then
                                                decZeroResult = FormatNumber(((MyTxt1.Text / MyTxt2.Text) * 100), 1, TriState.False)
                                            Else
                                                decZeroResult = 0
                                            End If
                                        End If
                                        For Each item3 As Control In panel3.Controls
                                            Select Case item3.[GetType]().Name
                                                Case "Label"
                                                    If item3.ID.ToUpper = strCommonID.ToUpper & "_Result".ToUpper Then

                                                        CType(item3, Label).Text = decZeroResult & " %"

                                                        Exit For
                                                    End If
                                            End Select
                                        Next
                                        Exit For
                                    End If
                            End Select
                        Next
                    End If
            End Select
        Next
    End Sub
jjj
No... pls dont use like this. I will put a short code for the same. please wait. Above code will be difficult to maintain.
Sachin
I have added the code which gives the same result as yours. It is quick fast what i can do. It can be further streamlined if needed.I know its how painful to work on such projects.
Sachin
@sachin .. thanks for your help .. but don't you think that my answer deserves at least one point..!!!
jjj
Ok given -nice try
Sachin
@sachin .. thanks ..^_^
jjj
+3  A: 

Here is the short and sweet code which gives the same result as given by your answer. Feel free if need clarification.

Private Sub Calculation()
    Dim CurParent As ContainerControl = Me
    For Each item As Control In CurParent.Controls
        Dim decZeroResult As Decimal = 0
        Select Case item.GetType().Name.ToUpper
            Case "LABEL"
                Dim ControlName As String
                Dim ResultControl As Control = item
                ControlName = ResultControl.Name
                If ControlName.ToUpper.EndsWith("_RESULT") Then
                    Dim ControlPartName As String = Mid(ControlName, 1, ControlName.Length - 7)
                    Dim TargetControl As TextBox = Nothing
                    Dim DoneControl As TextBox = Nothing
                    Dim controlsFound() As Control
                    controlsFound = CurParent.Controls.Find(ControlPartName & "_Target", True)
                    If controlsFound.Length > 0 Then
                        TargetControl = controlsFound(0)
                    End If
                    controlsFound = CurParent.Controls.Find(ControlPartName & "_Done", True)
                    If controlsFound.Length > 0 Then
                        DoneControl = controlsFound(0)
                    End If
                    If TargetControl IsNot Nothing And DoneControl IsNot Nothing Then
                        If TargetControl.Text > 0 Then
                            decZeroResult = FormatNumber(((DoneControl.Text / TargetControl.Text) * 100), 1, TriState.False)
                        Else
                            decZeroResult = 0
                        End If
                        ResultControl.Text = decZeroResult & " %"
                    End If
                End If
        End Select

    Next

End Sub
Sachin
+1 For the Control.Find technique, which I was going to tinker with but which you've employed to great effect here. Super readable; no 'redundant' cut and pasting of control names. OP, have you tried this out? (There's a tiny error at the top where ctl type Case condition should be "TEXTBOX" not "LABEL")
LesterDove
@lesterdove. Thank. I have tried it and it gives exactly same result as the answer given below by jjj who himself has tried to solve his own question. I have used LABEL because the answer of the question owner jjj is using Label. So it means tha the result is displayed on a label to make it readonly.
Sachin
+1 for helping ...and thanks.. i'll try it when i have a time..
jjj
A: 

I don't suppose you have the flexibility to create a user control that groups the three text boxes together and centralizes the logic that calculates the result? That way in the code behind you could loop on all of the controls in the Panel, testing for control type using "is", cast to that type and call the calculation method.

Pseudo-code:

Public Class ThreeTextboxUserControl
    Private doneTextBox
    Private targetTextBox
    Private resultTextBox

Public Sub loadValues(doneTextBoxValue, targetTextBoxValue)
Public Sub calculateResult()

In Page code behind:

Public Sub Calculation()
    For Each item As Control In panel4.Controls
        If (item is ThreeTextboxUserControl)
            [Cast item and call calculateResult()]
        End IF
    Next
End Sub
Mark
thanks any way...
jjj