Txt-Datei auslesen und Teile davon im Gui anzeigen

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

Fresh Janine
Posts: 29
Joined: 07 May 2017, 10:15

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

13 Oct 2017, 09:39

Ich würde sagen, das hast du echt richtig gut hinbekommen und vor allem Dingen wieder so schnell! Funktioniert absolut fehlerlos. Ich bin auch froh, dass dir das mit den Sektionen so gefällt, denn da war ich mir nicht sicher, ob das so der richtige Weg ist. Ich habe gleich mal die Liste.txt fast alle in Historie-1.txt und eine Liste in Historie-2.txt und eine Liste in Historie-3.txt umbenannt. Für Historie-2.txt hab ich jetzt mal eine echte Liste verwendet, die auch nicht nur EURUSD eingetragen hat und anhand dieser Liste sieht man auch mal, was für komische Kommentare da manchmal gespeichert werden. Hat zwar eine feste Magicnumber, was ein bisschen langweilig ist, doch trotzdem interessant. Die gebe ich dir natürlich alle als Anhang mit.
Analyse01.ahk
(7.05 KiB) Downloaded 39 times
Historie-1.txt
(3.82 KiB) Downloaded 38 times
Historie-2.txt
(38.39 KiB) Downloaded 40 times
Zum Thema, was du noch unter dem Skript geschrieben hast: So gefällt mir das! Jetzt sind wir auf einer Wellenlänge und hier ist auch nichts als kommerzielle Weiterverwertung gedacht. Für mich ist das somit alles ok und mein nächster Vorschlag wäre, dass erst mal alles im Tab 1 fehlerlos funktionieren soll und danach kannst du (ja, du, ich kann da wirklich nicht mehr viel mitreden) gerne dafür sorgen, dass per Doppelklick im Listview(LV1) die 2 Tabellen im Tab 2 sich anhand der angeklickten Magicnumbers füllen. Wenn das auch funktioniert, dann erst mal das Wichtigste, nämlich, dass anhand der im Tab 2 befindlichen Dropdownliste(EURUSD,GBPUSD,AUDUSD) die Informationen auch noch mal nach dem Symbol(z.B. EURUSD) gefiltert wird. Und die 3 Beispiele (EURUSD,GBPUSD,AUDUSD), die ich da schon in der DDL eingetragen habe sind nur Beispiele, denn das Programm soll anhand der Historieliste selbstständig die DDL mit den Symbolen(z.B. EURUSD,GBPUSD usw.) füllen. Also wenn das Programm z.B. nur EURUSD mit z.B. der Magicnumber 22222 in der Historie, der jeweiligen MT4-Instanz findet, dann soll in der DDL auch nur EURUSD angezeigt werden. Zum Gegensatz der 1. DDL soll diese DDL, ohne das ich diese schon angeklickt habe, schon was ausgewählt haben. Ich denke, alphabetische Sortierung der Symbole in der DDL ist da am besten. Ich weiß gar nicht, ob Dropdownlisten sowas können. Mein Bauchgefühl hat mir jetzt nur gesagt, dass die das können. Gib bescheid, wenn was gar nicht umsetzbar ist :)
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

13 Oct 2017, 10:54

Fresh Janine wrote:Ich bin auch froh, dass dir das mit den Sektionen so gefällt, denn da war ich mir nicht sicher, ob das so der richtige Weg ist.
Es ist zumindest ein richtiger Weg, solange keine Maximalgrößen der INI-Dateien erreicht werden. Und es hat den Vorteil, dass das Deine eigene Idee ist und Du das deshalb auch locker pflegen kannst. Weil wir gerade beim Thema Größe sind. Wie groß werden die MT4-Log-Dateien, die hier verarbeitet werden sollen, in etwa? Wenn sie nicht zu groß werden, sollte man sie besser doch komplett einlesen.
Fresh Janine wrote:... und mein nächster Vorschlag wäre, dass erst mal alles im Tab 1 fehlerlos funktionieren soll und danach ...
Um alles geht es hier nicht. Ich will Dich ja schließlich mit schrittweiser Umsetzung dazu motivieren, Dich auch an der Entwicklung zu beteiligen. Mir ist auch z.B. noch unklar, wie die Copy-Funtion arbeiten soll. Das Auslesen und die Anzeige wird ja über das LV2 ausgelöst. Ist damit für die Anwendung schon alles erledigt? Ich beschäftige mich jetzt erst einmal mit der Edit-Funktion. Das sollte Dir ein paar Hinweise darauf liefern, wie man die anderen Funktionen in den Griff bekommt. Vielleicht klappt das noch heute abend, spätestens aber morgen vormittag

Ansonsten stimmt mein Bauchgefühl mit Deinem überein. ;)
Fresh Janine
Posts: 29
Joined: 07 May 2017, 10:15

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

13 Oct 2017, 13:15

Ich schätze maximal 10 Handelssysteme pro MT4-Instanz mit maximal 20 verschiedenen Magicnumbers. Die Copy-Funktion ist schon komplett fertig. Das ist schon so nützlich und praktisch wie möglich. Wenn ich irgendwie weiter weiß, dann mach ich gern mit :)
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

14 Oct 2017, 02:44

Moin,

die Edit-Funktion sollte jetzt tun. Ich musste dafür aber den Aufbau der INI-Dateien ändern. Ohne Wertnamen kann AHK die INI zwar problemlos einlesen, hat dann aber beim Schreiben Probleme. Ich habe deshalb den Magicnumbers den Namen Numbers= gegeben und die Routine NewIni: angepasst. Beispiel:

Code: Select all

[EA]
Numbers=12380 12381 12382 12383 12385 12386 12387 12388 12390
Außerdem habe ich die Routine SaveIni: eingebaut, die die INI-Datei nach jeder Änderung sofort zurückschreibt. Wenn Du das nicht willst, musst Du diese Aktion irgendwie anders kontrollieren.

Und natürlich habe ich die Routinen Edit: bis Save: geändert bzw. ergänzt.

Code: Select all

#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
SetBatchLines -1 ; maximale Ausführungsgeschwindigkeit
; --------------------------------------------------------------------------------------------------------------------------------
; Objekt für die MT4-Instanzen. Als Schlüssel wird der Name der zugehörigen INI-Datei verwendet, die im Skriptverzeichnis liegen
; muss. Der zugewiesene Wert ist der vollständige Pfad der jeweiligen Log-Datei.
MT4_Instanzen := {"MT4-1": A_ScriptDir . "\Historie-1.txt"
                , "MT4-2": A_ScriptDir . "\Historie-2.txt"
                , "MT4-3": A_ScriptDir . "\Historie-3.txt"
                , "MT4-4": A_ScriptDir . "\Historie-1.txt"
                , "MT4-5": A_ScriptDir . "\Historie-1.txt"
                , "MT4-6": A_ScriptDir . "\Historie-1.txt"
                , "MT4-7": A_ScriptDir . "\Historie-1.txt"
                , "MT4-8": A_ScriptDir . "\Historie-1.txt"}
