danielg1974
Goto Top

Vergleichsoperatoren in PowerShell-Skript

Hallo.

Ich bin gerade dabei ein PowerShell Skript zu schreiben.
Dieses Skript soll am Ende automatisiert in fast 21000 Zeichnungen (PDF-Dokumente) einen QR-Code einfügen.
Diese Funktion kommt erst viel später ins ERP-System.
Bis dahin soll das Skript dies erledigen.
Im QR-Code stehen dann einige Daten zu dem Werkstück das in der Zeichnung dargestellt wird.
Die Daten kommen aus einer exportierten Excel-Datei.

Ich werde das Skript Stück für Stück aufbauen.
Aktuell bin ich soweit, dass er die Word-Dateien erstellt.
Dabei bin ich bei dem verwendeten Vergleichsoperator "-le" über ein Problem gestolpert.
Er erstellt am Ende eine Word-Datei mehr als er soll.
Und der Zähler ist auch um eines höher als erwartet.

Hab ich hier ein Verständnisproblem mit den Vergleichsoperatoren?
Bei Verwendung von "-eq" werden keine Word-Dateien erstellt.
Obwohl ich dachte, dies wäre der richtige Vergleichsoperator...

Könne mir das eventuell jemand "Dummie"-Freundlich erklären?

Anbei der Code:
###################################################################################################
# Skript zum Hinzufügen eines QR-Codes in ein PDF-Dokument
# Version: 0.1a
# Author: xxxxxx
# Erstellt am: 05.10.2021
# Geändert am: 
#
###################################################################################################

# Host- und Computernamen ermitteln
$Benutzer = $env:USERNAME
$Benutzerprofilpfad = $env:USERPROFILE
$Hostname = $env:COMPUTERNAME

# Windows Module einbinden
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Pfade setzen
$HostTempPath = "\\$Hostname\c$\temp\"  
$HostImportPDFPath = "\\$Hostname\c$\temp\PDFs\"  


# $QRPDFFilePath = "C:\temp\PDFs\PDF_mit_QR-Code"  
$desktop = [Environment]::GetFolderPath("Desktop")  
$logfile = $desktop + "\QR-MergeLog.txt"  
$MergList = $desktop + "\QR-MergeList.txt"  

###################################################################################################
# Verarbeitungsverzeichnisse vorbereiten
$ImportPDFPath = "C:\temp\PDFs\"  
# Abfrage des Pfades und ggf Erstellen
if (!(Test-Path $ImportPDFPath)) {New-Item -Path $ImportPDFPath -ItemType Directory}
$QRMergePath = "C:\temp\PDFs\PDF_mit_QR-Code\"  
# Abfrage des Pfades und ggf Erstellen
if (!(Test-Path $QRMergePath)) {New-Item -Path $QRMergePath -ItemType Directory}
$QRFilePath = "C:\temp\PDFs\QR-Code\"  
# Abfrage des Pfades und ggf Erstellen
if (!(Test-Path $QRFilePath)) {New-Item -Path $QRFilePath -ItemType Directory}
if (!(Test-Path $logfile)) {New-Item -Path "$Benutzerprofilpfad\Desktop\QR-MergeLog.txt" -ItemType File}  
if (!(Test-Path $MergList)) {New-Item -Path "$Benutzerprofilpfad\Desktop\QR-MergeList.txt" -ItemType File}  
$XLSXExportPath = "C:\temp\PDFs\XLSX-Export\"  
if (!(Test-Path $XLSXExportPath)) {New-Item -Path $XLSXExportPath -ItemType Directory}
$WordVorlagenPath = "C:\temp\PDFs\QR-Word-Vorlage\"  
if (!(Test-Path $WordVorlagenPath)) {New-Item -Path $WordVorlagenPath -ItemType Directory}

# Software Ghostscript auslesen und als Array anlegen
$SoftwareGS =@(Get-ChildItem 'HKLM:\SOFTWARE\GPL Ghostscript' -Recurse | Get-ItemProperty -Name GS_DLL)  

# Ghostscript-EXE-Pfad angeben
$GS = ("C:\Program Files\gs\gs" + $SoftwareGS.PSChildName + "\bin\gswin64.exe")  

###################################################################################################
# SQL-Datenbankeinträge abfragen






