IniWrite/Read mit Wert aus Variable als Key

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

Folllast
Posts: 91
Joined: 24 Jan 2018, 04:57

IniWrite/Read mit Wert aus Variable als Key

14 Mar 2018, 06:10

Hallo,

ich möchte mit IniRead, menge, test.ini, Sektion, "%Feld6%" , 0 einen Wert auslesen, dessen Key der Inhalt der Variable Feld6 ist.
im Schritt vorher erstelle ich mit StringSplit, Feld, A_LoopReadLine,`; die Variablen FeldX. Nun möchte ich aus der .ini genau den Wert auslesen, der der Variable Feld6 zugeornet ist.

getestet habe ich: IniRead, menge, test.ini, Sektion, "%Feld6%" , 0 funktioniert, allerdings haben die Keys dann auch "" am Anfang und am Ende. Wenn ich die "" aber weglasse, geht es nicht.

Wo liegt mein Fehler?
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: IniWrite/Read mit Wert aus Variable als Key

14 Mar 2018, 06:24

Hallo,

das hier "%Feld6%" sieht schon mal nicht gut aus. Die " haben da normalerweise nichts zu suchen. Der Rest ist abhängig vom Inhalt der Variablen Feld6.
Folllast
Posts: 91
Joined: 24 Jan 2018, 04:57

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 00:30

Hallo,

anders geht es leider nicht.
nehmen wir an Feld6 = Hallo dann kommt bei "%Feld6%" in der .ini die Zeile "Hallo"=15 zustande.
Wenn ich nur %Feld6% benutze entsteht in der .ini nur eine Zeile mit 0.
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 00:56

Code: Select all

Feld := StrSplit(A_LoopReadLine,";")
Key := Feld[6]
IniRead, menge, test.ini, Sektion, %Key% , 0
MsgBox % menge

Code: Select all

Feld := StrSplit(A_LoopReadLine,";")
IniRead, menge, test.ini, Sektion, % "%Feld%" , 0
MsgBox % menge

Code: Select all

Feld := StrSplit(A_LoopReadLine,";")
IniRead, menge, test.ini, Sektion, % Feld[6], 0
MsgBox % menge
Nicht getestet.
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 03:16

Folllast wrote:Wenn ich nur %Feld6% benutze entsteht in der .ini nur eine Zeile mit 0.
Wirklich?

Code: Select all

#NoEnv
IniFile = Test.Ini
Feld6 = Hallo
FileDelete, %IniFile%
IniWrite, 15, %IniFile%, Sektion, %Feld6%
FileRead, Contents, %IniFile%
MsgBox, 0, IniFile, %Contents%
MsgBox wrote:---------------------------
IniFile
---------------------------
[Sektion]

Hallo=15


---------------------------
OK
---------------------------
Wie sieht denn die Datei aus, die Du mit StringSplit, Feld, A_LoopReadLine,`; verarbeitest? Und wie entsteht Deine INI-Datei?
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 03:22

Wenn ich nur %Feld6% benutze entsteht in der .ini nur eine Zeile mit 0.
Die 0 ist als INIRead default-rückgabewert gesetzt. Ansonsten stände da ERROR (was sachdienlicher gewesen wäre)

Code: Select all

#SingleInstance, Force

Line := "A;B;C;D;E;F;G;H"
Feld := StrSplit(Line,";")
INIWrite, hello, test.ini, Section,% Feld[6]

Key := Feld[6]
IniRead, menge, test.ini, Section, %Key%
MsgBox % menge

IniRead, menge, test.ini, Section,% Feld[6]
MsgBox % menge

F11:: Run test.ini
F12::Reload
Das funzt beides.
Folllast
Posts: 91
Joined: 24 Jan 2018, 04:57

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 05:31

Code: Select all

Loop, Read, %eingabe%
{
	If A_Index < 67									
		Continue
	Feld := StrSplit(A_LoopReadLine,";", ",")	
	If !Feld[1]							
		continue
	IniRead, menge, test.ini, Section,% Feld[6], 0
	menge += Feld[18]
	INIWrite, %menge%, test.ini, Section,% Feld[6]
	continue
}
eine Zeile sieht wie folgt aus: 4;;;;;V124P0003;;;;;;;;;;28.03.18;;2,;;;;;Stck;;1;77,58;114,04;;;;;;;;;

