thomas1972
Goto Top

Gewisse Excel Spalten seperat als einzelne TXT Datei speichern

Hallo,

ich habe eine Frage bzw. Problem.

habe eine CSV Datei, welche ich in Excel öffne,

Diese hat ab Zeile 8 Spalten befüllt ( Spaltenbezeichnung z.b. ID, STATUS, Titel, Description ect...
nun möchte ich folgendes erreichen.

Aus jeder Zeile soll eine sep. TXT Datei erzeugt werden,
Hier möchte ich aber per VBA die Spalten beeinflussen, welche exportiert werden.
Gleichzeitig soll aus 2 Spalten der Dateiname gebildet werden (Sondezeichen die für Dateinamen nicht zulässig sind sollen per "blank" gefiltert werden.

Wie kann dieses am besten umgesetzt werden.

Grüße aus München

Content-Key: 268482

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

Printed on: April 23, 2024 at 20:04 o'clock

Mitglied: 114757
114757 Apr 07, 2015 updated at 18:56:48 (UTC)
Goto Top
Moin,
ich würde das schnell ohne Excel mit Powershell abfackeln geht wesentlich schneller:
Hier ne Demo
function Replace-IllegalPathChars([parameter(ValueFromPipeline=$true)]$string,$replaceString='_'){  
   return ($string -replace '^com[1-9]|^lpt[1-9]|^con|^nul|^prn|[\\/:?<>|"*]',$replaceString)  
}

# Ausgabepfad der einzelnen Zeilen
$outPath = "C:\temp\ordner"  
# Spalten welche exportiert werden sollen
$spalten = "ID","Description","Titel"  

# CSV-Datei importieren ab Zeile 8 als Objekt importieren
$csv = gc "C:\temp\data.csv" | select -skip 7 | convertfrom-csv -Delimiter ";"  

# für jede Zeile der CSV-Datei
$csv | select $spalten | %{
    # setze Namen der Textdatei zusammen aus Spalte 'Description' + '_' + 'Titel' und ersetze illegale Zeichen im Namen 
    $newpath = $outPath + "\" + (($_.Description + "_" + $_.Titel) | Replace-IllegalPathChars -replaceString ' ').Trim()  
    # übertrage die Zeile in die neue Datei
    $_ | convertto-csv -Delimiter ";" -NoTypeInformation | select -skip 1 | set-content $newpath  
}
Gruß jodel32
Member: thomas1972
thomas1972 Apr 10, 2015 updated at 06:29:20 (UTC)
Goto Top
Guten Morgen Jodel32,

danke für das Script,

wollte dieses testen, erhalte aber eine FM, selbst im powershell_ise

PS C:\temp\KB_IM> ps kb.ps1
Get-Process : Es kann kein Prozess mit dem Namen "kb.ps1" gefunden werden. Überprüfen Sie den Prozessnamen, und rufen Sie das Cmdlet erneut auf.
Bei Zeile:1 Zeichen:3

back-to-topps <<<< kb.ps1

+ CategoryInfo : ObjectNotFound: (convert_kb.ps1:String) [Get-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand

Eine Fage habe ich, mit Lerrstellen in dne Zeilen kommt er ohne Probleme klar?
Dein Script sieht nun Modifiziert so aus

function Replace-IllegalPathChars([parameter(ValueFromPipeline=$true)]$string,$replaceString='_'){  
   return ($string -replace '^com[1-9]|^lpt[1-9]|^con|^nul|^prn|[\\/:?<>|"*]',$replaceString)  
}

# Ausgabepfad der einzelnen Zeilen
$outPath = "C:\temp\KB_IM"  
# Spalten welche exportiert werden sollen
$spalten = "Ticket ID","Title","Incident Description","Solution"  

# CSV-Datei importieren ab Zeile 8 als Objekt importieren
$csv = gc "C:\temp\kb_im\Monatsreport_67_7806504256175727660.csv" | select -skip 7 | convertfrom-csv -Delimiter ";"  

# für jede Zeile der CSV-Datei
$csv | select $spalten | %{
    # setze Namen der Textdatei zusammen aus Spalte 'Description' + '_' + 'Titel' und ersetze illegale Zeichen im Namen 
    $newpath = $outPath + "\" + (($_.Ticket ID + "_" + $_.Title) | Replace-IllegalPathChars -replaceString ' ').Trim()  
    # übertrage die Zeile in die neue Datei
    $_ | convertto-csv -Delimiter ";" -NoTypeInformation | select -skip 1 | set-content $newpath  
Mitglied: 114757
114757 Apr 10, 2015 updated at 07:05:02 (UTC)
Goto Top
Moin,
du weißt aber schon das man immer den kompletten Pfad oder den relativen zum Script angeben muss face-wink !!
Wenn du sich im gleichen Verzeichnis wie das Script befindest musst du
.\kb.ps1
schreiben.

Und was soll das ps vor dem Scriptnamen ? Das geht natürlich nicht face-smile ... das ist ja selber ein Alias für das CMDLet get-process... deswegen die Fehlermeldung.

Eine Fage habe ich, mit Lerrstellen in dne Zeilen kommt er ohne Probleme klar?
Was heißt das ? ganze leere Zeilen oder nur Blanks in den Spalten ? Das ist kein Problem ...

Gruß jodel32
Member: thomas1972
thomas1972 Apr 10, 2015 updated at 07:25:08 (UTC)
Goto Top
Nein, das wusste ich nicht, kannte die Powershell vorher nicht.

PS:Aus dem Copy der Fehlermeldung, hat das Forum aus
+ ps <<<<  kb.ps1
ps <<<< kb.ps1
gemacht.

anscheinendkann ich die Powershell nicht nutzen, da ich folgenden Fehler nun erhalte
PS C:\temp\KB_IM> .\kb.ps1
Die Datei "C:\temp\KB_IM\kb.ps1" kann nicht geladen werden, da die Ausführung von Skripts auf diesem System deaktiviert ist. Weitere Informationen erhalten Sie mit "get-help about_signing".  
Bei Zeile:1 Zeichen:17
+ .\kb.ps1 <<<< 
    + CategoryInfo          : NotSpecified: (:) , PSSecurityException
    + FullyQualifiedErrorId : RuntimeException

PS C:\temp\KB_IM> get-executionpolicy
Restricted

auch kann ich dieses nicht aufheben

PS C:\temp\KB_IM> Set-ExecutionPolicy
Set-ExecutionPolicy : Der Zugriff auf den Registrierungsschlüssel "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" wurde verweigert.  
Bei Zeile:1 Zeichen:20
+ Set-ExecutionPolicy <<<< 
    + CategoryInfo          : NotSpecified: (:) [Set-ExecutionPolicy], UnauthorizedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.SetExecutionPolicyCommand


Ich kann zwar die Registry öffnen,
kann / darf aber beschrieben weg nicht durchführen

HKLM\SOFTWARE\Microsoft\PowerShell\1\

Erzeugen des Pfades ShellIds\Microsoft.PowerShell
und somit fällt die Erstellung weg
Type: REG_SZ
Name: "ExecutionPolicy"
value: "Unrestricted"

Somit bleibt die Powershell für mich nicht greifbar..
Welchen Weg gibt es hier sonst noch, ggf über ein VBS Script??

Groß
Thomas1972
Mitglied: 114757
114757 Apr 10, 2015 updated at 07:26:32 (UTC)
Goto Top
Du musst die Executionpolicy in einer administrativen Powershell-Konsole umstellen !
Und dort dann
Set-Executionpolicy RemoteSigned 
eingeben
Mitglied: 114757
114757 Apr 10, 2015 updated at 07:28:43 (UTC)
Goto Top
Zur Info...
@colinardo hat hier auch eine Anfänger Anleitung für Powershell-Scripte gepostet ...
Batch bei bestimmten Wörtern jeweilige Zeile entfernen
Member: thomas1972
thomas1972 Apr 10, 2015 updated at 07:35:51 (UTC)
Goto Top
Hilft mir leider nicht weiter.

Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

PS C:\Windows\system32> Set-ExecutionPolicy

Cmdlet Set-ExecutionPolicy an der Befehlspipelineposition 1
Geben Sie Werte für die folgenden Parameter an:
ExecutionPolicy: Unrestricted

Ausführungsrichtlinie ändern
Die Ausführungsrichtlinie trägt zum Schutz vor nicht vertrauenswürdigen Skripts
 bei. Wenn Sie die Ausführungsrichtlinie ändern, sind Sie möglicherweise den im
 Hilfethema "about_Execution_Policies" beschriebenen Sicherheitsrisiken  
ausgesetzt. Möchten Sie die Ausführungsrichtlinie ändern?
[J] Ja  [N] Nein  [H] Anhalten  [?] Hilfe (Standard ist "J"): j  
Set-ExecutionPolicy : Der Zugriff auf den Registrierungsschlüssel "HKEY_LOCAL_M  
ACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" wurde ver  
weigert.
Bei Zeile:1 Zeichen:20
+ Set-ExecutionPolicy <<<<
    + CategoryInfo          : NotSpecified: (:) [Set-ExecutionPolicy], Unautho
   rizedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.Pow
   erShell.Commands.SetExecutionPolicyCommand

PS C:\Windows\system32>


Keine Rechte, wie vorher beschrieben.
Somit ist die Powershell für mich weiterhin verschlossen.
Mitglied: 114757
114757 Apr 10, 2015 updated at 08:19:24 (UTC)
Goto Top
OK also bist du Domain-User ohne lokale Admin-Rechte ?
Na dann ... melde ich mich später nochmal mit einem VBS.

Ist das korrekt das die Werte/Überschriften erst ab Zeile 8 in der CSV stehen ? wenn ja, mit welchem Delimiter sind die Spalten voneinander getrennt ?

Am besten du postest hier mal die ersten 10 Zeilen als Beispiel, so sind Missverständnisse ausgeschlossen.

Gruß jodel32
Member: thomas1972
thomas1972 Apr 10, 2015 updated at 08:58:40 (UTC)
Goto Top
Hallo Jodel32,

danke für deine Hilfe,
leider ja, keine Rechte


Monatsreport;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;
Evaluation Period;;01.03.2015 to 31.03.2015;;;;;;;;;;;;;;
Definition;;The report shows all incidents which were active in the reporting period. By selecting additional attributes the user is able to build his individual detail report.;;;;;;;;;;;;;;
Scope;;XXXX;;;;;;;;;;;;;;
Data Range;;XXXXXX;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;
No.;Ticket ID;Incident Status;Location;Title;Incident Description;Solution;;CI;Open Time;Close Time;VW ISH Cause Code;Prio;Ticket Type;Layer 1;Layer 2;Layer 3
1;IM11111;Closed;DExxx;Test123;"gfgdggf  
gfdg
dg
gfgdggf";;Test12343;25.03.2015;26.03.2015;Customer KnowHow;5;Additional Info;Interfaces;;  
2;IM234545;Transferred;DExxx;...ist der Kunde Löschmarkiert ....;"gergergerger  
gergergergergera";;Test34455;26.03.2015;;;5;Additional Info;Process;Used Cars;Akt  
3;IM678766;Working;DExxx;nicht erreicht !! ....nicht möglich;"rgtergerg  
gergergerger";;;znhtnbhgffhg;08.10.2013;;;5;Incident;Function;;  

In den jeweiligen Spalten können Texte stehen welche deutlich länger und Umgebrochen werden,
Jede Zeile beginnt aber mit einer fortlaufenden Nummer (NO)
Es können aber hier und da mal Spalten hinzukommen / wegfallen, daher ist es wichtig, dass ich diese im Vorfeld beeinflussen kann.
Mitglied: 114757
114757 Apr 10, 2015 updated at 11:09:08 (UTC)
Goto Top
Hier der VBA-Code für dein Excel-Sheet. Kommentare findest du im Code.
http://we.tl/k4FAFMiqSl
Sub ExportData()
    'Ausgabe-Pfad für die neuen Dateien  
    Const OUTPATH = "C:\temp\ordner"  
    Dim rngTable As Range, strNewFile As String, cell As Range, fso As Object, arrBuildNameFromColumns As Variant, arrColumns As Variant
    Set fso = CreateObject("Scripting.FileSystemObject")  
    'Array der zu exportierenden Spalten (beginnend mit 0)  
    arrColumns = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
    'Spalten aus denen der Name der Datei gebildet wird (beginnt mit 0 zu zählen)  
    arrBuildNameFromColumns = Array(3, 4)
    
    With ActiveSheet
        'Anzahl der Zeilen ermitteln  
        Set rngRows = .Range("A9:A" & .Cells(Rows.Count, "A").End(xlUp).row)  
        'Für jede Zeile  
        For Each cell In rngRows
            'Array der Spalten der aktuellen Zeile  
            Dim arrLine()
            ReDim arrLine(UBound(arrColumns))
            'Die gewünschten Spalten ins Array schreiben  
            For i = 0 To UBound(arrColumns)
                arrLine(i) = cell.Offset(0, arrColumns(i)).Value
            Next
            'Neuen Dateinamen zusammensetzen  
            strNewFile = OUTPATH & "\" & ReplaceIllegalChars(arrLine(arrBuildNameFromColumns(0)) & "_" & arrLine(arrBuildNameFromColumns(1))) & ".csv"  
            'Zeile in neue Datei schreiben  
            fso.OpenTextFile(strNewFile, 2, True).WriteLine (Join(arrLine, ";"))  
        Next
    End With
    Set fso = Nothing
End Sub

'Funktion um Sonderzeichen durch ein Leerzeichen zu ersetzen  
Function ReplaceIllegalChars(strText)
    Set regex = CreateObject("vbscript.regexp")  
    regex.Pattern = "[\\/:?<>|""*]"  
    regex.Global = True
    ReplaceIllegalChars = regex.Replace(strText, " ")  
    Set regex = Nothing
End Function
Gruß jodel
Member: thomas1972
thomas1972 Apr 10, 2015 updated at 13:32:39 (UTC)
Goto Top
Hallo Jodel,

vielen Dank für deine Hilfe.

ich habe deinen code an ein paar stellen ( Spalten anpassen, Länge der auszugebenen Datei beschränken )
funktioniert soweit gut.

Sub KB_einlesen()
    'Ausgabe-Pfad für die neuen Dateien  
    Const OUTPATH = "C:\temp\KB_IM"  
    Dim rngTable As Range, strNewFile As String, cell As Range, fso As Object, arrBuildNameFromColumns As Variant, arrColumns As Variant
    Set fso = CreateObject("Scripting.FileSystemObject")  
    'Array der zu exportierenden Spalten (beginnend mit 0)  
    arrColumns = Array(1, 3, 4, 5, 6)
    'Spalten aus denen der Name der Datei gebildet wird (beginnt mit 0 zu zählen)  
    arrBuildNameFromColumns = Array(0, 2)
    
    With ActiveSheet
        'Anzahl der Zeilen ermitteln  
        Set rngRows = .Range("A9:A" & .Cells(Rows.Count, "A").End(xlUp).Row)  
        'Für jede Zeile  
        For Each cell In rngRows
            'Array der Spalten der aktuellen Zeile  
            Dim arrLine()
            ReDim arrLine(UBound(arrColumns))
            'Die gewünschten Spalten ins Array schreiben  
            For i = 0 To UBound(arrColumns)
                arrLine(i) = cell.Offset(0, arrColumns(i)).Value
            Next
            'Neuen Dateinamen zusammensetzen  
            If Len(arrLine(arrBuildNameFromColumns(1))) > 100 Then
            arrLine(arrBuildNameFromColumns(1)) = Left(arrLine(arrBuildNameFromColumns(1)), 100)
            End If
            strNewFile = OUTPATH & "\" & ReplaceIllegalChars(arrLine(arrBuildNameFromColumns(0)) & "_" & arrLine(arrBuildNameFromColumns(1))) & ".txt"  
            'Zeile in neue Datei schreiben  
            fso.OpenTextFile(strNewFile, 2, True).WriteLine (Join(arrLine, ";"))  
        Next
    End With
    Set fso = Nothing
End Sub

'Funktion um Sonderzeichen durch ein Leerzeichen zu ersetzen  
Function ReplaceIllegalChars(strText)
    Set regex = CreateObject("vbscript.regexp")  
    regex.Pattern = "[\\/:?<>|""*]"  
    regex.Global = True
    ReplaceIllegalChars = regex.Replace(strText, " ")  
    Set regex = Nothing
End Function

Es erfolgt ein Fehler dass er den Pfad nicht findet, sobald die Spalten welche ich Vorgebe leer sind.
Gleichzeitig ist das Problem, dass er die Werte nicht jeweils untereinander schreibt, sondern als zusammenhägenden String ausgibt.

Besteht die Möglichkeit dieses ( Beispiel )

IMxxxxx;Dxxxx - Test;dieses ist der Titel;dieses ist ein Beispieltext
und sollte untereinder stehen......;

in folgender Weise auzugeben?
Spaltenbezeichnung (Aray 1):
IMxxxxx
Spaltenbezeichnung (Aray 3): 
Dxxxx - Test;

Spaltenbezeichnung(Aray 4):
dieses ist der Titel

Spaltenbezeichnung: (Aray 5)
dieses ist ein Beispieltext
und sollte untereinder stehen......
...

Grüße aus München
Mitglied: 114757
114757 Apr 10, 2015, updated at Apr 11, 2015 at 08:32:26 (UTC)
Goto Top
Es erfolgt ein Fehler dass er den Pfad nicht findet, sobald die Spalten welche ich Vorgebe leer sind
Was soll dann deiner Meinung nach passieren, das kann man natürlich mit einer einfachen IF-Abfrage prüfen .. was in diesem Fall passieren soll weißt nur du face-wink Da gibt's ja 1001 Möglichkeiten (Random string generieren, File auslassen, etc)
Im unten stehenden Code wird einfach unspecified ergänzt. Ich gehe mal davon aus das die No. aber nicht leer ist, wenn das der Fall ist musst du diesen Fall unten noch ergänzen.
Gleichzeitig ist das Problem, dass er die Werte nicht jeweils untereinander schreibt, sondern als zusammenhägenden String ausgibt.
wurde ja eingangs nicht erwähnt face-wink, war davon ausgegangen das die Zeile so wie sie ist übertragen werden sollte.

Ist aber kein Problem, indem Fall dann etwas abgeändert:
Sub KB_einlesen()
    'Ausgabepfad der neuen Dateien  
    Const OUTPATH = "C:\temp\KB_IM"   
    Dim rngTable As Range, strNewFile As String, cell As Range, fso As Object, arrBuildNameFromColumns As Variant, arrColumns As Variant, strPart1 as String, strPart2 as String
    Set fso = CreateObject("Scripting.FileSystemObject")  
    'Array der zu exportierenden Spalten (beginnend mit 0)  
    arrColumns = Array(1, 3, 4, 5, 6)
    'Spalten aus denen der Name der Datei gebildet wird (beginnt mit 0 zu zählen)  
    arrBuildNameFromColumns = Array(0, 2)
    
    With ActiveSheet
        'Anzahl der Zeilen ermitteln  
        Set rngRows = .Range("A9:A" & .Cells(Rows.Count, "A").End(xlUp).row)  
        'Für jede Zeile  
        For Each cell In rngRows
            'Werte für den Dateinamen  
            strPart1 = cell.Offset(0, arrBuildNameFromColumns(0)).Value
            strPart2 = cell.Offset(0, arrBuildNameFromColumns(1)).Value
            'Wenn länge des zweiten Parts länger als 100 Zeichen, kürzen  
            If Len(strPart2) > 100 Then
                strPart2 = Left(strPart2, 100)
            End If
            'Neuen Dateinamen zusammensetzen / wenn  Incident Status leer ist schreibe stattdessen 'unspecified' als Name der Textdatei  
            If strPart2 <> "" Then  
                strNewFile = OUTPATH & "\" & ReplaceIllegalChars(strPart1 & "_" & strPart2) & ".txt"  
            Else
                strNewFile = OUTPATH & "\" & ReplaceIllegalChars(strPart1) & "_" & "unspecified.txt"  
            End If
            'Neue Textdatei erstellen  
            Set f = fso.CreateTextFile(strNewFile, True, True)
            
            'Die gewünschten Spalten in die Textdatei schreiben  
            For i = 0 To UBound(arrColumns)
                f.WriteLine .Range("A8").Offset(0, arrColumns(i)).Value & ":"   'Spaltenüberschrift  
                f.WriteLine cell.Offset(0, arrColumns(i)).Value                 'Spaltenwert  
                f.WriteLine ""                                                  'Leerzeile  
            Next
            'Datei schließen  
            f.Close
        Next
    End With
    Set fso = Nothing
End Sub

'Funktion um Sonderzeichen durch ein Leerzeichen zu ersetzen  
Function ReplaceIllegalChars(strText)
    Set regex = CreateObject("vbscript.regexp")  
    regex.Pattern = "[\\/:?<>|""*]"  
    regex.Global = True
    ReplaceIllegalChars = regex.Replace(strText, " ")  
    Set regex = Nothing
End Function
Gruß jodel32
Member: thomas1972
thomas1972 Apr 13, 2015 at 08:09:51 (UTC)
Goto Top
Vielen vielen Danke für deine Ausführliche Hilfe.
Super Toll..