IniListe := ""
For Ini, Log In MT4_Instanzen
{
   IniDatei := A_ScriptDir . "\" . Ini . ".ini"
   If !FileExist(IniDatei)
   {
      MsgBox, 16, Fehler!, Die Ini-Datei %IniDatei% fehlt!
      Continue
   }
   If !FileExist(Log)
   {
      MsgBox, 16, Fehler!, Die Log-Datei %Log% konnte nicht gefunden werden!
      Continue
   }
   IniListe .= Ini . "|"
}
IniListe := RTrim(IniListe, "|")
; --------------------------------------------------------------------------------------------------------------------------------
Menu Tray, Icon, shell32.dll, 50
; --------------------------------------------------------------------------------------------------------------------------------
Gui Font, s10, Verdana
Gui Add, Tab2, x0 y0 w1000 h510 +Buttons +0x8 +AltSubmit vTabVariable, Hauptmenu|Expert Advisor|Detail
Gui Tab, 1
Gui, Add, ListView, x100 y45 w800 h200 gShow vLV1, Expert Advisor                |Magicnumber
Gui Add, DropDownList, x100 y255 w305 vDDL1 gNewIni, %IniListe%
Gui Add, Button, x415 y254 w100 h23 gEdit, &Edit
Gui Add, Button, x520 y254 w100 h23 gNew, &New
Gui Add, Button, x625 y254 w100 h23 gDelete, &Delete
Gui Add, ListView,backgroundteal csilver grid x100 y290 w800 h195 altsubmit gCopy vLV2, Kommentar                    |Magicnumber
Gui Tab, 2
Gui Add, ListView, x40 y35 w400 h460 vLV3, Datum              |Tag              |Gewinn
Gui Add, ListView, x460 y35 w300 h460 vLV4, Jahr         |Monat           |Gewinn
Gui Add, Button, x780 y60 w150 h23, &Komplette Historie
Gui Add, DropDownList, x780 y100 w150, EURUSD||GBPUSD|AUDUSD
Gui Tab, 3
Gui Add, ListView, x0 y20 w1000 h468 vLV5, Kommentar|Ordernummer|Closetime|Slippage|Typ|Volumen|Symbol|Gewinn
Gui Add, Text, x780 y488 w220 h23 +E0x200, Gesamtsumme:
; --------------------------------------------------------------------------------------------------------------------------------
Gui Show, w1000 h510, Analyse
Return
; --------------------------------------------------------------------------------------------------------------------------------
GuiEscape:
GuiClose:
ExitApp
; --------------------------------------------------------------------------------------------------------------------------------
NewIni:
GuiControlGet, IniName, , DDL1
IniDatei := A_ScriptDir . "\" . IniName . ".ini"
AnalyseDatei := MT4_Instanzen[IniName]
Loop, 5 ; ListViews leeren
{
   Gui, ListView, LV%A_Index%
   LV_Delete()
}
IniObject := {}
IniRead, Sections, %IniDatei%
Loop, Parse, Sections, `n
{
   Section := A_LoopField
   IniRead, Numbers, %IniDatei%, %Section%, Numbers
   IniObject[Section] := Numbers
}
GoSub, FillLV2
GoSub, FillLV1
Return
; --------------------------------------------------------------------------------------------------------------------------------
SaveIni:
For Section, Numbers In IniObject
{
   IniWrite, %Numbers%, %IniDatei%, %Section%, Numbers
   If (ErrorLevel)
   {
      MsgBox, 16, Fehler!, Fehler beim Schreiben der Datei %IniDatei%
      Break
   }
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
FillLV1:
Gui, ListView, LV1
GuiControl, -ReDraw, LV1
For Section, Numbers In IniObject
   LV_Add("", Section, Numbers)
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV1
Return
; --------------------------------------------------------------------------------------------------------------------------------
FillLV2:
Gui, ListView, LV2
GuiControl, -ReDraw, LV2
LV2_Array := []
LV2_Columns := 2
EA_Index := 12
MN_Index := 4
Loop, Read, %AnalyseDatei%
{
   If (A_Index > 1)
   {
      Split := StrSplit(A_LoopReadLine, ";")
      EA := Split[EA_Index]
      MN := Split[MN_Index]
      If LV2_Array.HasKey(EA)
         LV2_Array[EA] .= " " . MN
      Else
         LV2_Array[EA] := MN
   }
}
For EA, MN In LV2_Array
{
   Sort, MN, D%A_Space% N U
   LV_Add("", EA, MN)
}
Loop, %LV2_Columns%
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV2
Return
; --------------------------------------------------------------------------------------------------------------------------------
Copy:
Gui, ListView, LV2
If (A_GuiEvent = "Normal") && (Selected := LV_GetNext())
{
   LV_GetText(MN, Selected, 2)
   Gui Copy: New
   Gui Font, s10, Verdana
   Gui Add, Edit, x0 y0 h80 w600 vCopyED, %MN%
   Gui Show, h80 w600, Copy
}
Return
CopyGuiclose:
Gui, Destroy
Return
; ================================================================================================================================
Edit:
Gui, ListView, LV1
If (Selected := LV_GetNext())
{
   LV_GetText(Section, Selected, 1)
   LV_GetText(Numbers, Selected, 2)
   Gui Edit: New
   Gui Font, s10, Verdana
   Gui Add, Edit, x12 y12 h25 w577 vSection, %Section%
   Gui Add, Edit, x12 y50 h80 w577 vNumbers, %Numbers%
   Gui Add, Button, x240 y140 w120 h25 gSave, &Save
   Gui 1: +Disabled ; während der Anzeige des GUI wird das Hauptfenster deaktiviert
   Gui Show, h177 w600, Edit
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
EditGuiclose:
Gui, 1: -Disabled
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
Save:
Gui, Submit, NoHide ; Werte der Edits auslesen
Section := Trim(Section) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Numbers := Trim(Numbers) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Gui, 1: Default ; GUI 1 als Standard setzen
Gui, ListView, LV1 ; sicherheitshalber auch LV1 als Standard setzen
GuiControl, -Redraw, LV1 ; visuelle Updates des ListViews abschalten
LV_Modify(Selected, "", Section, Numbers)
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV1
IniObject[Section] := Numbers
Gosub, SaveIni
Gui, 1: -Disabled
Gui, Edit: Destroy
Return
; ================================================================================================================================
New:
Gui, ListView, LV1
Gui New: New
Gui Font, s10, Verdana
Gui Add, Edit, x12 y12 h25 w577 vNew1
Gui Add, Edit, x12 y50 h80 w577 vNew2
Gui Add, Button, x240 y140 w120 h25 gSave, &Save
Gui Show, h177 w600, New
Return
NewGuiclose:
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
Delete:
Gui, ListView, LV1
If (Selected := LV_GetNext())
{
   Loop, 5
    LV_GetText(CurrentIndex, Selected, 1)
   Gui Delete: New
   Gui Font, s10, Verdana
   Gui Add, Text, x10 y22 w380 h25 +0x200 Center, %CurrentIndex% löschen?
   Gui Add, Button, x50 y65 w120 h25 gJa, &Ja
   Gui Add, Button, x220 y65 w120 h25 gNein, &Nein
   Gui Show, w400 h115, Delete
}
Return
Nein:
DeleteGuiclose:
Gui, Destroy
Return

Ja:
Loop, % Line0 - CurrentIndex + 1
{
CurrentIndex := A_Index - 1
CurrentSection := A_LoopField - 1
IniObject[CurrentIndex] := [CurrentSection]
}
Line0--
;GoSub,Filllist
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
Show:
Gui, ListView, LV1
If (A_GuiEvent = "Doubleclick") && (Selected := LV_GetNext())
{
   LV_GetText(CurrentSection, Selected, 2)
}
Guicontrol, Focus, Gui Tab 2
Return
Meine Frage bezog sich auf die nackten Dateigrößen, nicht den Inhalt. Sind das Kilobytes, Megabytes oder gar Gigabytes?
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

14 Oct 2017, 05:51

Ich würde Dir und mir lieber mehr Zeit lassen, doch mir läuft sie gerade davon. Ich gehe Anfang kommender Woche für einige Tage in den Offline-Urlaub und muss noch ein paar Dinge vorbereiten. Deshalb die vorgezogene Frage, welche Informationen in den ListViews auf Tab2 angezeigt werden sollen.

Sollen für die Auswahl EA und MagicNumbers genutzt werden? (Beide Informationen sieht man auf Tab2 z.Zt. nicht!)
Sollen Tage (links) und Jahre/Monate (rechts) aufsummiert ausgegeben werden?
Soll für den Gewinn brutto oder netto genutzt werden? (Nach Deiner Log-Datei scheint in der heilen Welt der Spekulanten immer noch brutto = netto zu sein!)
Wie viele Stellen sollen für den Gewinn angezeigt werden?
Fresh Janine
Posts: 29
Joined: 07 May 2017, 10:15

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

14 Oct 2017, 06:22

Das die INI-Datei nach jeder Änderung sofort überschrieben wird, ist genau so wie es ist, richtig so. Das hatte ich in meiner Anforderungsliste gar nicht definiert, doch du hast es trotzdem gleich richtig umgesetzt.

Also ich habe es mal getestet, in dem ich die allerlängsten Namen der Handelssysteme 20 mal mit jeweils 20 Magicnumbers reingeschrieben habe und dann war die Datei 3,94 Kb groß. Doch nun zu deiner Frage. Die INI-Dateien werden jeweils eine maximale Größe von 4 Kilobyte erreichen.

Ich hab nun noch versucht New und Delete fertig zu schreiben und in im Listview ist zwar alles korrekt, doch er speichert es nicht so:
Analyse01.ahk
(9.41 KiB) Downloaded 76 times

Sollen für die Auswahl EA und MagicNumbers genutzt werden?
Antwort: Für die Auswahl sollen nur die Magicnumbers aus der doppelangeklickten jeweiligen Zeile von Listview LV1 genommen werden, denn die EAs dienen nur der Übersicht in LV1.

Sollen Tage (links) und Jahre/Monate (rechts) aufsummiert ausgegeben werden?
Antwort: Genau, links die Tage und alles was für diesen Tag in der Historieliste gefunden wird, soll summiert in der Spalte "Gewinn" angezeigt werden. Und für die rechte Liste, ist es das Gleiche, nur das ein ganzer Monat aufsummiert werden soll.

Soll für den Gewinn brutto oder netto genutzt werden?
Antwort: Witzig, bei mir ist Brutto immer noch Netto, nein nein. Ich hab das Skript (Visual C#), was diese Historielisten ausgibt, ursprünglich nicht selbst programmiert und habe es aber umprogrammiert, da sonst viel zu viel unnötige Informationen in der Historieliste wäre. Doch das Brutto bekam ich nicht rausgelöscht, denn ich möchte gerne das NETTO in meinen AHK-Skript verarbeitet haben, da manchmal die Bruttozahlen keine runden Zahlen sind und das Netto ist immer exakt (Nur eben diese vielen Nullen sind überflüssig).

Wie viele Stellen sollen für den Gewinn angezeigt werden?
Antwort: Gute Überleitung, denn wo wir doch gerade bei dem Thema sind, antworte ich direkt mit 2 Kommastellen nach dem Komma. Also z.B.: 25,00

Wir machen es dann eben einfach weiter, wenn du wieder den Kopf dafür hast.
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

14 Oct 2017, 09:43

Ich habe das wohl soweit verstanden. Aber meine Frage nach den Dateigrößen war wohl missverständlich. Ich meinte nicht die INI-Dateien, sondern die Log-/Historie-Dateien.
Fresh Janine
Posts: 29
Joined: 07 May 2017, 10:15

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

14 Oct 2017, 09:54

Ach so, bei den Historie-Dateien schätze ich maximal pro Datei 5 Mb.
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

14 Oct 2017, 10:08

Danke! Dann lese ich die mal am Stück ein. Das sollte auf halbwegs aktuellen Rechnern keine Probleme bereiten.

Hast Du Dir die Änderungen zu Edit: mal angeschaut? Das, was für New: gebraucht wird, ist sehr ähnlich. ;)
Fresh Janine
Posts: 29
Joined: 07 May 2017, 10:15

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

14 Oct 2017, 10:18

Oh, Moment, ich glaube es ist doch besser, wenn die Historie-listen nicht an einem Stück geladen werden, weil 1. es funktioniert doch so wie es jetzt ist. Also warum es ändern? Und 2. wollte ich, wenn das Programm fertig ist, noch einprogrammieren, das wenn man in der ersten DDL z.B. MT4-1 auswählt, der Metatrader dieser Instanz gestartet wird und nach 5 Sekunden wieder geschlossen wird. Weil dann hat sich die Historie-Liste aktualisiert. Alle Instanzen laufen sowieso immer auf einen Server und das stört nicht, wenn ich diese Instanzen doppelt starte.
Fresh Janine
Posts: 29
Joined: 07 May 2017, 10:15

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

14 Oct 2017, 15:01

Hab mir das mit Edit:, New: und Delete: noch mal genau angeschaut und das Resultat ist, dass New: jetzt fehlerlos funktioniert, Delete: geht immer noch nicht und bei Edit: ist mir aufgefallen, dass zwar im Programm alles korrekt zu funktionieren zu scheint, doch wenn man dann nach dem Beenden des Programms sich die INI-Datei anschaut, dann hat er auf einmal die Sektion und Numbers 2 mal angelegt, doch das passiert nur wenn man die Sektion(Expert Advisor) im Programm bearbeitet. Wenn man die Numbers(Magicnumbers) im Programm bearbeitet, dann ist auch alles in der INI-Datei korrekt abgespeichert.
Analyse01.ahk
(9.65 KiB) Downloaded 78 times
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

15 Oct 2017, 03:50

Moin,

ich habe nicht daran gedacht, dass man bei Edit:auch den Sektionsnamen ändern kann. Folgende Änderung sollte helfen:

Code: Select all

; --------------------------------------------------------------------------------------------------------------------------------
Save:
OriginalName := Section ; alten Sektionsnamen sichern
Gui, Submit, NoHide ; Werte der Edits auslesen
Section := Trim(Section) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Numbers := Trim(Numbers) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Gui, 1: Default ; GUI 1 als Standard setzen
Gui, ListView, LV1 ; sicherheitshalber auch LV1 als Standard setzen
GuiControl, -Redraw, LV1 ; visuelle Updates des ListViews abschalten
LV_Modify(Selected, "", Section, Numbers)
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV1
If (Section <> OriginalName)
{
   IniDelete, %IniDatei%, %OriginalName%
   IniObject.Delete(OriginalName)
}
IniObject[Section] := Numbers
Gosub, SaveIni
Gui, 1: -Disabled
Gui, Edit: Destroy
Return
Die Funktion Delete: ist relativ einfach:

Code: Select all

; ================================================================================================================================
Delete:
Gui, ListView, LV1
If (Selected := LV_GetNext())
{
   LV_GetText(Section, Selected, 1)
   Gui Delete: New
   Gui Font, s10, Verdana
   Gui Add, Text, x10 y22 w380 h25 +0x200 Center, %Section% löschen?
   Gui Add, Button, x50 y65 w120 h25 gDeleteJa, &Ja
   Gui Add, Button, x220 y65 w120 h25 gDeleteNein, &Nein
   Gui 1: +Disabled
   Gui Show, w400 h115, Delete
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
DeleteNein:
DeleteGuiclose:
Gui, 1: -Disabled
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
DeleteJa:
Gui, 1: Default ; GUI 1 als Standard setzen
Gui, ListView, LV1 ; sicherheitshalber auch LV1 als Standard setzen
LV_Delete(Selected)
IniObject.Delete(Section)
IniDelete, %IniDatei%, %Section%
Gui, 1: -Disabled
Gui, Delete: Destroy
Return
; ================================================================================================================================
Zu den Historiendateien habe ich noch Zweifel. Dein 'Echtbeispiel' ist ca. 39 KB groß und enthält 343 Sätze. Eine 5 MB große Historiendatei könnte danach über 40.000 Sätze enthalten. Die ListViews können bis auf das Jahr-Monat-ListView auf Tab2 nur relativ wenige Informationen darstellen. Ist die bisher angedachte Verarbeitung/Darstellung bei so großen Dateien sinnvoll?

Mit "Laden am Stück" meine ich, dass die jeweils passende Historiendatei bei jedem Wechsel nur einmal komplett eingelesen wird. Wenn dann z.B. die Auswahl/Anzeigekriterien in Tab2 geändert werden, muss nicht neu gelesen werden. Wenn man nicht ausschließlich mit SSDs oder schnellen Serverplatten arbeitet, erhöht das die Performance.
Fresh Janine
Posts: 29
Joined: 07 May 2017, 10:15

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

15 Oct 2017, 09:03

Danke dir, jetzt ist ungefähr die Hälfte fertig! Wie meinst du das mit wenige Informationen darstellen? Meinst du das, weil es doch eine Begrenzung für Listviews gibt? Und natürlich ist das sinnvoll, denn wenn das Tool fertig ist, dann ist das absolut genial! Mein 'Echtbeispiel' lief als Handelssystem auch nicht lange. Manche Handelssysteme schreiben 1000 Zeilen pro Monat.

Jetzt weiß ich, wie du das meinst mit "Laden am Stück".
Wenn die Historiedatei über die DDL gewechselt wurde, soll auch nur einmal der jeweilige Metatrader für 5 Sekunden gestartet und wieder geschlossen werden, damit die jeweilige Historiedatei aktualisiert wurde. Erst wenn das Analyse-Programm geschlossen wurde und man startet wieder das Analyse-Programm, dann wird wieder bei jeder Instanz-Auswahl die Historiedatei aktualisiert.

Ich machte noch kleine Änderungen bei "Copy:":
Analyse01.ahk
(9.71 KiB) Downloaded 80 times
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

15 Oct 2017, 16:00

Moin moin,

das ist "Datenverarbeitung", wie ich sie über viele Jahre hinweg beruflich praktiziert habe: Daten einlesen -> Daten verarbeiten -> Ergebnis ausgeben. Ich hatte deshalb bereits aus meinem Bauchgefühl heraus weitergemacht, ohne Deine Antwort abzuwarten. Das Problem mit den großen Historiendateien hat sich inzwischen auch relativiert. Ich hatte in meiner Testversion versehentlich ein paar Zeilen in einer Schleife, die dort nicht hingehören, aber den Verarbeitingsprozess um den Faktor 60 - 70 verlangsamt haben. Das ist nun weg. Deine letzte Änderung zu Copy: ist in dieser Version noch nicht enthalten. Die wesentlichen Änderungen finden sich im Bereich GUI (vVariablen und gLabel) sowie NewIni:, FillLV2: und in den neuen Routinen ReadHis:, FilterHis: und NewSymbol:. Der Rest ist Kleinkram.

Code: Select all

#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
SetBatchLines -1 ; maximale Ausführungsgeschwindigkeit
; ================================================================================================================================
; Objekt für die MT4-Instanzen. Als Schlüssel wird der Name der zugehörigen INI-Datei verwendet, die im Skriptverzeichnis liegen
; muss. Der zugewiesene Wert ist der vollständige Pfad der jeweiligen Historien-Datei.
MT4_Instanzen := {"MT4-1": A_ScriptDir . "\Historie-1.txt"
                , "MT4-2": A_ScriptDir . "\Historie-2.txt"
                , "MT4-3": A_ScriptDir . "\Historie-3.txt"
                , "MT4-4": A_ScriptDir . "\Historie-1.txt"
                , "MT4-5": A_ScriptDir . "\Historie-1.txt"
                , "MT4-6": A_ScriptDir . "\Historie-1.txt"
                , "MT4-7": A_ScriptDir . "\Historie-1.txt"
                , "MT4-8": A_ScriptDir . "\Historie-1.txt"}
IniListe := ""
For Ini, His In MT4_Instanzen
{
   IniDatei := A_ScriptDir . "\" . Ini . ".ini"
   If !FileExist(IniDatei)
   {
      MsgBox, 16, Fehler!, Die Ini-Datei %IniDatei% fehlt!
      Continue
   }
   If !FileExist(His)
   {
      MsgBox, 16, Fehler!, Die Datei %His% konnte nicht gefunden werden!
      Continue
   }
   IniListe .= Ini . "|"
}
IniListe := RTrim(IniListe, "|")
; ================================================================================================================================
Menu Tray, Icon, shell32.dll, 50
; ================================================================================================================================
Gui Font, s10, Verdana
Gui Add, Tab2, x0 y0 w1000 h510 +Buttons +0x8 +AltSubmit vTabVariable, Hauptmenu|Expert Advisor|Detail
Gui Tab, 1
Gui Add, ListView, x100 y45 w800 h200 gShow vLV1, Expert Advisor                |Magicnumber
Gui Add, DropDownList, x100 y255 w305 vDDL1 gNewIni, %IniListe%
Gui Add, Button, x415 y254 w100 h23 gEdit, &Edit
Gui Add, Button, x520 y254 w100 h23 gNew, &New
Gui Add, Button, x625 y254 w100 h23 gDelete, &Delete
Gui Add, ListView,backgroundteal csilver grid x100 y290 w800 h195 altsubmit gCopy vLV2, Kommentar                    |Magicnumber
Gui Tab, 2
Gui Add, ListView, x40 y35 w400 h460 vLV3, Datum              |Tag              |Gewinn
Gui Add, ListView, x460 y35 w300 h460 vLV4, Jahr         |Monat           |Gewinn
Gui Add, Button, x780 y60 w150 h23, &Komplette Historie
Gui Add, DropDownList, x780 y100 w150 vDDL2 gNewSymbol
Gui Tab, 3
Gui Add, ListView, x0 y20 w1000 h468 vLV5, Kommentar|Ordernummer|Closetime|Slippage|Typ|Volumen|Symbol|Gewinn
Gui Add, Text, x780 y488 w220 h23 +E0x200, Gesamtsumme:
; --------------------------------------------------------------------------------------------------------------------------------
Gui Show, w1000 h510, Analyse
Return
; --------------------------------------------------------------------------------------------------------------------------------
GuiEscape:
GuiClose:
ExitApp
; ================================================================================================================================
NewIni:
GuiControlGet, IniName, , DDL1
IniDatei := A_ScriptDir . "\" . IniName . ".ini"
AnalyseDatei := MT4_Instanzen[IniName]
Loop, 5 ; ListViews leeren
{
   Gui, ListView, LV%A_Index%
   LV_Delete()
}
IniObject := {}
IniRead, Sections, %IniDatei%
Loop, Parse, Sections, `n
{
   Section := A_LoopField
   IniRead, Numbers, %IniDatei%, %Section%, Numbers
   IniObject[Section] := Numbers
}
GoSub, ReadHis
If !(HisArray.Length())
   Return
