behandelte Themen
0.
Basisfunktionen von Excel
1.1Starten von Excel
Beispiel 1: Starten von Excel mit einer existierenden Arbeitsmappe
Beispiel 2: Starten von Excel mit einer neuen Arbeitsmappe
Beispiel 3: Anzeige aller registrierten Com-Objekte
1.2Beenden von Excel
Beispiel 1: SaveAs() und Quit()Tabellen in Excel
2.1Zellen
2.1.1Zellen beschreiben und formatieren
Beispiel 1: Zellen beschreiben und formatieren
2.1.2Zellen mit Skriptergebnisse beschreiben
Beispiel 1: Prozesseigenschaften in Excel darstellenDiagramme oder Charts
Beispiel 1: Diagramm erstellenDaten
4.1Tabellen sortieren
Beispiel 1: Tabelle sortierenSonstiges
5.1Farben / Colors
5.1.1Farbauswahl über den ColorIndex
Beispiel 1: Farben des Colorindexes auflisten
5.1.2Farbdarstellung über RGB
5.2Erforschen von Excelklassen und Objekten
5.2.1Excel Entwicklertool anzeigen
5.2.1.1Makroeditor
5.2.1.2Objektkatalog
5.2.1.3MSDN
******************************************************************************************************
0 Einleitung
Ein Nachteil der Powershell oder generell von Skriptsprachen gegenüber ausgewachsenen Programmiersprachen ist die eingeschränkte Möglichkeit mit Daten grafisch umzugehen. Man kann die Klasse Windows.Forms verwenden, bestes Beispiel ist der WMI-Explorer von thepowershellguy.com, komfortabel zum Programmieren ist das allerdings nicht.
Bei der Eingabe verzichten Administratoren gerne auf Masken mit Eingabefeldern zugunsten der Commandline mit einfachen Textdateien, während bei der Ausgabe eine grafische Darstellung von Daten zur Analyse manchmal durchaus hilfreich ist. Dafür bietet sich eine Aufbereitung solcher von Powershell erzeugter Daten mit Microsoft Excel an.
Excel lässt sich weitgehend von außen über die Powershell steuern, so dass man für die Eingabe der Daten, die Formatierung von Zellen, das Sortieren von Tabellen, die Erstellung von Diagrammen und vieles mehr innerhalb von Excel selbst keine Aktionen durchführen braucht. Das verhindert möglicherweise den einen oder anderen Bedienungsfehler.
1 Basisfunktionen von Excel
1.1 Starten von Excel
Beispiel 1: Starten von Excel mit einer existierenden Arbeitsmappe
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$filepath="C:\Powershell\mappe1.xls"
$workbook=$excel.Workbooks.open($filepath)
Beispiel 2: Starten von Excel mit einer neuen Arbeitsmappe
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$workbook=$excel.Workbooks.add()
$worksheet=$excel.worksheets.add()
In jeweils der ersten Zeile der beiden Beispiele wird das ComObjekt "$excel" erstellt, mit dem wir alle weiteren Funktionen ausführen werden.
Die visible-Eigenschaft gibt an, ob die Ausführung des Skripts sichtbar oder unsichtbar ablaufen soll.
Beispiel 3: Anzeige aller registrierten Com-Objekte
$a = dir REGISTRY::HKEY_CLASSES_ROOT -include PROGID -recurse | foreach {$_.GetValue("")}
$a|Where{$_ -like "*Excel*"}
1.2 Beenden von Excel
Beispiel 1: Speichern mit SaveAs() und Beenden mit Quit()
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$workbook=$excel.Workbooks.add()
$worksheet=$excel.worksheets.add()
start-sleep 2 #Pause von 2 Sekunden
$filepath="C:\Powershell\mappe2.xls" #Pfad muss vorhanden sein
$workbook.SaveAs($filepath)
$excel.Application.DisplayAlerts = $False #.Application muss nicht sein
$excel.quit()
$ExcelProcess=get-process excel
$ExcelProcess | foreach {stop-process ($_.id)}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) #Entfernen des ComObjekts aus dem Speicher
- Der erste Teil des Skripts öffnet Excel wie unter 1.1 schon beschrieben.
- die Methode SaveAs speichert die Arbeitsmappe auf den angegebenen Pfad
- Die Eigenschaft DisplayAlerts steuert, ob Hinweise, wie nach dem Speichern einer Arbeitsmappe, angezeigt werden sollen.
- Die quit()-Methode beendet das Programm
- $ExcelProcess | foreach {stop-process ($_.id)} stoppt alle Excelprozesse
- [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel): Ohne Aufruf dieses Befehls bleibt nach Beenden von Excel das ComObjekt $excel im Arbeitsspeicher.
Die spannende Frage ist nun, wie man die eingesetzten Methoden .add(), saveAs(), quit() oder die Eigenschaft .displayalerts() erhält. Zwei mögliche Antworten gibt der nächste Abschnitt
2 Tabellen in Excel
2.1 Zellen
Um auf Zellen in Excel zugreifen zu können, muss man den Excelobjektbaum von der Excelapplikation bis zur Zelle durchlaufen
Application (=Com-Objekt) -> Workbook (=Arbeitsmappe) -> Worksheet (=Arbeitsblatt) -> Cells (Zellen) oder Range (Bereich)
2.1.1 Zellen beschreiben und formatieren
Im folgenden Skript zeige ich einige Beispiele, Zellen in Excel mit Werten und Formeln zu füllen, sowie das Formatieren von Zellen.
In meiner Entwicklungsumgebung habe ich dieses Skript in die powershell_ise.exe geladen und auf einem zweiten Bildschirm wird die von dem Skript erzeugte Arbeitsmappe angezeigt.
Beim ersten Aufruf des Skripts wird bei $excel.close ein ignorierbarer Fehler erscheinen, da noch kein $excel existiert. Die Erklärung steht unten nach dem Skript.
Das Skript ist auf deutschem Excel 2003(WinXP) und 2007(Win7) getestet
Beispiel 1: Zellen beschreiben und formatieren
#Abschnitt A)*****************************************************
if($excel){
$excel.Application.DisplayAlerts = $false
$excel.quit()
$ExcelProcess=get-process excel
$ExcelProcess | foreach {stop-process ($_.id)}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | out-null
}
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$workbook=$excel.Workbooks.add()
$sheet = $workbook.Worksheets.Item(1)
#Abschnitt B)*****************************************************
#Zellen mit Werten füllen
$sheet.Cells.Item(1,2).value2="Hallo Powershell"
$sheet.Range("B3").value2=$sheet.Range("B1").text
#Zellen mit Formeln füllen
$sheet.Range("D2:F2").FormulaR1C1="3"
$sheet.Range("D3:F3").FormulaR1C1="4"
$sheet.Range("D4:F4").FormulaR1C1="5"
$sheet.Range("D5").Formula = "=Summe(D2:D4)"
$sheet.Cells.Item(5,5).Value2 = "=Mittelwert(`$E`$2:E4)"
$sheet.Range("F5").FormulaR1C1 = "=Produkt(Z2S6:Z4S6)"
#Abschnitt C)*****************************************************
#Zellen formtiern
$green=10 #Colorindex
$red=0x000000FF #RGB in Hex
$sheet.Range("D2:F2").Numberformat="00,00"
$sheet.Range("D5").Interior.ColorIndex = $green
$sheet.Range("E5").Interior.Color = $red
$sheet.Range("F5").Font.Size = 15
$sheet.Range("F5").Font.Bold = $true
# $sheet.Range("F5").Font.Fontstyle = "Fett" #alternativ zur .Bold-Property
$sheet.Range("F5").Font.Strikethrough = $true
$sheet.Range("F5").Orientation=45
#$range = $sheet.usedRange
#$range.EntireColumn.AutoFit() | out-null #autom. Anpassen der Spaltenbreiten
Das Ergebnis sieht in Excel so aus:
(Die untere Formelansicht kann man mit "STRG+#" ein- und ausschalten)
Erläuterungen zu Beispiel 1
Abschnitt A)
#Abschnitt A)*****************************************************
if($excel){
$excel.Application.DisplayAlerts = $false
$excel.quit()
$ExcelProcess=get-process excel
$ExcelProcess | foreach {stop-process ($_.id)}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | out-null
}
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$workbook=$excel.Workbooks.add()
$sheet = $workbook.Worksheets.Item(1)
if($excel){
Dieser Abschnitt schliesst automatisch ein vorhandenes Excel-Objekt $excel. Beim ersten Aufruf dieses Skripts wird dieser Befehl umgangen, da $excel noch nicht exisitert und die if-Abfrage $false liefert. Dadurch bekommt man nicht nach jedem Testlauft eine zusätzliche, offene Excelmappe auf den Desktop.
$excel.Application.DisplayAlerts = $false
Verhindert, dass beim Beenden von Excel nachgefragt wird, ob die Datei gespeichert werden soll
$excel.quit()
Schliessen des Com-Objektes
$ExcelProcess=get-process excel
$ExcelProcess | foreach {stop-process ($_.id)}
Beendet alle Excel Processe
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | out-null
Entfernt ein altes Com-Objekt aus dem Speicher. (siehe unter
$excel = new-object -comobject excel.application
Hier wird das Wurzelobjekt erzeugt, von dem wir alle weiteren Obekte ableiten können. Sollte hier ein Fehler auftauchen "Altes Format oder ungültige Typbibliothek" dann liegt das an Schwierigkeiten zwischen der Betriebssystem- und der Officesprache (siehe
$excel.visible = $true
wir wollen schliesslich etwas sehen
$workbook=$excel.Workbooks.add()
Hinzufügen einer neuen Arbeitsmappe
$sheet = $workbook.Worksheets.Item(1)
Das erste Tabellenblatt wird als Objekt $sheet angelegt. Statt Item(1) funktioniert auch die Angabe des Tabellennamens: $sheet = $workbook.Worksheets.Item("Tabelle1")
Möchte man mit einer bestehenden Arbeitsmappe arbeiten, so kann man die beiden letzten Zeilen in Abschnitt A) ersetzen durch
$filepath="C:\Powershell\PPraxis\Arbeitsmappen\mappe1.xls"
$workbook=$excel.Workbooks.open($filepath)
$sheet = $workbook.Worksheets.Item(1)
wobei dann die übrigen Abschnitte keinen Sinn mehr ergeben.
Abschnitt B)
#Zellen mit Werten füllen
$sheet.Cells.Item(1,2).value2="Hallo Powershell"
$sheet.Range("B3").value2=$sheet.Range("B1").text
#Zellen mit Formeln füllen
$sheet.Range("D2:F2").FormulaR1C1="3"
$sheet.Range("D3:F3").FormulaR1C1="4"
$sheet.Range("D4:F4").FormulaR1C1="5"
$sheet.Range("D5").Formula = "=Summe(D2:D4)"
$sheet.Cells.Item(5,5).Value2 = "=Mittelwert(`$E`$2:E4)"
$sheet.Range("F5").FormulaR1C1 = "=Produkt(Z2S6:Z4S6)"
$sheet.Cells.Item(1,2).value2="Hallo Powershell"
Warum die Eigenschaft Value2 lautet, kann ich nicht sagen. Führt man an dieser Stelle ein "$sheet.Cells.Item(1,2) | get-member aus, so taucht in den Properties nur Value2 und kein Value auf. Die Fähigkeiten von get-member zum Erforschen von Eigenschaften und Methoden sind
$sheet.Range("B3").value2=$sheet.Range("B1").text
Kopieren des Inhalts von B1 nach B3. Die Eigenschaft .text ist readonly
Die Zelle wird mit dem A1-Bezugssystem angesprochen
$sheet.Range("D2:F2").FormulaR1C1="3"
Befüllen des Ranges D2:F2 mit dem Wert 3
$sheet.Cells.Item(5,5).Value2 = "=Mittelwert(`$E`$2:E4)"
Die Zelle E5 wird mit ihrem Spalten- und Zeilenindex (5,5) angesprochen. Diese Schreibweise ist am Besten für die Verwendung von Schleifen geeignet.
Der Inhalt von E5 ist die ExcelFormel Mittelwert, die mit absoluten Zellbezügen $E$2 arbeitet. Der Backtick verhindert, dass Powershell das $-Zeichen als den Beginn einer Variablen ansieht.
$sheet.Range("F5").FormulaR1C1 = "=Produkt(Z2S6:Z4S6)" #Z1S1 - Schreibweise
die Z1S1-Notation ist veraltet. In den ExcelOptionen kann diese Notation generell eingeschaltet werden.
Abschnitt C)
#Abschnitt C)*****************************************************
#Zellen formtiern
$green=10 #Colorindex
$red=0x000000FF #RGB in Hex
$sheet.Range("D2:F2").Numberformat="00,00"
$sheet.Range("D5").Interior.ColorIndex = $green
$sheet.Range("E5").Interior.Color = $red
$sheet.Range("F5").Font.Size = 15
$sheet.Range("F5").Font.Bold = $true
# $sheet.Range("F5").Font.Fontstyle = "Fett" #alternativ zur .Bold-Property
$sheet.Range("F5").Font.Strikethrough = $true
$sheet.Range("F5").Orientation=45
#$range = $sheet.usedRange
#$range.EntireColumn.AutoFit() | out-null #autom. Anpassen der Spaltenbreiten
Hier wird gezeigt, wie man Zellen formatieren kann. Die Eigenschaften habe ich aus einem aufgezeichneten Makro erhalten
$green=10 #Colorindex
$red=0x000000FF #RGB in Hex
Auf die Farben gehe ich in
$sheet.Range("D2:F2").Numberformat="00,00"
"00,00" bedeutet 2 Stellen vor und 2 Stellen nach dem Komma
Auf die Formatierungsmöglichkeiten gehe ich im
#$range = $sheet.usedRange
#$range.EntireColumn.AutoFit() | out-null #autom. Anpassen der Spaltenbreiten
Damit kann man die Spaltenbreiten des benutzten Bereichs auf dem Tabellenblatt anpassen
2.1.2 Zellen mit Skriptergebnissen befüllen
Beispiel 1: Prozesseigenschaften in Excel darstellen
#Abschnitt A)*****************************************************
# Erklärung siehe Beispiel 1 in Kapitel 2.1.1 Abschnitt A)
if($excel){
$excel.Application.DisplayAlerts = $false
$excel.quit()
$ExcelProcess=get-process excel
$ExcelProcess | foreach {stop-process ($_.id)}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | out-null
}
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$workbook=$excel.Workbooks.add()
$sheet = $workbook.Worksheets.Item(1)
#Abschnitt B)*****************************************************
#Zellen mit Werten füllen
$sheet.Cells.Item(1,2).value2="Name"
$sheet.Cells.Item(1,3).value2="Handles"
$sheet.Cells.Item(1,4).value2="Workingset"
$sheet.Cells.Item(1,5).value2="CPU(s)"
$sheet.range($sheet.cells.item(1,2),$sheet.cells.item(1,5)).Font.Bold = $true
$i=2
get-process | sort cpu -desc | select -first 10 | foreach {
$sheet.Cells.Item($i,2).value2="{0}" -f $_.name
$sheet.Cells.Item($i,3).value2="{0}" -f $_.handlecount
$sheet.Cells.Item($i,4).value2="{0}" -f $_.workingset
$sheet.Cells.Item($i,5).value2="{0:f}" -f $_.cpu
$i++
}
$range = $sheet.usedRange
$range.EntireColumn.AutoFit() | out-null #autom. Anpassen der Spaltenbreiten
#Skript 2.1.2a