###################################################################################################
# Excel-Daten abfragen
#------der Pfad zur Excel Datei wird erfragt------------------------
$resultMB = [System.Windows.Forms.MessageBox]::Show("Die Verarbeitungspfade wurden angelegt.`nArtikel-PDF: C:\temp\PDFs`nExcel-Dateien: C:\temp\PDFs\XLSX-Export`nQR-PDFs: C:\temp\PDFs\QR-Code`nZusammengefuehrte PDF: C:\temp\PDFs\PDF_mit_QR-Code`n`nBitte Excel Datei auswaehlen","",1)  
IF ($resultMB -eq "OK")  
{
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        InitialDirectory = [Environment]::GetFolderPath('Desktop')   
        Filter = 'SpreadSheet (*.xlsx)|*.xlsx'}  
    $null = $FileBrowser.ShowDialog()
    $dateipfad = $FileBrowser.FileName
    $NameXLSX = $FileBrowser.SafeFileName.Replace(".xlsx","")  
    }
else
{
    exit
}
#----------Array anlegen
$InputArray_ARTNR1 =@()
$InputArray_ABEZ4 =@()

#-----------Logfile anlegen
$MergeLog = $NameXlSX + " " + (Get-Date).ToString("HH:mm:ss")  
$MergeLog > $logfile                       #Logfile erstellen

#-----------das Excelfile wird ausgelesen und die in Spalte 1 enhaltenen Daten an ein Array übergeben.--------------------------
[int]$zeile = 2
[int]$spalte = 1
$Excel = New-Object -ComObject excel.application # Excel starten
$Excel.Visible = $false
$Workbook = $Excel.Workbooks.Open($dateipfad)
$Table = $Workbook.Worksheets.Item(1) #----es wird das zweite Arbeitsblatt ausgelesen. Auf dem ersten steht eine Struktur die wir nicht brauchen----#
$DerWert = $Table.Cells.Item($zeile,$spalte).Text





#----Schleife erstellen die ab Zeile 2 im Exceldokument die Spalte 1 ausliest und in das $InputArray schreibt.
do
{
    $DerWert = $Table.Cells.Item($zeile,$spalte).Text
    $InputArray_ARTNR1 += $DerWert



    $zeile++
}
while($Table.Cells.Item($zeile,$spalte).Text.Length -gt 0) #---Die Schleife läuft so lange bis im Exceldokumente eine Zeile kommt die keine Einträge enthält

# Zurueck in Zeile 2 wechseln und in die naechste Spalte wechseln
$zeile = 2
$spalte++
do
{
    $DerWert = $Table.Cells.Item($zeile,$spalte).Text
    $InputArray_ABEZ4 += $DerWert
    $zeile++
}
while($Table.Cells.Item($zeile,$spalte).Text.Length -gt 0)
$Excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)  #----hier wird das Auslesen des Exceldokumentes geschlossen

###################################################################################################
# Write-Host Werte zur Kontrolle

Write-Host "ARTNR1-Eintrag 0: " $InputArray_ARTNR1  
Write-Host "ARTNR1-Eintrag 01: " $InputArray_ARTNR1[1]  
Write-Host "ARTNR1-Eintrag 02: " $InputArray_ARTNR1[2]  
Write-Host "ARTNR1-Eintrag 03: " $InputArray_ARTNR1[3]  
Write-Host "ARTNR1-Eintrag 04: " $InputArray_ARTNR1[4]  
Write-Host "ARTNR1-Eintrag 05: " $InputArray_ARTNR1[5]  
Write-Host "ARTNR1-Eintrag 06: " $InputArray_ARTNR1[6]  
Write-Host "ARTNR1-Eintrag 07: " $InputArray_ARTNR1[7]  
Write-Host "ARTNR1-Eintrag 08: " $InputArray_ARTNR1[8]  
Write-Host "ARTNR1-Eintrag 09: " $InputArray_ARTNR1[9]  
Write-Host "ARTNR1-Eintrag 10: " $InputArray_ARTNR1[10]  

Write-Host "ABEZ4-Eintrag 0: " $InputArray_ABEZ4  
Write-Host "ABEZ4-Eintrag 01: " $InputArray_ABEZ4[1]  
Write-Host "ABEZ4-Eintrag 02: " $InputArray_ABEZ4[2]  
Write-Host "ABEZ4-Eintrag 03: " $InputArray_ABEZ4[3]  
Write-Host "ABEZ4-Eintrag 04: " $InputArray_ABEZ4[4]  
Write-Host "ABEZ4-Eintrag 05: " $InputArray_ABEZ4[5]  
Write-Host "ABEZ4-Eintrag 06: " $InputArray_ABEZ4[6]  
Write-Host "ABEZ4-Eintrag 07: " $InputArray_ABEZ4[7]  
Write-Host "ABEZ4-Eintrag 08: " $InputArray_ABEZ4[8]  
Write-Host "ABEZ4-Eintrag 09: " $InputArray_ABEZ4[9]  
Write-Host "ABEZ4-Eintrag 10: " $InputArray_ABEZ4[10]  

