Da hast Du aber eine Spitze auf einen frischen Austrieb eines jüngst gefällten Tannenbaums gesteckt.
Definiere Weihnachtsbaum...
![]()
Da hast Du aber eine Spitze auf einen frischen Austrieb eines jüngst gefällten Tannenbaums gesteckt.
Definiere Weihnachtsbaum...
![]()
$iZeilen > 32
Es gibt keinen maximalen Zeilenparameter. Nur das Minimum existiert, ist m.M.n. aber 3:
Mein Beitrag:
_WriteXMasTree(8)
Func _WriteXMasTree($_nLines)
Local $sSpaces = '', $sX = '', $sOut = ''
For $i = 1 To $_nLines -1
$sSpaces &= ' '
$sX &= 'X'
Next
$sX &= $sX & 'X'
For $i = 0 To $_nLines -2
If ($i = 0 Or $i = 1) Then
$sOut &= StringLeft($sSpaces, $_nLines) & ($i = 0 ? '*' : 'X') & @CRLF
Else
$sOut &= StringLeft($sSpaces, $_nLines -$i) & StringLeft($sX, 2*($i-1)+1) & @CRLF
EndIf
Next
$sOut &= StringLeft($sSpaces, $_nLines -2) & '| |' & @CRLF
ConsoleWrite($sOut & @CRLF)
EndFunc
Alles anzeigen
Sicher das die Liste korrekt ist? Das sieht etwas durcheinander aus
SATCODX103Astra 1 (19.2E) TMPG20111120001Eurospor0192___ ______220002____________125020000101043_____________t 1 HD
SATCODX103Astra 1 (19.2E) TMPG20113030001ServusTV0192___ ______220002____________049140000101007_____________ HD Deutschl
SATCODX103Astra 1 (19.2E) TMPG20110530001tagessch0192___ ______220002____________103750000101039_____________au24 HD
SATCODX103Astra 1 (19.2E) TMPG20119730000Comedy C0192___ ______275003____________286520000101078_____________entral HD
SATCODX103Astra 1 (19.2E) TMPG20108030001Deluxe M0192___ ______220003____________055030000101055_____________usic HD
SATCODX103Astra 1 (19.2E) TMPG20119730000Nick/Com0192___ ______275003____________286800000101078_____________edy Central+
Vielleicht eher so?
SATCODX103Astra 1 (19.2E) TMPG20111120001___0192______220002____________125020000101043_____________Eurosport 1 HD
SATCODX103Astra 1 (19.2E) TMPG20113030001___0192______220002____________049140000101007_____________ServusTVHD Deutschl
SATCODX103Astra 1 (19.2E) TMPG20110530001___0192______220002____________103750000101039_____________tagesschau24 HD
SATCODX103Astra 1 (19.2E) TMPG20119730000___0192______275003____________286520000101078_____________Comedy Central HD
SATCODX103Astra 1 (19.2E) TMPG20108030001___0192______220003____________055030000101055_____________Deluxe Music HD
SATCODX103Astra 1 (19.2E) TMPG20119730000___0192______275003____________286800000101078_____________Nick/Comedy Central+
Alles anzeigen
Ich habe mal eine kleine Datenbank UDF erstellt auf Maps basierend. Ich würde mal sagen: Beta-Status, da ich noch nicht alles auf Herz und Nieren getestet habe.
Die Geschwindigkeit, Einlesen ~500kB CSV Datei (16700) in Datensätze in <1 s gefällt mir. Selbst meine recht rudimentäre Suchfunktion ist relativ flott.
Ich denke, ich werde das noch weiter ausbauen.
;-- TIME_STAMP 2022-12-12 18:37:27 v 0.1
#cs FUNCTIONS
About The database is a map. The map stores some administrative keys that are for
internal use only. The datasets are added as a map and the passed
(or automatically generated) ID is their key in the DB map.
_MapDB_New Creates a new database map. Pass the dataset field names as semicolon-separated string or array.
Stores the passed field names inside. Field names are case sensitive!
Returns the map. The number of datasets is indicated by: $myDBMap.Count
The user can add an array of additional database fields. When you remove all
datasets from the DB, you can keep their values or delete the values as well (default).
_MapDB_FromCSV Creates a map database from a passed csv file.
_MapDB_ToCSV Stores a map database as passed csv file.
_MapDB_Add Adds a new dataset. Each field must be assigned a value (empty string if necessary).
- A maximum of 10 single values can be passed as direct parameters.
- Values can also be passed as an array. The number is not limited here, it only
has to match the defined number of fields.
- Values can also be passed as an map. The field names must match the field
names in the database definition.
To make the record unique, an ID must be passed.
If an empty string is passed instead, a consecutive numeric ID is generated.
The return value of the function is the ID.
_MapDB_Modify Modifies one or more values of a dataset.
If data is passed as direct parameters, array or map, an empty string must be passed
for values that are not to be changed. Each field must be assigned a value.
The fourth and certainly most common variant is to pass an assignment string of
the form "field1=value<DELIM>field2=value<DELIM>...".
Opt('GUIDataSeparatorChar') is used as <DELIM>. A sequence or number of values
need not be considered here.
Note!
Field names must be passed in the same notation (case sensitive) as stored
in the database definition.
_MapDB_Remove Removes a dataset or, if an empty ID is passed, all datasets from the database.
Returns the number of deletions.
_MapDB_DSToString Returns field and values of an DS by passed ID as string: "[field1] = value; [field2] = value;... "
_MapDB_DSToArray Returns field and values of an DS by passed ID as 2D array: [[field1,value],[field2,value],...] "
Rudimentary search functions:
_MapDB_SearchAnd Searches with one or more conditions passed as a string like "field1=val<DELIM>field2=val<DELIM>...".
All conditions must match.
Returns a map with one or more datasets matching the conditions.
_MapDB_SearchOr Searches with one or more conditions passed as a string like "field1=val<DELIM>field2=val<DELIM>...".
At least one condition must match.
Returns a map with one or more datasets matching the conditions.
#ce
#include-once
#include <File.au3>
#include <FileConstants.au3>
Func _MapDB_New($_vKeyNames, $_aAdditionalDBKeys='')
Local $map[], $map2compare[]
Switch VarGetType($_vKeyNames)
Case 'String'
$_vKeyNames = StringSplit($_vKeyNames, ';', 2)
Case 'Array'
; nothing
Case Else
Return SetError(1,0,0)
EndSwitch
$map.__KEYNAMES_ARRAY__ = $_vKeyNames
For $i = 0 To UBound($_vKeyNames) -1
$map2compare[$_vKeyNames[$i]] = ''
Next
$map.__MAP_2_COMPARE__ = $map2compare
$map.__MAP_MAX_NUMKEY__ = -1
$map.Count = 0
$map.__ADDKEYS_ARRAY__ = $_aAdditionalDBKeys
If IsArray($_aAdditionalDBKeys) Then
For $i = 0 To UBound($_aAdditionalDBKeys) -1
$map[$_aAdditionalDBKeys[$i]] = ''
Next
EndIf
Return $map
EndFunc
Func _MapDB_FromCSV($_sPathCSV, $_sDelim=';')
Local $aCSV
_FileReadToArray($_sPathCSV, $aCSV, 0)
If @error Then Return SetError(@error,0,0)
If $_sDelim <> ';' Then $aCSV[0] = StringReplace($aCSV[0], $_sDelim, ';')
Local $map = _MapDB_New($aCSV[0]), $aLine
For $i = 1 To UBound($aCSV) -1
$aLine = StringSplit($aCSV[$i], $_sDelim, 2)
_MapDB_Add($map, '', $aLine)
Next
Return $map
EndFunc
Func _MapDB_ToCSV(ByRef $_mDB, $_sPathCSV, $_bOverwrite=False, $_sDelim=';')
If $_mDB.Count = 0 Then Return SetError(1,0,0)
If FileExists($_sPathCSV) And Not $_bOverwrite Then Return SetError(2,0,0)
Local $sHead = '', $sLine = '', $sLines = ''
Local $mDS, $sSkip = ' __ADDKEYS_ARRAY__ __KEYNAMES_ARRAY__ __MAP_2_COMPARE__ __MAP_MAX_NUMKEY__ Count '
Local $addKeys = $_mDB.__ADDKEYS_ARRAY__
If IsArray($addKeys) Then
For $i = 0 To UBound($addKeys) -1
$sSkip &= $addKeys[$i] & ' '
Next
EndIf
Local $aKeys = $_mDB.__KEYNAMES_ARRAY__
For $i = 0 To UBound($aKeys) -1 ; column names
$sHead &= $aKeys[$i] & $_sDelim
Next
$sHead = StringTrimRight($sHead, 1) & @CRLF
For $kDB In MapKeys($_mDB)
If StringInStr($sSkip, ' ' & $kDB & ' ') Then ContinueLoop ; reserved keys
$mDS = $_mDB[$kDB]
$sLine = ''
For $i = 0 To UBound($aKeys) -1
$sLine &= $mDS[$aKeys[$i]] & $_sDelim
Next
$sLines &= StringTrimRight($sLine, 1) & @CRLF
Next
Local $fH = FileOpen($_sPathCSV, BitOR($FO_OVERWRITE,$FO_CREATEPATH,$FO_UTF8_NOBOM))
FileWrite($fH, $sHead & $sLines)
FileClose($fH)
EndFunc
; Aufruf:
; 1. Daten als geordnete Variablen (max. 10), Reihenfolge wie Key-Liste ODER
; 2. Daten als Array in "$_v1", Reihenfolge wie Key-Liste ODER
; 3. Daten als Map in "$_v1", Keys müssen übereinstimmen mit DB
; Zur Erstellung eines DS ist eine eindeutige ID (String od. positiv Integer) notwendig. Bei Weglassung (Leerstring) wird eine nummerische ID automatisch generiert.
; Die ID ist der Returnwert der Funktion.
Func _MapDB_Add(ByRef $_mDB, $_ID='', $_v1='', $_2=Null, $_3=Null, $_4=Null, $_5=Null, $_6=Null, $_7=Null, $_8=Null, $_9=Null, $_10=Null)
If $_ID = '' Then
$_mDB.__MAP_MAX_NUMKEY__ += 1
$_ID = $_mDB.__MAP_MAX_NUMKEY__
Else
If MapExists($_mDB, $_ID) Then
Return SetError(1,0,0)
Else
If IsInt($_ID) Then
If $_mDB.__MAP_MAX_NUMKEY__ < $_ID Then $_mDB.__MAP_MAX_NUMKEY__ = $_ID
EndIf
EndIf
EndIf
Switch VarGetType($_v1)
Case 'Array'
Local $aVal[UBound($_mDB.__KEYNAMES_ARRAY__)]
If UBound($_v1) <> UBound($aVal) Then Return SetError(4,0,0)
For $i = 0 To UBound($aVal) -1
$aVal[$i] = $_v1[$i]
Next
$_mDB.Count += 1
Return __MapDB_AddDSArray($_mDB, $_ID, $aVal)
Case 'Map'
Local $resComp = __MapCompareKeys($_v1, $_mDB.__MAP_2_COMPARE__)
If @error Then
Return SetError(@error,0,$resComp) ; @error: 2=Key-Count, 3=Key-Names
Else
$_mDB[$_ID] = $_v1
$_mDB.Count += 1
Return $_ID
EndIf
Case 'String'
Local $aParam[] = [$_v1,$_2,$_3,$_4,$_5,$_6,$_7,$_8,$_9,$_10], $n = 0
For $i = 0 To UBound($aParam) -1
$n += 1
If $aParam[$i] = Null Then
$n -= 1
ExitLoop
EndIf
Next
ReDim $aParam[$n]
If $n <> UBound($_mDB.__KEYNAMES_ARRAY__) Then
Return SetError(4,0,0)
Else
$_mDB.Count += 1
Return __MapDB_AddDSArray($_mDB, $_ID, $aParam)
EndIf
EndSwitch
EndFunc
; Aufruf:
; 1. Daten als geordnete Variablen (max. 10), Felder, die nicht verändert werden sollen, werden als Leerstring übergeben ODER
; 2. Daten als Array in "$_v1", Reihenfolge und Belegung, wie vorab ODER
; 3. Daten als Map in "$_v1", hier eigentlich nur sinnvoll, wenn alle Inhalte geändert werden sollen ODER
; 4. "$_v1" enthält Zuweisungsstring der Form: "field-1=val<DELIM>field-2=val<DELIM>....". <DELIM> = Opt('GUIDataSeparatorChar')
Func _MapDB_Modify(ByRef $_mDB, $_ID, $_v1='', $_2=Null, $_3=Null, $_4=Null, $_5=Null, $_6=Null, $_7=Null, $_8=Null, $_9=Null, $_10=Null)
If Not MapExists($_mDB, $_ID) Then Return SetError(1,0,0)
Switch VarGetType($_v1)
Case 'Array'
Local $aVal[UBound($_mDB.__KEYNAMES_ARRAY__)]
If UBound($_v1) <> UBound($aVal) Then Return SetError(1,0,0)
For $i = 0 To UBound($aVal) -1
$aVal[$i] = $_v1[$i]
Next
Return __MapDB_ModifyByArray($_mDB, $_ID, $aVal)
Case 'Map'
Local $resComp = __MapCompareKeys($_v1, $_mDB.__MAP_2_COMPARE__)
If @error Then
Local $aErr[] = [$resComp]
Return SetError(@error,0,$aErr) ; @error: 2=Key-Count, 3=Key-Names
Else
For $k In MapKeys($_v1)
If $_v1[$k] <> '' Then $_mDB[$_ID][$k] = $_v1[$k]
Next
Return $_ID
EndIf
Case 'String'
Local $mKeyNames = $_mDB.__MAP_2_COMPARE__, $sKeyErr = ''
Local $sDelim = Opt('GUIDataSeparatorChar')
Local $aFieldVal = StringSplit($_v1, $sDelim, 1), $aAssignment
If Not @error Then
For $i = 1 To $aFieldVal[0]
$aAssignment = StringSplit($aFieldVal[$i], '=', 2)
If MapExists($mKeyNames, $aAssignment[0]) Then
$_mDB[$_ID][$aAssignment[0]] = $aAssignment[1]
Else
$sKeyErr &= $aAssignment[0] & ';'
EndIf
Next
If $sKeyErr <> '' Then
Local $aKeyErr = StringSplit(StringTrimRight($sKeyErr, 1), ';', 2)
Return SetError(3,UBound($aKeyErr),$aKeyErr)
EndIf
Else
Local $aParam[] = [$_v1,$_2,$_3,$_4,$_5,$_6,$_7,$_8,$_9,$_10], $n = 0
For $i = 0 To UBound($aParam) -1
$n += 1
If $aParam[$i] = Null Then
$n -= 1
ExitLoop
EndIf
Next
ReDim $aParam[$n]
If $n <> UBound($_mDB.__KEYNAMES_ARRAY__) Then
Return SetError(1,0,0)
Else
Return __MapDB_ModifyByArray($_mDB, $_ID, $aParam)
EndIf
EndIf
EndSwitch
EndFunc
; $_ID='' removes all datasets
; $_bClearAddkeyValues=False leaves the additional keys untouched
; returns number of removed datasets
Func _MapDB_Remove(ByRef $_mDB, $_ID='', $_bClearAddkeyValues=True)
Local $nDeleted = 0, $aAddKeys
If $_ID = '' Then
$nDeleted = $_mDB.Count
If Not $_bClearAddkeyValues Then
$aAddKeys = $_mDB.__ADDKEYS_ARRAY__
Local $aAddVal[UBound($aAddKeys)]
For $i = 0 To UBound($aAddKeys) -1
$aAddVal[$i] = $_mDB[$aAddKeys[$i]]
Next
EndIf
$_mDB = _MapDB_New($_mDB.__KEYNAMES_ARRAY__)
; restore AddValues
If Not $_bClearAddkeyValues Then
For $i = 0 To UBound($aAddKeys) -1
$_mDB[$aAddKeys[$i]] = $aAddVal[$i]
Next
EndIf
Else
If MapExists($_mDB, $_ID) Then
MapRemove($_mDB, $_ID)
$_mDB.Count -= 1
$nDeleted = 1
EndIf
EndIf
Return SetError(($nDeleted = 0 ? 1 : 0),0,$nDeleted)
EndFunc
Func _MapDB_SearchAnd(ByRef $_mDB, $_sConditions)
Return __MapDB_Search($_mDB, $_sConditions, 'and')
EndFunc
Func _MapDB_SearchOr(ByRef $_mDB, $_sConditions)
Return __MapDB_Search($_mDB, $_sConditions, 'or')
EndFunc
Func __MapDB_Search(ByRef $_mDB, $_sConditions, $_mode='and')
Local $mKeyNames = $_mDB.__MAP_2_COMPARE__, $sKeyErr = ''
Local $sDelim = Opt('GUIDataSeparatorChar')
Local $aFieldVal = StringSplit($_sConditions, $sDelim, 1), $aComparison
; check field names
For $i = 1 To $aFieldVal[0]
$aComparison = StringSplit($aFieldVal[$i], '=', 2)
If Not MapExists($mKeyNames, $aComparison[0]) Then Return SetError(1,0,0)
Next
; comparison
Local $mDS, $sSkip = ' __ADDKEYS_ARRAY__ __KEYNAMES_ARRAY__ __MAP_2_COMPARE__ __MAP_MAX_NUMKEY__ Count '
Local $addKeys = $_mDB.__ADDKEYS_ARRAY__
If IsArray($addKeys) Then
For $i = 0 To UBound($addKeys) -1
$sSkip &= $addKeys[$i] & ' '
Next
EndIf
Local $mResults[], $iRes
For $key In MapKeys($_mDB)
If StringInStr($sSkip, ' ' & $key & ' ') Then ContinueLoop ; reserved keys
$mDS = $_mDB[$key]
$iRes = 0
For $i = 1 To $aFieldVal[0]
$aComparison = StringSplit($aFieldVal[$i], '=', 2)
If $mDS[$aComparison[0]] = $aComparison[1] Then $iRes += 1
If $_mode = 'or' And $iRes > 0 Then ; at least one comparison successful
$mResults[$key] = $mDS
ExitLoop
EndIf
Next
If $_mode = 'and' And $iRes = $aFieldVal[0] Then ; each comparison successful
$mResults[$key] = $mDS
EndIf
Next
Return $mResults
EndFunc
; one DS as string
Func _MapDB_DSToString(ByRef $_mDB, $_ID)
If Not MapExists($_mDB, $_ID) Then Return SetError(1,0,0)
Local $mDS = $_mDB[$_ID]
$sDS = ''
For $kDS In MapKeys($mDS)
$sDS &= StringFormat('[%s] = %s; ', $kDS, $mDS[$kDS])
Next
Return StringTrimRight($sDS, 2)
EndFunc
; one DS as 2D array
Func _MapDB_DSToArray(ByRef $_mDB, $_ID)
If Not MapExists($_mDB, $_ID) Then Return SetError(1,0,0)
Local $mDS = $_mDB[$_ID], $n = 0
Local $aKeys = MapKeys($mDS)
Local $aResult[UBound($aKeys)][2]
For $kDS In $aKeys
$aResult[$n][0] = $kDS
$aResult[$n][1] = $mDS[$kDS]
$n += 1
Next
Return $aResult
EndFunc
; all DS as 2D array
Func _MapDB_ToArray(ByRef $_mDB)
Local $sSkip = '', $aResult[1], $aKeysM, $aKeys[1], $iR = 1, $iCount, $mDS
If MapExists($_mDB, 'Count') And MapExists($_mDB, '__KEYNAMES_ARRAY__') And MapExists($_mDB, '__ADDKEYS_ARRAY__') Then
$sSkip = ' __ADDKEYS_ARRAY__ __KEYNAMES_ARRAY__ __MAP_2_COMPARE__ __MAP_MAX_NUMKEY__ Count '
Local $addKeys = $_mDB.__ADDKEYS_ARRAY__
If IsArray($addKeys) Then
For $i = 0 To UBound($addKeys) -1
$sSkip &= $addKeys[$i] & ' '
Next
EndIf
$aKeys = $_mDB.__KEYNAMES_ARRAY__
ReDim $aResult[$_mDB.Count+1][UBound($aKeys)]
Else
$aKeysM = MapKeys($_mDB)
$iCount = UBound($aKeysM)
$mDS1 = $_mDB[$aKeysM[0]]
$aKeys = MapKeys($mDS1)
ReDim $aResult[$iCount+1][UBound($aKeys)]
EndIf
For $i = 0 To UBound($aKeys) -1 ; column names
$aResult[0][$i] = $aKeys[$i]
Next
For $kDB In MapKeys($_mDB)
If StringInStr($sSkip, ' ' & $kDB & ' ') Then ContinueLoop ; reserved keys
$mDS = $_mDB[$kDB]
For $i = 0 To UBound($aKeys) -1
$aResult[$iR][$i] = $mDS[$aKeys[$i]]
Next
$iR += 1
Next
Return $aResult
EndFunc
#Region - Internal only
; adds new data set by a passed array
Func __MapDB_AddDSArray(ByRef $_mDB, $_ID, $_array)
Local $map[]
Local $aKeyNames = $_mDB.__KEYNAMES_ARRAY__
For $i = 0 To UBound($_array) -1
$map[$aKeyNames[$i]] = $_array[$i]
Next
$_mDB[$_ID] = $map
Return $_ID
EndFunc
; modifies a data set by a passed array
Func __MapDB_ModifyByArray(ByRef $_mDB, $_ID, $_aVal)
Local $aKeyNames = $_mDB.__KEYNAMES_ARRAY__
For $i = 0 To UBound($aKeyNames) - 1
If $_aVal[$i] <> '' Then $_mDB[$_ID][$aKeyNames[$i]] = $_aVal[$i]
Next
Return $_ID
EndFunc
; compares a test map with a comparison map regarding 1. the number of keys and 2. the names of the keys
; - different numbers: @error = 2, returns: [count map_test, count map_comparison]
; - different names: @error = 3, returns: number of differences
Func __MapCompareKeys(ByRef $_test_map, ByRef $_comparison_map)
; 1. Comparison Key-Count
Local $aCount[] = [__MapCountKeys($_test_map),__MapCountKeys($_comparison_map)]
If $aCount[0] <> $aCount[1] Then Return SetError(2,0,$aCount)
; 2. Comparison Key-Names
Local $countDiff = 0
For $k In MapKeys($_test_map)
If Not MapExists($_comparison_map, $k) Then $countDiff += 1
Next
Return SetError(($countDiff = 0 ? 0 : 3),0,$countDiff)
EndFunc
; counts the keys of a map
Func __MapCountKeys(ByRef $_map)
Local $count = 0
For $k In MapKeys($_map)
$count += 1
Next
Return $count
EndFunc
#EndRegion
Alles anzeigen
EDIT:
Kein Fehler, aber wenig sinnvoll - keine Ahnung warum ich die interne Funktion __MapCountKeys so kompliziert gestaltet habe.
Hier die korrigierte Version:
Mann kann natürlich stattdessen direkt die Ubound-Funktion nutzen. Manchmal finde ich es aber sinnvoll, wenn ich beim späteren Lesen anhand des Funktionsnamens sofort die Absicht dahinter erkenne.
;-- TIME_STAMP 2022-12-12 18:36:50
#include 'MapDataBase.au3'
#include <Array.au3>
_SimpleDB()
; verwendet diese CSV:
; https://freetestdata.com/wp-content/uploads/2021/09/Free_Test_Data_500KB_CSV-1.csv <-- nicht normgerecht, verwendet "," | ab Zeile #10672 nur noch ",,,," - Löschen.
_CSV_Map()
Func _SimpleDB()
Local $aFields[] = ['Name','VName','PLZ','Ort','Strasse','Nr']
Local $MyMapDB = _MapDB_New($aFields)
; alternativ
; Local $MyMapDB = _MapDB_New('Name;VName;PLZ;Ort;Strasse;Nr')
Local $ID
; DS erfassen - automatische ID Generierung
; Übergabe als Einzelparameter (max. 10)
$ID = _MapDB_Add($MyMapDB, '', 'Müller', 'Hans', '12345', 'Irgendwo-Bei-Berlin', 'Hauptsr.', 15)
ConsoleWrite("@@_Debug_line" & @TAB & @TAB & @ScriptLineNumber & " var: $ID --> " & $ID & @LF)
; Übergabe als Array (kein Limit)
Local $aVal[] = ['Lehmann','Hanna','06789','Halle','Hochstr.',123]
$ID = _MapDB_Add($MyMapDB, '', $aVal)
ConsoleWrite("@@_Debug_line" & @TAB & @TAB & @ScriptLineNumber & " var: $ID --> " & $ID & @LF)
; Übergabe als Map
Local $mVal[], $sVal = 'Chan,Jackie,CHN 022 300000,Tianjin,Gu Wenhua Ji,45', $aVal = StringSplit($sVal, ',',2)
For $i = 0 To UBound($aFields) -1
$mVal[$aFields[$i]] = $aVal[$i]
Next
$ID = _MapDB_Add($MyMapDB, '', $mVal)
ConsoleWrite("@@_Debug_line" & @TAB & @TAB & @ScriptLineNumber & " var: $ID --> " & $ID & @LF)
; Erfassung mit Übergabe ID
$ID = _MapDB_Add($MyMapDB, 25, 'Köhler', 'Jenny', '88221', 'XMashausen', 'Fichtenweg', 23)
ConsoleWrite("@@_Debug_line" & @TAB & @TAB & @ScriptLineNumber & " var: $ID --> " & $ID & @LF)
_ArrayDisplay(_MapDB_ToArray($MyMapDB), 'Alle Datensätze')
; DS modifizieren
; Übergabe als Einzelparameter (max. 10), Felder, die nicht verändert werden sollen, werden als Leerstring übergeben
_ArrayDisplay(_MapDB_DSToArray($MyMapDB, 0), 'Vor Änderung')
_MapDB_Modify($MyMapDB, 0, '', '', '12346', 'Irgendwoanders-Bei-Berlin', 'Neue Str.', 88)
_ArrayDisplay(_MapDB_DSToArray($MyMapDB, 0), 'Nach Änderung')
; Übergabe als Array
Local $aVal[] = ['Lehmann-Rosenringk','','','','','']
_ArrayDisplay(_MapDB_DSToArray($MyMapDB, 1), 'Vor Änderung')
_MapDB_Modify($MyMapDB, 1, $aVal)
_ArrayDisplay(_MapDB_DSToArray($MyMapDB, 1), 'Nach Änderung')
; Übergabe als Map
Local $mVal[], $sVal = ',,,,,333', $aVal = StringSplit($sVal, ',',2)
For $i = 0 To UBound($aFields) -1
$mVal[$aFields[$i]] = $aVal[$i]
Next
_ArrayDisplay(_MapDB_DSToArray($MyMapDB, 2), 'Vor Änderung')
_MapDB_Modify($MyMapDB, 2, $mVal)
_ArrayDisplay(_MapDB_DSToArray($MyMapDB, 2), 'Nach Änderung')
; Übergabe Zuweisungsstring (sicherlich häufigste Verwendung)
_ArrayDisplay(_MapDB_DSToArray($MyMapDB, 25), 'Vor Änderung')
_MapDB_Modify($MyMapDB, 25, 'Strasse=Waldweg|Nr=75 B')
_ArrayDisplay(_MapDB_DSToArray($MyMapDB, 25), 'Nach Änderung')
MsgBox(0, 'Anzahl DS', $MyMapDB.Count)
; als CSV speichern
_MapDB_ToCSV($MyMapDB, @ScriptDir & '\test_db.csv')
; Ausgabe CSV in Console
ConsoleWrite(FileRead(@ScriptDir & '\test_db.csv') & @CRLF)
EndFunc
Func _CSV_Map()
Local $CSV = @ScriptDir & "\Free_Test_Data_500KB_CSV-1.csv"
Local $Timer = TimerInit()
Local $MyMapDB = _MapDB_FromCSV($CSV, ',')
MsgBox(0, 'Import CSV', 'Einlesedauer: ' & (TimerDiff($Timer) / 1000) & ' s' & @CRLF & 'Anzahl Datensätze: ' & $MyMapDB.Count)
_ArrayDisplay(_MapDB_ToArray($MyMapDB), 'Alle Datensätze')
Local $mMatch = _MapDB_SearchAnd($MyMapDB, "NAME=Tommye|GENDER=Female|AGE=56|DATE=16/08/2025")
MsgBox(0, 'Matches', 'Die Suche ergab' & @CRLF & __MapCountKeys($mMatch) & ' Treffer.')
_ArrayDisplay(_MapDB_ToArray($mMatch), 'Datensätze der Suche')
_ArrayDisplay(_MapDB_DSToArray($MyMapDB, 2785), 'Einzelner DS als Array')
MsgBox(0, 'Einzelner Datensatz als String', _MapDB_DSToString($MyMapDB, 2790))
EndFunc
Alles anzeigen
Kommentare sind erwünscht. ![]()
In der MsgBox wird die korrekte Seriennummer angezeigt, aber beim erstellen des Directories wird das Verzeichnis
aus dem String mit der Seriennummer nicht erstellt, wohl aber das myAFTVs Verzeichnis!?
Kannst du denn händisch einen Ordner mit der SerNum als Bezeichnung erstellen? Sind evtl. unzulässige Zeichen enthalten? Wie sieht denn so eine SerNum aus?
EDIT:
StdOutRead enthält garantiert mindestens einen Zeilenumbruch - musst du vorher bereinigen.
Stelle mal die Energieeinstellungen von der VM auf "Höchstleistung"...vielleicht hilft es das hier nicht ewas "zu müde" wird....
Virtual Box bietet keine Energieeinstellungen. Ich kann nur auswählen, wie viel RAM und Grafikspeicher ich für die VM freigebe und wie viel Kerne (wenn mehrere).
Ich habe jetzt mal in die OS-Energieoptionen geschaut. Zu dem Verhalten würde nur die Einstellung für Batteriebetrieb passen (lag bei 5 min). Habe auch diesen Teil jetzt auf niemals gesetzt und werde das beobachten.
Hab gerade herausfinden müssen: Wenn man negative Doubles als Key verwenden will (z.B. $map[-1.234] = 5) schmiert AutoIt nach ab
Wenn man einen negativen Integer nutzt gibts die übliche "Variable subscript badly formatted" Meldung, bei negativem Double rechnet er erst eine halbe Sekunde und crasht dann.
Da hatte ich gar nicht dran gedacht (negative Key). Also Änderung:
Resultat: Es gibt genau 2 Datentypen als Key - String und positive Int64.
Letztlich bestimme ich ja beim Erstellen des Skriptes, wie der Key eingesetzt wird. Bleibt die Überlegung, ob es erforderlich ist eine Key-Prüfung vorzuschalten. Aber kann eigentlich die Situation eintreten, dass ich keinen Einfluss auf den Key habe? Wohl nicht, und sollte der Key aus irgendeiner Userinteraktion entstehen, bleibt mir programmiertechnisch ja in diesem speziellen Fall sowieso die Pflicht zur Fehlerprüfung.
Also ist alles gut, wie es ist.
Ich weiß, welche Keys erlaubt sind und wenn ich das ignoriere, fliegt's mir halt um die Ohren.
Wer wider besseren Wissens seine Suppe mit der Gabel essen will, braucht sich ja auch nicht wundern, dass er nicht satt wird. ![]()
Welche Office Version nutzt Du für die WaWi?
Die WaWi kann nur mit Office 2000 (mit den Versionstypen bin ich nicht so vertraut) oder davor kommunizieren, also Dateitypen ohne "x" am Ende.
Das Problem ist hier, dass Windows 10 schon bei der Installation dieses Office recht zickig war. Daher vermute ich, dass die DDE Probleme daher rühren.
Ich hänge es mal hier mit dran, auch wenn es nicht die direkte Fragestellung betrifft:
Maps lassen sich auch prima verschachteln
Func _MapNew()
Local $map[]
Return $map
EndFunc
Global $mMap = _MapNew()
$mMap["eins"] = "Val-1"
$mMap["zwei"] = _MapNew()
$mMap["zwei"]["insideMap-1"] = "Val-In-1"
$mMap["zwei"]["insideMap-2"] = "Val-In-2"
$mMap["zwei"]["insideMap-3"] = _MapNew()
$mMap["zwei"]["insideMap-3"]["insideMap-3-1"] = "Val-In-3-1"
$mMap["zwei"]["insideMap-3"]["insideMap-3-2"] = "Val-In-3-2"
ConsoleWrite('KEY ["eins"]: ' & $mMap["eins"] & @CRLF)
ConsoleWrite('KEY ["zwei"]: Type-' & VarGetType($mMap["zwei"]) & @CRLF)
ConsoleWrite('KEY ["zwei"]["insideMap-1"]: ' & $mMap["zwei"]["insideMap-1"] & @CRLF)
ConsoleWrite('KEY ["zwei"]["insideMap-2"]: ' & $mMap["zwei"]["insideMap-2"] & @CRLF)
ConsoleWrite('KEY ["zwei"]["insideMap-3"]: Type-' & VarGetType($mMap["zwei"]["insideMap-3"]) & @CRLF)
ConsoleWrite('KEY ["zwei"]["insideMap-3"]["insideMap-3-1"]: ' & $mMap["zwei"]["insideMap-3"]["insideMap-3-1"] & @CRLF)
ConsoleWrite('KEY ["zwei"]["insideMap-3"]["insideMap-3-2"]: ' & $mMap["zwei"]["insideMap-3"]["insideMap-3-2"] & @CRLF)
Alles anzeigen
Ausgabe
Floats werden offenbar auf den Integerteil zusammengekürzt, die anderen Datentypen werden als Key 0 abgebildet.
Ja. Ich hätte eigentlich nur von Anfang an das Skript so ausführen müssen:
Global $gmMap[]
$gmMap['mein Key#1'] = 'mein Wert #1'
$gmMap['mein Key#2'] = 'mein Wert #2'
MapAppend($gmMap, 'mein Wert #3')
MapAppend($gmMap, 'mein Wert #4')
; WELCHE DATEN KÖNNEN SCHLÜSSEL SEIN?
Func _KeyAssignCheck($_vKey, $_vValue)
Local $sType = VarGetType($_vKey), $sResult = 'SUCCESS'
If Not MapExists($gmMap, $_vKey) Then
$gmMap[$_vKey] = $_vValue
If $gmMap[$_vKey] <> $_vValue Then $sResult = 'FAILURE'
Else
$sResult = 'THE KEY ALREADY EXISTS. [' & $_vKey & ']'
EndIf
Return StringFormat('[%-20s - %s', $sType & ']', $sResult)
EndFunc
ConsoleWrite(_KeyAssignCheck(123, '$i') & @CRLF)
ConsoleWrite(_KeyAssignCheck('abcd', '$s') & @CRLF)
ConsoleWrite(_KeyAssignCheck(Binary('abc'), '$bin') & @CRLF)
ConsoleWrite(_KeyAssignCheck(DllStructGetPtr(DllStructCreate('byte[4]')), '$ptr') & @CRLF)
For $key In MapKeys($gmMap)
ConsoleWrite(StringFormat('KEY: %-10s, KEY-TYPE: [%-8s, VALUE: %s', $key, VarGetType($key) & ']', $gmMap[$key]) & @CRLF)
Next
Alles anzeigen
Ausgabe
[Int32] - SUCCESS
[String] - SUCCESS
[Binary] - SUCCESS
[Ptr] - SUCCESS
KEY: mein Key#1, KEY-TYPE: [String] , VALUE: mein Wert #1
KEY: mein Key#2, KEY-TYPE: [String] , VALUE: mein Wert #2
KEY: 0 , KEY-TYPE: [Int64] , VALUE: mein Wert #3
KEY: 1 , KEY-TYPE: [Int64] , VALUE: mein Wert #4
KEY: 123 , KEY-TYPE: [Int64] , VALUE: $i
KEY: abcd , KEY-TYPE: [String] , VALUE: $s
KEY: 6513249 , KEY-TYPE: [Int64] , VALUE: $bin
KEY: 10607096 , KEY-TYPE: [Int64] , VALUE: $ptr
Alles anzeigen
Resultat: Es gibt genau 2 Datentypen als Key - String und Int64.
Problem im Griff? Ich gehe mal davon aus dass die WaWi auch unter XP läuft.
Das Problem hatte ich ja bereits mit Erteilung der Adminrechte gelöst. Mir war eben nur schleierhaft, warum Win 10 auf identischen Maschinen so unterschiedlich reagiert. Sei es drum, es läuft (einigermaßen).
Inzwischen habe ich ein anderes Problem: Die WaWi verlangt als Schreibprogramm Word und für Datenexport Excel. Läuft beides über die DDE-Schnittstelle und manchmal (zuletzt immer häufiger) wird diese von Win 10 nicht gefunden. Natürlich passiert das erst, wenn das Word-Dokument fertig erstellt wurde und nun gespeichert und indexiert werden sollte. Da hilft dann nur: WaWi neu starten und Dokument nochmals erstellen.
Die WaWi läuft unter XP, aber auch problemlos (zumindest auf Userseite) auf Win 7.
VM nutze ich bisher mit Oracle Virtual Box. Da habe ich eine Kopie unseres Systems laufen und teste z.B. neue SQL-Abfragen oder erstell Reports. Was mich daran etwas stört ist, dass das Teil irgendwie "ruhebedürftig" ist und jede Möglichkeit zum Pause machen nutzt.
- Konkret: Öffne ich die WaWi, die in der VM installiert ist, und bin einige Minuten inaktiv, dann geht meine SQL-Datenbank auch schlafen. Bei einer neuen Datenaktivität muss sie erst "aufwachen" - und das dauert so 2 - 3 Minuten. Kann natürlich sein, dass dieses Verhalten auf den SQL-Server Dienst beschränkt ist. Da ich aber nichts anderes in der VM mache, kann ich das nicht beurteilen. Vielleicht gibt es da auch irgendwelche Einstelloptionen, die ich noch nicht gefunden habe. Solch ein Verhalten könnte ich natürlich im Produktivbetrieb nicht gebrauchen.
Glaube mir ich spreche aus Erfahrung:
Du musst mindestens 40 % mehr dazu lernen.
Denn durch das alter vergisst du wieder 60 % und es wird immer mehr
Hmm, kann ich eigentlich nicht bestätigen. Als Post-Sixty habe ich eher den Eindruck, dass das Lernen mit jedem neuen Lebensjahr leichter fällt. Die richtigen Lerntechniken hat man in den vergangenen Jahrzehnten immer weiter verfeinert und da die Basis immer größer wird, sind es immer nur recht wenige wirklich neue Lerninhalte.
OK, das Erinnerungsvermögen nimmt manchmal unerwartet eine kleine Auszeit - aber nicht wirklich dramatisch. ![]()
Ich habe mir mal ein kleines Bsp.-Skript für Maps erstellt. Im letzten Schritt wollte ich testen, welche Datentypen sich als Schlüssel verwenden lassen.
Lasst es einfach mal durchlaufen und im zweiten Schritt aktiviert die MapExist-Prüfung in der Funktion _KeyAssignCheck (Kommentare freigeben).
Ohne Prüfung wird alles als erfolgreich angegeben, mit Prüfung werden einige Datentypen aber als existierende Schlüssel betrachtet, ich hätte eigentlich erwartet, dass Objekte oder Strukturen beim Hinzufügen als Key einen Fehler auswerfen.
Dass Bool und Keyword mit den AutoItersetzungen (Bool=0/1; Keyword=0) interpretiert werden und somit als Integer-Key Verwendung finden war erwartbar. Aber was für Werte sind dann Strukturen, Arrays oder Objekte? Eine Art UNKNOWN_KEY, der dann für alle gleichermaßen Verwendung findet?
Ist sicher etwas abstrakt - aber es interessiert mich halt, was machbar ist. ![]()
;-- TIME_STAMP 2022-12-01 11:36:41
; DEKLARATION
; wie ein Array nur ohne Elementzahl und ohne Wertzuweisung
Global $gmMap[]
; WERTE HINZUFÜGEN
; 1. mit benanntem Schlüssel
$gmMap['mein Key#1'] = 'mein Wert #1'
$gmMap['mein Key#2'] = 'mein Wert #2'
; 2. mit Funktion
; Schlüssel ist der nächste freie Integerwert bei '0' beginnend, wird von der Funktion zurückgegeben
Global $keyReturn = MapAppend($gmMap, 'mein Wert #3')
$keyReturn = MapAppend($gmMap, 'mein Wert #4')
; AUSGABE INHALT
; 1. für einen benannten Schlüssel
ConsoleWrite(StringFormat('KEY: %-10s, VALUE: %s', $keyReturn, $gmMap[$keyReturn]) & @CRLF & @CRLF)
; 2. für alle Schlüssel mit Iteratorfunktion
For $key In MapKeys($gmMap)
ConsoleWrite(StringFormat('KEY: %-10s, VALUE: %s', $key, $gmMap[$key]) & @CRLF)
Next
ConsoleWrite(@CRLF)
; PRÜFEN OB KEY EXISTIERT
ConsoleWrite('MapExists "mein Key#2": ' & (MapExists($gmMap, 'mein Key#2') = 1) & @CRLF & @CRLF)
; INHALT EINES SCHLÜSSELS LÖSCHEN - ABER NICHT DEN SCHLÜSSEL
$gmMap['mein Key#2'] = Null ; ein Map-Schlüssel ist leer, wenn der Wert "Null" ist
ConsoleWrite(StringFormat('"mein Key#2" existiert: %s, VALUE: %s', (MapExists($gmMap, 'mein Key#2') = 1), ($gmMap['mein Key#2'] = Null ? 'Null' : '')) & @CRLF & @CRLF)
; SCHLÜSSEL LÖSCHEN
MapRemove($gmMap, 'mein Key#2')
ConsoleWrite(StringFormat('"mein Key#2" existiert: %s', (MapExists($gmMap, 'mein Key#2') = 1)) & @CRLF & @CRLF)
; WELCHE DATEN KÖNNEN SCHLÜSSEL SEIN?
Func _KeyAssignCheck($_vKey, $_vValue)
Local $sType = VarGetType($_vKey), $sResult = 'SUCCESS'
;~ If Not MapExists($gmMap, $_vKey) Then
$gmMap[$_vKey] = $_vValue
If $gmMap[$_vKey] <> $_vValue Then $sResult = 'FAILURE'
;~ Else
;~ $sResult = 'THE KEY ALREADY EXISTS. [' & $_vKey & ']'
;~ EndIf
Return StringFormat('[%-20s - %s', $sType & ']', $sResult)
EndFunc
ConsoleWrite(_KeyAssignCheck(12345, '$i') & @CRLF)
ConsoleWrite(_KeyAssignCheck('abcd', '$s') & @CRLF)
ConsoleWrite(_KeyAssignCheck(123.456, '$f') & @CRLF)
ConsoleWrite(_KeyAssignCheck(Binary('abc'), '$bin') & @CRLF)
ConsoleWrite(_KeyAssignCheck(DllStructCreate('byte[4]'), '$t') & @CRLF)
ConsoleWrite(_KeyAssignCheck(DllStructGetPtr(DllStructCreate('byte[4]')), '$ptr') & @CRLF)
Global $ar[2] = [22,33]
ConsoleWrite(_KeyAssignCheck($ar, '$ar') & @CRLF)
ConsoleWrite(_KeyAssignCheck(True, '$b') & @CRLF)
ConsoleWrite(_KeyAssignCheck(ObjCreate('Scripting.Dictionary'), '$o') & @CRLF)
ConsoleWrite(_KeyAssignCheck(Default, '$keyWord') & @CRLF)
Alles anzeigen
Prüfergebnis ohne MapExists
[Int32] - SUCCESS
[String] - SUCCESS
[Double] - SUCCESS
[Binary] - SUCCESS
[DLLStruct] - SUCCESS
[Ptr] - SUCCESS
[Array] - SUCCESS
[Bool] - SUCCESS
[Object] - SUCCESS
[Keyword] - SUCCESS
Alles anzeigen
Prüfergebnis mit MapExists
[Int32] - SUCCESS
[String] - SUCCESS
[Double] - SUCCESS
[Binary] - SUCCESS
[DLLStruct] - THE KEY ALREADY EXISTS. []
[Ptr] - SUCCESS
[Array] - THE KEY ALREADY EXISTS. []
[Bool] - THE KEY ALREADY EXISTS. [True]
[Object] - THE KEY ALREADY EXISTS. []
[Keyword] - THE KEY ALREADY EXISTS. [Default]
Alles anzeigen
EMail-Adressen per RegEx auf Gültigkeit zu prüfen ist hartes Brot. ![]()
Kaum ein Ausdruck ist variabler (und in den Erstellungsregeln inkonsistenter) als eine Mail-Adresse. Waren Umlaute in den Adressen einst undenkbar, sind diese inzwischen normal. Und es würde mich nicht mal wundern, wenn eines Tages auch schwachsinnige Leerzeichen ermöglicht werden, ![]()
Du könntest auch einfach die Domain abtrennen und versuchen diese anzupingen. Wäre ein guter Plausibilitätstest.
Das bringt mir leider in meinem Anwendungsfall (Nicht in dem Beispiel) auch nicht das was ich brauche.
Ach, hab ich zu spät gesehen - du nutzt die Button.au3. Da bin ich raus, habe ich selbst nie wirklich Verwendung dafür gehabt und die Button-Ctrl sind ja sowieso als Standard-Ctrl verfügbar (die du mit den von mr genannten Funktionen verwenden kannst).
war das die einzige Möglichkeit, welche ich gefunden habe
Hier mal ein Bsp. für CHECKED / UN_CHECKED
#include <GUIConstantsEx.au3>
_Example()
Func _Example()
Local $hGui = GUICreate('Test')
Local $cb1 = GUICtrlCreateCheckbox(' Check 1', 20, 20)
Local $cb2 = GUICtrlCreateCheckbox(' Check 2', 20, 60)
GUISetState()
; Statuswerte findest du hier: https://autoit.de/onlinehilfe/online/html/functions/GUICtrlSetState.htm
Local $nMsg, $sCheck
While True
$nMsg = GUIGetMsg()
Switch $nMsg
Case $cb1, $cb2
If BitAND(GUICtrlRead($nMsg), $GUI_CHECKED) Then
$sCheck = "CHECKED"
Else
$sCheck = "UN_CHECKED"
EndIf
MsgBox(0, 'Checkbox', '"' & ControlGetText($hGui, '', $nMsg) & '" - ' & $sCheck)
Case -3
Exit
EndSwitch
WEnd
EndFunc
Alles anzeigen
Ohne direkt auf dene Frage einzugehen,
mir ist aufgefallen:
- doppelte While-Schleife (wozu)
- "ControlCommand" für eigene GUI-Elemente - warum nicht die GUI-Funktionen?
- Titelbar ist nicht per se "30", kannst du mit _WinAPI_GetSystemMetrics erfragen
Vielleicht ist dafür die Darstellung in einem Treeview besser geeignet. Zumal Änderungen in einem Child das jeweilige Parent nicht beeinflussen.
Die Routinen (in Treeview lesen - aus Treeview schreiben) musst du dir wahrscheinlich nicht mal selbst erstellen, findest du bestimmt im Forum (hier od. EN)