3 Diagramme - Charts
Beispiel 1: Diagramm erstellen
Das folgende Skript dient hier nur zu Demozwecken, wie ein ExcelChart vielfältig von der Powershell aus formatiert werden kann.
Die Hilfsmittel zur richtigen Syntax sind der Makroeditor in Excel, sowie die get-member Methode von Powershell.
#Abschnitt A)*****************************************************
# Erklärung siehe Skript 2.1.1a Abschnitt A)
if($excel){
$excel.Application.DisplayAlerts = $false
$excel.quit()
$ExcelProcess=get-process excel
$ExcelProcess | foreach {stop-process ($_.id)}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | out-null
}
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$workbook=$excel.Workbooks.add()
$sheet = $workbook.Worksheets.Item(1)
#Abschnitt B) ***********************************************
#Arbeitsblatt mit Werten füllen , siehe Skript 2.1.2a
$i=2
$sheet.Cells.Item(1,2).value2="Name"
$sheet.Cells.Item(1,3).value2="cpu"
$sheet.range($sheet.cells.item(1,2),$sheet.cells.item(1,3)).Font.Bold = $true
get-process | sort cpu -desc | select -first 5 | foreach {
$sheet.Cells.Item($i,2).value2="{0}" -f $_.name
$sheet.Cells.Item($i,3).value2="{0}" -f $_.cpu
$i++
}
#Abschnitt C)*****************************************************
#Chart erstellen und in Tabelle einbetten
#BasisDiagrmm erstellen
$sheet.range("b1").select()
$excel.Selection.CurrentRegion.Select()
$workbook.charts.add() | out-null
$workbook.ActiveChart.Location(2,$($sheet.name)) | out-null #Chart in Tabellenblatt einbinden
#Abschnitt D)*****************************************************
#ChartType
$workbook.ActiveChart.chartType = 65
#Linienstyle
$workbook.ActiveChart.seriescollection(1).border.LineStyle = -4118 #(Dashdot)
#weitere LineStyles unter msdn.microsoft.com/en-us/library/bb241348(v=office.12).aspx
#Abschnitt E)*****************************************************
#Beschriftungen
#Überschrift
$workbook.ActiveChart.hasTitle=$true #titel erscheint oder nicht
$workbook.ActiveChart.ChartTitle.Text = "die Überschrift"
#Achsenbeschriften
$workbook.ActiveChart.Axes(1).HasTitle = $True
$workbook.ActiveChart.Axes(2).HasTitle = $True
$workbook.ActiveChart.Axes(1).AxisTitle.Text = "die x-Achse"
$workbook.ActiveChart.Axes(2).AxisTitle.Text = "die y-Achse"
$workbook.ActiveChart.Axes(1).AxisTitle.font.ColorIndex=46 #siehe Abschnitt Farben
$workbook.ActiveChart.Axes(1).AxisTitle.Font.Bold=$true
$workbook.ActiveChart.Axes(1).AxisTitle.Font.Size=15
#Abschnitt F)*****************************************************
#Zeichnungsfläche formatieren
$workbook.ActiveChart.PlotArea.Fill.TwoColorGradient(1,4) #zweifarbiger Fülleffekt
$workbook.ActiveChart.PlotArea.Fill.ForeColor.SchemeColor=45
$workbook.ActiveChart.PlotArea.Fill.BackColor.SchemeColor=8

