Rechenschritte verursachen Rundungsfehler

  • Hallo liebe AutoIt-Freunde,

    hab ein etwas komplexeres problem.
    habe für meine arbeit ein programm entworfen das meinen kunden bei der auswahl einer meiner produkte hilft. hierbei übernimmt es lässtige rechenschritte jedoch habe ich probleme mit der rundung...

    folgendes:

    ich habe mehrere Produkte => Produkt 1, Produkt 2 usw
    jedes Produkt setzt sich aus 4 verschiedenen Grundstoffen zusammen. nennen wir sie der Einfachheit halber a, b, c, d
    jdes produkt wird anders gemischt, zB produkt 1 braucht 2 x material a, 3 x material b, 5 x material c und 1 x material d

    meine kunden kommen und sagen sie haben eine bestimmte anzahl an a, b, c und d und wollen nun 20% von produkt 1, 40% von produkt 2 usw (insgesammt immer 100%)

    hab das dann mal so geschrieben:

    Spoiler anzeigen
    [autoit]

    $a_kosten_produkt1 = 3 ; kosten produkt eins von material "a"
    $a_kosten_produkt1 = 2 ; " " " " " "b"
    $a_kosten_produkt1 = 5 ; " " " " " "c"
    $a_kosten_produkt1 = 1 ; " " " " " "d"

    [/autoit] [autoit][/autoit] [autoit]

    If GUICtrlRead($Produkt1) = $GUI_CHECKED Then ;wenn der haken bei checkbox "$Produkt1" gesetzt wurde dann..
    $produkt1_a_ges = Floor($a_aviable / $produkt1_kosten_a) ; errechne wie viele produkte1 von material a hergestellt werden könnten und rundet auf die nächste Ganzzahl, die kleiner oder gleich dem angegebenen Wert ist
    $produkt1_b_ges = Floor($b_aviable/ $produkt1_kosten_b) ; " " " " " " " b " " " " "
    $produkt1_c_ges = Floor($c_aviable / $produkt1_kosten_c) ; " " " " " " " c " " " " "
    $produkt1_d_ges = Floor($d_aviable / $produkt1_kosten_d) ; " " " " " " " d " " " " "

    [/autoit] [autoit][/autoit] [autoit]

    $stringload_produkt1 = StringSplit($produkt1_a_ges & "," & $produkt1_b_ges & "," & $produkt1_c_ges & "," & $produkt1_a_ges, ",", 2) ; die ausgerechneten werte werden in einen string gesetzt bei der ein komma das trennzeichen ist
    $nummberMin_produkt1 = _MathEx_Min($stringload_produkt1) ; ermittelt den kleinsten wert der 4 ausgerechneten zahlen (das produkt kann immer nur fertig gestellt wenn alle materialien vorhanden sind kleinste zahl ist somit die max. zahl an produkten1
    $Produkt1_end = Floor($nummberMin_produkt1 * $prozent_1_is / 100) ; max anzahl an produkten1 mal die prozentzahl die der user angegeben hat die von diesem produkt hergestellt werden sollen durch 100 = prozentuale mänge an produkten1

    [/autoit] [autoit][/autoit] [autoit]

    $Produkt1_end_a = $Produkt1_end * $a_kosten_produkt1 ; anzahl an produkten1 mal materialkosten a für produkt1 = material a gesammt benötigt
    $Produkt1_end_b = $Produkt1_end * $b_kosten_produkt1 ; " " " " " " b " " " " b " " "
    $Produkt1_end_c = $Produkt1_end * $c_kosten_produkt1 ; " " " " " " c " " " " c " " "
    $Produkt1_end_d = $Produkt1_end * $d_kosten_produkt1 ; " " " " " " d " " " " d " " "

    $Produkt1_end_ges = $Produkt1_end_a + $produkt1_end_b + $produkt1_end_c + $produkt1_end_d ; gesammt material a + gesammt material b + gesammt material c + gesammt material d = gesammtmaterialien
    EndIf

    [/autoit]

    das programm funktioniert und stimmt soweit schon nur entsteht durch das ständige abrunden rundungsfehler.
    durch eine größere auswahl an produkten wird der rundungsfehler von der anzahl der ausgewählten produkten größer und größer und die restmaterialien sind dann so viel das man aus denen nochmals produkte herstellen könnte

    ich hoffe mir kann überhaut noch jemand folgen.. hat jemand eine idee wie man die rundungsfehler vermeiden könnte bzw wie man hinterher die übrig gebliebenen materialien mit einer gewissen toleranz in ein produkt noch aufteilen könnte?

    WENN ETWAS UNKLAR IST (WEIL ES JA WIRKLICH EIN WENIG KOMPLEX IST) DER KANN GERN NOCHMAL FRAGEN.
    wäre sehr sehr schön und ich wäre unheimlich dankbar wenn mir da jemand helfen könnte

    viele grüße Inferior

    EDIT:

    was mir noch so einfällt.
    meine Variante ist sicher nicht die einfachste und ich bin mir sicher das es auch einfacher geht.
    im moment steht mir zwar die funktionalität im Vordergrund jedoch wenn jemand eine andere Vorgehensweise hat mit dem er besseren überblick hat und das rundungsproblem in den griff bekommt würde ich auch nicht nein sagen ;)
    was ich sagen will: mein script ist nicht bindend ;)

    6 Mal editiert, zuletzt von Inferior (7. Januar 2011 um 15:38)

    • Offizieller Beitrag

    Bitte ein lauffähiges Beispiel posten!

  • ok hier ist ein "kleines" beispielscript:

    Spoiler anzeigen
    [autoit]

    #include <MathEx.au3>
    #include <EditConstants.au3>
    #include <UpdownConstants.au3>
    #include <GUIConstantsEX.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $a_kosten_produkt1 = 3 ; kosten produkt eins von material "a"
    Dim $b_kosten_produkt1 = 2 ; " " " " " "b"
    Dim $c_kosten_produkt1 = 5 ; " " " " " "c"
    Dim $d_kosten_produkt1 = 1 ; " " " " " "d"

    [/autoit] [autoit][/autoit] [autoit]

    Dim $a_aviable_is, $b_aviable_is, $c_aviable_is, $d_aviable_is
    Dim $Produkt1_end_a, $Produkt1_end_b, $Produkt1_end_c, $Produkt1_end_d, $Produkt1_end_ges

    [/autoit] [autoit][/autoit] [autoit]

    $Main = GUICreate("kalkulator", 500, 200)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateLabel("a", 8, 57, 18, 12)
    GUICtrlCreateLabel("b", 133, 57, 18, 12)
    GUICtrlCreateLabel("c", 257, 57, 18, 12)
    GUICtrlCreateLabel("d", 378, 57, 18, 12)

    [/autoit] [autoit][/autoit] [autoit]

    $a_aviable = GUICtrlCreateInput("", 28, 53, 50, 20, $ES_NUMBER)
    $b_aviable = GUICtrlCreateInput("", 153, 53, 50, 20, $ES_NUMBER)
    $c_aviable = GUICtrlCreateInput("", 275, 53, 50, 20, $ES_NUMBER)
    $d_aviable= GUICtrlCreateInput("", 397, 53, 50, 20, $ES_NUMBER)

    [/autoit] [autoit][/autoit] [autoit]

    $produkt1 = GUICtrlCreateCheckbox("produkt1", 202, 100)

    [/autoit] [autoit][/autoit] [autoit]

    $prozent_1 = GUICtrlCreateInput("0", 113, 100, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $updown1 = GUICtrlCreateUpdown($prozent_1, $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 104, 18, 12)

    [/autoit] [autoit][/autoit] [autoit]

    $ok = GUICtrlCreateButton("Berechnen", 171, 150, 160, 40)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $Main = GUIGetMsg()
    Switch $Main
    Case $GUI_EVENT_CLOSE
    Exit
    Case $ok

    [/autoit] [autoit][/autoit] [autoit]

    $prozent_1_is = GUICtrlRead($prozent_1)

    [/autoit] [autoit][/autoit] [autoit]

    $a_aviable_is = GUICtrlRead($a_aviable)
    $b_aviable_is = GUICtrlRead($b_aviable)
    $c_aviable_is = GUICtrlRead($c_aviable)
    $d_aviable_is = GUICtrlRead($d_aviable)

    [/autoit] [autoit][/autoit] [autoit]

    If GUICtrlRead($Produkt1) = $GUI_CHECKED Then ;wenn der haken bei checkbox "$Produkt1" gesetzt wurde dann..
    $produkt1_a_ges = Floor($a_aviable_is / $a_kosten_produkt1) ; errechne wie viele produkte1 von material a hergestellt werden könnten und rundet auf die nächste Ganzzahl, die kleiner oder gleich dem angegebenen Wert ist
    $produkt1_b_ges = Floor($b_aviable_is/ $b_kosten_produkt1) ; " " " " " " " b " " " " "
    $produkt1_c_ges = Floor($c_aviable_is / $c_kosten_produkt1) ; " " " " " " " c " " " " "
    $produkt1_d_ges = Floor($d_aviable_is / $d_kosten_produkt1) ; " " " " " " " d " " " " "

    [/autoit] [autoit][/autoit] [autoit]

    $stringload_produkt1 = StringSplit($produkt1_a_ges & "," & $produkt1_b_ges & "," & $produkt1_c_ges & "," & $produkt1_d_ges, ",", 2) ; die ausgerechneten werte werden in einen string gesetzt bei der ein komma das trennzeichen ist
    $nummberMin_produkt1 = _MathEx_Min($stringload_produkt1) ; ermittelt den kleinsten wert der 4 ausgerechneten zahlen (das produkt kann immer nur fertig gestellt wenn alle materialien vorhanden sind kleinste zahl ist somit die max. zahl an produkten1
    $Produkt1_end = Floor($nummberMin_produkt1 * $prozent_1_is / 100) ; max anzahl an produkten1 mal die prozentzahl die der user angegeben hat die von diesem produkt hergestellt werden sollen durch 100 = prozentuale mänge an produkten1

    [/autoit] [autoit][/autoit] [autoit]

    $Produkt1_end_a = $Produkt1_end * $a_kosten_produkt1 ; anzahl an produkten1 mal materialkosten a für produkt1 = material a gesammt benötigt
    $Produkt1_end_b = $Produkt1_end * $b_kosten_produkt1 ; " " " " " " b " " " " b " " "
    $Produkt1_end_c = $Produkt1_end * $c_kosten_produkt1 ; " " " " " " c " " " " c " " "
    $Produkt1_end_d = $Produkt1_end * $d_kosten_produkt1 ; " " " " " " d " " " " d " " "

    [/autoit] [autoit][/autoit] [autoit]

    $Produkt1_end_ges = $Produkt1_end_a + $produkt1_end_b + $produkt1_end_c + $produkt1_end_d ; gesammt material a + gesammt material b + gesammt material c + gesammt material d = gesammtmaterialien
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $rest_a = $a_aviable_is - $Produkt1_end_a
    $rest_b = $b_aviable_is - $Produkt1_end_b
    $rest_c = $c_aviable_is - $Produkt1_end_c
    $rest_d = $d_aviable_is - $Produkt1_end_d
    $rest_gesammt = ($a_aviable_is + $b_aviable_is + $c_aviable_is + $d_aviable_is) - $Produkt1_end_ges

    [/autoit] [autoit][/autoit] [autoit]

    $ergebnis = GUICreate("test", 562, 243)
    $listview = GUICtrlCreateListView("name: |Anzahl: |material a: |material b: |material c |material d: |Gesammt: ", 5, 10, 552, 203)
    If GUICtrlRead($produkt1) = $GUI_CHECKED Then GUICtrlCreateListViewItem("produkt1 (" & $prozent_1_is & "%)|" & $Produkt1_end & "|" & $Produkt1_end_a & "|" & $Produkt1_end_b & "|" & $Produkt1_end_c & "|" & $Produkt1_end_d & "|" & $Produkt1_end_ges, $listview)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateListViewItem("______________________", $listview)
    GUICtrlSetColor(-1, 0x757575)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateListViewItem("Rest:||" & $rest_a & "|" & $rest_b & "|" & $rest_c & "|" & $rest_d & "|" & $rest_gesammt, $listview)
    GUICtrlSetColor(-1, 0xFF0000)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $ergebnis = GUIGetMsg()
    Switch $ergebnis
    Case $GUI_EVENT_CLOSE
    GUISetState(@SW_HIDE)
    ExitLoop
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Case $produkt1
    If GUICtrlRead($produkt1) = $GUI_CHECKED Then
    GUICtrlSetState($prozent_1, $GUI_ENABLE)
    Else
    GUICtrlSetData($prozent_1, "0")
    GUICtrlSetState($prozent_1, $GUI_DISABLE)
    EndIf
    EndSwitch
    WEnd

    [/autoit]

    im anhang findet ihr die MathEx.au3 die ihr für das script benötigt

    EDIT:

    hier das ganze mit 2 produkten:

    Spoiler anzeigen
    [autoit]

    #include <MathEx.au3>
    #include <EditConstants.au3>
    #include <UpdownConstants.au3>
    #include <GUIConstantsEX.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $a_kosten_produkt1 = 3 ; kosten produkt1 von material "a"
    Dim $b_kosten_produkt1 = 2 ; " " " " "b"
    Dim $c_kosten_produkt1 = 5 ; " " " " "c"
    Dim $d_kosten_produkt1 = 1 ; " " " " "d"

    [/autoit] [autoit][/autoit] [autoit]

    Dim $a_kosten_produkt2 = 10 ; kosten produkt2 von material "a"
    Dim $b_kosten_produkt2 = 12 ; " " " " "b"
    Dim $c_kosten_produkt2 = 18 ; " " " " "c"
    Dim $d_kosten_produkt2 = 7 ; " " " " "d"

    [/autoit] [autoit][/autoit] [autoit]

    Dim $a_aviable_is, $b_aviable_is, $c_aviable_is, $d_aviable_is
    Dim $Produkt1_end_a, $Produkt1_end_b, $Produkt1_end_c, $Produkt1_end_d, $Produkt1_end_ges
    Dim $Produkt2_end_a, $Produkt2_end_b, $Produkt2_end_c, $Produkt2_end_d, $Produkt2_end_ges

    [/autoit] [autoit][/autoit] [autoit]

    $Main = GUICreate("kalkulator", 500, 200)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateLabel("a", 8, 57, 18, 12)
    GUICtrlCreateLabel("b", 133, 57, 18, 12)
    GUICtrlCreateLabel("c", 257, 57, 18, 12)
    GUICtrlCreateLabel("d", 378, 57, 18, 12)

    [/autoit] [autoit][/autoit] [autoit]

    $a_aviable = GUICtrlCreateInput("", 28, 53, 50, 20, $ES_NUMBER)
    $b_aviable = GUICtrlCreateInput("", 153, 53, 50, 20, $ES_NUMBER)
    $c_aviable = GUICtrlCreateInput("", 275, 53, 50, 20, $ES_NUMBER)
    $d_aviable= GUICtrlCreateInput("", 397, 53, 50, 20, $ES_NUMBER)

    [/autoit] [autoit][/autoit] [autoit]

    ;-------- produkt 1

    [/autoit] [autoit][/autoit] [autoit]

    $produkt1 = GUICtrlCreateCheckbox("produkt1", 202, 90)

    [/autoit] [autoit][/autoit] [autoit]

    $prozent_1 = GUICtrlCreateInput("0", 113, 90, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $updown1 = GUICtrlCreateUpdown($prozent_1, $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 94, 18, 12)

    [/autoit] [autoit][/autoit] [autoit]

    ;-------- produkt 2

    [/autoit] [autoit][/autoit] [autoit]

    $produkt2 = GUICtrlCreateCheckbox("produkt2", 202, 120)

    [/autoit] [autoit][/autoit] [autoit]

    $prozent_2 = GUICtrlCreateInput("0", 113, 120, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $updown2 = GUICtrlCreateUpdown($prozent_2, $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 124, 18, 12)

    [/autoit] [autoit][/autoit] [autoit]

    $ok = GUICtrlCreateButton("Berechnen", 171, 150, 160, 40)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $Main = GUIGetMsg()
    Switch $Main
    Case $GUI_EVENT_CLOSE
    Exit
    Case $ok

    [/autoit] [autoit][/autoit] [autoit]

    $prozent_1_is = GUICtrlRead($prozent_1)
    $prozent_2_is = GUICtrlRead($prozent_2)

    [/autoit] [autoit][/autoit] [autoit]

    $a_aviable_is = GUICtrlRead($a_aviable)
    $b_aviable_is = GUICtrlRead($b_aviable)
    $c_aviable_is = GUICtrlRead($c_aviable)
    $d_aviable_is = GUICtrlRead($d_aviable)

    [/autoit] [autoit][/autoit] [autoit]

    ;-------- produkt 1

    [/autoit] [autoit][/autoit] [autoit]

    If GUICtrlRead($Produkt1) = $GUI_CHECKED Then ;wenn der haken bei checkbox "$Produkt1" gesetzt wurde dann..
    $produkt1_a_ges = Floor($a_aviable_is / $a_kosten_produkt1) ; errechne wie viele produkte1 von material a hergestellt werden könnten und rundet auf die nächste Ganzzahl, die kleiner oder gleich dem angegebenen Wert ist
    $produkt1_b_ges = Floor($b_aviable_is/ $b_kosten_produkt1) ; " " " " " " " b " " " " "
    $produkt1_c_ges = Floor($c_aviable_is / $c_kosten_produkt1) ; " " " " " " " c " " " " "
    $produkt1_d_ges = Floor($d_aviable_is / $d_kosten_produkt1) ; " " " " " " " d " " " " "

    [/autoit] [autoit][/autoit] [autoit]

    $stringload_produkt1 = StringSplit($produkt1_a_ges & "," & $produkt1_b_ges & "," & $produkt1_c_ges & "," & $produkt1_d_ges, ",", 2) ; die ausgerechneten werte werden in einen string gesetzt bei der ein komma das trennzeichen ist
    $nummberMin_produkt1 = _MathEx_Min($stringload_produkt1) ; ermittelt den kleinsten wert der 4 ausgerechneten zahlen (das produkt kann immer nur fertig gestellt wenn alle materialien vorhanden sind kleinste zahl ist somit die max. zahl an produkten1
    $Produkt1_end = Floor($nummberMin_produkt1 * $prozent_1_is / 100) ; max anzahl an produkten1 mal die prozentzahl die der user angegeben hat die von diesem produkt hergestellt werden sollen durch 100 = prozentuale mänge an produkten1

    [/autoit] [autoit][/autoit] [autoit]

    $Produkt1_end_a = $Produkt1_end * $a_kosten_produkt1 ; anzahl an produkten1 mal materialkosten a für produkt1 = material a gesammt benötigt
    $Produkt1_end_b = $Produkt1_end * $b_kosten_produkt1 ; " " " " " " b " " " " b " " "
    $Produkt1_end_c = $Produkt1_end * $c_kosten_produkt1 ; " " " " " " c " " " " c " " "
    $Produkt1_end_d = $Produkt1_end * $d_kosten_produkt1 ; " " " " " " d " " " " d " " "

    [/autoit] [autoit][/autoit] [autoit]

    $Produkt1_end_ges = $Produkt1_end_a + $produkt1_end_b + $produkt1_end_c + $produkt1_end_d ; gesammt material a + gesammt material b + gesammt material c + gesammt material d = gesammtmaterialien
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;-------- produkt 2

    [/autoit] [autoit][/autoit] [autoit]

    If GUICtrlRead($Produkt2) = $GUI_CHECKED Then ;wenn der haken bei checkbox "$Produkt1" gesetzt wurde dann..
    $produkt2_a_ges = Floor($a_aviable_is / $a_kosten_produkt2) ; errechne wie viele produkte1 von material a hergestellt werden könnten und rundet auf die nächste Ganzzahl, die kleiner oder gleich dem angegebenen Wert ist
    $produkt2_b_ges = Floor($b_aviable_is/ $b_kosten_produkt2) ; " " " " " " " b " " " " "
    $produkt2_c_ges = Floor($c_aviable_is / $c_kosten_produkt2) ; " " " " " " " c " " " " "
    $produkt2_d_ges = Floor($d_aviable_is / $d_kosten_produkt2) ; " " " " " " " d " " " " "

    [/autoit] [autoit][/autoit] [autoit]

    $stringload_produkt2 = StringSplit($produkt2_a_ges & "," & $produkt2_b_ges & "," & $produkt2_c_ges & "," & $produkt2_d_ges, ",", 2) ; die ausgerechneten werte werden in einen string gesetzt bei der ein komma das trennzeichen ist
    $nummberMin_produkt2 = _MathEx_Min($stringload_produkt2) ; ermittelt den kleinsten wert der 4 ausgerechneten zahlen (das produkt kann immer nur fertig gestellt wenn alle materialien vorhanden sind kleinste zahl ist somit die max. zahl an produkten1
    $Produkt2_end = Floor($nummberMin_produkt2 * $prozent_2_is / 100) ; max anzahl an produkten1 mal die prozentzahl die der user angegeben hat die von diesem produkt hergestellt werden sollen durch 100 = prozentuale mänge an produkten1

    [/autoit] [autoit][/autoit] [autoit]

    $Produkt2_end_a = $Produkt2_end * $a_kosten_produkt2 ; anzahl an produkten1 mal materialkosten a für produkt1 = material a gesammt benötigt
    $Produkt2_end_b = $Produkt2_end * $b_kosten_produkt2 ; " " " " " " b " " " " b " " "
    $Produkt2_end_c = $Produkt2_end * $c_kosten_produkt2 ; " " " " " " c " " " " c " " "
    $Produkt2_end_d = $Produkt2_end * $d_kosten_produkt2 ; " " " " " " d " " " " d " " "

    [/autoit] [autoit][/autoit] [autoit]

    $Produkt2_end_ges = $Produkt2_end_a + $produkt2_end_b + $produkt2_end_c + $produkt2_end_d ; gesammt material a + gesammt material b + gesammt material c + gesammt material d = gesammtmaterialien
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $rest_a = $a_aviable_is - ($Produkt1_end_a + $Produkt2_end_a)
    $rest_b = $b_aviable_is - ($Produkt1_end_b + $Produkt2_end_b)
    $rest_c = $c_aviable_is - ($Produkt1_end_c + $Produkt2_end_c)
    $rest_d = $d_aviable_is - ($Produkt1_end_d + $Produkt2_end_d)

    [/autoit] [autoit][/autoit] [autoit]

    $rest_gesammt = ($a_aviable_is + $b_aviable_is + $c_aviable_is + $d_aviable_is) - ($Produkt1_end_ges + $Produkt2_end_ges)

    [/autoit] [autoit][/autoit] [autoit]

    $ergebnis = GUICreate("test", 562, 243)
    $listview = GUICtrlCreateListView("name: |Anzahl: |material a: |material b: |material c |material d: |Gesammt: ", 5, 10, 552, 203)
    If GUICtrlRead($produkt1) = $GUI_CHECKED Then GUICtrlCreateListViewItem("produkt1 (" & $prozent_1_is & "%)|" & $Produkt1_end & "|" & $Produkt1_end_a & "|" & $Produkt1_end_b & "|" & $Produkt1_end_c & "|" & $Produkt1_end_d & "|" & $Produkt1_end_ges, $listview)
    If GUICtrlRead($produkt2) = $GUI_CHECKED Then GUICtrlCreateListViewItem("produkt2 (" & $prozent_2_is & "%)|" & $Produkt2_end & "|" & $Produkt2_end_a & "|" & $Produkt2_end_b & "|" & $Produkt2_end_c & "|" & $Produkt2_end_d & "|" & $Produkt2_end_ges, $listview)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateListViewItem("______________________", $listview)
    GUICtrlSetColor(-1, 0x757575)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateListViewItem("Rest:||" & $rest_a & "|" & $rest_b & "|" & $rest_c & "|" & $rest_d & "|" & $rest_gesammt, $listview)
    GUICtrlSetColor(-1, 0xFF0000)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $ergebnis = GUIGetMsg()
    Switch $ergebnis
    Case $GUI_EVENT_CLOSE
    GUISetState(@SW_HIDE)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetState($produkt1, $GUI_UNCHECKED)
    GUICtrlSetState($produkt2, $GUI_UNCHECKED)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetData($prozent_1, "0")
    GUICtrlSetData($prozent_2, "0")

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetState($prozent_1, $GUI_DISABLE)
    GUICtrlSetState($prozent_2, $GUI_DISABLE)

    [/autoit] [autoit][/autoit] [autoit]

    $Produkt1_end_a = 0
    $Produkt1_end_b = 0
    $Produkt1_end_c = 0
    $Produkt1_end_d = 0
    $Produkt1_end_ges = 0

    [/autoit] [autoit][/autoit] [autoit]

    $Produkt2_end_a = 0
    $Produkt2_end_b = 0
    $Produkt2_end_c = 0
    $Produkt2_end_d = 0
    $Produkt2_end_ges = 0

    [/autoit] [autoit][/autoit] [autoit]

    ExitLoop
    EndSwitch
    WEnd
    Case $produkt1
    If GUICtrlRead($produkt1) = $GUI_CHECKED Then
    GUICtrlSetState($prozent_1, $GUI_ENABLE)
    Else
    GUICtrlSetData($prozent_1, "0")
    GUICtrlSetState($prozent_1, $GUI_DISABLE)
    EndIf
    Case $produkt2
    If GUICtrlRead($produkt2) = $GUI_CHECKED Then
    GUICtrlSetState($prozent_2, $GUI_ENABLE)
    Else
    GUICtrlSetData($prozent_2, "0")
    GUICtrlSetState($prozent_2, $GUI_DISABLE)
    EndIf
    EndSwitch
    WEnd

    [/autoit]

    da erkennt man schon das oft reste übrig bleiben von dem man noch produkte herstellen könnte
    grund ist der rundungsfehler

    hat nun jemand schon eine idee?

    • Offizieller Beitrag

    Meiner Meinung nach ist es entscheidend, in welcher Einheit a,b,c,d vorliegen (kg, m², m³, etc.). Denn von diesen Einheiten ausgehend kannst du kleinste Teilmengen festlegen und diese zur Berechnung heranziehen. Mit reinen Prozenten rechnen ist nicht sehr sinnvoll.
    Du gehst dann denn umgekehrten Weg von einer Kombination möglicher Teilmengen zur gewünschten Gesamtmenge. Somit bleiben Fehlmengen durch Rundungsdifferenzen außen vor.

  • Meiner Meinung nach ist es entscheidend, in welcher Einheit a,b,c,d vorliegen (kg, m², m³, etc.). Denn von diesen Einheiten ausgehend kannst du kleinste Teilmengen festlegen und diese zur Berechnung heranziehen. Mit reinen Prozenten rechnen ist nicht sehr sinnvoll.
    Du gehst dann denn umgekehrten Weg von einer Kombination möglicher Teilmengen zur gewünschten Gesamtmenge. Somit bleiben Fehlmengen durch Rundungsdifferenzen außen vor.

    das bringt mir leider nichts, denn diese materialien haben keine einheit. die einheit ist vordefiniert, ich kann nur sagen 2 "teile" von material a
    selbst wenn es einheiten gäbe verstehe ich nicht was das ändert.

    die sache ist:

    ich kann zB 5,8 mal produkt 1 herstellen (mein programm rundet ab auf 5 da die materialien für 6 nicht vorhanden sind -> erster rundungsfehler)
    ich kann 9,6 mal produkt 2 herstellen -> selber effekt - rundungsfehler
    klar das wenn es viele produkte gibt das immer mehr "rest" über bleibt und von dem rest noch bestimmte produkte hergestellt werden können
    das script soll sich aber so verhalten, dass so viel material wie möglich verbraucht wird bis von einem nur noch so wenig über ist das man daraus keine der ausgewählten produkte mehr herstellen kann

    das muss doch irgendwie gehen oder?

    • Offizieller Beitrag

    Na dann verwende Int(Wert) (oder Floor(Wert)) um an die Ganzzahl zu kommen, speichere den Rest in einer Variablen und addiere bei jeweiliger Verwendung Reste hinzu. Wobei bei jeder Berechnung zu prüfen ist, ob die Restsumme in einer neuen Berechnung verwertet werden kann. (z.B. Restsumme ist 0,6 und neue Berechnung verlangt 5,4 ==> dann kannst du die 0,4 aus der Restsumme verwerten)

  • Na dann verwende Int(Wert) (oder Floor(Wert)) um an die Ganzzahl zu kommen, speichere den Rest in einer Variablen und addiere bei jeweiliger Verwendung Reste hinzu. Wobei bei jeder Berechnung zu prüfen ist, ob die Restsumme in einer neuen Berechnung verwertet werden kann. (z.B. Restsumme ist 0,6 und neue Berechnung verlangt 5,4 ==> dann kannst du die 0,4 aus der Restsumme verwerten)

    ich sehe du kannst mir folgen, jedoch scheitert es bei mir an der umsetzung
    hab schon mehrere lösungen im kopf jedoch kann ich sie nicht mit autoit umsetzen

    deswegen suche ich ja hilfe
    vllt könnte ja jemand sich daran versuchen
    geht ja nur um die rechenschritte
    um den rest des programmes kümmer ich mich ja selbst

    lg Inferior

    • Offizieller Beitrag

    Wenn es nur am Auffangen der Rundungsdifferenzen liegt - berechne die möglichen Produktmengen, wie im Bsp.
    Hoffe, du hast kein Problem mit der Verwendung von Arrays ;). Das verkürzt den Code deutlich.

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ; Kosten je Komponente [$Komp_A, $Komp_B, $Komp_C, $Komp_D]
    Local Const $aKomp[4] = [3,2,5,1]

    [/autoit] [autoit][/autoit] [autoit]

    ; Anteil Komponenten je Produkt [Produkt1..3][$Komp_A, $Komp_B, $Komp_C, $Komp_D]
    Local Const $aProds[3][4] = [[2,1,5,3],[3,2,4,2],[1,1,4,3]]

    [/autoit] [autoit][/autoit] [autoit]

    ; Array für mgl. Produktanzahl und Reste der Komponenten
    Enum $prod1, $prod2, $prod3
    Local $aAnzProd[3], $aReste[4]

    [/autoit] [autoit][/autoit] [autoit]

    ; Bsp:
    ; Kunde hat 15*A, 12*B, 8*C, 8*D
    Local $aVorrat[4] = [15,12,8,8]
    Local $aTmp[4], $n, $diff

    [/autoit] [autoit][/autoit] [autoit]

    ; mögliche Anzahl je Produkt aus vorhandenem Material ermitteln
    For $i = $prod1 To $prod3
    For $j = 0 To 3
    $n = Floor( $aVorrat[$j] / $aProds[$i][$j] )
    $diff = Mod( $aVorrat[$j] / $aProds[$i][$j] )
    If Floor( ($diff + $aReste[$j] + $aVorrat[$j]) / $aProds[$i][$j] ) <> $n Then
    $n = Floor( ($diff + $aReste[$j] + $aVorrat[$j]) / $aProds[$i][$j] )
    $diff = Mod( ($diff + $aReste[$j] + $aVorrat[$j]) / $aProds[$i][$j] )
    $aReste[$j] = $diff
    EndIf
    $aTmp[$j] = $n
    Next
    $aAnzProd[$i] = _ArrayMin($aTmp)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    #cs
    Die restliche Logik ist dir ja klar. Durch diese Methode der Anzahlermittlung
    gehen keine Rundungsmengen verloren.
    #ce

    [/autoit]
  • Hallo,

    so ganz verstehe ich das nicht. Wenn die "Kunden" einen Prozentsatz vorgeben, der dazu führt, das ein Produkt mit hohem Materialverbrauch in kleineren Mengen als erwartet erzeugt werden kann, was haben sie dann davon, wenn die dadurch verbleibenden Restmengen für ein anderes Produkt verbraucht werden, dessen Menge dem vorgegebenen Prozentsatz entspricht?

    Kannst Du das mit den Materialien und den Produkten an einem Beispiel aus Deiner Praxis konkreter erläutern? Man könnte sonst auf den Gedanken kommen, es geht um ein Spiel.

  • @ BugFix

    also hab das mal mit deiner Variante versucht umzusetzen die ja wirklich sehr viel kürzer ist. ich wusste das meine nicht die kürzeste war jedoch für mich die einfachste. bei deiner lösung blicke ich nur zum teil durch und sie beinhaltet anscheinend fehler und zwar in zeile 22 und 25.

    ERROR: Mod() [built-in] called with wrong number of args.
    hab mir das mal angesehn und für mod() dürfen nur 2 werte angegeben werden.

    könntest du mir auch nochmal genauer beschreiben was dein script wo in welcher zeile macht?

    @ Großvater

    also das verstehst du völlig falsch:

    der kunde liefert für mich bestimmte wahrengüter die er verarbeiten möchte. er kann auch konkret angeben das er 5 mal produkt 1 und 5 mal produkt 2 haben möchte und entweder nur die nötigen Materialien liefert oder ich im die reste zurück gebe.
    jedoch ist der kunde meist darauf getrimmt möglichst viele produkte aus seinen materialien zu bekommen (was für mich auch an interesse ist da ich dementsprechend mehr produkte fertigen muss / darf,)

    das script soll die materialien so gut es geht verbrauchen, jedoch um nicht irgend welche produkte als lösung anzugeben soll der kunde schon wählen können, das von den 100% (alle materialien), 20% in produkt 1, 50% in produkt 2 und 30% in produkt 3 fließen sollen

    meine kunden sind wiederum auch firmen die bestimmte vorangefertigte materialen haben und die sie weiter verarbeitet haben wollen (von mir)
    diese produkte die ich fertige sind auch noch keine endprodukte und gehen an den kunden zurück der sie letztendlich wieder verwendet um sein endprodukt zu fertigen.

    dem kunden ist es nicht so wichtig wie viele meiner produkte er genau von mir zurück bekommt, die prozentzahl ist nur da damit der kunde sagen kann produkt 1 wird im moment dringender benötigt und dafür weniger an produkt 2

    • Offizieller Beitrag

    anscheinend fehler und zwar in zeile 22 und 25.


    Passiert ;) statt des Kommas habe ich den Teiler gesetzt.

    Hier nochmal korrekt mit Erklärung.

    Spoiler anzeigen
    [autoit]

    ; mögliche Anzahl je Produkt aus vorhandenem Material ermitteln
    For $i = $prod1 To $prod3
    For $j = 0 To 3
    $n = Floor( $aVorrat[$j] / $aProds[$i][$j] ) ; Anzahl (Ganzzahl) Vorrat Komponente teilen durch Anzahl Anteile Komponente des jeweiligen Produkts
    $diff = Mod( $aVorrat[$j] , $aProds[$i][$j] ) ; Rest aus voriger Berechnung
    If Floor( ($diff + $aReste[$j] + $aVorrat[$j]) / $aProds[$i][$j] ) <> $n Then ; ergibt die Verwendung von Komponentenrest andere Anzahl?
    $n = Floor( ($diff + $aReste[$j] + $aVorrat[$j]) / $aProds[$i][$j] ) ; Berechnung wie oben - aber unter Verwendung Rest
    $diff = Mod( ($diff + $aReste[$j] + $aVorrat[$j]) , $aProds[$i][$j] )
    $aReste[$j] = $diff ; neue Restzuweisung
    EndIf
    $aTmp[$j] = $n ; Anzahl die mit Vorrat je Komponente möglich wäre
    Next
    $aAnzProd[$i] = _ArrayMin($aTmp) ; kleinsten Wert aus Anzahl ermitteln der für dieses Produkt aus Komponenten erstellt werden kann
    Next

    [/autoit]
  • {OT]würde mich jetzt wirklich interessieren, welche Zwischenprodukte du fertigst, mir ist nämlich kein ProduktMaterial bekannt dass

    denn diese materialien haben keine einheit.


    dein Beispiel bzw. Erklärung dazu erscheint mir absolut realitätsfremd und ist mir nicht untergekommen[/OT]

    ich kann zB 5,8 mal produkt 1 herstellen (mein programm rundet ab auf 5 da die materialien für 6 nicht vorhanden sind -> erster rundungsfehler)
    ich kann 9,6 mal produkt 2 herstellen -> selber effekt - rundungsfehler

    stellt für mich keinen Rundungsfehler dar, denn dein Kunde will nur ganze Stückzahlen, Um das Optimum aus gebenen Mengenn zu erreichen solltest du dich mit linearer Optimierung beschäftigen. Das

    mfg autoBert

  • Hallo Inferior,

    Du bist das realitätsnahe Beispiel schuldig geblieben. Wenn es nicht um ein Spiel geht, geht es dann um das Mischen der Grundsubstanzen für rote, grüne, blaue und gelbe Pillen? ;)

    Frohe Weihnachten!

  • Hallo,

    hab mich nun mal eingehenst mit BugFix`s script beschäftigt und bin zum entschluss gekommen das es wohl nicht das ist was ich suche. deshalb warscheinlich auch diese ganzen fragen um wleche produkte es sich handelt.

    nochmal:
    ja die materialien haben keine einheit. das sind zB wiederstände bzw vor angefertigte Leiterplatten ect. (also nur in stückzahlen anzugeben)
    das ganze wird von einer firma in massenwahre produziert. meiner firma kommt es aber günstiger diese Komponenten zusammen zu bauen.
    wir haben mehrere produkte zu fertigen die sich aus den 4 grundmaterialien des kunden und den zu ergänzenden materialien unserer seits ergeben.

    wie gesagt der kunde liefert uns diese produkte als massenwahre und ihm ist es nur teilweiße wichtig wie viele produkte wir ihm von welcher art liefern, da er jedes unserer produkte zur weiterverarbeitung braucht.
    jedoch um nicht ganz aus dem gleichgewicht zu kommen soll er schon eine gewisse prozentzahl angeben können um nicht in einen engpass bei einem produkt zu kommen.

    es ist ein wenig kompliziert und deshalb hatte ich das ganze anfangs ein wenig einfacher gestaltet und den ganzen hintergrund weggelassen
    aber so wie ich das sehe machen die bisherigen lösungen nich nicht das was sie sollen
    nämlich genau das was ich schon als beispiel geliefert habe nur ohne rundungsfehler.

    autoBert

    natürlich möchte der kunde nur ganze produkte haben jedoch hat mein script folgendes getan:

    - ausrechnen wie oft produkt 1 von den vorhandenen materialien hergestellt werden könnte >>> nehmen wir an 101 mal produkt1
    - berücksichtigung der prozentangabe des kunden >>> nehmen wir an 25% --> ist 25,25 produkte also abgerundet 25 ( da ja nur 25 produkte gefertigt weden können) 0,25 mal produkt1 als rest
    und das selbe passiert bei allen produkten und jedesmal passiert es das rest übrig bleibt da ja immer abgerundet wird

    ich bekomm das auch nicht hin den lösungsweg von bugfix dann in mein script einzubauen (zudem denke ich das es nicht die lösung ist die ich suche)

    das script sollte folgendes machen:

    - kunde kann material a, b, c, und d in inputfeldern eingeben
    - es gibt 3 produkte die unterschiedlich viele stückzahlen der 4 materialien benötigen (zB produkt1: 4*A, 3*B, 5*C, 1*D usw) dabei kann der kunde wählen welche produkte ausgewählt werden sollen und welche gar nicht hergestellt werden sollen
    - der kunde kann prozente angeben wie seine materialen verarbeitet werden sollen zB. produkt1 25% usw. insgesammt immer 100%)
    das script soll die materialien dann prozentual an die produkte verteilen und nur ganze produkte die mit der bestimmten prozentzahlen hergestellt werden können anzeigen
    - wenn nun von produkt1 99,99 produkte hergestellt werden können dann rundet es ja auf 99 ab also sind 0,99 * produkt1 ( 4*A, 3*B, 5*C, 1*D) rest
    - der rest sollte produkt 2 wieder zur verfügung stehen

    sonst entsteht das was bei meinem script ist: 0,99*produkt1 rest + 0.78*produkt2 rest + 0.41*produkt3 rest = zB. gesammtrest: 25*A, 12*B, 58*C, 22*D davon ließen sich aber noch produkte herstelllen da ja solange hergestellt werden soll bis von einer art rohstoffe nur noch so wenig da ist das keiner der ausgewählten produkte mehr hergestellt werden können

    wäre wirklich sehr schön wenn das jemand hinbekommen könnte

    lg Inferior

    Einmal editiert, zuletzt von Inferior (25. Dezember 2010 um 13:55)

  • nochmal:
    ja die materialien haben keine einheit. das sind zB wiederstände bzw vor angefertigte Leiterplatten ect. (also nur in stückzahlen anzugeben)


    Auch Stückzahlen sind eine Einheit nämlich Stück,
    Mein einfachster Lösungsvorschlag wäre, du rechnest anhand der Prozentzahl für 2 Produkte den exakten Materialverbrauch, ziehst diesen vom vorhandenen ab. Was du jetzt noch übrig hast verwendest du für Produkt 3. Ist zwar nicht das Optimum, kommt ihm aber mit sehr einfacher Berechnungsmöglichkeit sehr nahe.
    Um das Optimum zu erzielen musst du schon deutlich mehr Aufwand betreiben, hier wäre mein Vorschlag du errechnest dir anhand der Prozentzahlen und der zu duldenden Abweichung (0-3% Unter- bzw. Überlieferung, dass musst du wissen) jeweils die Mindest- und die Höchststückzahl eines Produkts, testest in einer Schleife alle möglichen Kombinationen, die Kombination mit der besten Materialausbeute nzw. Gesamtgewinn fertigst du dann.

    frohe Weihnachten autoBert

  • hallo autoBert,

    ja genau das ist das was ich brauche!
    hab schon sehr viel versucht in dieser richtung.. aber es wäre schön wenn mir da jemand unter die arme greifen könnte. mein script hab ich hier ja schon gepostet aber mit den ganzen arrays bin ich wohl nicht so fit :( und arrays sind hier wohl unabdingbar

    variante 1 ist schwierig, weil das produkt 3 wohlmöglich teuerer ist als produkt 1 und 2 und nachdem die reste dort noch verarbeitet werden dennoch produkt 1 und/oder 2 noch hergestellt werden könnten
    durch die auswahl des kunden welche produkte ausgewählt werden können (und welche eben nicht) ist das also ein wenig schwer..

    also die 2. Variante wäre wohl die bessere. könnte sich daran jemand mal versuchen und mir ein beispielscript posten?

    FROHE WEIHNACHTEN EUCH ALLEN!

  • Na ja, so ganz geheuer ist mir die Sache immer noch nicht, aber, weil Weihnachten ist, das könnte ungefähr in Deine Richtung zielen:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEX.au3>
    #include <Array.au3>
    #include <EditConstants.au3>
    #include <UpdownConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    ; Konstanten ====================================================================================================================
    ; Anzahl der Produkte und Materialien
    Global Const $Produkte = 3
    Global Const $Materialien = 4
    ; Arrays ========================================================================================================================
    ; Array für den Materialverbrauch je Produkt
    Global $aKosten[$Produkte][$Materialien] = _
    [ _
    [3, 2, 5, 1], _ ; Materialverbrauch Produkt 1
    [7, 0, 5, 13], _ ; Materialverbrauch Produkt 2
    [10, 12, 18, 7] _ ; Materialverbrauch Produkt 3
    ]
    ; Arrays für die Material-, Produkt- und Prozenteingabe
    Global $aMaterial[$Materialien]
    Global $aProdukt[$Produkte]
    Global $aProzent[$Produkte]
    ; Array für die Materialvorräte
    Global $aVorrat[$Materialien]
    ; Array für die Restmengen
    Global $aRest[$Materialien]
    ; Array für die ausgewählten Produkte
    Global $aAuswahl[$Produkte][2]
    ; Array für die Ergebnisse
    Global $aErgebnis[$Produkte][7]
    ; GUI für Eingabe ===============================================================================================================
    Global $MainGUI = GUICreate("Kalkulator", 500, 230)
    ;-------- Materialvorräte
    GUICtrlCreateLabel("A", 8, 57, 18, 12)
    $aMaterial[0] = GUICtrlCreateInput("", 28, 53, 50, 20, $ES_NUMBER)
    GUICtrlCreateLabel("B", 133, 57, 18, 12)
    $aMaterial[1] = GUICtrlCreateInput("", 153, 53, 50, 20, $ES_NUMBER)
    GUICtrlCreateLabel("C", 257, 57, 18, 12)
    $aMaterial[2] = GUICtrlCreateInput("", 275, 53, 50, 20, $ES_NUMBER)
    GUICtrlCreateLabel("D", 378, 57, 18, 12)
    $aMaterial[3] = GUICtrlCreateInput("", 397, 53, 50, 20, $ES_NUMBER)
    ;-------- Produkt 1
    $aProdukt[0] = GUICtrlCreateCheckbox("Produkt1", 202, 90)
    $aProzent[0] = GUICtrlCreateInput("0", 113, 90, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlCreateUpdown($aProzent[0], $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 94, 18, 12)
    ;-------- Produkt 2
    $aProdukt[1] = GUICtrlCreateCheckbox("Produkt2", 202, 120)
    $aProzent[1] = GUICtrlCreateInput("0", 113, 120, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlCreateUpdown($aProzent[1], $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 124, 18, 12)
    ;-------- Produkt 2
    $aProdukt[2] = GUICtrlCreateCheckbox("Produkt3", 202, 150)
    $aProzent[2] = GUICtrlCreateInput("0", 113, 150, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlCreateUpdown($aProzent[2], $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 154, 18, 12)
    ;-------- Berechnen
    Global $OK = GUICtrlCreateButton("Berechnen", 171, 190, 160, 30)
    GUISetState()
    ; MessageLoop ===================================================================================================================
    While True
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    Case $aProdukt[0]
    If GUICtrlRead($aProdukt[0]) = $GUI_CHECKED Then
    GUICtrlSetState($aProzent[0], $GUI_ENABLE)
    Else
    GUICtrlSetData($aProzent[0], "0")
    GUICtrlSetState($aProzent[0], $GUI_DISABLE)
    EndIf
    Case $aProdukt[1]
    If GUICtrlRead($aProdukt[1]) = $GUI_CHECKED Then
    GUICtrlSetState($aProzent[1], $GUI_ENABLE)
    Else
    GUICtrlSetData($aProzent[1], "0")
    GUICtrlSetState($aProzent[1], $GUI_DISABLE)
    EndIf
    Case $aProdukt[2]
    If GUICtrlRead($aProdukt[2]) = $GUI_CHECKED Then
    GUICtrlSetState($aProzent[2], $GUI_ENABLE)
    Else
    GUICtrlSetData($aProzent[2], "0")
    GUICtrlSetState($aProzent[2], $GUI_DISABLE)
    EndIf
    Case $OK
    _Berechnen()
    _Anzeigen()
    EndSwitch
    WEnd
    ; Func _Berechnen ===============================================================================================================
    Func _Berechnen()
    Local $ErgebnisIndex = 0
    ; Array für die Berechnung leeren
    Dim $aVorrat[$Materialien]
    Dim $aRest[$Materialien]
    Dim $aAuswahl[$Produkte][2]
    Dim $aErgebnis[$Produkte][7]
    ; Materialeingaben und Produktauswahl auslesen
    For $I = 0 To $Materialien - 1
    $aVorrat[$I] = GUICtrlRead($aMaterial[$I])
    Next
    $aRest = $aVorrat
    For $I = 0 To $Produkte - 1
    If GUICtrlRead($aProdukt[$I]) = $GUI_CHECKED Then
    $aAuswahl[$ErgebnisIndex][0] = GUICtrlRead($aProzent[$I])
    $aAuswahl[$ErgebnisIndex][1] = $I
    $ErgebnisIndex += 1
    EndIf
    Next
    ; Produktauswahl absteigend nach Prozenten sortieren
    _ArraySort($aAuswahl, 1)
    ; Produktauswahl nach Prozenten verarbeiten
    For $I = 0 To $Produkte - 1
    If $aAuswahl[$I][0] Then
    _RechneProdukt($I, $aAuswahl[$I][0], $aAuswahl[$I][1])
    EndIf
    Next
    ; Restmengen verteilen
    _RechneReste()
    EndFunc ;==>_Berechnen
    ; Func _RechneProdukt ===========================================================================================================
    Func _RechneProdukt($ErgebnisIndex, $ProduktProzent, $ProduktIndex)
    ; Stückzahlen gemäß vorgegebener Prozente berechnen
    Local $ProduktMenge = 0x7FFFFFFF, $Min
    For $I = 0 To $Materialien - 1
    If $aKosten[$ProduktIndex][$I] > 0 Then
    $Min = Floor($aVorrat[$I] / 100 * $ProduktProzent / $aKosten[$ProduktIndex][$I])
    If $Min < $ProduktMenge Then $ProduktMenge = $Min
    EndIf
    Next
    For $I = 0 To $Materialien - 1
    $aErgebnis[$ErgebnisIndex][$I] = $ProduktMenge * $aKosten[$ProduktIndex][$I]
    $aRest[$I] -= $aErgebnis[$ErgebnisIndex][$I]
    Next
    $aErgebnis[$ErgebnisIndex][4] = $ProduktIndex
    $aErgebnis[$ErgebnisIndex][5] = $ProduktProzent
    $aErgebnis[$ErgebnisIndex][6] = $ProduktMenge
    EndFunc ;==>_RechneProdukt
    ; Func _RechneReste =============================================================================================================
    Func _RechneReste()
    ; Restmengen verteilen
    Local $ProduktIndex, $Zugeordnet = True
    While $Zugeordnet
    $Zugeordnet = False
    For $I = 0 To $Produkte - 1
    $ProduktIndex = $aErgebnis[$I][4]
    For $J = 0 To $Materialien - 1
    If $aKosten[$ProduktIndex][$J] > $aRest[$J] Then ContinueLoop 2
    Next
    For $J = 0 To $Materialien - 1
    $aErgebnis[$I][$J] += $aKosten[$ProduktIndex][$J]
    $aRest[$J] -= $aKosten[$ProduktIndex][$J]
    Next
    $aErgebnis[$I][6] += 1
    $Zugeordnet = True
    Next
    WEnd
    EndFunc ;==>_RechneReste
    ; Func _Anzeigen ================================================================================================================
    Func _Anzeigen()
    ; Ergebnis GUI anzeigen
    Local $GesamtMenge = 0, $Gesamtrest = 0, $ProduktName
    Local $ErgebnisGUI = GUICreate("Ergebnis", 600, 243, -1, -1, -1, -1, $MainGUI)
    Local $ListView = GUICtrlCreateListView("Name: |Anzahl: |Material a: |Material b: |Material c |Material d: |Gesamt: ", 5, 10, 590, 203)
    For $I = 0 To $Produkte - 1
    If $aErgebnis[$I][6] Then
    $GesamtMenge = 0
    For $J = 0 To $Materialien - 1
    $GesamtMenge += $aErgebnis[$I][$J]
    Next
    $ProduktName = "Produkt " & ($aErgebnis[$I][4] + 1) & " (" & $aErgebnis[$I][5] & " %)"
    GUICtrlCreateListViewItem($ProduktName & "|" & $aErgebnis[$I][6] & "|" & $aErgebnis[$I][0] & "|" & $aErgebnis[$I][1] & "|" & $aErgebnis[$I][2] & "|" & $aErgebnis[$I][3] & "|" & $GesamtMenge, $ListView)
    EndIf
    Next
    GUICtrlCreateListViewItem("______________________", $ListView)
    GUICtrlSetColor(-1, 0x757575)
    For $I = 0 To $Materialien - 1
    $Gesamtrest += $aRest[$I]
    Next
    GUICtrlCreateListViewItem("Rest:||" & $aRest[0] & "|" & $aRest[1] & "|" & $aRest[2] & "|" & $aRest[3] & "|" & $Gesamtrest, $ListView)
    GUICtrlSetColor(-1, 0xFF0000)
    GUISetState()
    GUISetState(@SW_DISABLE, $MainGUI)

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_ENABLE, $MainGUI)
    GUIDelete($ErgebnisGUI)
    EndFunc ;==>_Anzeigen

    [/autoit]


    Es ist sicher nicht perfekt, aber vielleicht ein neuer Anfang.

    Frohe Weihnachten!

  • Hallo Großvater,

    dein script ist echt schon sehr sehr toll!
    hab mich mal gründlich damit beschäftigt und das mit den restbeständen hast du, so wie es scheint sehr gut gelöst, kannst du mir dennoch nochmal genauer erklären wie du das problem löst.. ich steig noch nicht ganz durch durch deine lösung.

    leider haben sich auch ein paar bugs eingeschlichen.
    hab mal den code als ergänzung eingefügt um immer nur 100% verteilen zu können:

    [autoit]

    Dim $prozent_ges = GUICtrlRead($aProzent[0]) + GUICtrlRead($aProzent[1]) + GUICtrlRead($aProzent[2])

    [/autoit][autoit][/autoit][autoit]

    If $prozent_ges < 100 Then
    MsgBox(48, "Fehler", "Es wurden noch nicht alle Prozente verteilt!" & @CRLF & "Alle Prozentangaben müssen zusammen genau 100% ergeben.")
    ElseIf $prozent_ges > 100 Then
    MsgBox(48, "Fehler", "Es wurden zu viele Prozente verteilt!" & @CRLF & "Alle Prozentangaben müssen zusammen genau 100% ergeben.")
    ElseIf $prozent_ges = 100 Then

    [/autoit][autoit][/autoit][autoit]

    _Berechnen()
    _Anzeigen()
    EndIf

    [/autoit]


    jedoch passiert es leider, das manchmal nicht ausgewählte produkte mit keiner prozentvergabe einfach mit in die rechnung einfließen.
    ich weiß leider noch nicht warum..

    zum nachtesten einfach mal alle materialien auf 1500 setzen und nur die ersten 2 produkte mit 50% verteilen.
    wäre wirklich fantastisch wenn wir das noch hinbekommen.

    ach und wie mach ich das, das ich meine produktnamen ändern kann. in der maingui ist es ja nicht schwer aber in der ergebnisgui zählst du einfach von produkt 1 bis 3 hoch.. würde aber auch der übersichtlichkeit unabhängige namen vergeben die auch in der maingui sind

    Frohe Weihnachten euch allen!

  • Es ist sicher nicht perfekt, aber vielleicht ein neuer Anfang.

    ... hab mich mal gründlich damit beschäftigt und das mit den restbeständen hast du, so wie es scheint sehr gut gelöst, kannst du mir dennoch nochmal genauer erklären wie du das problem löst..


    Das ist eigentlich sehr simpel. Das Skript rödelt mit der Restmenge solange der Reihe nach über alle ausgewählten Produkte, bis sie nicht mehr ausreicht, um das Material für eines der Produkte zu liefern ($Zugeordnet = False).

    jedoch passiert es leider, das manchmal nicht ausgewählte produkte mit keiner prozentvergabe einfach mit in die rechnung einfließen.
    ich weiß leider noch nicht warum..


    Das ist mir heute beim Probieren auch aufgefallen. Es lag an einer unglücklichen Abfrage, die nicht richtig funktionierte und die ich deshalb einfach weggelassen habe. Ich habe das jetzt mit einem zusätzlichen Merkmal im Ergebnisarray anscheinend lösen können.

    Hier ist eine neue Fassung:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEX.au3>
    #include <Array.au3>
    #include <EditConstants.au3>
    #include <UpdownConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    ; Konstanten ====================================================================================================================
    ; Anzahl der Produkte und Materialien
    Global Const $Produkte = 3
    Global Const $Materialien = 4

    [/autoit] [autoit][/autoit] [autoit]

    ; Arrays ========================================================================================================================
    ; Array für den Materialverbrauch je Produkt
    Global $aKosten[$Produkte][$Materialien] = _
    [ _
    [3, 2, 5, 1], _ ; Materialverbrauch Produkt 1
    [7, 0, 5, 13], _ ; Materialverbrauch Produkt 2
    [10, 12, 18, 7] _ ; Materialverbrauch Produkt 3
    ]
    ; Arrays für die Material-, Produkt- und Prozenteingabe
    Global $aMaterial[$Materialien]
    Global $aProdukt[$Produkte]
    Global $aProzent[$Produkte]
    ; Array für die Materialvorräte
    Global $aVorrat[$Materialien]
    ; Array für die Restmengen
    Global $aRest[$Materialien]
    ; Array für die ausgewählten Produkte
    Global $aAuswahl[$Produkte][2]
    ; Array für die Ergebnisse
    Global $aErgebnis[$Produkte][8]

    [/autoit] [autoit][/autoit] [autoit]

    ; GUI für Eingabe ===============================================================================================================
    Global $MainGUI = GUICreate("Kalkulator", 500, 230)
    ;-------- Materialvorräte
    GUICtrlCreateLabel("A", 8, 57, 18, 12)
    $aMaterial[0] = GUICtrlCreateInput("", 28, 53, 50, 20, $ES_NUMBER)
    GUICtrlCreateLabel("B", 133, 57, 18, 12)
    $aMaterial[1] = GUICtrlCreateInput("", 153, 53, 50, 20, $ES_NUMBER)
    GUICtrlCreateLabel("C", 257, 57, 18, 12)
    $aMaterial[2] = GUICtrlCreateInput("", 275, 53, 50, 20, $ES_NUMBER)
    GUICtrlCreateLabel("D", 378, 57, 18, 12)
    $aMaterial[3] = GUICtrlCreateInput("", 397, 53, 50, 20, $ES_NUMBER)
    ;-------- Produkt 1
    $aProdukt[0] = GUICtrlCreateCheckbox("Brötchen", 202, 90)
    $aProzent[0] = GUICtrlCreateInput("0", 113, 90, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlCreateUpdown($aProzent[0], $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 94, 18, 12)
    ;-------- Produkt 2
    $aProdukt[1] = GUICtrlCreateCheckbox("Semmeln", 202, 120)
    $aProzent[1] = GUICtrlCreateInput("0", 113, 120, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlCreateUpdown($aProzent[1], $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 124, 18, 12)
    ;-------- Produkt 2
    $aProdukt[2] = GUICtrlCreateCheckbox("Brezeln", 202, 150)
    $aProzent[2] = GUICtrlCreateInput("0", 113, 150, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlCreateUpdown($aProzent[2], $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 154, 18, 12)
    ;-------- Berechnen
    Global $OK = GUICtrlCreateButton("Berechnen", 171, 190, 160, 30)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    ; MessageLoop ===================================================================================================================
    While True
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    Case $aProdukt[0]
    If GUICtrlRead($aProdukt[0]) = $GUI_CHECKED Then
    GUICtrlSetState($aProzent[0], $GUI_ENABLE)
    Else
    GUICtrlSetData($aProzent[0], "0")
    GUICtrlSetState($aProzent[0], $GUI_DISABLE)
    EndIf
    Case $aProdukt[1]
    If GUICtrlRead($aProdukt[1]) = $GUI_CHECKED Then
    GUICtrlSetState($aProzent[1], $GUI_ENABLE)
    Else
    GUICtrlSetData($aProzent[1], "0")
    GUICtrlSetState($aProzent[1], $GUI_DISABLE)
    EndIf
    Case $aProdukt[2]
    If GUICtrlRead($aProdukt[2]) = $GUI_CHECKED Then
    GUICtrlSetState($aProzent[2], $GUI_ENABLE)
    Else
    GUICtrlSetData($aProzent[2], "0")
    GUICtrlSetState($aProzent[2], $GUI_DISABLE)
    EndIf
    Case $OK
    _Berechnen()
    _Anzeigen()
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    ; Func _Berechnen ===============================================================================================================
    Func _Berechnen()
    Local $ErgebnisIndex = 0
    ; Array für die Berechnung leeren
    Dim $aVorrat[$Materialien]
    Dim $aRest[$Materialien]
    Dim $aAuswahl[$Produkte][2]
    Dim $aErgebnis[$Produkte][8]
    ; Materialeingaben und Produktauswahl auslesen
    For $I = 0 To $Materialien - 1
    $aVorrat[$I] = GUICtrlRead($aMaterial[$I])
    Next
    $aRest = $aVorrat
    For $I = 0 To $Produkte - 1
    If GUICtrlRead($aProdukt[$I]) = $GUI_CHECKED Then
    $aAuswahl[$ErgebnisIndex][0] = GUICtrlRead($aProzent[$I])
    $aAuswahl[$ErgebnisIndex][1] = $I
    $ErgebnisIndex += 1
    EndIf
    Next
    ; Produktauswahl absteigend nach Prozenten sortieren
    _ArraySort($aAuswahl, 1)
    ; Produktauswahl nach Prozenten verarbeiten
    For $I = 0 To $Produkte - 1
    If $aAuswahl[$I][0] Then
    _RechneProdukt($I, $aAuswahl[$I][0], $aAuswahl[$I][1])
    EndIf
    Next
    ; Restmengen verteilen
    _RechneReste()
    EndFunc ;==>_Berechnen

    [/autoit] [autoit][/autoit] [autoit]

    ; Func _RechneProdukt ===========================================================================================================
    Func _RechneProdukt($ErgebnisIndex, $ProduktProzent, $ProduktIndex)
    ; Stückzahlen gemäß vorgegebener Prozente berechnen
    Local $ProduktMenge = 0x7FFFFFFF, $Min
    For $I = 0 To $Materialien - 1
    If $aKosten[$ProduktIndex][$I] > 0 Then
    $Min = Floor($aVorrat[$I] / 100 * $ProduktProzent / $aKosten[$ProduktIndex][$I])
    If $Min < $ProduktMenge Then $ProduktMenge = $Min
    EndIf
    Next
    For $I = 0 To $Materialien - 1
    $aErgebnis[$ErgebnisIndex][$I] = $ProduktMenge * $aKosten[$ProduktIndex][$I]
    $aRest[$I] -= $aErgebnis[$ErgebnisIndex][$I]
    Next
    $aErgebnis[$ErgebnisIndex][4] = $ProduktIndex
    $aErgebnis[$ErgebnisIndex][5] = $ProduktProzent
    $aErgebnis[$ErgebnisIndex][6] = $ProduktMenge
    $aErgebnis[$ErgebnisIndex][7] = True
    EndFunc ;==>_RechneProdukt

    [/autoit] [autoit][/autoit] [autoit]

    ; Func _RechneReste =============================================================================================================
    Func _RechneReste()
    ; Restmengen verteilen
    Local $ProduktIndex, $Zugeordnet = True
    While $Zugeordnet
    $Zugeordnet = False
    For $I = 0 To $Produkte - 1
    If Not $aErgebnis[$I][7] Then ContinueLoop
    $ProduktIndex = $aErgebnis[$I][4]
    For $J = 0 To $Materialien - 1
    If $aKosten[$ProduktIndex][$J] > $aRest[$J] Then ContinueLoop 2
    Next
    For $J = 0 To $Materialien - 1
    $aErgebnis[$I][$J] += $aKosten[$ProduktIndex][$J]
    $aRest[$J] -= $aKosten[$ProduktIndex][$J]
    Next
    $aErgebnis[$I][6] += 1
    $Zugeordnet = True
    Next
    WEnd
    EndFunc ;==>_RechneReste

    [/autoit] [autoit][/autoit] [autoit]

    ; Func _Anzeigen ================================================================================================================
    Func _Anzeigen()
    ; Ergebnis GUI anzeigen
    Local $GesamtMenge = 0, $Gesamtrest = 0, $ProduktName
    Local $ErgebnisGUI = GUICreate("Ergebnis", 600, 243, -1, -1, -1, -1, $MainGUI)
    Local $ListView = GUICtrlCreateListView("Name: |Anzahl: |Material a: |Material b: |Material c |Material d: |Gesamt: ", 5, 10, 590, 203)
    For $I = 0 To $Produkte - 1
    If $aErgebnis[$I][7] Then
    $GesamtMenge = 0
    For $J = 0 To $Materialien - 1
    $GesamtMenge += $aErgebnis[$I][$J]
    Next
    $ProduktName = GUICtrlRead($aProdukt[$aErgebnis[$I][4]], 1) & " (" & $aErgebnis[$I][5] & " %)"
    GUICtrlCreateListViewItem($ProduktName & "|" & $aErgebnis[$I][6] & "|" & $aErgebnis[$I][0] & "|" & $aErgebnis[$I][1] & "|" & $aErgebnis[$I][2] & "|" & $aErgebnis[$I][3] & "|" & $GesamtMenge, $ListView)
    EndIf
    Next
    GUICtrlCreateListViewItem("______________________", $ListView)
    GUICtrlSetColor(-1, 0x757575)
    For $I = 0 To $Materialien - 1
    $Gesamtrest += $aRest[$I]
    Next
    GUICtrlCreateListViewItem("Rest:||" & $aRest[0] & "|" & $aRest[1] & "|" & $aRest[2] & "|" & $aRest[3] & "|" & $Gesamtrest, $ListView)
    GUICtrlSetColor(-1, 0xFF0000)
    GUISetState()
    GUISetState(@SW_DISABLE, $MainGUI)

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_ENABLE, $MainGUI)
    GUIDelete($ErgebnisGUI)
    EndFunc ;==>_Anzeigen

    [/autoit]


    Das mit den Produktnamen ist enthalten, Deine Änderung zur Prüfung auf 100 % aber nicht.

    • Offizieller Beitrag

    Hallo,

    Ich hab's etwas gekürzt und den Fehler mit der Prozentberechnung ist auch beseitigt!

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEX.au3>
    #include <Array.au3>
    #include <EditConstants.au3>
    #include <UpdownConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    ; Konstanten ====================================================================================================================
    ; Anzahl der Produkte und Materialien
    Global Const $Produkte = 3
    Global Const $Materialien = 4
    ; Arrays ========================================================================================================================
    ; Array für den Materialverbrauch je Produkt
    Global $aKosten[$Produkte][$Materialien] = _
    [ _
    [3, 2, 5, 1], _ ; Materialverbrauch Produkt 1
    [7, 0, 5, 13], _ ; Materialverbrauch Produkt 2
    [10, 12, 18, 7] _ ; Materialverbrauch Produkt 3
    ]

    [/autoit] [autoit][/autoit] [autoit]

    Global $aProduktNamen[$Produkte] = _
    [ _
    "Produkt1", _ ; Name für Produkt 1
    "Produkt2", _ ; Name für Produkt 2
    "Produkt3" _ ; Name für Produkt 3
    ]

    [/autoit] [autoit][/autoit] [autoit]

    Global $aMaterialNamen[$Materialien] = _
    [ _
    "A", _ ; Name für Material 1
    "B", _ ; Name für Material 2
    "C", _ ; Name für Material 3
    "D" _ ; Name für Material 4
    ]

    [/autoit] [autoit][/autoit] [autoit]

    ; Arrays für die Material-, Produkt- und Prozenteingabe
    Global $aMaterial[$Materialien]
    Global $aProdukt[$Produkte]
    Global $aProzent[$Produkte]
    ; Array für die Materialvorräte
    Global $aVorrat[$Materialien]
    ; Array für die Restmengen
    Global $aRest[$Materialien]
    ; Array für die ausgewählten Produkte
    Global $aAuswahl[$Produkte][2]
    ; Array für die Ergebnisse
    Global $aErgebnis[$Produkte][7]
    ; Variable zur Validierung
    Global $ProzentGesamt
    ; GUIGetMsg
    Global $GGM
    ; GUI für Eingabe ===============================================================================================================
    Global $MainGUI = GUICreate("Kalkulator", 500, 230)
    ;-------- Materialvorräte
    For $i = 0 To $Materialien - 1
    GUICtrlCreateLabel($aMaterialNamen[$i], 8 + $i * 125, 57, 18, 12)
    $aMaterial[$i] = GUICtrlCreateInput("", 28 + $i * 125, 53, 50, 20, $ES_NUMBER)
    Next
    ;-------- Produkte
    For $i = 0 To $Produkte - 1
    $aProdukt[$i] = GUICtrlCreateCheckbox($aProduktNamen[$i], 202, 90 + $i * 30)
    $aProzent[$i] = GUICtrlCreateInput("0", 113, 90 + $i * 30, 40, 20, $ES_NUMBER)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlCreateUpdown($aProzent[$i], $UDS_ARROWKEYS)
    GUICtrlSetLimit(-1, 100, 0)
    GUICtrlCreateLabel("%", 156, 94 + $i * 30, 18, 12)
    Next
    ;-------- Berechnen
    Global $OK = GUICtrlCreateButton("Berechnen", 171, 190, 160, 30)
    GUISetState()
    ; MessageLoop ===================================================================================================================
    While True
    $GGM = GUIGetMsg()
    ; Bearbeitung der Produktauswahl
    For $iProdukt = 0 To $Produkte - 1
    If $GGM = $aProdukt[$iProdukt] Then
    If GUICtrlRead($aProdukt[$iProdukt]) = $GUI_CHECKED Then
    GUICtrlSetState($aProzent[$iProdukt], $GUI_ENABLE)
    Else
    GUICtrlSetData($aProzent[$iProdukt], "0")
    GUICtrlSetState($aProzent[$iProdukt], $GUI_DISABLE)
    EndIf
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Switch $GGM
    Case $GUI_EVENT_CLOSE
    Exit
    Case $OK
    $ProzentGesamt = 0
    For $i = 0 To $Produkte - 1
    $ProzentGesamt += GUICtrlRead($aProzent[$i])
    Next
    If $ProzentGesamt < 100 Then
    MsgBox(48, "Fehler", "Es wurden noch nicht alle Prozente verteilt!" & @CRLF & "Alle Prozentangaben müssen zusammen genau 100% ergeben.")
    ElseIf $ProzentGesamt > 100 Then
    MsgBox(48, "Fehler", "Es wurden zu viele Prozente verteilt!" & @CRLF & "Alle Prozentangaben müssen zusammen genau 100% ergeben.")
    ElseIf $ProzentGesamt = 100 Then
    _Berechnen()
    _Anzeigen()
    EndIf
    EndSwitch
    WEnd
    ; Func _Berechnen ===============================================================================================================
    Func _Berechnen()
    Local $ErgebnisIndex = 0
    ; Array für die Berechnung leeren
    Dim $aVorrat[$Materialien]
    Dim $aRest[$Materialien]
    Dim $aAuswahl[$Produkte][2]
    Dim $aErgebnis[$Produkte][7]
    ; Materialeingaben und Produktauswahl auslesen
    For $i = 0 To $Materialien - 1
    $aVorrat[$i] = GUICtrlRead($aMaterial[$i])
    Next
    $aRest = $aVorrat
    For $i = 0 To $Produkte - 1
    If GUICtrlRead($aProdukt[$i]) = $GUI_CHECKED Then
    $aAuswahl[$ErgebnisIndex][0] = GUICtrlRead($aProzent[$i])
    $aAuswahl[$ErgebnisIndex][1] = $i
    $ErgebnisIndex += 1
    EndIf
    Next
    ; Produktauswahl absteigend nach Prozenten sortieren
    _ArraySort($aAuswahl, 1)
    ; Produktauswahl nach Prozenten verarbeiten
    For $i = 0 To $Produkte - 1
    If $aAuswahl[$i][0] Then
    _RechneProdukt($i, $aAuswahl[$i][0], $aAuswahl[$i][1])
    EndIf
    Next
    ; Restmengen verteilen
    _RechneReste()
    EndFunc ;==>_Berechnen
    ; Func _RechneProdukt ===========================================================================================================
    Func _RechneProdukt($ErgebnisIndex, $ProduktProzent, $ProduktIndex)
    ; Stückzahlen gemäß vorgegebener Prozente berechnen
    Local $ProduktMenge = 0x7FFFFFFF, $Min
    For $i = 0 To $Materialien - 1
    If $aKosten[$ProduktIndex][$i] > 0 Then
    $Min = Floor($aVorrat[$i] / 100 * $ProduktProzent / $aKosten[$ProduktIndex][$i])
    If $Min < $ProduktMenge Then $ProduktMenge = $Min
    EndIf
    Next
    For $i = 0 To $Materialien - 1
    $aErgebnis[$ErgebnisIndex][$i] = $ProduktMenge * $aKosten[$ProduktIndex][$i]
    $aRest[$i] -= $aErgebnis[$ErgebnisIndex][$i]
    Next
    $aErgebnis[$ErgebnisIndex][4] = $ProduktIndex
    $aErgebnis[$ErgebnisIndex][5] = $ProduktProzent
    $aErgebnis[$ErgebnisIndex][6] = $ProduktMenge
    EndFunc ;==>_RechneProdukt
    ; Func _RechneReste =============================================================================================================
    Func _RechneReste()
    ; Restmengen verteilen
    Local $ProduktIndex, $Zugeordnet = True
    While $Zugeordnet
    $Zugeordnet = False
    For $i = 0 To $Produkte - 1
    If Not $aAuswahl[$i][0] Then ContinueLoop
    $ProduktIndex = $aErgebnis[$i][4]
    For $J = 0 To $Materialien - 1
    If $aKosten[$ProduktIndex][$J] > $aRest[$J] Then ContinueLoop 2
    Next
    For $J = 0 To $Materialien - 1
    $aErgebnis[$i][$J] += $aKosten[$ProduktIndex][$J]
    $aRest[$J] -= $aKosten[$ProduktIndex][$J]
    Next
    $aErgebnis[$i][6] += 1
    $Zugeordnet = True
    Next
    WEnd
    EndFunc ;==>_RechneReste
    ; Func _Anzeigen ================================================================================================================
    Func _Anzeigen()
    ; Ergebnis GUI anzeigen
    Local $GesamtMenge = 0, $Gesamtrest = 0, $ProduktName
    Local $ErgebnisGUI = GUICreate("Ergebnis", 600, 243, -1, -1, -1, -1, $MainGUI)
    Local $ListView = GUICtrlCreateListView("Name: |Anzahl: |Material a: |Material b: |Material c |Material d: |Gesamt: ", 5, 10, 590, 203)
    For $i = 0 To $Produkte - 1
    If $aErgebnis[$i][6] Then
    $GesamtMenge = 0
    For $J = 0 To $Materialien - 1
    $GesamtMenge += $aErgebnis[$i][$J]
    Next
    $ProduktName = "Produkt " & ($aErgebnis[$i][4] + 1) & " (" & $aErgebnis[$i][5] & " %)"
    GUICtrlCreateListViewItem($ProduktName & "|" & $aErgebnis[$i][6] & "|" & $aErgebnis[$i][0] & "|" & $aErgebnis[$i][1] & "|" & $aErgebnis[$i][2] & "|" & $aErgebnis[$i][3] & "|" & $GesamtMenge, $ListView)
    EndIf
    Next
    GUICtrlCreateListViewItem("______________________", $ListView)
    GUICtrlSetColor(-1, 0x757575)
    For $i = 0 To $Materialien - 1
    $Gesamtrest += $aRest[$i]
    Next
    GUICtrlCreateListViewItem("Rest:||" & $aRest[0] & "|" & $aRest[1] & "|" & $aRest[2] & "|" & $aRest[3] & "|" & $Gesamtrest, $ListView)
    GUICtrlSetColor(-1, 0xFF0000)
    GUISetState()
    GUISetState(@SW_DISABLE, $MainGUI)

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_ENABLE, $MainGUI)
    GUIDelete($ErgebnisGUI)
    EndFunc ;==>_Anzeigen

    [/autoit]