100000 Excel Zellen Püfen

  • Hallo zusammen,

    wie die Überschrift schon sagt möchte ich ca. 100000 Excel Zellen prüfen.

    Aus Tabelle2 wird Zelle1 gelesen und mit Tabelle1 Zelle1 bis 100000 in Spalte A verglichen usw.

    Nur mit ner For Schleife dauert das ja eeeewig.

    Gibt es da ne schnellere Lösung?


    Gruß
    Norman

  • Speichere die Datei als csv und lies sie in ein Array, such mal nach _CSV2Array da ist schon eine Fertige Funktion.
    Ansonsten könntest du die Datei in eine Datenbank importieren (phpmyadmin kann es, MSSQL hat da auch ne Funktion für) und dann mit SQL Befehelen arbeiten

    Hier mal ein Beispiel mit SQLite

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <SQLite.au3>
    #include <SQLite.dll.au3>
    Local $aResult, $iRows, $iColumns
    $Allarray = _CSV2Array("Datei Nr 1.csv", ";")
    $Sucharray = _CSV2Array("Suchdatei.csv", ";")
    _SQLite_Startup()
    _SQLite_Open()
    $columns = ""
    For $i = 0 To UBound($Allarray, 2) - 1
    $columns &= $i & " VARCHAR(255),"
    Next
    _SQLite_Exec(-1, "CREATE TABLE Search (" & StringTrimRight($columns, 1) & ");")
    $aSql = 'Begin Transaction ;' & @CRLF
    For $i = 1 To UBound($Allarray) - 1
    $values = ""
    For $k = 0 To UBound($Allarray, 2) - 1
    $values &= _SQLite_Escape($Allarray[$i][$k]) & ","
    Next
    $aSql &= "INSERT INTO Search VALUES (" & StringTrimRight($values, 1) & ");" & @CRLF
    Next
    _SQLite_Exec(-1, $aSql)
    For $i = 1 To UBound($Sucharray) - 1
    _SQLite_GetTable2d(-1, "SELECT * FROM Search WHERE 1 = " & _SQLite_Escape($Sucharray[$i][0]) & ";", $aResult, $iRows, $iColumns)
    _ArrayDisplay($aResult)
    Next

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

    Func _CSV2Array($hFile, $cSeperator = "auto", $bFilterString = True, $iColumnMode = 0)
    Local $s = FileRead($hFile)
    If @error Then Return SetError(1)
    If $cSeperator = Default Then $cSeperator = "auto"
    If Not $cSeperator Then $cSeperator = Opt("GUIDataSeparatorChar")
    ; searching the line-seperator and splitting the lines into an array
    Local $aLines
    If StringInStr($s, @CRLF) Then
    $aLines = StringSplit($s, @CRLF, 1)
    ElseIf StringInStr($s, @CR) Then
    $aLines = StringSplit($s, @CR)
    Else
    $aLines = StringSplit($s, @LF)
    EndIf
    ; searching the delimiter in the first line
    Local $aTMP
    If $cSeperator = "auto" Then
    Local $iMax = 0
    Local $iC[5] = [0, 0, 0, 0, 0]
    Local $sC[4] = [";", ",", @TAB, "|"]
    $aTMP = StringRegExp($aLines[1], ";", 3)
    If Not @error Then $iC[0] = UBound($aTMP)
    $aTMP = StringRegExp($aLines[1], ",", 3)
    If Not @error Then $iC[1] = UBound($aTMP)
    $aTMP = StringRegExp($aLines[1], "\t", 3)
    If Not @error Then $iC[2] = UBound($aTMP)
    $aTMP = StringRegExp($aLines[1], "\|", 3)
    If Not @error Then $iC[3] = UBound($aTMP)
    ;~ $aTMP = StringRegExp($aLines[1], "[ ]", 3)
    ;~ If Not @error Then $iC[4] = UBound($aTMP)
    For $i = 0 To UBound($sC) - 1
    If $iC[$i] > $iMax Then
    $iMax = $iC[$i]
    $cSeperator = $sC[$i]
    EndIf
    Next
    EndIf
    ; creating 2-dim array based on the number of data in the first line
    $aTMP = StringSplit($aLines[1], $cSeperator)
    Local $iCol = $aTMP[0]
    Local $aRet[$aLines[0]][$iCol]
    ; splitting and filling the lines
    For $i = 1 To $aLines[0]
    $aTMP = StringSplit($aLines[$i], $cSeperator)
    If @error Then ContinueLoop
    If $aTMP[0] > $iCol Then
    Switch $iColumnMode
    Case 0
    Return SetError(2, $i)
    Case 1
    ReDim $aRet[$aLines[0] - 1][$aTMP[0]]
    Case 2
    $aTMP[0] = $iCol
    Case Else
    Return SetError(3)
    EndSwitch
    EndIf
    For $j = 1 To $aTMP[0]
    $aTMP[$j] = StringStripWS($aTMP[$j], 7)
    If $bFilterString Then ; removing leading and trailing " or '
    $aTMP[$j] = StringRegExpReplace($aTMP[$j], '^("|'')(.*?)\1$', '$2')
    EndIf
    $aRet[$i - 1][$j - 1] = $aTMP[$j]
    Next ; /cols
    Next ; /lines
    Return $aRet
    EndFunc ;==>_CSV2Array

    [/autoit]
  • Du brauchst die Excel-Datei nicht in eine Datenbank zu exportieren um SQL-Befehle abzusetzen.
    Excel kann per ADO direkt als Datenbank angesprochen werden.
    Details liefere ich, falls Du diesen Ansatz weiterverfolgen möchtest.

  • Du brauchst die Excel-Datei nicht in eine Datenbank zu exportieren um SQL-Befehle abzusetzen.
    Excel kann per ADO direkt als Datenbank angesprochen werden.
    Details liefere ich, falls Du diesen Ansatz weiterverfolgen möchtest.

    Wäre super wenn Du da einen Lösungsansatz hast.


    Gruß

    Norman

  • Bei diesem Thread geht's los. Weitere Beispiele findest Du, wenn Du nach "Excel ADO SQL" suchst.

    • Offizieller Beitrag

    Ist das nicht schnell genug?

    Spoiler anzeigen
    [autoit]

    #region ;************ Includes ************
    #include <Array.au3>
    #include <File.au3>
    #endregion ;************ Includes ************
    ; CSV_Vergleich

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

    Global $filePath_1 = @ScriptDir & '\T1.csv'
    Global $filePath_2 = @ScriptDir & '\T2.csv'

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

    FileOpen($filePath_1, 2)
    FileOpen($filePath_2, 2)

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

    Global $str_1 = ''
    Global $str_2 = ''

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

    For $i = 1 To 100000
    $str_1 &= $i & @CRLF
    Next
    FileWrite($filePath_1, $str_1)

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

    $str_2 = $str_1

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

    For $y = 0 To 10
    $str_2 = StringReplace($str_2, String(Random(10000, 100000, 1)), 'Oh oh', 1)
    Next
    FileWrite($filePath_2, $str_2)

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

    Local $lines_1_A, $lines_2_A
    If Not _FileReadToArray($filePath_1, $lines_1_A) Then MsgBox(4096, "Error", " error:" & $filePath_1)
    If Not _FileReadToArray($filePath_2, $lines_2_A) Then MsgBox(4096, "Error", " error:" & $filePath_2)

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

    ;~ _ArrayDisplay($lines_1_A)
    ;~ _ArrayDisplay($lines_2_A)

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

    For $i = 1 To UBound($lines_1_A) - 1
    ;~ ConsoleWrite('>' & $lines_1_A[$i] & ' <> ' & $lines_2_A[$i] & @LF)
    If $lines_1_A[$i] <> $lines_2_A[$i] Then ConsoleWrite('!' & $lines_1_A[$i] & ' <> ' & $lines_2_A[$i] & @LF)
    Next

    [/autoit]
  • @ Xenobiologist

    Das sieht schonmal Gut aus. Ich probiere es mal in meinen Code zu übernehmen


    EDIT:

    Hat einer einen Lösungsansatz. Ich bekomme es auf anhieb nicht hin.


    So sieht mein Code aus:

    [autoit]

    #include<Excel.au3>
    $excel = _ExcelBookOpen("C:\Users\" & @Username &"\Desktop\Book1.xls")
    For $i = 1 To 1
    _ExcelSheetActivate($excel,"Sheet2")
    $aread_cell = _ExcelReadCell ($excel,$i,1)
    ;MsgBox(0,"Tabelle 2", "Cell " &$i & " Inhalt = " & $aread_cell)
    For $j = 2 to 108016
    _ExcelSheetActivate($excel,"Sheet1")
    $bread_cell = _ExcelReadCell ($excel,$j,7)
    ;MsgBox(0,"Tabelle 1", "Cell " &$j & " Inhalt = " & $bread_cell)
    If $aread_cell = $bread_cell Then
    _ExcelSheetActivate($excel,"Sheet2")
    ;MsgBox(0, "", "$aread_cell = $bread_cell")
    $excel.cells($i,1).Interior.ColorIndex = 3
    EndIf
    Next
    Next

    [/autoit]

    Einmal editiert, zuletzt von Norman Bates (31. Januar 2012 um 21:11)

    • Offizieller Beitrag

    Ich automatisiere ja auch gern und viel - aber hier geht das m.M. nach am Ziel vorbei, wenn du versuchst eine in VBA bzw. normalen Excel-Funktionen relativ unklompiziert vorzunehmende Aufgabe per Skript zu lösen.
    Zellen vergleichen kann Excel intern schneller als ein Export/externer Lesezugriff dauert.
    Das einzige, was ich evtl. automatisieren würde, ist das Eintragen der Auswerteformel in die Exceltabelle. ;)