GoSub, FillLV2
GoSub, FillLV1
Return
; ================================================================================================================================
SaveIni:
For Section, Numbers In IniObject
{
   IniWrite, %Numbers%, %IniDatei%, %Section%, Numbers
   If (ErrorLevel)
   {
      MsgBox, 16, Fehler!, Fehler beim Schreiben der Datei %IniDatei%
      Break
   }
}
Return
; ================================================================================================================================
FillLV1:
Gui, ListView, LV1
GuiControl, -ReDraw, LV1
For Section, Numbers In IniObject
   LV_Add("", Section, Numbers)
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV1
Return
; ================================================================================================================================
FillLV2:
Gui, ListView, LV2
GuiControl, -ReDraw, LV2
LV2_Array := []
LV2_Columns := 2
EA_Index := 12
MN_Index := 4
For Index, LineArray In HisArray
{
   EA := LineArray[EA_Index]
   MN := LineArray[MN_Index]
   If LV2_Array.HasKey(EA)
      LV2_Array[EA] .= " " . MN
   Else
      LV2_Array[EA] := MN
}
For EA, MN In LV2_Array
{
   Sort, MN, D%A_Space% N U
   LV_Add("", EA, MN)
}
Loop, %LV2_Columns%
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV2
Return
; ================================================================================================================================
Copy:
Gui, ListView, LV2
If (A_GuiEvent = "Normal") && (Selected := LV_GetNext())
{
   LV_GetText(MN, Selected, 2)
   Gui Copy: New
   Gui Font, s10, Verdana
   Gui Add, Edit, x0 y0 h80 w600 vCopyED, %MN%
   Gui 1: +Disabled ; während der Anzeige des GUI wird das Hauptfenster deaktiviert
   Gui Show, h80 w600, Copy
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
CopyGuiclose:
Gui, 1: -Disabled
Gui, Destroy
Return
; ================================================================================================================================
Edit:
Gui, ListView, LV1
If (Selected := LV_GetNext())
{
   LV_GetText(Section, Selected, 1)
   LV_GetText(Numbers, Selected, 2)
   Gui Edit: New
   Gui Font, s10, Verdana
   Gui Add, Edit, x12 y12 h25 w577 vSection, %Section%
   Gui Add, Edit, x12 y50 h80 w577 vNumbers, %Numbers%
   Gui Add, Button, x240 y140 w120 h25 gSave, &EditSave
   Gui 1: +Disabled ; während der Anzeige des GUI wird das Hauptfenster deaktiviert
   Gui Show, h177 w600, Edit
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
EditGuiclose:
Gui, 1: -Disabled
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
EditSave:
OriginalName := Section ; alten Sektionsnamen sichern
Gui, Submit, NoHide ; Werte der Edits auslesen
Section := Trim(Section) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Numbers := Trim(Numbers) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Gui, 1: Default ; GUI 1 als Standard setzen
Gui, ListView, LV1 ; sicherheitshalber auch LV1 als Standard setzen
GuiControl, -Redraw, LV1 ; visuelle Updates des ListViews abschalten
LV_Modify(Selected, "", Section, Numbers)
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV1
If (Section <> OriginalName)
{
   IniDelete, %IniDatei%, %OriginalName%
   IniObject.Delete(OriginalName)
}
IniObject[Section] := Numbers
IniWrite, %Numbers%, %IniDatei%, %Section%, Numbers
; Gosub, SaveIni
Gui, 1: -Disabled
Gui, Edit: Destroy
Return
; ================================================================================================================================
New:
Gui, ListView, LV1
Gui New: New
Gui Font, s10, Verdana
Gui Add, Edit, x12 y12 h25 w577 vSection
Gui Add, Edit, x12 y50 h80 w577 vNumbers
Gui Add, Button, x240 y140 w120 h25 gNewSave, &Save
Gui 1: +Disabled ; während der Anzeige des GUI wird das Hauptfenster deaktiviert
Gui Show, h177 w600, New
Return
; --------------------------------------------------------------------------------------------------------------------------------
NewGuiclose:
Gui, 1: -Disabled
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
NewSave:
Gui, Submit, NoHide ; Werte der Edits auslesen
Section := Trim(Section) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Numbers := Trim(Numbers) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
If IniObject.HasKey(Section)
{
   MsgBox, 16, Fehler!, Der Eintrag %Section% ist bereits vorhanden!
   Return
}
Gui, 1: Default ; GUI 1 als Standard setzen
Gui, ListView, LV1 ; sicherheitshalber auch LV1 als Standard setzen
GuiControl, -Redraw, LV1 ; visuelle Updates des ListViews abschalten
LV_Add("", Section, Numbers)
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV1
IniObject[Section] := Numbers
IniWrite, %Numbers%, %IniDatei%, %Section%, Numbers
Gui, 1: -Disabled
Gui, New: Destroy
Return
; ================================================================================================================================
Delete:
Gui, ListView, LV1
If (Selected := LV_GetNext())
{
   LV_GetText(Section, Selected, 1)
   Gui Delete: New
   Gui Font, s10, Verdana
   Gui Add, Text, x10 y22 w380 h25 +0x200 Center, Eintrag %Section% löschen?
   Gui Add, Button, x50 y65 w120 h25 gDeleteJa, &Ja
   Gui Add, Button, x220 y65 w120 h25 gDeleteNein, &Nein
   Gui 1: +Disabled ; während der Anzeige des GUI wird das Hauptfenster deaktiviert
   Gui Show, w400 h115, Delete
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
DeleteNein:
DeleteGuiclose:
Gui, 1: -Disabled
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
DeleteJa:
Gui, 1: Default ; GUI 1 als Standard setzen
Gui, ListView, LV1 ; sicherheitshalber auch LV1 als Standard setzen
LV_Delete(Selected)
IniObject.Delete(Section)
IniDelete, %IniDatei%, %Section%
Gui, 1: -Disabled
Gui, Delete: Destroy
Return
; ================================================================================================================================
Show:
Gui, ListView, LV1
If (A_GuiEvent = "Doubleclick") && (Selected := LV_GetNext())
{
   NumberArray := []
   LV_GetText(Numbers, Selected, 2)
   Numbers := Trim(Numbers)
   If (Numbers = "")
      Return
   Loop, Parse, Numbers, %A_Space%
      NumberArray[A_LoopField] := ""
   Gosub, FilterHis
   Gosub, NewSymbol
}
Guicontrol, Choose, TabVariable, 2
Return
; ================================================================================================================================
NewSymbol:
GuiControlGet, Symbol, , DDL2
; ListView 3
Gui, ListView, LV3
GuiControl, -Redraw, LV3
LV_Delete()
For Day, Values In LV3_Array
{
   If Values.HasKey(Symbol)
      LV_Add("", Day, Values.CD, Format("{:0.2f}", Values[Symbol]))
}
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +Redraw, LV3
; ListView 4
Gui, ListView, LV4
GuiControl, -Redraw, LV4
LV_Delete()
For Year, MonthArray In LV4_Array
{
   For Month, Symbols In MonthArray
   {
      If Symbols.HasKey(Symbol)
         LV_Add("", Year, Format("{:02}", Month), Format("{:0.2f}", Symbols[Symbol]))
   }
}
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +Redraw, LV4
Return
; ================================================================================================================================
ReadHis:
HisArray := []
FileRead, HisContents, %AnalyseDatei%
If (ErrorLevel)
{
   MsgBox, 16, Fehler!, Die Datei %AnalyseDatei% konnte nicht gelesen werden!
   Return
}
HisSplit := StrSplit(HisContents, "`n", "`r")
HisArray.SetCapacity(HisSplit.Length())
For Index, Line In HisSplit
{
   If (Index > 1) && (Line <> "")
   {
      HisArray.Push(StrSplit(Line, ";"))
   }
}
HisSplit := ""
VarSetCapacity(HisContents, 0)
Return
; ================================================================================================================================
FilterHis:
SB_Index := 2  ; symbol
MN_Index := 4  ; magicnumber
CT_Index := 6  ; closetime
NT_Index := 8  ; netto
CD_Index := 9  ; closeday
CM_Index := 10 ; closemonth
CY_Index := 11 ; closeyear
SymbolArray := []
SymbolCount := 0
LV3_Array := []
LV3_Array.SetCapacity(2048)
LV4_Array := []
LV4_Array.SetCapacity(512)
For Each, Line In HisArray
{
   MN := Line[MN_Index]
   If !NumberArray.HasKey(MN)
      Continue
   SB := Line[SB_Index]
   If !SymbolArray.HasKey(SB)
   {
      SymbolArray[SB] := ""
      SymbolCount++
   }
   CT := SubStr(Line[CT_Index], 1, 10)
   CD := Line[CD_Index]
   ; CM := Line[CM_Index]
   CM := SubStr(CT, 6, 2)
   CY := Line[CY_Index]
   NT := StrReplace(Line[NT_Index], ",", ".")
   NT := Format("{:0.2f}", NT)
   If !LV3_Array.HasKey(CT)
      LV3_Array[CT] := {CD: CD, "Gesamt": NT, (SB): NT}
   Else
   {
      LV3_Array[CT, "Gesamt"] += NT
      If LV3_Array[CT].HasKey(SB)
         LV3_Array[CT, SB] += NT
      Else
         LV3_Array[CT, SB] := NT
   }
   If !LV4_Array[CY, CM]
      LV4_Array[CY, CM] := {"Gesamt": NT, (SB): NT}
   Else
   {
      LV4_Array[CY, CM, "Gesamt"] += NT
      If LV4_Array[CY, CM].HasKey(SB)
         LV4_Array[CY, CM, SB] += NT
      Else
         LV4_Array[CY, CM, SB] := NT
   }
}
SymbolListe := (SymbolCount > 1) ? "|Gesamt" : ""
For Symbol In SymbolArray
   SymbolListe .= "|" . Symbol
GuiControl, , DDL2, %SymbolListe%
GuiControl, Choose, DDL2, 1
Return
Jetzt hast Du die dankbare Aufgabe, nachzurechnen.

Wenn Du mir zeitnah sagen kannst, was unter welchen Bedingungen im ListView auf TAb3 erscheinen soll, kann ich Dir morgen vielleicht noch einen Prototypem dafür basteln. Danach ist erst mal für einige Zeit Schluss.

Mit "wenige Informationen darstellen" meine ich, dass es recht mühsam ist, Infomationen in einem ListView durchzusehen, der bei vielleicht 10.000 Zeilen Inhalt nur 20+ Zeilen gleichzeitig anzeigt.

Gute Nacht!
Fresh Janine
Posts: 29
Joined: 07 May 2017, 10:15

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

16 Oct 2017, 01:47

Das schüttet enorme Glücksgefühle aus. Wenn man dann sieht, wie das Programm, was man sich vorgestellt hat, wie genial das doch wäre, dann auf einmal tatsächlich so funktioniert. Ich hab alles getestet und bis auf den kleinen Fehler in Zeile 160 (gEditSave, &Save war vertauscht), scheint alles fehlerlos zu funktionieren. Ich bin auch absolut von dem Einfall begeistert, dass man in der DDL2 auch "gesamt" auswählen kann bzw. dass es das Erste ist, was ausgewählt ist. Im Nachhinein finde ich das sogar sehr wichtig und bin froh, dass du das einfach so mit einprogrammiert hast!

Bei Copy: hattest du noch "Gui 1: +Disabled" und "Gui 1: -Disabled" hinzugefügt, doch ich finde es praktischer ohne diese Gui-Sperre und hab es wieder rausgelöscht.

-Es würde dann weitergehen mit, dass wenn bei LV3 in eine Zeile doppelgeklickt wird, das dann Tab 3 fokussiert wird und Informationen nur für diesen Tag zu den Informationen, die in der DDL2 ausgewählt wurden und die im Tabellenkopf von LV5 geschrieben stehen, angezeigt werden.
-Wenn man bei LV4 in eine Zeile doppelklickt, dann soll Tab 3 auch fokussiert werden und soll dann den ganzen Monat anhand der Informationen, die in der DDL2 ausgewählt wurden und die im Tabellenkopf von LV5 geschrieben stehen, angezeigt werden.
-Wenn man auf den Button "Komplette Historie" klickt, dann soll Tab 3 auch fokussiert werden und soll dann anhand der Informationen, die in der DDL2 ausgewählt wurden und die im Tabellenkopf von LV5 geschrieben stehen, alles anzeigen.
-LV5 brauch niemals neu sortiert werden, da die Historielisten sowieso schon alle korrekt nach Closetime sortiert sind.
-Um "Slippage" besser zu verarbeiten zu können, gebe ich dir noch eine andere Liste mit, wo auch Daten zu Slippage gespeichert wurden:
Historie-4.txt
(25.21 KiB) Downloaded 78 times
Und Slippage soll in LV5 bis zur 5. Kommastelle angezeigt werden. Z.B. "0,000199999999999978" wird zu "0,00019" oder "2,999999999997449e-05" wird zu "2,99999" oder "-0" wird zu "0,00000" oder "0" wird zu "0,00000". Zur Übersicht würde es besser aussehen, wenn eine 0 auch 5 Kommastellen bekommt.
-Closetime soll in LV5 komplett angezeigt werden. Also z.B. so: 2017.09.22 09:04:14
-Der Text unten in Tab 3 (Gesamtsumme:) zeigt nur noch mal die Gesamtsumme des jeweils Ausgewählten. Eine Gesamtsumme, die man auch schon in LV3 und LV4 lesen kann. Nur wenn man den Button "Komplette Historie" geklickt hat, würde man eine Gesamtsumme lesen, die man noch nicht las.

Die aktuelle Version:
Analyse01.ahk
(13.46 KiB) Downloaded 96 times

Wie lange machst du denn Offline-Urlaub?
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

16 Oct 2017, 02:53

Moin,

ich hoffe, Du hattest eine erholsame Nacht. ;)
Wenn man auf den Button "Komplette Historie" klickt, dann soll Tab 3 auch fokussiert werden und soll dann anhand der Informationen, die in der DDL2 ausgewählt wurden und die im Tabellenkopf von LV5 geschrieben stehen, alles anzeigen.
Da bin ich mir noch nicht sicher. In diesem Fall wird keine Auswahl in LV3 btw. LV4 berücksichtigt. Sollen also alle Sätze mit dem ausgewählten symbol ohne Beschränkung auf einen Zeitraum ausgegeben werden, d.h. bei Gesamt alle Sätze der Datei?
Und Slippage soll in LV5 bis zur 5. Kommastelle angezeigt werden. Z.B. "0,000199999999999978" wird zu "0,00019" oder "2,999999999997449e-05" wird zu "2,99999" ...
2,999999999997449e-05 ist aber eigentlich 0,000029.... Soll es trotzdem 2,99999 oder lieber 2,99999e-05 bzw. 0,00003sein?

Mein Urlaub geht bis zum 27.10.
Fresh Janine
Posts: 29
Joined: 07 May 2017, 10:15

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

16 Oct 2017, 12:32

Ja, ich hatte eine sehr erholsame Nacht :)

Genau, beim Klick auf den Button "Komplette Historie" sollen alle Sätze mit dem ausgewählten Symbol ohne Beschränkung auf einen Zeitraum ausgegeben werden. Doch nicht alle Sätze der Datei ausgeben, denn es wird natürlich immer noch nach dem ausgewählten Magicnumbers aus LV1 gefiltert.

Du hast recht "2,999999999997449e-05" ist "0,000029" und am besten wäre es, wenn "2,999999999997449e-05" zu "0,00003" wird.

Dann erhol dich gut :)
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