ergibt bei mir folgendes .ini-File:

Code: Select all

[Section]
30
25
20
15
10
5
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 08:08

Liest sich für mich so ...

Code: Select all

Loop, Read, %eingabe%   ; lies den inhalt der genannten datei?
{
	If A_Index < 67   ; ignoriere alle zeilen vor der 67ten	(?)				
		Continue
	Feld := StrSplit(A_LoopReadLine,";", ",")   ; zerlege die aktuele zeile. Übergabe der werte in den array "Feld"
	If !Feld[1]	   ; wenn der wert aus dem 1 element des arrays der aktuellen zeile "nicht wahr ist" (?)
		continue   ; ... dann auf zur nächsten nächste zeile.
	IniRead, menge, test.ini, Section,% Feld[6], 0   ; ... ansonsten, lese den wert des schlüssels mit dem namen, welcher im 6. element des Feld-arrays angegeben ist.
	menge += Feld[18]   ; ... addiere dazu den wert des 18. elements des arrays ...
	IniWrite,% menge, test.ini, Section,% Feld[6]   ; und schreibe die 'gesamtmenge' in den vorher ermittelten schlüssel.
	continue   ; und hier schreibe ich nochmal continue weils lustig ist.
}
... und es erschließt sich mir nicht, was das ganze überhaupt soll ... so ohne (gesamt)story :yawn:
Und diese "INI" wird hier ohne schlüsselnamen geschrieben, weil vorab das für den schlüsselnamen vorgesehene namengebende 6. element leer war.
Dadurch wird INIWrite schlicht zum FileAppend.
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 10:30

Ich gehe auch davon aus, dass Feld[6] ab und zu leer ist. In diesem Fall überschreibt

Code: Select all

IniWrite,% menge, test.ini, Section,% Feld[6]
die komplette Sektion. Und weil menge kein Gleichheitszeichen enthält:
IniWrite wrote:Paare kann Zeilen ohne Gleichheitszeichen (=) enthalten, allerdings könnte das zu inkonsistenten Ergebnissen führen.
Du solltest prüfen, ob Feld[6] und Feld[18] 'vernünftige' Inhalte haben.
Folllast
Posts: 91
Joined: 24 Jan 2018, 04:57

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 10:31

Code: Select all