Erläuterungen zu Beispiel 1
#Abschnitt C)*****************************************************
#Chart erstellen und formatieren
#BasisDiagrmm erstellen
$sheet.range("b1").select()
$excel.Selection.CurrentRegion.Select()
$workbook.charts.add() | out-null
$workbook.ActiveChart.Location(2,$($sheet.name)) | out-null #Chart in Tabellenblatt einbinden
$sheet.range("b1").select()
$range=$excel.Selection.CurrentRegion.Select()
die beiden Zeilen haben denselben Effekt, wie ein "STRG+*". Die gesamte Tabelle um "B1" herum, wird damit ausgewählt.
$workbook.charts.add() | out-null
Ein neues Diagramm wird der Arbeitsmappe hinzugefügt, zunächst als eigenes Blatt
$workbook.ActiveChart.Location(2,$($sheet.name)) | out-null #Chart in Tabellenblatt einbinden
# Alternativ: $workbook.ActiveChart.Location(2,"Tabelle1") | out-null
Mit diesem Befehl und dem Wert "2" der XlChartLocation wird das Diagramm als Objekt in die Exceltabelle eingebettet.
die Auflistung der Enumerations für XLChartLocation finden sich hier
#Excel 2007
#Excel 2003
#Abschnitt D)*****************************************************
#ChartType
$workbook.ActiveChart.chartType = 65 #xlLineMarkers
#Linienstyle
$workbook.ActiveChart.seriescollection(1).border.LineStyle = -4118 #(Dashdot)
#ChartType
$workbook.ActiveChart.chartType = 65
Die 65 steht für xlLineMarkers oder "Line with Markers"
weitere Charttypes unter
Alternativ kann man auch mit Enumerations arbeiten, wie in diesem Beispiel der ScriptingGuys
$xlChartType = "microsoft.office.interop.excel.xlChartType" -as [type]
$workbook.ActiveChart.chartType = $xlChartType::xlLineMarkers
Bei mir funktionieren die Enumerations nur unter Excel 2003
# Linienstyle
$workbook.ActiveChart.seriescollection(1).border.LineStyle = -4118 #(Dashdot)
#weitere LineStyles unter msdn.microsoft.com/en-us/library/bb241348(v=office.12).aspx
Abschnitt E)*****************************************************
#Beschriftungen
#Überschrift
$workbook.ActiveChart.hasTitle=$true #titel erscheint oder nicht
$workbook.ActiveChart.ChartTitle.Text = "die Überschrift"
#Achsenbeschriften
$workbook.ActiveChart.Axes(1).HasTitle = $True
$workbook.ActiveChart.Axes(2).HasTitle = $True
$workbook.ActiveChart.Axes(1).AxisTitle.Text = "die x-Achse"
$workbook.ActiveChart.Axes(2).AxisTitle.Text = "die y-Achse"
$workbook.ActiveChart.Axes(1).AxisTitle.font.ColorIndex=46 #siehe Abschnitt Farben
$workbook.ActiveChart.Axes(1).AxisTitle.Font.Bold=$true
$workbook.ActiveChart.Axes(1).AxisTitle.Font.Size=15
#Abschnitt F)*****************************************************
#Zeichnungsfläche formatieren
$workbook.ActiveChart.PlotArea.Fill.TwoColorGradient(1,4) #zweifarbiger Fülleffekt
$workbook.ActiveChart.PlotArea.Fill.ForeColor.SchemeColor=45
$workbook.ActiveChart.PlotArea.Fill.BackColor.SchemeColor=8
$workbook.ActiveChart.PlotArea.Fill.TwoColorGradient(1,4) #mit zweifarbigem Fülleffekt
$workbook.ActiveChart.PlotArea.Fill.ForeColor.SchemeColor=45
$workbook.ActiveChart.PlotArea.Fill.BackColor.SchemeColor=8
Die Plotarea wird mit mit einem Fülleffekt aus hellblau (Schemecolor=8) und orange (Schemecolor=45) gebildet. Die gewünschte Art des Fülleffektes (Schattierungsart, Variante) erzeugt man sich am besten wieder über den Makroeditor, der beispielsweise diesen VBA-Code zurückliefert
Selection.Fill.TwoColorGradient Style:=msoGradientHorizontal, Variant:=4
With Selection
.Fill.Visible = True
.Fill.ForeColor.SchemeColor = 45
.Fill.BackColor.SchemeColor = 8
Unter
Alternativ der Code für einen einfarbigen Fülleffekt:
$workbook.ActiveChart.PlotArea.Interior.ColorIndex=28 #einfarbiger Hintergrund
$workbook.ActiveChart.PlotArea.Fill.OneColorGradient(7,1,0.3) #mit einfarbigem Fülleffekt
$workbook.ActiveChart.PlotArea.Fill.ForeColor.SchemeColor=46
Im Vergleich zum TwoColorGradient hat der OneColorGradient einen weiteren Paramater. Der dritte Parameter gibt die Stärke des Gradienten an.
"Degree Required Single. The gradient degree. Can be a value from 0.0 (dark) through 1.0 (light)"
Anmerkung: Die Farbverläufe unterscheiden sich etwas zwischen Excel 2003 und Excel 2007.
4 Daten
Mit dem folgenden Skript erzeuge ich eine Tabelle mit Prozessdaten, um ein paar Spieldaten zu haben.
#Abschnitt A)*****************************************************
# Erklärung siehe Skript 2.1.1a Abschnitt A)
if($excel){
$excel.Application.DisplayAlerts = $false
$excel.quit()
$ExcelProcess=get-process excel
$ExcelProcess | foreach {stop-process ($_.id)}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | out-null
}
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$workbook=$excel.Workbooks.add()
$sheet = $workbook.Worksheets.Item(1)
#Abschnitt B)*****************************************************
#Zellen mit Werten füllen
$sheet.Cells.Item(1,2).value2="Name"
$sheet.Cells.Item(1,3).value2="Handles"
$sheet.Cells.Item(1,4).value2="Workingset"
$sheet.Cells.Item(1,5).value2="CPU(s)"
$sheet.range($sheet.cells.item(1,2),$sheet.cells.item(1,5)).Font.Bold = $true
$i=2
get-process | sort cpu -desc | foreach {
$sheet.Cells.Item($i,2).value2="{0}" -f $_.name
$sheet.Cells.Item($i,3).value2="{0}" -f $_.handlecount
$sheet.Cells.Item($i,4).value2="{0}" -f $_.workingset
$sheet.Cells.Item($i,5).value2="{0:f}" -f $_.cpu
$i++
}
$range = $sheet.usedRange
$range.EntireColumn.AutoFit() | out-null #autom. Anpassen der Spaltenbreiten
Die Abschnitte A) und B) sind bereits aus den Kapiteln 2) und 3) oben bekannt.
Um die Tabelle interessanter zu gestalten, habe ich einige Zeilen manuell ergänzt und anschliessend die Tabelle unter dem Filepath "C:\Powershell\PPraxis\Arbeitsmappen\sortData.xlsx" abgespeichert. Diese Daten dienen hier rein zu Demonstrationszwecken und sind systemtechnisch betrachtet nicht sehr sinnvoll.

