Aus Array nur bestimmte Werte ausgeben in Textdatei

  • ich bin am verzweifeln ich und und die Arrays vielleicht könnt ihr mir ein paar tips geben

    Also Zuerst wird eine Excel Datei in ein Array eingelesen funktioniert
    Dann wird das Array nach einer ID sortiert funktioniert

    Zum Schuss soll es möglich sein einen Computerbericht je nach Angaben der IDs zu erstellen der nur bestimmte informationen liefert oder eine Kurzübersicht erstellt
    Beispiel so

    Betriebssystem: Microsoft Windows XP Professional
    OS Service Pack Service Pack 3 Build 2600
    Systemname PC3
    CPU Typ DualCore Intel Core 2 Duo E7500
    usw.

    Link zu Report.csv

    Nun möchte ich nur eine bestimmte Zeile bzw einen bestimmten Wert ausdem Array in ein neues Textdokument

    aber ich weiß nicht wie könnt Ihr mir helfen ?


    [autoit]

    #include<File.au3>
    #include <Excel.au3>
    #include <Array.au3>

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

    ; ***************************************************************
    ; Example 1 - Open an existing workbook and returns its object identifier.
    ; *****************************************************************

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

    #include <Excel.au3>

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

    $sFilePath1 = "D:\Report.csv"
    $oExcel = _ExcelBookOpen($sFilePath1)

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

    If @error = 1 Then
    MsgBox(0, "Error!", "Unable to Create the Excel Object")
    Exit
    ElseIf @error = 2 Then
    MsgBox(0, "Error!", "File does not exist - Shame on you!")
    Exit
    EndIf

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

    $aArray = _ExcelReadSheetToArray($oExcel) ;Using Default Parameters
    _ArrayDisplay($aArray, "Array using Default Parameters")

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

    _ArraySort($aArray, 0, 0, 0, 1)
    _ArrayDisplay($aArray, "$avArray AFTER _ArraySort() ascending column 1" )

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

    MsgBox(0, "Exiting", "Press OK to Save File and Exit")
    _ExcelBookSaveAs($oExcel, @TempDir & "\Temp.xls", "xls", 0, 1) ; Now we save it into the temp directory; overwrite existing file if necessary
    _ExcelBookClose($oExcel) ; And finally we close out

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


    Danke und Greets bitworker

  • Hi progandy

    kannst du mir vielleicht ein Beispiel geben wie die Schleife aufgebaut sein soll

    ist das der richtige Ansatz

    [autoit]


    For $i = 0 To UBound($aArray) -1 ; $i ist der Zähler für die Zeilen
    For $k = 0 To UBound($aArray, 2) -1 ; $k ist der Zähler für die Spalten
    $aArray[$i][$k] = 'Zeile' & $i & '/Spalte' & $k

    IF ID = "528" Then

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

    schreibe in Datei

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

    Next
    Next

    [/autoit]

    Welche von deinen 2 Vorschlägen ist die bessere Variante ?

  • Das kommt darauf an, wie die IDs angeordnet sein sollen und auf die Menge der Einträge.

  • Hallo progandy

    Anhand von den IDs sollen nur die Werte ausgegeben werden
    wie sie angeordnet sind ist egal bzw ergibt sich aus dem Computerbericht

    Kannst du mir anhand einem Beispiel zeigen wie ich vorgehen muss ?

    Grüße Andreas

  • Wenn die Anordnung der IDs in der Ausgabe von niedrig nach hoch ist, kannst du mit der Schleife durchlaufen.
    Ansonsten benötigst du die Array-Suche.

    [autoit]

    $aiMyIDs[3] = [34, 12, 565]
    For $i = 0 To Ubound($aiMyIDs)-1
    $indx = _ArrayBinarySearch_2D($aArray, $aiMyIDs[$i], $iColumnOfID) ; irgend eine Position mit dieser ID finden
    If $indx > -1 Then
    While $indx > 0 And $aArray[$indx-1][$iColumnOfID] = $aiMyIDs[$i] ; Den Anfang des Blocks mit der ID finden
    $indx -= 1
    WEnd
    $iMax = Ubound($aArray)-1
    Do
    ConsoleWrite($aArray[$indx][$iColumnOfData] & @CRLF)
    $indx += 1
    Until $indx > $iMax Or $aArray[$indx-1][$iColumnOfID] <> $aiMyIDs[$i] ; so lange ausgeben, bis kein Eintrag mit dieser ID mehr vorhanden.
    EndIf
    Next

    [/autoit]


    Edit: Ich sehe gerade, dass es mehrere Einträge mit der selben ID gibt.

    Einmal editiert, zuletzt von progandy (3. August 2010 um 16:00)

  • ich würde es mir nicht so kompliziert machen und deine liste als excel datei ansehen!
    csv (comma separated values) kannste auch problemlos ohne _Excel-Funtionen auslesen z.B. so liest er die ID's ein.

    [autoit]

    #include <File.au3>
    #include <Array.au3>

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

    _ReadCSV("Report.csv")

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

    Func _ReadCSV($SourceFile)
    Dim $aCSV, $i, $iID[100]
    _FileReadToArray($SourceFile,$aCSV)
    For $i = 2 To $aCSV[0] ;$i = 2 Um den Header zu überspringen
    $iID[$i] = StringLeft($aCSV[$i],3)
    Next
    _ArrayDisplay($iID)
    EndFunc

    [/autoit]

    Um den Rest deiner Daten ohne viel Arbeit zu erkennen und einzulesen empfehle ich StrinRegExp oder _StringBetween zu benutzen!
    Wenn du damit hilfe brauchst, sag bescheid, dann würd ich das script weiter schreiben - hatte jetzt nur 5 minuten ...

  • Zum Einlesen der CSV-Datei kann ich diese Funktion empfehlen, solange sie ein einfaches Format ohne Zeilenumbrüche in den Zellen hat:
    https://autoit.de/index.php?page=Thread&amp;threadID=16199

    Edit: Das Format ist ja nicht besonders intelligent... Semikolon als Feldtrenner und gleichzeitig Werte, die ein Semikolon beinhalten. Wo kommt die Datei denn her?
    Edit: Die von mir verlinkte _ArrayBinarySearch_2D funkioniert nicht wie gewünscht. Verwende lieber die:

    Spoiler anzeigen
    [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayBinarySearch2D
    ; Description ...: Uses the binary search algorithm to search through a 2-dimensional array.
    ; Syntax.........: _ArrayBinarySearch2D(Const ByRef $avArray, $vValue[, $iStart = 0[, $iEnd = 0, $iCol = 0]])
    ; Parameters ....: $avArray - Array to search
    ; $vValue - Value to find
    ; $iStart - [optional] Index of array to start searching at
    ; $iEnd - [optional] Index of array to stop searching at
    ; $iCol - [optional] Column of 2D array to stop searching at
    ; Return values .: Success - Index that value was found at
    ; Failure - -1, sets @error to:
    ; |1 - $avArray is not an array
    ; |2 - $vValue outside of array's min/max values
    ; |3 - $vValue was not found in array
    ; |4 - $iStart is greater than $iEnd
    ; |5 - $avArray is not a 2 dimensional array
    ; |6 - $iCol is not within the column range
    ; Author ........: Jos van der Zande <jdeb at autoitscript dot com>
    ; Modified.......: Ultima - added $iEnd as parameter, code cleanup
    ; ProgAndy - changed to 2D
    ; Remarks .......: When performing a binary search on an array of items, the contents MUST be sorted before the search is done.
    ; Otherwise undefined results will be returned.
    ; Related .......: _ArrayFindAll, _ArraySearch
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func _ArrayBinarySearch2D(Const ByRef $avArray, $vValue, $iStart = 0, $iEnd = 0, $iCol = 0)
    If Not IsArray($avArray) Then Return SetError(1, 0, -1)
    If UBound($avArray, 0) = 1 Then
    Local $ret = _ArrayBinarySearch($avArray, $vValue, $iStart, $iEnd)
    Return SetError(@error, @extended, $ret)
    ElseIf UBound($avArray, 0) <> 2 Then
    Return SetError(5, 0, -1)
    EndIf

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

    Local $iUBound = UBound($avArray) - 1

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

    ; Bounds checking
    If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound
    If $iStart < 0 Then $iStart = 0
    If $iStart > $iEnd Then Return SetError(4, 0, -1)
    If $iCol < 0 Or $iCol >= UBound($avArray, 2) Then Return SetError(6,0,-1)

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

    Local $iMid = Int(($iEnd + $iStart) / 2)

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

    If $avArray[$iStart][$iCol] > $vValue Or $avArray[$iEnd][$iCol] < $vValue Then Return SetError(2, 0, -1)

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

    ; Search
    While $iStart <= $iMid And $vValue <> $avArray[$iMid][$iCol]
    If $vValue < $avArray[$iMid][$iCol] Then
    $iEnd = $iMid - 1
    Else
    $iStart = $iMid + 1
    EndIf
    $iMid = Int(($iEnd + $iStart) / 2)
    WEnd

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

    If $iStart > $iEnd Then Return SetError(3, 0, -1) ; Entry not found

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

    Return $iMid
    EndFunc ;==>_ArrayBinarySearch2D

    [/autoit]

    2 Mal editiert, zuletzt von progandy (3. August 2010 um 16:23)

  • Also so soll der Bericht zum Schluss aussehen
    Anhand de ids will ich nur die einzelnen Kompnenten erkennen

    261;Computer;ITINSPECTOR-PC;
    262;Ersteller;a1;
    263;Betriebssystem;Microsoft Windows 7 Professional 6.1.7600 (Win7 RTM);
    582;Computertyp;ACPI x64-based PC;
    513;Betriebssystem;Microsoft Windows 7 Professional;
    540;OS Service Pack;-;
    564;Internet Explorer;8.0.7600.16385;
    566;DirectX;DirectX 11.0;
    514;Computername;ITINSPECTOR-PC;
    515;Benutzername;a1;
    517;CPU Typ;DualCore Intel Core 2 Duo E7500; 2933 MHz (11 x 267);;;;;
    518;Motherboard Name;Asus P5W DH Deluxe (3 PCI; 2 PCI-E x1; 2 PCI-E x16; 4 DDR2 DIMM; Audio; Dual Gigabit LAN; IEEE-1394)
    519;Motherboard Chipsatz;Intel Glenwood-DG i975X;
    520;Arbeitsspeicher;6144 MB (DDR2-800 DDR2 SDRAM);

    wie Geht sowas mit der Funktion StringRegExp ?
    liest die Funktion dann zwischen ;Textext; aus habe ich das richtig verstanden

  • Ach ja, stimmt per RegExp geht es ja auch :D

    [autoit]

    $sFileContent = FileRead("Report.csv")

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

    Local $aMyIDs[3] = ["536", "265", "514"]
    For $i = 0 To UBound($aMyIDs)-1
    $aFound = StringRegExp($sFileContent, "(?m)^(" & $aMyIDs[$i] & ";.*)$", 3) ; Filtere alle Zeilen, die mit der ID anfangen
    If @error Then ContinueLoop ; nichts gefunden
    For $i = 0 To UBound($aFound)-1
    ConsoleWrite(StringStripWS($aFound[$i],3) & @CRLF)
    Next
    Next

    [/autoit]
  • Hallo Progandy

    danke für deine unterstützung

    was wäre den ein besseres Trennzeichen für die Daten ?
    ursprünglich war sie durch Kommas getrennt Die Datei selber kommt von everest

  • Dann lass doch entweder das Komma oder verwende Tabs. Auch eine Pipe | sollte problemlos funktionieren ;) Du musst dann nur den regulären Ausruck anpassen, der enthält den Separator nach der ID.

  • So habe jetzt getestet läuft ganz gut

    aber sobald ich eine Id mit 500 hinzufüge egal welche bleibt er in einer Dauerschleife hängen und gibt endlos z.B 514 den Computernamen aus.

    [autoit]

    #include<File.au3>
    #include <Excel.au3>
    #include <Array.au3>

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

    $sFileContent = FileRead("Report.csv")

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

    msgbox("","test", $sFileContent)

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

    Local $aMyIDs[7] = ["261", "263", "520", "514" , "585"]

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

    _ArrayDisplay($aMyIDs, "Array using Default Parameters")

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

    For $i = 0 To UBound($aMyIDs)-1
    $aFound = StringRegExp($sFileContent, "(?m)^(" & $aMyIDs[$i] & ";.*)$", 3) ; Filtere alle Zeilen, die mit der ID anfangen
    If @error Then ContinueLoop ; nichts gefunden
    For $i = 0 To UBound($aFound)-1
    ConsoleWrite(StringStripWS($aFound[$i],3) & @CRLF)
    Next
    Next

    [/autoit]


    mach ich was falsch beim Anpassen ich vergrößer das Array wenn ich mehr Werte haben will

  • öhh, tausche bitte die Schleifenvariable aus. Zwei mal $i ist nicht ganz optimal ... Hab ich in der Schnelle übersehen.

  • Hallo progandy

    Ich habe die textausgbe versucht anzupassen
    Ich will zum Schluss nicht mehr die IDs haben aber egal was ich schreibe er schreibt immer die komplette Zeile
    und ich hab noch ein Problem die richtige OrginalDatei Report.csv hat noch eine zusätzlich Spalte ganz am Anfang vor den Ids
    welchen Parameter muss ich ändern


    $aFound = StringRegExp($sFileContent, "(?m)^(" & $aMyIDs[$i] & ";.*)$", 3)

    Ich hab schon in der hilfe nachgeschaut aber verstehen tu ichs nicht wirklich
    Zu meinem Verständnis was beduetet diese Zeile was passiert hier ?

    Wenn du mir das erklären könntest wäre ich sehr dankbar

  • Die Erklärung:

    Code
    (?m) - ^ steht für Zeilenanfang, $ für Zeilenende
    ^ - Zeilenanfang
    ( - Start einer Rückgabegruppe
    dann die ID
    ; - Semikolon
    .* beliebig viele Zeichen
    ) - Ende der Treffergruppe
    $ Ende der Zeile


    Du musst wohl folgendes machen:

    [autoit]

    "(?m)^[^;]*;" & $aMyIDs[$i] & ";(.*)$"

    [/autoit]
    Code
    (?m)^ - bekannt
    --> [^;]* -> beliebig viele Zeichen, nur kein Semikolon
    ; Semikolon
    die ID
    ;Semikolon
    (.*) - Treffergruppe, beliebig viele zeichen
    $ Ende der Zeile
  • ich habe noch eine frage die Ursprungsdatei(siehe Anhang Report.csv) von Everest funktioniert nicht mit dem Script
    hab alles mögliche versucht aber es will nicht klappen wie kann den steuern das er erst ab der 7 Zeile und der Dritten Spalte
    den Rest ind die textdatei schreibt?
    und wenn ich in der zeile StringRegExp das Semikolon in ein Komma tausche dann ist die Textdatei immer leer


    [autoit]

    #include<File.au3>
    #include <Excel.au3>
    #include <Array.au3>

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

    $sFileContent = FileRead("D:\Report1.csv")

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

    ;msgbox("","test", $sFileContent)

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

    Dim $text
    dim $var1, $var2
    $var1 = 265
    $var2 = 263

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

    Local $aMyIDs[15] = [$var1, $var2, "540", "515", "517", "520", "523", "528", "529", "586", "538", "555", "556"]

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

    _ArrayDisplay($aMyIDs, "Array using Default Parameters")

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

    $hFile = FileOpen("D:\Test.txt", 2)

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

    For $i = 0 To UBound($aMyIDs)-1

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

    $aFound = StringRegExp($sFileContent, "(?m)^(" & $aMyIDs[$i] & ";.*)$", 3) ; Filtere alle Zeilen, die mit der ID anfangen

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

    If @error Then ContinueLoop ; nichts gefunden
    For $k = 0 To UBound($aFound)-1
    $text =(StringStripWS($aFound[$k],3) & @CRLF)

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

    FileWriteLine($hFile,$text)
    Next
    Next

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

    FileClose($hFile)

    [/autoit]


    Die fertige Datei sollso aussehen

    Computertyp ACPI x64-based PC Betriebssystem Microsoft Windows 7 Professional
    OS Service Pack -
    Internet Explorer 8.0.7600.16385
    DirectX DirectX 11.0
    Computername ITINSPECTOR-PC
    Benutzername a1
    CPU Typ DualCore Intel Core 2 Duo E7500; 2933 MHz (11 x 267)
    Motherboard Name Asus P5W DH Deluxe
    Motherboard Chipsatz Intel Glenwood-DG i975X
    Arbeitsspeicher 6144 MB (DDR2-800 DDR2 SDRAM)
    DIMM1: Corsair XMS2 CM2X2048-6400C5 2 GB DDR2-800 DDR2 SDRAM (5-5-5-18 @ 400 MHz) (4-4-4-13 @ 270 MHz)
    DIMM2: Corsair XMS2 CM2X2048-6400C5 2 GB DDR2-800 DDR2 SDRAM (5-5-5-18 @ 400 MHz) (4-4-4-13 @ 270 MHz)
    DIMM3: Corsair XMS2 DHX CM2X2048-6400C4DHX 2 GB DDR2-800 DDR2 SDRAM (5-5-5-18 @ 400 MHz) (4-4-4-13 @ 270 MHz)


    Wie kann ich das am besten lösen

  • Spoiler anzeigen
    [autoit]

    #include<File.au3>
    #include <Excel.au3>
    #include <Array.au3>

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

    $sFileContent = FileRead("Report.csv.txt")

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

    ;msgbox("","test", $sFileContent)

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

    Dim $text
    Dim $var1, $var2
    $var1 = 265
    $var2 = 263

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

    Local $aMyIDs[13] = [$var1, $var2, "540", "515", "517", "520", "523", "528", "529", "586", "538", "555", "556"]

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

    ;_ArrayDisplay($aMyIDs, "Array using Default Parameters")

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

    $hFile = FileOpen("Test.txt", 2)
    ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $hFile = ' & $hFile & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

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

    For $i = 0 To UBound($aMyIDs) - 1
    ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $i = ' & $i & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

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

    $aFound = StringRegExp($sFileContent, "," & $aMyIDs[$i] & ",(.*)", 3) ; Filtere alle Zeilen, die mit der ID anfangen
    ;_arraydisplay($aFound)
    If @error Then ContinueLoop ; nichts gefunden
    For $k = 0 To UBound($aFound) - 1
    $text = (StringStripWS($aFound[$k], 3) & @CRLF)
    $text = StringReplace($text, ",", " ")

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

    FileWriteLine($hFile, $text)
    ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $text = ' & $text & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

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

    Next
    Next

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

    FileClose($hFile)

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

    ShellExecute("Test.txt")

    [/autoit]

    habe mal die "Debug"-infos auskommentiert, so findet man die "Fehler" relativ schnell. Regex angepasst