###################################################################################################
# Ausgabe der Werte in ein Word-Dokument mittels QR-Word-Vorlage
#
# QR-Word-Vorlagen:
# Ort: "C:\temp\PDFs\QR-Word-Vorlage"  
# DIN A4 Hochformat: _H_A4_QR.dotx
# DIN A4 Querformat: _Q_A4_QR.dotx
# DIN A3 Hochformat: _H_A3_QR.dotx
# DIN A3 Querformat: _Q_A3_QR.dotx
#
###################################################################################################


$i = $InputArray_ARTNR1.Count
$k = $InputArray_ARTNR1.Length
Write-Host "Count ARTNR1: " $i  
Write-Host "Length ARTNR1: " $k  

for($h=0; $h -le $InputArray_ARTNR1.Length; $h++)
{
    $NameQRWord = ($InputArray_ARTNR1[$h] + "_QR.docx")  
    $outputPath = $WordVorlagenPath + $NameQRWord
    $Word = New-Object -Com Word.Application
    $Word.Visible = $false
    $ARTNR1 = $Word.Documents.Add()
    $ARTNR1.SaveAs($outputPath)
    $ARTNR1.Close()
    $Word.Quit()
    [System.Runtime.InteropServices.Marshal]::ReleaseComObject($Word)
    
}

Write-Host "Count ARTNR1 am Ende: " $i  
Write-Host "Length ARTNR1 am Ende: " $k  
Write-Host "h am Ende: " $h  

Hier noch die Ausgabe eines Durchlaufs mit "-le":
PS C:\Users\xxx> \\netapp2\xxx\EDV\PowerShell-Skripte\QR-Code-to-PDF\Add_QR-Code-to-PDF_2021-10-06_15-33.ps1
0
ARTNR1-Eintrag 0:  S-1-1095
ARTNR1-Eintrag 01:  S-1-717
ARTNR1-Eintrag 02:  S-1-558
ARTNR1-Eintrag 03:  S-1-542
ARTNR1-Eintrag 04:  S-1-820
ARTNR1-Eintrag 05:  S-1-1052
ARTNR1-Eintrag 06:  S-1-1003
ARTNR1-Eintrag 07:  2015495
ARTNR1-Eintrag 08:  
ARTNR1-Eintrag 09:
ARTNR1-Eintrag 10:
ABEZ4-Eintrag 0:  AlMg4,5Mn/421x355x80mm/fr
ABEZ4-Eintrag 01:  AlMg4,5Mn/1191x491x75mm/fr
ABEZ4-Eintrag 02:  AlMg4,5Mn/505x405x80mm/fr
ABEZ4-Eintrag 03:  AlMg4,5Mn/755x405x80mm/fr
ABEZ4-Eintrag 04:  AlMg4,5Mn/605x405x80mm/fr
ABEZ4-Eintrag 05:  AlMg4,5Mn/755x405x80mm/fr
ABEZ4-Eintrag 06:  AlMg4,5Mn/991x391x45mm/fr
ABEZ4-Eintrag 07:  Delrin/629x30x40mm/fr
ABEZ4-Eintrag 08:  
ABEZ4-Eintrag 09:
ABEZ4-Eintrag 10:
Count ARTNR1:  8
Length ARTNR1:  8
0
0
0
0
0
0
0
0
Count ARTNR1 am Ende:  8
Length ARTNR1 am Ende:  8
h am Ende:  9

Gruß Daniel

Content-Key: 1405762826

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

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

Member: Doskias
Solution Doskias Oct 19, 2021 updated at 11:14:56 (UTC)
Goto Top
Zitat von @DanielG1974:

Hallo.

Ich bin gerade dabei ein PowerShell Skript zu schreiben.
Dieses Skript soll am Ende automatisiert in fast 21000 Zeichnungen (PDF-Dokumente) einen QR-Code einfügen.
Diese Funktion kommt erst viel später ins ERP-System.
Bis dahin soll das Skript dies erledigen.
Im QR-Code stehen dann einige Daten zu dem Werkstück das in der Zeichnung dargestellt wird.
Die Daten kommen aus einer exportierten Excel-Datei.

