milord
Goto Top

Ecxel per Script bearbeiten jeden Tag

Moin Zusammen,
ich hoffe die Frage ist hier halbwegs richtig. Und zwar habe ich folgendes "Problem".
Wir in der Firma haben eine Excel Tabelle, die aus dem System ausgegeben wird. Die Mitarbeiter passen diese dann händisch an. Das passiert jeden Tag.
Das Ding ist, es kostet Zeit und ist im endeffekt immer die selbe Aufgabe.

Ich versuche das mal halbwegs zu erklären.
Wir bekommen aus dem System Auswertungen als csv raus. In diesen Feldern stehen Abkürzungen vom System, die wir leider bei der Ausgabe nicht verändern können.
Nun ist unser Ablauf wie folgt. In der CSV stehen dann Werte wie 11 oder 1004 oder 2243 (hinter diesen Steckt dann eine Information.
Die Mitarbeiter gehen nun bei und löschen dieses kürzel und ersetzen es durch den richtigen Wert.

Beispiele:
11 - ersetzt durch - 0800P11700
1004 - ersetzt durch - 0900P05160

Diese Werte können dann von einem anderen System weiterverarbeitet werden.
Das sind jeden Tag etwa 100 Felder die die Mitarbeiter händisch ersetzen. Die Werte sind dabei immer gleich, also die 11 steht immer für 0800P11700

Da ich in Excel nicht so fitt bin, wüsste ich nicht wie ich das richtig lösen sollte. Ich hatte schon an einen querverweis gedacht.
Aber auch ein Skript wäre möglich, in dem dann die Werte verändert werden. Nach dem Motto: Überall wo 11 steht, durch 0800P11700 ersetzen.
Die 11 taucht nämlich öfter in der csv aus und das leider immer in verschiednen Spalten, je nachdem wie das System auswertet.

Irgendwie stehe ich auf dem Schlauch und würde das den Mitarbeitern gerne vereinfachen. Die verbringen jeden Tag 15-20 Minuten dabei das zu ändern.

Ich bin für jeden Vorschlag dankbar.

Mit freundlichen Grüßen
Milord

Content-Key: 379673

Url: https://administrator.de/contentid/379673

Printed on: April 18, 2024 at 19:04 o'clock

Member: Kraemer
Kraemer Jul 09, 2018 at 20:42:25 (UTC)
Goto Top
Moin,
Mit der Powershell ist das in wenigen Minuten Erledigt.

Gruß
Member: em-pie
em-pie Jul 09, 2018 at 20:52:03 (UTC)
Goto Top
Moin,

korrekt, mit der PowerShell recht zügig erledigt:
PowerShell Skript suchen und ersetzen in einer CSV

Wenn du im WW etwas weiter suchst,kannst du noch folgendes bauen:
erstelle eine Umsetzung.txt, welche deine Umsetzung enthält
11;0800P11700
1004;0900P05160
Für jede Zeile in der Umsetzung lässt du die Werte in deiner csv dann ersetzen.
Weitere Hilfe:
https://www.msxfaq.de/code/powershell/pscsv.htm
https://www.windowspro.de/script/schleifen-powershell-foreach-while-do-u ...

Gruß
em-pie
Member: Milord
Milord Jul 09, 2018 at 20:56:59 (UTC)
Goto Top
Das war auch mein Gedanke. Bin da leider noch nicht so fit drin.

get-ChildItem export.csv | Foreach-Object {Get-Content $_ | Out-String | Foreach-Object {$_.Replace(„11“,“0800P11700“)} | Set-Content $_}

Damit sollte das wohl gehen oder? Werde ich morgen mal ausprobieren. Wie gesagt, bin im Scripten noch nicht so fit, da ich kaum was damit gemacht habe.
Als batch könnte man sowas versuchen.

@echo off & setlocal enabledelayedexpansion
set "Quelle=C:\export.csv"  
set "Ziel=C:\exportneu.csv"  


>"%Ziel%" (for /f "usebackq eol=° delims=" %%z in ("%Quelle%") do (  
    set "ZeileEin=%%z"  
    set "ZeileAus="  
    set /a Feld=1
    for %%a in ("!ZeileEin:;=","!") do (  
        if !Feld!==%Spalte% (
            set "Wert=%%~a"  
            if "%%~a"=="11" set "Wert=0800P11700"  
            if "%%~a"=="1004" set "Wert=123456"  
            if "%%~a"=="2243" set "Wert=123696"  
            set "ZeileAus=!ZeileAus!;!Wert!"  
        ) else (
            set "ZeileAus=!ZeileAus!;%%~a"  
        )
        set /a Feld+=1
    )
    echo(!ZeileAus:~1!
))

Das ist das, was mir nun eingefallen ist. Ich muss das morgen mal probieren und berichte dann.
Member: erikro
erikro Jul 10, 2018 at 06:28:36 (UTC)
Goto Top
Moin,

vorsicht! Das kann schnell nach hinten losgehen. Nehmen wir mal an, dass in einer Spalte die 11 wie gewünscht steht. In der nächsten Spalte steht 110 z. B. als Mengenangabe. Wenn Du blind 11 durch 0800P11700 ersetzt, dann ersetzt Du das in beiden Spalten, so dass auch in der zweiten nicht mehr 110, sondern 0800P117000 steht. Du solltest also vor dem Ersetzen per Regex prüfen, ob das zu ersetzende alleine steht oder Teil eines anderen Strings ist.

hth

Erik
Member: Milord
Milord Jul 10, 2018 at 07:54:54 (UTC)
Goto Top
Danke für die Info. Das wird wohl aber nicht vorkommen, ich habe das eben geprüft.
Nun ist es so, dass ich mich bei der CSV vertan habe. Aus dem System kommt eine .xls Datei.

Ich bin nun dabei etwas in Powershell zu basteln, aber ich bekomm das noch nicht ganz hin.

Ich bin nun soweit gekommen:
$File = "c:\Backup\Test.xls"  
# Setup Excel, open $File and set the the first worksheet
$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $true
$Workbook = $Excel.workbooks.open($file)
$Worksheets = $Workbooks.worksheets
$Worksheet = $Workbook.Worksheets.Item(1)

$SearchString = "1000"  # Danach wird gesucht   

$Range = $Worksheet.Range("G10").EntireColumn  


$Search = $Range.find($SearchString)
if ($search -ne $null) {
	$FirstAddress = $search.Address
	do {
		$Search.value() = "08001700"  
		$search = $Range.FindNext($search)
	} while ( $search -ne $null -and $search.Address -ne $FirstAddress)
}

$WorkBook.Save()
$WorkBook.Close()
[void]$excel.quit()
Jetzt habe ich irgendwie einen Denkfehler. Es wird aktuell nur in der Spalte G gesucht und geändert. Zudem ist es eine .xls, dass heißt er streicht die vorderste 0 weg.
Member: godlie
godlie Jul 10, 2018 at 08:01:52 (UTC)
Goto Top
Hallo,
das dir die vorderste Null abhanden kommt, dürfte an der Formatierung der Zelle liegen.

Ich tippe mal die Zelle hat eine Formatierung des Typs Nummer oder Standart, da kommt das gerne mal vor.

Setz die Formatierung auf Text und deine Null wird nicht mehr verschwinden.
Member: Milord
Milord Jul 10, 2018 at 14:43:53 (UTC)
Goto Top
Ich hab das nun wie folgt hinbekommen.
In der CSV kann ich nun folgendes anwenden
get-ChildItem c:\backup\test.csv | Foreach-Object {Get-Content $_ | Out-String | Foreach-Object {$_.Replace(„1000“,“0800P11700“)} | Set-Content $_}

Wenn ich allerdings eine xls Datei damit anpassen will, dann ist die Datei danach beschädigt. Hat noch jemand einen Tipp für mich?
Member: Kraemer
Kraemer Jul 10, 2018 at 14:46:14 (UTC)
Goto Top
Zitat von @Milord:
Wenn ich allerdings eine xls Datei damit anpassen will, dann ist die Datei danach beschädigt. Hat noch jemand einen Tipp für mich?
Jupp: XLS-Dateien sind Binär-Dateien: https://msdn.microsoft.com/en-us/library/office/cc313154(v=office.12).as ...
Member: Milord
Milord Jul 10, 2018 at 15:06:26 (UTC)
Goto Top
Okay, das wird wohl nichts werden. Dafür sind meine Skript Skills zu schlecht.
Hab das eben zuhause nun soweit hinbekommen, dass er in der Spalte E alles durchsucht und anpasst.
Ich bekomme das aber nicht hin, wie ich das einfach vereinfachen kann, sonst wir das Skript ja 1000 zeichen lang :D

Trotzdem danke für die Antworten.

$File = "c:\Backup\Test.xls"  
$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $true
$Workbook = $Excel.workbooks.open($file)
$Worksheets = $Workbooks.worksheets
$Worksheet = $Workbook.Worksheets.Item(1)

$SearchString = "1000"    

$Range = $Worksheet.Range("E10").EntireColumn  


$Search = $Range.find($SearchString)
if ($search -ne $null) {
	$FirstAddress = $search.Address
	do {
		$Search.value() = "08001700"  
		$search = $Range.FindNext($search)
	} while ( $search -ne $null -and $search.Address -ne $FirstAddress)
}

$WorkBook.Save()
$WorkBook.Close()
[void]$excel.quit()
Member: colinardo
Solution colinardo Jul 10, 2018 updated at 15:23:26 (UTC)
Goto Top
Servus,
ersetzt alle Zellen die genau dem Suchstring entsprechen:
Das $objExcel.Visible = $true ist optional und zeigt dir nur das etwas passiert.
# Quelldatei
$quelle = 'D:\demo.xls'  
# Suchstring
$searchString = '1000'  
# Ersetzungs String 
$replaceWith = '0800P11700'  

# Excel Objekt
$objExcel = New-Object -Com Excel.Application
# Mappe öffnen
$wb = $objExcel.Workbooks.Open($quelle)
# Excel anzeigen, Dialoge und Screenupdating deaktivieren
$objExcel.Visible = $true
$objExcel.DisplayAlerts = $false
# Finde Zellen mit dem Inhalt
$wb.Sheets.Item(1).UsedRange | ?{$_.Value() -eq $searchString} | %{
    # Zellenformat auf Text setzen
    $_.NumberFormat = "@"  
    # Wert setzen
    $_.Value() = $replaceWith 
}
# Datei speichern, Dialoge und Screenupdating wieder einschalten
$wb.Save()
$objExcel.DisplayAlerts = $true
# Dokument schließen
$wb.Close($true)
# Excel schließen
$objExcel.Quit()
# Ressourcen freigeben
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($objExcel)
Grüße Uwe
Member: Milord
Milord Jul 11, 2018 at 10:21:14 (UTC)
Goto Top
Vielen Dank. Nun sehe ich, dass ich komplett falsche Ansätze hatte.
Ich muss mich wohl einfach mehr mit Powershell beschäftigen.
Nun muss ich noch die Spaltengröße anpassen, das werde ich mir wohl irgendwie zurechtbasteln können.
Member: colinardo
Solution colinardo Jul 11, 2018 updated at 10:45:29 (UTC)
Goto Top
Nun muss ich noch die Spaltengröße anpassen
Kein Thema, folgendes passt alle Spalten mit Daten automatisch an den Inhalt an:
$wb.Sheets.Item(1).UsedRange.EntireColumn.Autofit()
Ich muss mich wohl einfach mehr mit Powershell beschäftigen.
Alls das was hier genutzt wird kommt aus VBA, d.h. vieles kannst du direkt aus Makros übernehmen, aber es gibt einige Ausnahmen für Konstanten und Eigenheiten bei der Nutzung mit der Powershell etc.pp.

Wenns das dann war, den Beitrag bitte noch auf gelöst setzen, und Lösungen markieren. Merci.
Member: Milord
Milord Jul 11, 2018 at 14:50:16 (UTC)
Goto Top
Habe ich gemacht.

Für alle die es interessiert, sieht der Code nun wie folgt aus.
# Quelldatei 
$quelle = 'C:\backup\test.xls'   
# Suchstring 
$searchString = '1000'   
# Ersetzungs String  
$replaceWith = '0800P11700'   
# Excel Objekt 
$objExcel = New-Object -Com Excel.Application 
# Mappe öffnen 
$wb = $objExcel.Workbooks.Open($quelle) 
# Excel anzeigen, Dialoge und Screenupdating deaktivieren 
$objExcel.Visible = $true 
$objExcel.DisplayAlerts = $false 
# Finde Zellen mit dem Inhalt 
$wb.Sheets.Item(1).UsedRange | ?{$_.Value() -eq $searchString} | %{ 
    # Zellenformat auf Text setzen 
    $_.NumberFormat = "@"   
    # Wert setzen 
    $_.Value() = $replaceWith  
} 
$wb.Sheets.Item(1).UsedRange.EntireColumn.Autofit()
# Datei speichern, Dialoge und Screenupdating wieder einschalten 
$wb.Save() 
$objExcel.DisplayAlerts = $true 
# Dokument schließen 
$wb.Close($true) 
# Excel schließen 
$objExcel.Quit() 
# Ressourcen freigeben 
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($objExcel)

Nun stehe ich aber vor dem nächsten Problem, wo ich eigentlich bis vorhin dachte, dass es klappt.
Ich wollte nun mehrere Änderungen machen. Dafür wollte ich mehrmals hintereinander folgenden Befehl einfügen.
$searchString = '1000'   
# Ersetzungs String  
$replaceWith = '0800P11700'   
Das klappt aber nicht, ich meine das hat vorhin noch funktioniert.
Member: Kraemer
Kraemer Jul 11, 2018 at 15:01:15 (UTC)
Goto Top
Zitat von @Milord:
Nun stehe ich aber vor dem nächsten Problem, wo ich eigentlich bis vorhin dachte, dass es klappt.
Ich wollte nun mehrere Änderungen machen. Dafür wollte ich mehrmals hintereinander folgenden Befehl einfügen.
$searchString = '1000'   
> # Ersetzungs String  
> $replaceWith = '0800P11700'   
das kannst du 1.000.000 mal machen - wird sich aber auf deine Datei nicht auswirken

Das klappt aber nicht, ich meine das hat vorhin noch funktioniert.
sicherlich nicht

Was dir fehlt, ist eine Schleife
Member: colinardo
Solution colinardo Jul 11, 2018 updated at 15:05:00 (UTC)
Goto Top
Dazu machst du dir z.B. einfach eine Liste (Hashtable) mit den Such- und Ersetzungsbegriffen und iterierst einfach über diese Liste in einer Schleife
# Quelldatei 
$quelle = 'C:\backup\test.xls'   

$map = @{
    '1000' = '0800P11700'  
    '2000' = '0800XXXX00'  
}

# Excel Objekt 
$objExcel = New-Object -Com Excel.Application 
# Mappe öffnen 
$wb = $objExcel.Workbooks.Open($quelle) 
# Excel anzeigen, Dialoge und Screenupdating deaktivieren 
$objExcel.Visible = $true 
$objExcel.DisplayAlerts = $false 
# Finde Zellen mit dem Inhalt
$map.GetEnumerator() | %{
    # Suchstring 
    $searchString = $_.Key 
    # Ersetzungs String  
    $replaceWith = $_.Value
    $wb.Sheets.Item(1).UsedRange | ?{$_.Value() -eq $searchString} | %{ 
        # Zellenformat auf Text setzen 
        $_.NumberFormat = "@"   
        # Wert setzen 
        $_.Value() = $replaceWith  
    } 
}

$wb.Sheets.Item(1).UsedRange.EntireColumn.Autofit()
# Datei speichern, Dialoge und Screenupdating wieder einschalten 
$wb.Save() 
$objExcel.DisplayAlerts = $true 
# Dokument schließen 
$wb.Close($true) 
# Excel schließen 
$objExcel.Quit() 
# Ressourcen freigeben 
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($objExcel)
Member: Milord
Milord May 21, 2019 at 12:59:54 (UTC)
Goto Top
@colinardo
Darf ich dich nochmal belästigen? Deine Hilfe hat mir nun ein Jahr lang super geholfen und ich konnte noch ein, zwei Dinge am Skript erweitern.

Mittlerweile haben wir aber neue Probleme, wo ich nichtmal weiß, ob ich diese lösen kann.

Erstmal wie folgt. Neben dem Skript von dir, habe ich noch eins, welches eine CSV anpasst, dass funktioniert auch gut.
Der Befehl sieht nun wie folge aus.
(Get-Content $searchFileName) | ForEach-Object { $_ -CReplace "[A-Z]+:", "1000" } | Set-Content "$searchFileName"  

$searchFileName = "C:\\Pfad\test.csv"   
(Get-Content $searchFileName) | ForEach-Object { $_ -CReplace "1000", "0800-1800-0850" } | ForEach-Object { $_ -CReplace "1001", "0900-1900-950" } |Set-Content "$searchFileName"  
Das funktioniert eben nur für csv Dateien.

Mein Problem ist nun, dass wir in den letzten Monaten von Office, zu Libreoffice gewechselt sind und das von dir genannte Skript nicht mehr funktioniert.
Ich hab das nicht hinbekommen es unter Libreoffice zum laufen zu bekommen und google spuckt mir da leider auch nichts aus.
Hättest du vielleicht eine Idee?
Oder jemand anderes?