Loop, Read, %eingabe%   ; lies den inhalt der genannten datei
{
	If A_Index < 67   ; ignoriere alle zeilen vor der 67ten, die dieser quasi nur den Kopf der "Liste" darstellen und für die Auswertung irrelevant sind			
		Continue
	Feld := StrSplit(A_LoopReadLine,";", ",")   ; zerlege die aktuele zeile. Übergabe der werte in den array "Feld". Kommas am Ende von einem "Feld" werden entfernt (kommt bei der Menge vor. Hier ist der Inhalt der Zelle nicht [c]5[/c] sondern [c]5,[/c]
	If !Feld[1]	   ; jede zweite Zeile ist leer. wenn das erste Feld leer ist, soll die Zeile übersprungen werden.
		continue   ; ... dann auf zur nächsten nächste zeile.
	IniRead, menge, test.ini, Section,% Feld[6], 0   ; ... ansonsten, lese den wert des schlüssels mit dem namen, welcher im 6. element des Feld-arrays angegeben ist. Wenn der Wert nicht verfügbar ist (noch nicht in der Liste steht) verwende 0 als Menge
	menge += Feld[18]   ; addiere zu der Menge aus der .ini-Datei die Menge, die in der Ursprungszeile aus der .csv im Feld 18 steht
	IniWrite,% menge, test.ini, Section,% Feld[6]   ; und schreibe die 'gesamtmenge' in den vorher ermittelten schlüssel.
	continue   ; und hier schreibe ich nochmal continue weils lustig ist.
}
... und es erschließt sich mir nicht, was das ganze überhaupt soll ... so ohne (gesamt)story :yawn:
Und diese "INI" wird hier ohne schlüsselnamen geschrieben, weil vorab das für den schlüsselnamen vorgesehene namengebende 6. element leer war.
Dadurch wird INIWrite schlicht zum FileAppend.
Ich habe festgestellt, das Der script funktioniert, wenn ich vor IniWrite eine MsgBox mit dem Feld6 einfüge. sobald ich sie wieder auskommentiert habe, hat es nichtmehr funktioniert.

Ich habe die Kommentare bisschen bearbeitet. Ich hoffe jetzt ist der sinn klar.
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 10:44

Kannst Du ein Beispiel einer kompletten Eingabedatei hier einstellen? Wie viele Sätze enthält die Datei in der Regel?
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 11:34

Das ist jetzt aber nicht die ganze geschichte. Warum überhaupt in eine INIdatei schreiben, wenn doch die csv schon einen datenpool bildet? Was ist denn der vorteil von mit mehr als 2 (angenommenen) INIdateien/-sektionen/-schlüsselpaaren herum zu hantieren??
Warum jede zweite zeile leer ist? Ich vermute mal es handelt sich um die ausgabedatei eines systems, welches mit einem `r als EOL character/zeilenendezeichen arbeitet.
Einfach mal ausprobieren ...

Code: Select all

FileRead, Content, my.csv
MsgBox % Content := StrReplace(Content,"`r","`n")
... oder im editor die EOLs anzeigen lassen (Notepad2 macht das. Hab ich den Kunden für genau diesen fall empfohlen).
gregster
Posts: 8916
Joined: 30 Sep 2013, 06:48

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 12:24

BoBo wrote:... oder im editor die EOLs anzeigen lassen (Notepad2 macht das. Hab ich den Kunden für genau diesen fall empfohlen).
Das sollte jeder gute Editor können - Scite4AHK kann es übrigens auch.
Folllast
Posts: 91
Joined: 24 Jan 2018, 04:57

Re: IniWrite/Read mit Wert aus Variable als Key

15 Mar 2018, 17:00

just me wrote:Kannst Du ein Beispiel einer kompletten Eingabedatei hier einstellen? Wie viele Sätze enthält die Datei in der Regel?
die Eingabedatei sind bis zu 300 Zeilen realistisch.
BoBo wrote:Das ist jetzt aber nicht die ganze geschichte. Warum überhaupt in eine INIdatei schreiben, wenn doch die csv schon einen datenpool bildet? Was ist denn der vorteil von mit mehr als 2 (angenommenen) INIdateien/-sektionen/-schlüsselpaaren herum zu hantieren??
Warum jede zweite zeile leer ist? Ich vermute mal es handelt sich um die ausgabedatei eines systems, welches mit einem `r als EOL character/zeilenendezeichen arbeitet.
die ursprüngliche .csv ist schreibgeschützt, deswegen kann ich sie nicht bearbeiten. Es gibt mehrere Stücklisten die man vergleichen muss. Eine Master-Stückliste und mehrere "unter-Stücklisten". wenn man alle unter-Stücklisten kumuliert sollte die Master-Stückliste vorkommen. Es kann aber auch sein, dass ein Artikel mehrmals in einer Liste vorkommt.

Deswegen war mein Fahrplan der folgende:
1. Schritt: jede Zeile aus der Master-Stückliste wird gelesen, und in die .ini-Datei geschrieben. Wenn schonmal eine Zeile mit dem selben Artikel vorgekommen ist, werden die beiden Mengen einfach addiert (deswegen immer das .ini-Read vor dem eigentlichen write).
2. Schritt: das selbe Rückwärts: es wird jede Zeile aus einer unter-stückliste gelesen und die Menge von der in der .ini Datei subtrahiert und wieder in die .ini geschrieben.
3. Wenn alle Unter-Stücklisten abgearbeitet sind sollte bei der .ini in jeder Zeile null stehen. Dann weiß man, dass die Stücklisten stimmen. Wenn nicht, kann man ausgeben bei welchen Artikeln es Probleme gab und diese Untersuchen.
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: IniWrite/Read mit Wert aus Variable als Key

16 Mar 2018, 01:40

Es gibt mehrere Stücklisten die man vergleichen muss. Eine Master-Stückliste und mehrere "unter-Stücklisten". wenn man alle unter-Stücklisten kumuliert sollte die Master-Stückliste vorkommen. Es kann aber auch sein, dass ein Artikel mehrmals in einer Liste vorkommt.
OK, so ...
Kannst Du ein Beispiel einer kompletten Eingabedatei hier einstellen?
... soll heißen, einen kompletten satz welchen du da wie beschrieben verprozessierst?!
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: IniWrite/Read mit Wert aus Variable als Key

16 Mar 2018, 04:14

Moin,

das ständig wiederholte Lesen und Schreiben einer INI-Datei kostet relativ viel Zeit und stresst Deine Festplatte. Wenn Du den kompletten Abgleich in einem Rutsch abarbeiten kannst, brauchst Du während der Abarbeitung auch keine externe Datei für die Zwischenergebnisse. Du kannst das schnell und zuverlässig mit einem assoziativen Array machen. Dein Code sähe dann z.B. so aus:

Code: Select all

#NoEnv

MasterListe := A_ScriptDir . "\Master.csv" ; hier den Dateipfad der Masterliste einfügen
MasterArray := [] ; ein neues leeres Array erstellen

Loop, Read, %MasterListe% ; lies den Inhalt der genannten Datei zeilenweise
{
	If A_Index < 67 ; ignoriere alle zeilen vor der 67ten, die dieser quasi nur den Kopf der "Liste" darstellen und für die Auswertung irrelevant sind
		Continue
	Feld := StrSplit(A_LoopReadLine,";", ",") ; zerlege die aktuele zeile. Übergabe der werte in den array "Feld". Kommas am Ende von einem "Feld" werden entfernt (kommt bei der Menge vor. Hier ist der Inhalt der Zelle nicht [c]5[/c] sondern [c]5,[/c]
	If !Feld[1]	; jede zweite Zeile ist leer. wenn das erste Feld leer ist, soll die Zeile übersprungen werden.
		Continue ; ... dann auf zur nächsten nächste zeile.
   If MasterArray.Haskey(Feld[6])       ; wenn der Key Feld[6] bereits im Array enthalten ist
      MasterArray[Feld[6]] += Feld[18]  ; ... Wert aus Feld[18] addieren
   Else                                 ; sonst
      MasterArray[Feld[6]] := Feld[18]  ; ... neuen Key mit dem Wert aus Feld[18] anlegen
}

; Test: Ergebnis erstellen, ausgeben und im Editor anzeigen
ErgebnisDatei := A_ScriptDir . "\Ergebnis.txt"
Ergebnis := ""
For ID, Menge In MasterArray ; für jedes Schlüssel-Wert-Paar im Array, den Schlüssel in ID und den Wert in Menge bereitstellen
   Ergebnis .= ID . "=" . Menge . "`n" ; ID und Menge in die Variable Ergebnis übernehmen
; Jetzt kommt ein Ersatz für FileDelete / FileAppend durch das File Object
If (DateiObjekt := FileOpen(Ergebnisdatei, "w")) { ; Ergebnisdatei zumm Schreiben öffnen, sie wird dabei ggfs. geleert
   DateiObjekt.Write(Ergebnis)                     ; ... Datei schreiben
   DateiObjekt.CLose()                             ; ... Datei schließen
   Run, Notepad.exe %ErgebnisDatei%                ; ... und für den Test im Editor anzeigen
}
Else
   MsgBox, 16, Fehler!, Die Ergebnisdatei konnte nicht erstellt werden!`nFehler: %A_LastError%
ExitApp
Nach Verarbeitung der Masterliste kannst Du dann die Teillisten gegen das MasterArray abarbeiten.

Eventuell hilfreich: 'Echte' Arrays - Grundlagen

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: Rohwedder and 33 guests