Ich werde das Skript Stück für Stück aufbauen.
Aktuell bin ich soweit, dass er die Word-Dateien erstellt.
Dabei bin ich bei dem verwendeten Vergleichsoperator "-le" über ein Problem gestolpert.
Er erstellt am Ende eine Word-Datei mehr als er soll.
Und der Zähler ist auch um eines höher als erwartet.

Hab ich hier ein Verständnisproblem mit den Vergleichsoperatoren?
Bei Verwendung von "-eq" werden keine Word-Dateien erstellt.
Obwohl ich dachte, dies wäre der richtige Vergleichsoperator...

Ohne das ganze Skript gelesen zu haben: Wenn immer eine Datei mehr erstellt wird, dann solltest du vielleicht von -le (lower equals, kleiner gleich) auf -lt (lower then, kleiner) wechseln.

for($h=0; $h -le $InputArray_ARTNR1.Length; $h++)

wenn h 0 ist und $InputArray_ARTNR1.Lengthebenfalsl 0, dann wird durch das LE die Schleife dennoch durchlaufen. bei LT würde sie nicht durchlaufen werden.

Gruß
Doskias
Member: DanielG1974
DanielG1974 Oct 19, 2021 at 11:19:25 (UTC)
Goto Top
Danke!
Das war es.

Kannst Du mir bitte erklären wieso es mit "-lt" funktioniert?
Müsste er dann nicht eigentlich bei "7" Daten aufhören?
Denn 7 ist doch kleiner als 8...

Gruß Daniel
Member: erikro
erikro Oct 19, 2021 at 11:24:52 (UTC)
Goto Top
Moin,

Zitat von @DanielG1974:

Danke!
Das war es.

Kannst Du mir bitte erklären wieso es mit "-lt" funktioniert?
Müsste er dann nicht eigentlich bei "7" Daten aufhören?
Denn 7 ist doch kleiner als 8...

Gruß Daniel

Weil die Länge eines Arrays mit 1 anfängt und nicht mit 0. Das erste Element aber ist das Element 0. Also, wenn das Array zwei Elemente hat, dann hat es die Länge 2. In der ersten Schleife hat $h den Wert 0 und Du verarbeitest das erste Element mit dem Index 0. Du zählst $h eins hoch. Es steht also im zweiten Schleifendurchlauf auf 1. Du verarbeitest das zweite Element mit dem Index 1. Du zählst $h eins hoch. Es ist jetzt gleich der Länge und die Schleife wird noch einmal durchlaufen. Aber da ist kein Element im Array mehr.

BTW: Sowas kannst Du einfach vermeiden, indem Du nicht for, sondern foreach nimmst.

Liebe Grüße

Erik
Member: em-pie
em-pie Oct 19, 2021 updated at 11:34:16 (UTC)
Goto Top
Moin,
Zitat von @DanielG1974:
Kannst Du mir bitte erklären wieso es mit "-lt" funktioniert?
Müsste er dann nicht eigentlich bei "7" Daten aufhören?
Denn 7 ist doch kleiner als 8...

Gruß Daniel

Das ist einfach:
lt = less then = kleiner
le = less equals = kleiner gleich


"Zähle von x bis 8, solange x kleiner 8 ist (lt) und erhöhe mit jedem durchlauf x um einen"
vs.
"Zähle von x bis 8, solange x kleiner ODER gleich 8 ist (le) und erhöhe mit jedem durchlauf x um einen"

Bei lt erreicht x dann 8. Da 8 aber nicht mehr kleiner 8 ist, hört die Schleife auf
Bei le erreicht x dann 8. Da 8 aber gleich 8 ist, hört die Schleife noch nicht auf. Erst wenn x > 8 wird (je nach Datentyp würde sogar ein 8,0000000000000001 ausreichen), wird die Schleife beendet.

Edit:
Meines ist zwar richtig, beantwortet aber deine Frage nicht face-big-smile
@erikro hat es ja schon erklärt: Länge != Array-Index


Gruß
em-pie
Member: DanielG1974
DanielG1974 Oct 19, 2021 at 11:31:26 (UTC)
Goto Top
Danke @erikro für die Erklärung.
Mit foreach hatte ich es schon probiert.
Ich weiß jetzt nur, dass es damit nicht ging.
Warum weiß ich nicht mehr.
Wahrscheinlich lag der Fehler bei mir. face-smile

Aber jetzt kann ich mich an die nächste Funktion machen.

Gruß Daniel