none
Ein Spalte in CSV mit EXL vergleichen und schreib das Ergebnis in CSV Date.

    Frage

  • Hallo

    Ich möchte mein CSV Datei mit EXL Datei vergleichen.

    EXL Datei hat Viele Spalten so wie „User ID“ und „Wave“.

    CSV Datei hat nur „UserID“ Spalte.

    Das Skript müsste CSV Spalte „UserID“ mit Spalte „USER ID“ in EXL vergleichen und finde der passende Wave Nummer dann importiert die Wave Nummer zu passende User in CSV.

    Falls kein Name von CSV in EXL gefunden ist, schreibt „NOT FOUND“

    Hier findet ihr was ich gemacht habe aber mehr kann ich leider nicht.

    Ich freue mich auf eure Hilfe.

    $TXTFile = "C:\A.txt" 
    $CSVFile = "C:\B.csv" 
    $EXLFIle = "C:\C.xlsx"
    $SheetName = "Tabelle1"
    
    #find all CNs in TXT file and list them in CSV File
    Select-String -Path $TXTFile  -Pattern 'CN=(.*?),' -AllMatches |
      Select-Object -Expand Matches |
      ForEach-Object { $_.Groups[1].Value } | 
      select @{L="UserID"; E={$_}} |
      Export-CSV $CSVFile -noTypeInformation
      
    # Read and Get Values from Excel 
    #Create an instance of Excel.Application and Open Excel file
    $ObjExcel = New-Object -ComObject Excel.Application
    $Workbook = $ObjExcel.Workbooks.Open($EXLFIle)
    $Sheet = $workbook.Worksheets.Item($SheetName)
    $ObjExcel.Visible = $false
    
    #Count max Rows
    $RowMax = ($sheet.UsedRange.rows).count
    
    #Declare the starting positions
    $rowUserID,$colUserID = 1,2
    $rowWave,$colWave = 1,9
    
    for ($i=1; $i -le $RowMax-1; $i++)
    {
    $UserID = $Sheet.Cells.Item($rowUserID+$i,$colUserID).text
    $Wave = $Sheet.Cells.Item($rowWave+$i,$colWave).text
    
    Write-Host ("USERID: "+$UserID)
    Write-Host ("Wave: "+$Wave)
    }
    
    $objExcel.quit() 


    • Bearbeitet frhling Samstag, 10. Februar 2018 13:02
    Samstag, 10. Februar 2018 13:02

Antworten

  • ich verstehe nicht was falsch ist und was fehlt.

    Ich würde empfehlen, den Fehler systematisch zu suchen. Was ist die Kernaufgabe? Vergleich von Daten? Könnte man auch sagen "Vergleich von Objekten"? Dann wäre eventuell das cmdlet Compare-Object ein gute Wahl. Wie man damit 2 Objecte vergleicht, hab ich weiter oben schon gezeigt. Vielelciht fängst Du damit an, Dein Script soweit abzuspecken, dass Du erst mal nur noch den Vergleich der Daten durchführtst und alles andere erst mal weglässt. Wenn das das gewünschte Ergebnis liefert, erweiterst Du Dein Script entsprechend.

    Hast Du die Kontrolle über die Datenquellen?  ... also Deine Txt-Datei und Deine XLS-Datei die Du verwenden möchtest? Wenn ja, könntest Du die bereits entsprechend (ausserhalb Deines Scriptes) aufbereiten. Das vermeidet Fehlerquellen im Script und nimmt Komplexität raus.


    Best regards,

    (79,108,97,102|%{[char]$_})-join''

    Dienstag, 13. Februar 2018 15:00