4.1 Tabellen sortieren
Beispiel 1: Tabelle sortieren
Im diesem Beispiel sortiere ich unter Excel 2007 die Spalten nach der ersten Spalte, berücksichtige den Header und Gross- und Kleinschreibung.
#Abschnitt A)*****************************************************
# Erklärung siehe Beispiel 1, Kapitel 2.1.1 Abschnitt A)
if($excel){
$excel.Application.DisplayAlerts = $false
$excel.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | out-null
}
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$filepath="C:\powershell\excel\Daten\Arbeitsmappen\sortdata.xlsx"
$workbook=$excel.Workbooks.open($filepath)
$sheet = $workbook.Worksheets.Item(1)
#Abschnitt B)*****************************************************
$sheet.range("b2").select() | out-null # optional
$excel.Selection.CurrentRegion.Select() | out-null # optional, da die Tabelle hier zusammenhängt
$key1=$sheet.range("b1")
$order1=1 #XLSortOrder
$key2=$null
$type=$null
$order2=2 # egal ob 1 oder 2, aber nichts anderes
$key3=$null
$order3=1 # egal ob 1 oder 2, aber nichts anderes
$Header=1 # Die Bedeutung findet man im erten MSDN-Link unter dem Skript
$OrderCustom = 1 # dieser Parameter hat sich mir nicht erschlossen
$MatchCase=$True #Gross- Kleinschreibung berücksichtigen
$excel.selection.sort($key1,$order1,$sheet.$key2,$type,$order2,$key3,$order3,$Header,$OrderCustom,$MatchCase) | out-null
#Die Bedeutung der Parameter findet man im zweiten MSDN-Link unter dem Skript
# XlYesNoGuess Enumeration: msdn.microsoft.com/en-us/library/bb216447(office.12).aspx
# Sort Method Excel 2007: msdn.microsoft.com/en-us/library/bb238871(office.12).aspx

