Ich verwende bei meiner Arbeit eine ASCII-Schnittstelle. Deren (sich ab und an ändernde) Definition habe ich in einer eigenen Konfigurationsdatei gespeichert.
Der Aufbau ähnelt einer INI, aber auch einer CSV. Ich habe hier die für mich wichtigen Funktionalitäten beider Typen zusammengeführt.
Eventuell auch für euch nützlich.
Aufbau der Konfigurationsdatei:
- Dateiendung - beliebig
- Die Gliederung in Sektionen ist zwingend. Sektionsnamen sind case sensitiv: [Section] <> [section]
- Jede Zeile enthält einen Eintrag
- Besteht der Eintrag aus mehreren Werten, sind diese ausschliesslich mit ";" zu trennen
- Enthält ein Wert ein ";", ist dieses zu maskieren: "\;"
- Kommentarzeilen beginnen mit "REM " - Großschreibung zwingend!
- Leerzeilen können beliebig eingefügt sein und werden ignoriert
Da in die Datei keine Werte zurückgeschrieben werden (jedenfalls für mich nicht relevant), habe ich mich vorerst auf eine Funktion zum Einlesen und Weiterverarbeiten (durch Übergabe einer Verarbeitungsfunktion) beschränkt.
AutoIt: Funktionsparameter:
$_File Dateipfad
$_Section Sektionsname
$_aReturn (ByRef) Variable zur Aufnahme des Ergebnisarrays
$_Ubound2 (optional) Wenn die Zeile in Einzelwerte gesplittet werden soll, deren Anzahl.
Der Wert darf kleiner sein, als die Anzahl der tatsächlich vorhandenen Splitwerte.
Zeilen mit weniger Einzelwerten werden jedoch ignoriert.
(Standard: 0 - Die gesamte Zeile als ein Array-Eintrag. Maskierte Trenner werden mit Maskierung angezeigt.
$_funcProgress (optional) Jede Zeile wird an diese Funktion zur Weiterverarbeitung übergeben. (Standard: Null)
Die Funktion darf nur einen Parameter besitzen: "Zeile" ( _MyFunc($line) )
Soll die Zeile ignoriert werden, muss die Funktion "" zurück geben.
Bei $_Ubound2 = 0 --> Die Funktion muss einen String zurück geben
Bei $_Ubound2 > 0 --> Die Funktion muss ein 1D-Array zurück geben, [0]..[$_Ubound2 -1], KEIN Zähler an [0]!
Beachten:
Wenn der Text maskierte Trenner enthält, muss die Funktion dieses beim Splitten berücksichtigen
Alles anzeigen
Im Anhang findet ihr ein Beispiel mit Konfigurationsdatei.
AutoIt: ConfigRead.au3
;-- TIME_STAMP 2022-07-14 10:16:45 v 0.1
; #FUNCTION# =======================================================================================
; Name ..........: _ConfigRead
; Description ...: Reading a configuration file, optionally filtered
; ...............: File rules: • Can have any file extension
; ...............: • Requires sections, spelling case sensitive: [Section] <> [section]
; ...............: • If the entries contain values that are to be split into
; ...............: individual fields, use only ";" as the separator.
; ...............: Separators in the text must be masked: "\;"
; ...............: • Comments start with "REM " at the beginning of the line
; ...............: • Blank lines may be included and will be ignored
; Parameter(s)...: $_File The file path
; ...............: $_Section The section name
; ...............: $_aReturn (ByRef) The variable to get the result array
; ....[optional].: $_Ubound2 If the lines are to be split into single values whose number is
; ...............: (Default: 0 - full line as one array item, masked separators are displayed with masking)
; ....[optional].: $_funcProgress Each line is passed to this function for evaluation. (Default: Null)
; ...............: Use only one parameter in your function: "line" ( _MyFunc($line) )
; ...............: Return "" from your function if the line should be ignored.
; ...............: If $_Ubound2 = 0 --> return a string.
; ...............: If $_Ubound2 > 0 --> return a 1D-array, [0]..[$_Ubound2 -1], NO counter at [0]!
; ...............: Note:
; ...............: If your text contains masked delimiters, your function must take this into account when splitting.
; Return values .: Success 1
; ...............: Failure 0 @error = 1 Section not exists or empty
; Author ........: BugFix
; ==================================================================================================
Func _ConfigRead($_File, $_Section, ByRef $_aReturn, $_Ubound2=0, $_funcProgress=Null)
Local $aSection[100], $n = 0
If $_Ubound2 > 0 Then ReDim $aSection[100][$_Ubound2]
Local $funcRet, $line, $aLine, $bInSection = False
Local $fh = FileOpen($_File)
Do
$line = FileReadLine($fh)
If Not @error Then
; check if the result array has to be enlarged
If $n > UBound($aSection) -1 Then
If $_Ubound2 > 0 Then
ReDim $aSection[UBound($aSection)+100][$_Ubound2]
Else
ReDim $aSection[UBound($aSection)+100]
EndIf
EndIf
; comment line --> skip
If StringRegExp($line, '^REM\s') Then ContinueLoop
; empty line --> skip
If $line = '' Then ContinueLoop
; while reading target section a new section starts --> stop reading
If $bInSection And StringRegExp($line, '^\[[^\]]+') Then
$bInSection = False
ExitLoop
EndIf
; target section starts
If StringRegExp($line, '^\[' & $_Section & '\]') Then
$bInSection = True
ContinueLoop
EndIf
; while reading target section
If $bInSection Then
If $_Ubound2 = 0 Then ; output: 1D-array (one line per item)
If $_funcProgress <> Null Then
$funcRet = $_funcProgress($line); call external funtion to evaluate the line
If $funcRet <> '' Then ; func returns empty string to skip the line
$aSection[$n] = $funcRet
$n += 1
EndIf
Else
$aSection[$n] = $line ; add each line to result array
$n += 1
EndIf
Else ; output: 2D-array, 2nd dimension according to $_Ubound2
If $_funcProgress <> Null Then
$funcRet = $_funcProgress($line); call external funtion to evaluate the line
If $funcRet <> '' Then ; func returns empty string to skip the line ...
If IsArray($funcRet) And UBound($funcRet) >= $_Ubound2 Then ; ... otherwise an array with ubound >= $_Ubound2 must be returned
For $i = 0 To $_Ubound2 -1
$aSection[$n][$i] = $funcRet[$i]
Next
$n += 1
EndIf
EndIf
Else
$aLine = StringRegExp($line, '(\\;[^;]+|[^;]+\\;[^;]+|[^;]+\\;|[^;]+)', 3) ; splits the line by ";", masked delimiters ("\;") are ignored
If UBound($aLine) >= $_Ubound2 Then ; line is ignored if the number of elements is less than $_Ubound2
For $i = 0 To $_Ubound2 -1
$aSection[$n][$i] = StringReplace($aLine[$i], '\;', ';')
Next
$n += 1
EndIf
EndIf
EndIf
EndIf
Else ; EOF reached
ExitLoop
EndIf
Until $line = -1
FileClose($fh)
If $n = 0 Then Return SetError(1,0,0)
If $_Ubound2 > 0 Then
ReDim $aSection[$n][$_Ubound2]
Else
ReDim $aSection[$n]
EndIf
$_aReturn = $aSection
Return 1
EndFunc
Alles anzeigen
AutoIt: Beispiel
;-- TIME_STAMP 2022-07-14 10:22:06
#include 'ConfigRead.au3'
#include <Array.au3>
Global $CFG = @ScriptDir & '\ASCII_Interface.txt'
Global $aRes
MsgBox(0, 'CFG Read', 'Lesen in 1D-Array' & @CRLF & 'Jede Zeile ein Eintrag')
_ConfigRead($CFG, 'Firmensatz', $aRes)
_ArrayDisplay($aRes, '1D-Array')
MsgBox(0, 'CFG Read', 'Lesen in 2D-Array' & @CRLF & '4 Spalten')
_ConfigRead($CFG, 'Kopfsatz', $aRes, 4)
_ArrayDisplay($aRes, '2D-Array')
MsgBox(0, 'CFG Read', 'Lesen in 2D-Array' & @CRLF & '4 Spalten mit Filterfunktion' & @CRLF & 'Nur nummerische Definitionen')
_ConfigRead($CFG, 'Positionssatz', $aRes, 4, _NumDef)
_ArrayDisplay($aRes, '2D-Array mit Filter: Nur nummerische Definitionen anzeigen')
Func _NumDef($_line)
If StringRegExp($_line, ';N\d+') Then
Return StringSplit($_line, ';', 2)
Else
Return ''
EndIf
EndFunc
Alles anzeigen