16 Oct 2017, 16:16

Hallo,

ich bin schon nah dran, aber dann hat ausgerechnet heute meine Kaffeemaschine ihren Geist aufgegeben und ich musste mir eine Ersatzmaschine besorgen, um nach dem Urlaub nicht ohne Kaffee dazustehen.

Deshalb, so long, Janine! ;)
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Txt-Datei auslesen und Teile davon im Gui anzeigen

17 Oct 2017, 01:42

Moin,

ich habe mich doch noch einmal drangesetzt und den Prototypen komplettiert, damit Du in den kommenden Tagen etwas zu tun hast. Ich habe das allerdings nicht mehr wirklich getestet.
Die wesentlichen Änderungen stecken in ShowDay:, ShowMonth:, ShowAll: und SelectFilter:. FilterHis: erstellt jetzt dafür ein eigenes Ergebnis-Array.

Code: Select all

#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
SetBatchLines -1 ; maximale Ausführungsgeschwindigkeit
; ================================================================================================================================
; Indizes für die Felder der Historiendateien
ON_Index := 1  ; ticket (Ordernummer)
SB_Index := 2  ; symbol
TP_Index := 3  ; typ
MN_Index := 4  ; magicnumber
VL_Index := 5  ; volume
CT_Index := 6  ; closetime
BT_Index := 7  ; brutto
NT_Index := 8  ; netto (Gewinn)
CD_Index := 9  ; closeday
CM_Index := 10 ; closemonth
CY_Index := 11 ; closeyear
CO_Index := 12 ; comment (Kommentar)
SL_Index := 13 ; slippage
; ================================================================================================================================
; Objekt für die MT4-Instanzen. Als Schlüssel wird der Name der zugehörigen INI-Datei verwendet, die im Skriptverzeichnis liegen
; muss. Der zugewiesene Wert ist der vollständige Pfad der jeweiligen Historien-Datei.
MT4_Instanzen := {"MT4-1": A_ScriptDir . "\Historie-1.txt"
                , "MT4-2": A_ScriptDir . "\Historie-2.txt"
                , "MT4-3": A_ScriptDir . "\Historie-1.txt"
                , "MT4-4": A_ScriptDir . "\Historie-4.txt"
                , "MT4-5": A_ScriptDir . "\Historie-1.txt"
                , "MT4-6": A_ScriptDir . "\Historie-1.txt"
                , "MT4-7": A_ScriptDir . "\Historie-1.txt"
                , "MT4-8": A_ScriptDir . "\Historie-1.txt"}
