Werte ermitteln und Array automatisch befüllen

  • Hallo AutoIt Gemeinde,

    folgende Herausforderung:
    Ich habe eine CSV mit folgendem Inhalt (Werte können abweichen, sind nur Beispielwerte):

    Spoiler anzeigen


    Datum;Wert
    25.06.2013;1000
    08.07.2013;2000
    20.07.2013;3000
    25.07.2013;4000
    04.08.2013;5000
    18.08.2013;6000
    25.08.2013;7000
    02.09.2013;8000
    27.09.2013;9000
    08.10.2013;10000


    Die CSV ist immer Datum aufsteigend sortiert. Der Wert kann von Datum zu Datum nur größer werden, nicht kleiner.

    Für allen Tagen zwischen dem ersten und dem letzten Datum sollen nun die Werte errechnet werden.
    Ich habe das ganze mal in Excel gerechnet um zu zeigen, wie das Ergebnis Array aussehen soll:

    Spoiler anzeigen


    25.06.2013;1000
    26.06.2013;1077
    27.06.2013;1154
    28.06.2013;1231
    29.06.2013;1308
    30.06.2013;1385
    01.07.2013;1462
    02.07.2013;1539
    03.07.2013;1616
    04.07.2013;1693
    05.07.2013;1770
    06.07.2013;1847
    07.07.2013;1924
    08.07.2013;2000
    09.07.2013;2083
    10.07.2013;2166
    11.07.2013;2249
    12.07.2013;2332
    13.07.2013;2415
    14.07.2013;2498
    15.07.2013;2581
    16.07.2013;2664
    17.07.2013;2747
    18.07.2013;2830
    19.07.2013;2913
    20.07.2013;3000
    21.07.2013;3200
    22.07.2013;3400
    23.07.2013;3600
    24.07.2013;3800
    25.07.2013;4000
    26.07.2013;4100
    27.07.2013;4200
    28.07.2013;4300
    29.07.2013;4400
    30.07.2013;4500
    31.07.2013;4600
    01.08.2013;4700
    02.08.2013;4800
    03.08.2013;4900
    04.08.2013;5000
    05.08.2013;5071
    06.08.2013;5142
    07.08.2013;5213
    08.08.2013;5284
    09.08.2013;5355
    10.08.2013;5426
    11.08.2013;5497
    12.08.2013;5568
    13.08.2013;5639
    14.08.2013;5710
    15.08.2013;5781
    16.08.2013;5852
    17.08.2013;5923
    18.08.2013;6000
    19.08.2013;6143
    20.08.2013;6286
    21.08.2013;6429
    22.08.2013;6572
    23.08.2013;6715
    24.08.2013;6858
    25.08.2013;7000
    26.08.2013;7125
    27.08.2013;7250
    28.08.2013;7375
    29.08.2013;7500
    30.08.2013;7625
    31.08.2013;7750
    01.09.2013;7875
    02.09.2013;8000
    03.09.2013;8040
    04.09.2013;8080
    05.09.2013;8120
    06.09.2013;8160
    07.09.2013;8200
    08.09.2013;8240
    09.09.2013;8280
    10.09.2013;8320
    11.09.2013;8360
    12.09.2013;8400
    13.09.2013;8440
    14.09.2013;8480
    15.09.2013;8520
    16.09.2013;8560
    17.09.2013;8600
    18.09.2013;8640
    19.09.2013;8680
    20.09.2013;8720
    21.09.2013;8760
    22.09.2013;8800
    23.09.2013;8840
    24.09.2013;8880
    25.09.2013;8920
    26.09.2013;8960
    27.09.2013;9000
    28.09.2013;9091
    29.09.2013;9182
    30.09.2013;9273
    01.10.2013;9364
    02.10.2013;9455
    03.10.2013;9546
    04.10.2013;9637
    05.10.2013;9728
    06.10.2013;9819
    07.10.2013;9910
    08.10.2013;10000

    Wie ich die Werte errechne ist mir bekannt; die Frage die sich mir nur stellt ist, wie ich das in AutoIt umsetze.

    Für eure Hilfe vorab besten Dank :thumbup:

    Einmal editiert, zuletzt von LordKingPin (27. Oktober 2013 um 20:03)

  • Moin!

    Hier mal mein Vorschlag. Voraussetzung ist, dass die Daten immer im gleichen Format sind (dd.mm.yyyy;Wert mit 1 bis unendlich vielen Stellen).
    Das Skript ist ausführlich kommentiert...bei Fragen, frag :rolleyes:

    Spoiler anzeigen
    [autoit]

    #include <Date.au3>
    #include <Array.au3>

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

    OnAutoItExitRegister("_Exit")

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

    $sCSVPath = FileOpenDialog("CSV-Datei öffnen (Abbrechen, um Datei zu generieren)", @ScriptDir, "CSV-Dateien (*.csv)", 3)

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

    If @error Then ;==> wird der Dialog agebrochen, wird eine CSV-Datei generiert und geladen
    _CreateCSV()
    $sCSVPath = @ScriptDir & "\CSVTest.csv"
    EndIf

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

    $hFile = FileOpen($sCSVPath, 0)
    $sCSVContent = FileRead($hFile)
    FileClose($hFile)

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

    ;==> Daten einlesen. Alternativ kann man auch FileReadLine benutzen
    $aCSVDateValue = StringRegExp($sCSVContent, '(\d{2}\.\d{2}\.\d{4};\d+)', 3);==> Datum und Wert in Array schreiben

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

    _ArrayDisplay($aCSVDateValue, "Ausgangswerte")

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

    $sStartDateFist = StringRegExpReplace($aCSVDateValue[0], '(\d{2})\.(\d{2})\.(\d{4});\d+', '$3/$2/$1')
    $sEndDateLast = StringRegExpReplace($aCSVDateValue[UBound($aCSVDateValue) - 1], '(\d{2})\.(\d{2})\.(\d{4});\d+', '$3/$2/$1')
    $iDiffDays = _DateDiff("D", $sStartDateFist, $sEndDateLast) ;==> Anzahl aller Tage ermitteln, um das Array zu dimensionieren

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

    Global $aFinalArray[$iDiffDays + 1]
    Global $iDays, $i

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

    For $i = 0 To UBound($aCSVDateValue) - 2
    ;==> Datumformat für _DateDiff anpassen und in Variable einlesen
    $sStartDate = StringRegExpReplace($aCSVDateValue[$i], '(\d{2})\.(\d{2})\.(\d{4});\d+', '$3/$2/$1')
    $sEndDate = StringRegExpReplace($aCSVDateValue[$i + 1], '(\d{2})\.(\d{2})\.(\d{4});\d+', '$3/$2/$1')
    ;==> Wert einlesen
    $iStartValue = Number(StringRegExpReplace($aCSVDateValue[$i], '\d{2}\.\d{2}\.\d{4};(\d+)', '$1'))
    $iEndValue = Number(StringRegExpReplace($aCSVDateValue[$i + 1], '\d{2}\.\d{2}\.\d{4};(\d+)', '$1'))

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

    $iDiffDays = _DateDiff("D", $sStartDate, $sEndDate) ;==> Anzahl Tage zwischen zwei Daten
    $iDiffValue = $iEndValue - $iStartValue ;==> Anzahl Tage zwischen zwei Werten
    $iValuePerDay = Round($iDiffValue / $iDiffDays) ; ==> Wert pro Tag
    For $ii = 0 To $iDiffDays - 1
    $sDaySingle = StringRegExpReplace(_DateAdd("D", $ii, $sStartDate), '(\d{4})/(\d{2})/(\d{2})', '$3.$2.$1');==> in deutsches Datumsformat umwandeln
    $aFinalArray[$iDays] = $sDaySingle & ";" & $iStartValue
    $iStartValue += $iValuePerDay
    $iDays += 1
    Next
    Next
    $aFinalArray[$iDays] = StringRegExpReplace($sEndDateLast, '(\d{4})/(\d{2})/(\d{2})', '$3.$2.$1') & ";" & $iEndValue ;==> letzte Zeile muß "manuell" angefügt werden
    _ArrayDisplay($aFinalArray, "Ergebnis")
    ;==> Speichern unter...
    $sFilenameNoSuffix = StringRegExpReplace($sCSVPath, '.+\\(.+)\.[^.]*$', '$1') ;==> Orginal Dateiname ohne Suffix für Namensvorschlag bei FileSaveDialog
    $sCSVPath = StringRegExpReplace($sCSVPath, '(.+\\).+', '$1') ;==> Orginal Pfad
    $sPathResult = FileSaveDialog("CSV-Ergebnis-Datei speichern...", $sCSVPath, "CSV-Dateien (*.csv)", 18, $sFilenameNoSuffix & "_Result" & ".csv")
    If @error Then
    MsgBox(0, "", "Speichern abgebrochen!")
    Else
    $hFile = FileOpen($sPathResult, 2)
    FileWrite($hFile, _ArrayToString($aFinalArray, @CRLF))
    FileClose($hFile)
    $idMsg = MsgBox(36, "", "Datei in Excel öffnen?")
    Switch $idMsg
    Case 6
    ShellExecute($sPathResult) ;==> Wenn Excel installiert ist, wird die Datei geöffnet (UDF "Excel.au3" zur Weiterverarbeitung nutzen!)
    EndSwitch
    EndIf

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

    Exit

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

    Func _CreateCSV() ;==> CSV-Datei erstellen, falls keine eigene geladen wird
    $sCSVContent = "25.06.2013;1000" & @CRLF & _
    "08.07.2013;2000" & @CRLF & _
    "20.07.2013;3000" & @CRLF & _
    "25.07.2013;4000" & @CRLF & _
    "04.08.2013;5000" & @CRLF & _
    "18.08.2013;6000" & @CRLF & _
    "25.08.2013;7000" & @CRLF & _
    "02.09.2013;8000" & @CRLF & _
    "27.09.2013;9000" & @CRLF & _
    "08.10.2013;10000" & @CRLF

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

    $hFile = FileOpen(@ScriptDir & "\CSVTest.csv", 2)
    FileWrite($hFile, $sCSVContent)
    FileClose($hFile)
    EndFunc ;==>_CreateCSV

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

    Func _Exit()
    FileDelete(@ScriptDir & "\CSVTest.csv") ;==> generierte CSV-Datei (falls vorhanden) bei Programmende löschen
    EndFunc ;==>_Exit

    [/autoit]


    Sicher nicht der Weisheit letzter Schluß, aber es funktioniert ;)


    Sanfte Grüße :D