5 Sonstiges
5.1 Farben / Colors
Farben können in Excel entweder mit dem Colorindex oder als RGB-Wert ausgewählt werden
5.1.1 Farbauswahl über den Colorindex
Im vorigen Skript wurde die Eigenschaft .Interior.ColorIndex benutzt. Dieser ColorIndex kann gültige Werte zwischen 1 und 56 annehmen, wobei jede Zahl eine andere Farbe repräsentiert. Bis Excel 2003 lassen sich auch nicht mehr Farben auf einem Arbeitsblatt darstellen
Beispiel 1: Farben des Colorindexes auflisten
#Abschnitt A)
if($excel){
$excel.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
}
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$workbook=$excel.Workbooks.add()
$sheet=$excel.worksheets.add()
$sheet = $workbook.Worksheets.Item(1)
#Abschnitt B)
#Farben des Colorindexes
for($i=1;$i -lt 29; $i++)
{
$sheet.cells.item($i,1).value2="Farbe $i"
$sheet.cells.item($i,2).Interior.ColorIndex = $i
$sheet.cells.item($i,4).value2="Farbe $($i+14)"
$sheet.cells.item($i,5).Interior.ColorIndex = $i+14
$sheet.cells.item($i,7).value2="Farbe $($i+28)"
$sheet.cells.item($i,8).Interior.ColorIndex = $i+28
}
#Abschnitt C)
$excel.Application.DisplayAlerts = $false