Alle Antworten

  • Ich weiß nicht, ob die Antwort, die Du auf StackOverflow erhalten hast zielführend ist und ich mag mich nicht mit Excel-Daten beschäftigen, aber Dein ursprüngliches Problem, wenn ich es richtig verstanden habe, könntest Du vielleicht so lösen:

    $CSVRaw = @'
    UserID,Wave,SomethingElse
    1234,Big,CTA
    1235,Small,Digital
    1236,Medium,Adjustable
    1237,Giant,Pedestal
    '@
    
    $EXLRaw = @'
    UserID
    1235
    1236
    1238
    1239
    '@
    
    $csv = ConvertFrom-Csv -Delimiter ',' -InputObject $CSVRaw
    $EXL = ConvertFrom-Csv -InputObject $EXLRaw
    
    Compare-Object -ReferenceObject $csv -DifferenceObject $EXL -Property UserID -IncludeEqual -PassThru

    Das erzeugt folgende Ausgabe:

    UserID Wave   SomethingElse SideIndicator
    ------ ----   ------------- -------------
    1235   Small  Digital       ==
    1236   Medium Adjustable    ==
    1238                        =>
    1239                        =>
    1234   Big    CTA           <=
    1237   Giant  Pedestal      <=

    Am SideIndicator siehst Du, wo eine Übereinstimmung gefunden wurde. Das kann man natürlich auch weiterverarbeiten.

    Viel Spaß.


    Best regards,

    (79,108,97,102|%{[char]$_})-join''

    • Bearbeitet BOfH_666 Sonntag, 11. Februar 2018 02:05
    Sonntag, 11. Februar 2018 01:50
  • ... was mir noch eingefallen ist: Um sich das Leben zu erleichtern, wenn man mit Excel-Dateien zu arbeiten hat, kann man das Modul ImportExcel benutzen.


    Best regards,

    (79,108,97,102|%{[char]$_})-join''

    Sonntag, 11. Februar 2018 03:53
  • Danke BOfh_666, 

    leider bis jetzt könnte ich die richtige Antwort nicht finden. 

    $TXTFile = "C:\A.txt" 
    $CSVFile1 = "C:\A.csv" 
    $EXLFile = "C:\B.xlsx"
    $Result = "C:\Result.csv" 
    $CSVFile2 = "C:\B.csv"
    
    
    #find all CNs in TXT file and list them in CSV File
    Select-String -Path $TXTFile  -Pattern 'CN=(.*?),' -AllMatches |
      Select-Object -Expand Matches |
      ForEach-Object { $_.Groups[1].Value } | 
      select @{L="UserID"; E={$_}} |
      Export-CSV $CSVFile1 -noTypeInformation -Encoding UTF8
    
    ########################################################################
    # Convert EXL file  to CSV File
    $excelwb = New-Object -ComObject excel.application
    $workbook = $excelwb.Workbooks.Open($EXLFile)
    $workbook.SaveAs($CSVFile2,6)
    $workbook.Close($false)
    $ExcelWB.quit()
    $csv = Import-Csv $CSVFile2 -Delimiter ";"
    ########################################################################
    # We Compare File1 with File2
    $file1 = import-csv $CSVFile1       
    $file2 = import-csv $CSVFile2       
    $UserID = "UserID"
    
    $Output = @()
    
        ForEach ($user in $file1)
        {
    
            #Write-Host $user.UserID
            $Match = $file2 | Where-Object {$_."UserID" -eq $user."UserID"}
            Write-Host User is $user.UserID and $_."UserID"
            
            If($Match)
            {
               $Output += New-Object PsObject -Property @{"UserID" = $user.UserID ; Wave = $Match.Wave}
               Write-Host $user.UserID is in $user.Wave Wave Number.
            }
            else
            {
               $Output += New-Object PsObject -Property @{"UserID" = $user.UserID ; Wave = "NA"}
               #Write-Host $Output
               Write-Host $user.UserID has no $user.Wave Number.
    
            }
        }
    $Output | Export-Csv $Result
    

    ** Result.csv müsste Zwei Spalte haben: UserID und Wave Nummer

    ** was ich sehe, das Skript liest kein Daten von $CSVFile2

    ich verstehe nicht was falsch ist und was fehlt.


    • Bearbeitet frhling Dienstag, 13. Februar 2018 14:47
    Dienstag, 13. Februar 2018 14:03
  • ich verstehe nicht was falsch ist und was fehlt.

    Ich würde empfehlen, den Fehler systematisch zu suchen. Was ist die Kernaufgabe? Vergleich von Daten? Könnte man auch sagen "Vergleich von Objekten"? Dann wäre eventuell das cmdlet Compare-Object ein gute Wahl. Wie man damit 2 Objecte vergleicht, hab ich weiter oben schon gezeigt. Vielelciht fängst Du damit an, Dein Script soweit abzuspecken, dass Du erst mal nur noch den Vergleich der Daten durchführtst und alles andere erst mal weglässt. Wenn das das gewünschte Ergebnis liefert, erweiterst Du Dein Script entsprechend.

    Hast Du die Kontrolle über die Datenquellen?  ... also Deine Txt-Datei und Deine XLS-Datei die Du verwenden möchtest? Wenn ja, könntest Du die bereits entsprechend (ausserhalb Deines Scriptes) aufbereiten. Das vermeidet Fehlerquellen im Script und nimmt Komplexität raus.


    Best regards,

    (79,108,97,102|%{[char]$_})-join''

    Dienstag, 13. Februar 2018 15:00
  • Das ist sicher nicht der eigentliche Fehler, aber dieser Befehl ist völlig sinnlos. 

    Write-Host User is $user.UserID and $_."UserID"

    $_ ist nur innerhalb einer Pipeline befüllt. Außerhalb ist es $null. Außerdem solltest du sichergehen, dass es ein String ist, d.h. entweder in "" setzen (Variablen mit Properties in $() setzen) oder du müsstest den String mit "+" zusammenbauen. Mich wundert, dass das keine Fehlermeldung gibt...

    Kann es sein, dass $Match mehr als ein Objekt enthält? In dem Fall wäre $Match.Wave auch ein Array und müsste vor der Ausgabe entsprechend in einen String gejoint (-join) werden.


    • Bearbeitet hpotsirhc Mittwoch, 14. Februar 2018 09:56
    Mittwoch, 14. Februar 2018 09:56