IniListe := ""
For Ini, His In MT4_Instanzen
{
   IniDatei := A_ScriptDir . "\" . Ini . ".ini"
   If !FileExist(IniDatei)
   {
      MsgBox, 16, Fehler!, Die Ini-Datei %IniDatei% fehlt!
      Continue
   }
   If !FileExist(His)
   {
      MsgBox, 16, Fehler!, Die Datei %His% konnte nicht gefunden werden!
      Continue
   }
   IniListe .= Ini . "|"
}
IniListe := RTrim(IniListe, "|")
; ================================================================================================================================
Menu Tray, Icon, shell32.dll, 16
; ================================================================================================================================
Gui Font, s10, Verdana
Gui Add, Tab2, x0 y0 w1000 h510 +Buttons +0x8 +AltSubmit vTabVariable, Hauptmenu|Expert Advisor|Detail
Gui Tab, 1
Gui Add, ListView, BackgroundEFFFFA x100 y45 w800 h200 gShow vLV1, Expert Advisor                |Magicnumber
Gui Add, DropDownList, x100 y255 w305 vDDL1 gNewIni, %IniListe%
Gui Add, Button, x415 y254 w100 h23 gEdit, &Edit
Gui Add, Button, x520 y254 w100 h23 gNew, &New
Gui Add, Button, x625 y254 w100 h23 gDelete, &Delete
Gui Add, ListView, Backgroundteal cDFDFDF grid x100 y290 w800 h195 altsubmit gCopy vLV2, Kommentar                    |Magicnumber
Gui Tab, 2
Gui Add, ListView, BackgroundEFFFFA x40 y35 w400 h460 vLV3 gShowDay, Datum              |Tag              |Gewinn
Gui Add, ListView, BackgroundEFFFFA x460 y35 w300 h460 vLV4 gShowMonth, Jahr         |Monat           |Gewinn
Gui Add, Button, x780 y60 w150 h23 gShowAll, &Komplette Historie
Gui Add, DropDownList, x780 y100 w150 vDDL2 gNewSymbol
Gui Tab, 3
Gui Add, ListView, BackgroundEFFFFA x0 y20 w1000 h468 vLV5, Kommentar|Ordernummer|Slippage|Closetime|Symbol|Typ|Volumen|Gewinn
Gui Add, Text, x780 y488 w220 h23 +E0x200 vGS, Gesamtsumme:
; --------------------------------------------------------------------------------------------------------------------------------
Gui Show, w1000 h510, Analyse
Return
; --------------------------------------------------------------------------------------------------------------------------------
GuiEscape:
GuiClose:
ExitApp
; ================================================================================================================================
NewIni:
GuiControlGet, IniName, , DDL1
IniDatei := A_ScriptDir . "\" . IniName . ".ini"
AnalyseDatei := MT4_Instanzen[IniName]
Loop, 5 ; ListViews leeren
{
   Gui, ListView, LV%A_Index%
   LV_Delete()
}
IniObject := {}
IniRead, Sections, %IniDatei%
Loop, Parse, Sections, `n
{
   Section := A_LoopField
   IniRead, Numbers, %IniDatei%, %Section%, Numbers
   IniObject[Section] := Numbers
}
GoSub, ReadHis
If !(HisArray.Length())
   Return
GoSub, FillLV2
GoSub, FillLV1
Return
; ================================================================================================================================
SaveIni:
For Section, Numbers In IniObject
{
   IniWrite, %Numbers%, %IniDatei%, %Section%, Numbers
   If (ErrorLevel)
   {
      MsgBox, 16, Fehler!, Fehler beim Schreiben der Datei %IniDatei%
      Break
   }
}
Return
; ================================================================================================================================
FillLV1:
Gui, ListView, LV1
GuiControl, -ReDraw, LV1
For Section, Numbers In IniObject
   LV_Add("", Section, Numbers)
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV1
Return
; ================================================================================================================================
FillLV2:
Gui, ListView, LV2
GuiControl, -ReDraw, LV2
LV2_Array := []
LV2_Columns := 2
EA_Index := 12
MN_Index := 4
For Index, LineArray In HisArray
{
   EA := LineArray[EA_Index]
   MN := LineArray[MN_Index]
   If LV2_Array.HasKey(EA)
      LV2_Array[EA] .= " " . MN
   Else
      LV2_Array[EA] := MN
}
For EA, MN In LV2_Array
{
   Sort, MN, D%A_Space% N U
   LV_Add("", EA, MN)
}
Loop, %LV2_Columns%
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV2
Return
; ================================================================================================================================
Copy:
Gui, ListView, LV2
If (A_GuiEvent = "Normal") && (Selected := LV_GetNext())
{
   LV_GetText(EA, Selected, 1)
   LV_GetText(MN, Selected, 2)
   Gui Copy: New
   Gui Font, s10, Verdana
   Gui Add, Edit, x0 y0 h80 w600, %EA%   | %MN%
   Gui Show, h80 w600, Copy
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
CopyGuiclose:
Gui, Destroy
Return
; ================================================================================================================================
Edit:
Gui, ListView, LV1
If (Selected := LV_GetNext())
{
   LV_GetText(Section, Selected, 1)
   LV_GetText(Numbers, Selected, 2)
   Gui Edit: New
   Gui Font, s10, Verdana
   Gui Add, Edit, x12 y12 h25 w577 vSection, %Section%
   Gui Add, Edit, x12 y50 h80 w577 vNumbers, %Numbers%
   Gui Add, Button, x240 y140 w120 h25 gEditSave, &Save
   Gui 1: +Disabled ; während der Anzeige des GUI wird das Hauptfenster deaktiviert
   Gui Show, h177 w600, Edit
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
EditGuiclose:
Gui, 1: -Disabled
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
EditSave:
OriginalName := Section ; alten Sektionsnamen sichern
Gui, Submit, NoHide ; Werte der Edits auslesen
Section := Trim(Section) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Numbers := Trim(Numbers) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Gui, 1: Default ; GUI 1 als Standard setzen
Gui, ListView, LV1 ; sicherheitshalber auch LV1 als Standard setzen
GuiControl, -Redraw, LV1 ; visuelle Updates des ListViews abschalten
LV_Modify(Selected, "", Section, Numbers)
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV1
If (Section <> OriginalName)
{
   IniDelete, %IniDatei%, %OriginalName%
   IniObject.Delete(OriginalName)
}
IniObject[Section] := Numbers
IniWrite, %Numbers%, %IniDatei%, %Section%, Numbers
; Gosub, SaveIni
Gui, 1: -Disabled
Gui, Edit: Destroy
Return
; ================================================================================================================================
New:
Gui, ListView, LV1
Gui New: New
Gui Font, s10, Verdana
Gui Add, Edit, x12 y12 h25 w577 vSection
Gui Add, Edit, x12 y50 h80 w577 vNumbers
Gui Add, Button, x240 y140 w120 h25 gNewSave, &Save
Gui 1: +Disabled ; während der Anzeige des GUI wird das Hauptfenster deaktiviert
Gui Show, h177 w600, New
Return
; --------------------------------------------------------------------------------------------------------------------------------
NewGuiclose:
Gui, 1: -Disabled
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
NewSave:
Gui, Submit, NoHide ; Werte der Edits auslesen
Section := Trim(Section) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
Numbers := Trim(Numbers) ; evtl. Leerzeichen und Tabs an Anfang und Ende entfernen
If IniObject.HasKey(Section)
{
   MsgBox, 16, Fehler!, Der Eintrag %Section% ist bereits vorhanden!
   Return
}
Gui, 1: Default ; GUI 1 als Standard setzen
Gui, ListView, LV1 ; sicherheitshalber auch LV1 als Standard setzen
GuiControl, -Redraw, LV1 ; visuelle Updates des ListViews abschalten
LV_Add("", Section, Numbers)
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +ReDraw, LV1
IniObject[Section] := Numbers
IniWrite, %Numbers%, %IniDatei%, %Section%, Numbers
Gui, 1: -Disabled
Gui, New: Destroy
Return
; ================================================================================================================================
Delete:
Gui, ListView, LV1
If (Selected := LV_GetNext())
{
   LV_GetText(Section, Selected, 1)
   Gui Delete: New
   Gui Font, s10, Verdana
   Gui Add, Text, x10 y22 w380 h25 +0x200 Center, Eintrag %Section% löschen?
   Gui Add, Button, x50 y65 w120 h25 gDeleteJa, &Ja
   Gui Add, Button, x220 y65 w120 h25 gDeleteNein, &Nein
   Gui 1: +Disabled ; während der Anzeige des GUI wird das Hauptfenster deaktiviert
   Gui Show, w400 h115, Delete
}
Return
; --------------------------------------------------------------------------------------------------------------------------------
DeleteNein:
DeleteGuiclose:
Gui, 1: -Disabled
Gui, Destroy
Return
; --------------------------------------------------------------------------------------------------------------------------------
DeleteJa:
Gui, 1: Default ; GUI 1 als Standard setzen
Gui, ListView, LV1 ; sicherheitshalber auch LV1 als Standard setzen
LV_Delete(Selected)
IniObject.Delete(Section)
IniDelete, %IniDatei%, %Section%
Gui, 1: -Disabled
Gui, Delete: Destroy
Return
; ================================================================================================================================
Show:
Gui, ListView, LV1
If (A_GuiEvent = "Doubleclick") && (Selected := LV_GetNext())
{
   NumberArray := []
   LV_GetText(Numbers, Selected, 2)
   Numbers := Trim(Numbers)
   If (Numbers = "")
      Return
   Loop, Parse, Numbers, %A_Space%
      NumberArray[A_LoopField] := ""
   Gosub, FilterHis
   Gosub, NewSymbol
}
Guicontrol, Choose, TabVariable, 2
Return
; ================================================================================================================================
NewSymbol:
GuiControlGet, Symbol, , DDL2
; ListView 3
Gui, ListView, LV3
GuiControl, -Redraw, LV3
LV_Delete()
For Day, Values In LV3_Array
{
   If Values.HasKey(Symbol)
      LV_Add("", Day, Values.CD, Format("{:0.2f}", Values[Symbol]))
}
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +Redraw, LV3
; ListView 4
Gui, ListView, LV4
GuiControl, -Redraw, LV4
LV_Delete()
For Year, MonthArray In LV4_Array
{
   For Month, Symbols In MonthArray
   {
      If Symbols.HasKey(Symbol)
         LV_Add("", Year, Format("{:02}", Month), Format("{:0.2f}", Symbols[Symbol]))
   }
}
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +Redraw, LV4
Return
; ================================================================================================================================
ShowDay:
Gui, ListView, LV3
If (A_GuiEvent = "Doubleclick") && (Selected := LV_GetNext())
{
   GuiControlGet, Symbol, , DDL2
   LV_GetText(SearchFor, Selected, 1)
   SearchLen := StrLen(SearchFor)
   GoSub, SelectFilter
   Guicontrol, Choose, TabVariable, 3
}
Return
; ================================================================================================================================
ShowMonth:
Gui, ListView, LV4
If (A_GuiEvent = "Doubleclick") && (Selected := LV_GetNext())
{
   GuiControlGet, Symbol, , DDL2
   LV_GetText(Year, Selected, 1)
   LV_GetText(Month, Selected, 2)
   SearchFor := Year . "." . Month
   SearchLen := StrLen(SearchFor)
   GoSub, SelectFilter
   Guicontrol, Choose, TabVariable, 3
}
Return
; ================================================================================================================================
ShowAll:
GuiControlGet, Symbol, , DDL2
SearchFor := ""
SearchLen := 0
GoSub, SelectFilter
Guicontrol, Choose, TabVariable, 3
Return
; ================================================================================================================================
ReadHis:
HisArray := []
FileRead, HisContents, %AnalyseDatei%
If (ErrorLevel)
{
   MsgBox, 16, Fehler!, Die Datei %AnalyseDatei% konnte nicht gelesen werden!
   Return
}
HisSplit := StrSplit(HisContents, "`n", "`r")
HisArray.SetCapacity(HisSplit.Length())
For Index, Line In HisSplit
{
   If (Index > 1) && (Line <> "")
   {
      HisArray.Push(StrSplit(Line, ";"))
   }
}
HisSplit := ""
VarSetCapacity(HisContents, 0)
Return
; ================================================================================================================================
FilterHis:
FilterArray := []
FilterArray.SetCapacity(HisArray.Length // 2)
LV3_Array := []
LV3_Array.SetCapacity(2048)
LV4_Array := []
LV4_Array.SetCapacity(512)
SymbolArray := []
SymbolCount := 0
For Each, Line In HisArray
{
   MN := Line[MN_Index]
   If !NumberArray.HasKey(MN)
      Continue
   FilterArray.Push(Line)
   SB := Line[SB_Index]
   If !SymbolArray.HasKey(SB)
   {
      SymbolArray[SB] := ""
      SymbolCount++
   }
   CT := SubStr(Line[CT_Index], 1, 10)
   CD := Line[CD_Index]
   CM := SubStr(CT, 6, 2)
   CY := Line[CY_Index]
   NT := StrReplace(Line[NT_Index], ",", ".")
   NT := Format("{:0.2f}", NT)
   If !LV3_Array.HasKey(CT)
      LV3_Array[CT] := {CD: CD, "Gesamt": NT, (SB): NT}
   Else
   {
      LV3_Array[CT, "Gesamt"] += NT
      If LV3_Array[CT].HasKey(SB)
         LV3_Array[CT, SB] += NT
      Else
         LV3_Array[CT, SB] := NT
   }
   If !LV4_Array[CY, CM]
      LV4_Array[CY, CM] := {"Gesamt": NT, (SB): NT}
   Else
   {
      LV4_Array[CY, CM, "Gesamt"] += NT
      If LV4_Array[CY, CM].HasKey(SB)
         LV4_Array[CY, CM, SB] += NT
      Else
         LV4_Array[CY, CM, SB] := NT
   }
}
SymbolListe := (SymbolCount > 1) ? "|Gesamt" : ""
For Symbol In SymbolArray
   SymbolListe .= "|" . Symbol
GuiControl, , DDL2, %SymbolListe%
GuiControl, Choose, DDL2, 1
Return
; ================================================================================================================================
SelectFilter:
Total := 0
Gui, ListView, LV5
GuiControl, -Redraw, LV5
LV_Delete()
For Each, Line In FilterArray
{
   MN := Line[MN_Index]
   If !NumberArray.HasKey(MN)
      Continue
   SB := Line[SB_Index]
   If (SB <> Symbol) && (Symbol <> "Gesamt")
      Continue
   CT := Line[CT_Index]
   If (SearchLen > 0)
   {
      LineDate := SubStr(CT, 1, SearchLen)
      If (LineDate < SearchFor)
         Continue
      If (LineDate > SearchFor)
         Break
   }
   CO := Line[CO_Index]
   SL := StrReplace(Line[SL_Index], ",", ".")
   SL := Format("{:0.5f}", SL)
   TP := Line[TP_Index]
   VL := Line[VL_Index]
   NT := StrReplace(Line[NT_Index], ",", ".")
   NT := Format("{:0.2f}", NT)
   LV_Add("", Line[CO_Index], Line[ON_Index], SL, CT, SB, TP, VL, NT)
   Total += NT
}
Loop, % LV_GetCount("Column")
   LV_ModifyCol(A_Index, "AutoHdr")
GuiControl, +Redraw, LV5
GuiControl, , GS, % "Gesamtsumme: " . Format("{:0.2f}", Total)
Return
Es gibt bestimmt noch Raum für Verbesserungen/Optimierungen, das muss aber bis nach dem Urlaub warten.

Bis dann!

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 39 guests