5.1.2 Farbdarstellung über RGB
Ein RGB (Red, Green, Blue) ist ein 4-Byte Wert, der üblicherweise im Hexadezimal Format 0x00RRGGBB angegeben wird. RRGGBB sind die Bytes für Red, Green, Blue (00 bis FF)
0x000000FF oder 255 bedeutet Rot
0x0000FF00 oder 65280 bedeutet Grün
0x00FF0000 oder 16711680 bedeutet Blau
Bis Excel 2003 kann Excel nur die 56 Farben des Colorindexes darstellen. Verarbeiten kann Excel RGB-Werte. Ab 2007 können mit RGB mehr als die 56 Farben dargestellt werden
Beispiel 1: RGB-Farbpalette
#Abschnitt A)*****************************************************
if($excel){
$excel.Application.DisplayAlerts = $false
$excel.quit()
$ExcelProcess=get-process excel
$ExcelProcess | foreach {stop-process ($_.id)}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | out-null
}
$excel = new-object -comobject excel.application # ComObjekt erstellen
$excel.visible = $true
$workbook=$excel.Workbooks.add()
$sheet = $workbook.Worksheets.Item(1)
#Abschnitt B)
#RGB-Farbpalette
$Red=0x000000FF
$Green=0x0000FF00
$Blue=0x00FF0000
$sheet.cells.item(1,1).value2=$Red
$sheet.Cells.Item(1,2).Value2 = "=DEZINHEX($Red,8)" #in Excel2003 das Add-In "Analyse Funktionen" installieren
$sheet.cells.item(1,3).Interior.Color = $Red
$sheet.cells.item(3,1).value2=$Green
$sheet.Cells.Item(3,2).Value2 = "=DEZINHEX($Green,8)"
$sheet.cells.item(3,3).Interior.Color=$Green
$sheet.cells.item(5,1).value2=$Blue
$sheet.Cells.Item(5,2).Value2 = "=DEZINHEX($Blue,8)"
$sheet.cells.item(5,3).Interior.Color=$Blue

5.2 Makroeditor und Objektkatalog
Natürlich geht der erste Weg zur Lösung einer Aufgabe meistens über die Suchmaschine meines Vertrauens. Da dieser Weg manchmal, aber bei weitem nicht immer zum Ziel führt, will ich hier die Möglichkeiten zeigen, die Excel und die anderen OfficeApplikationen nativ mitbringen.
5.2.1 Excel Entwicklertools anzeigen
Ohne eine kleine Anpassung zeigt Excel seine Entwicklertools, nämlich den Makroeditor und seine VBA-Umgebung nicht an. In der Schaltfläche "Office Optionen" muss man in den ExcelOptionen die Entwcklerregisterkarte aktivieren, wie im den folgenden Bildern gezeigt wird
5.2.1.1 Makroeditor
Der Makroeditor ist ideal, wenn man manuelle Schritte in Excel automatisieren möchte. Bei gestartetem Makroeditor werden alle Schritte, die man in Excel manuell ausführt, als VBA Code aufgezeichnet. Am Ende sollte man das Schließen des Makroeditors nicht vergessen. Danach findet man seinen Code durch Drücken der Schaltfläche Makros und Auswahl seines Makros zum Bearbeiten.
Der Makroeditor zeigt alle notwendige Schritte in Excel-VBA, die nun "nur" noch nach Powershell konvertiert werden müssen. So wird zum Beispiel aus ActiveWorkbook.Saveas Filename:="....." unter Powershell $workbook.SaveAs("..."). Diese Umsetzung ist oft mehr oder weniger knifflig.
5.2.1.2 Objektkatalog
Der Objektkatalog wird in der Excel-Entwicklungsumgebung (erreichbar über Alt + F11 oder die oben beschriebenen Entwicklertools) mit F2 gestartet. Der Objektkatalog eignet sich besonders gut, um eine bekannte Klasse oder die Instanz einer Klasse auf dessen Methoden und Eigenschaften zu untersuchen.
Das folgende Bild zeigt die Eigenschaften "visible" und "workbooks" des Excel.Application Objekts. Geht man in der linken Hälfte des Objektkatalogs nach unten, so findet man auch noch eine Methode "workbooks". Durch einen Klick auf das Fragezeichen oben in der Symbolleiste erhält man weitere Informationen und meist ein Beispiel in Excel-VBA.
Die Kunst besteht nun weiter, diese VBA-Beispiele in Powershellsyntax zu konvertieren. Die richtigen Methoden und Eigenschaften zu kennen, ist aber oft mehr als die halbe Miete.

5.2.1.3 MSDN
Wie immer ist die MSDN eine sehr gute Informationsquelle:
(zu Excel 2007)







