PowerShell字符串转数组与GUI事件间数据共享技术问询
解决方案
1. 在Click事件间共享数据
要在搜索按钮的Click事件(search_csv函数)和打印按钮的Click事件之间共享查询到的$data,需将数据存储在脚本作用域的变量中,而非函数局部变量。这样两个事件就能访问同一数据实例。
修改search_csv函数,将找到的数据赋值给脚本级变量:
function search_csv { $searchThis = $textbox_Search.Text.Trim() $script:selectedData = $script:csvData | Where-Object {$_.Username -like "*$searchThis*"} if ([string]::IsNullOrWhiteSpace($searchThis)) { $output_TextBox.Clear() $script:selectedData = $null # 清空选中数据 } elseif ($script:selectedData) { $output_TextBox.Text = ($script:selectedData | Format-List | Out-String).Trim() } else { $output_TextBox.Text = "Nichts gefunden .." $script:selectedData = $null } }
2. 获取单个数据值(无需拆分字符串)
Import-Csv已将CSV数据转换为带属性的对象,无需拆分字符串即可直接获取单个值:
- 用户名:
$script:selectedData.Username - 设备:
$script:selectedData.Device - 耳机:
$script:selectedData.Headset - 以此类推...
若需将值存入数组,可直接构造:
$valueArray = @( $script:selectedData.Username, $script:selectedData.Device, $script:selectedData.Headset, $script:selectedData.Dockingstation, $script:selectedData.Monitor, $script:selectedData.Transponder ) # $valueArray[0] = "John", $valueArray[1] = "Lenovo T15"
修改后的完整脚本
整合上述修改,修复打印按钮无法访问数据的问题,同时添加错误提示:
Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.Application]::EnableVisualStyles() $csvData = Import-Csv -path 'C:\temp\offboarding_skript.csv' -Header "Username", "Device", "Headset", "Dockingstation", "Monitor", "Transponder" $script:selectedData = $null # 初始化脚本作用域变量 function search_csv { $searchThis = $textbox_Search.Text.Trim() $script:selectedData = $script:csvData | Where-Object {$_.Username -like "*$searchThis*"} if ([string]::IsNullOrWhiteSpace($searchThis)) { $output_TextBox.Clear() $script:selectedData = $null } elseif ($script:selectedData) { $output_TextBox.Text = ($script:selectedData | Format-List | Out-String).Trim() } else { $output_TextBox.Text = "Nichts gefunden .." $script:selectedData = $null } } $search_csvtool = New-Object System.Windows.Forms.Form $search_csvtool.Text = "Offboarding-Skript" $search_csvtool.Size = New-Object System.Drawing.Size(674,500) $search_csvtool.FormBorderStyle ="FixedDialog" $search_csvtool.Backcolor="white" $search_csvtool.TopMost = $true $search_csvtool.MaximizeBox = $false $search_csvtool.MinimizeBox = $true $search_csvtool.ControlBox = $true $search_csvtool.StartPosition = "CenterScreen" $search_csvtool.Font = "Microsoft Sans Serif" $label_Search = New-Object System.Windows.Forms.Label $label_Search.Location = New-Object System.Drawing.Size(195,18) $label_Search.Size = New-Object System.Drawing.Size(265,32) $label_Search.TextAlign ="MiddleCenter" $label_Search.Text = "Bitte Nutzernamen eingeben:" $search_csvtool.Controls.Add($label_Search) $textbox_Search = New-Object System.Windows.Forms.TextBox $textbox_Search.Location = New-Object System.Drawing.Size(195,50) $textbox_Search.Size = New-Object System.Drawing.Size(266,37) $search_csvtool.Controls.Add($textbox_Search) $button_Search = New-Object System.Windows.Forms.Button $button_Search.Location = New-Object System.Drawing.Size(195,80) $button_Search.Size = New-Object System.Drawing.Size(266,24) $button_Search.TextAlign = "MiddleCenter" $button_Search.Text = "Suche" $button_Search.Add_Click({search_csv}) $search_csvtool.Controls.Add($button_Search) $output_TextBox = New-Object System.Windows.Forms.TextBox $output_TextBox.Multiline = $true; $output_TextBox.Location = New-Object System.Drawing.Size(130,130) $output_TextBox.Size = New-Object System.Drawing.Size(400,250) $output_TextBox.ScrollBars = "Vertical" $output_TextBox.ReadOnly = $true; $search_csvtool.Controls.Add($output_TextBox) $search_csvtool.Add_Shown({$search_csvtool.Activate()}) # 打印按钮 $PrintButton = New-Object System.Windows.Forms.Button $PrintButton.Location = New-Object System.Drawing.Size(35,420) $PrintButton.Size = New-Object System.Drawing.Size(75,23) $PrintButton.Text = "Drucken" $PrintButton.Name = "Drucken" $PrintButton.Add_Click({ if (-not $script:selectedData) { [System.Windows.Forms.MessageBox]::Show("Bitte zuerst einen Nutzer suchen!", "Fehler", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning) return } $template = "c:\tempory\Inventarliste.docx" $tempFolder = $env:TEMP + "\Populate-Word-DOCX" Add-Type -AssemblyName System.IO.Compression.FileSystem function Unzip { param([string]$zipfile, [string]$outpath) [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath) } function Zip { param([string]$folderInclude, [string]$outZip) [System.IO.Compression.CompressionLevel]$compression = "Optimal" $ziparchive = [System.IO.Compression.ZipFile]::Open( $outZip, "Update" ) $realtiveTempFolder = (Resolve-Path $tempFolder -Relative).TrimStart(".\") foreach ($file in (Get-ChildItem $folderInclude -Recurse)) { if ($file.GetType().ToString() -ne "System.IO.DirectoryInfo") { $relpath = "" if ($file.FullName) { $relpath = (Resolve-Path $file.FullName -Relative) } if (!$relpath) { $relpath = $file.Name } else { $relpath = $relpath.Replace($realtiveTempFolder, "") $relpath = $relpath.TrimStart(".\").TrimStart("\\\\") } [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($ziparchive, $file.FullName, $relpath, $compression) | Out-Null } } $ziparchive.Dispose() } Remove-Item $tempFolder -ErrorAction SilentlyContinue -Recurse -Confirm:$false | Out-Null mkdir $tempFolder | Out-Null Unzip $template $tempFolder $bodyFile = Join-Path $tempFolder "word\document.xml" $body = Get-Content $bodyFile -Raw $body = $body.Replace("[placeholder1]", $script:selectedData.Username) $body = $body.Replace("[placeholder2]", $script:selectedData.Device) $body = $body.Replace("[placeholder3]", $script:selectedData.Headset) $body = $body.Replace("[placeholder4]", $script:selectedData.Dockingstation) $body = $body.Replace("[placeholder5]", $script:selectedData.Monitor) $body = $body.Replace("[placeholder6]", $script:selectedData.Transponder) $body | Out-File $bodyFile -Force -Encoding ascii $destfile = $template.Replace(".docx", "-after.docx") Remove-Item $destfile -Force -ErrorAction SilentlyContinue Zip $tempFolder $destfile Remove-Item $tempFolder -ErrorAction SilentlyContinue -Recurse -Confirm:$false | Out-Null [System.Windows.Forms.MessageBox]::Show("Dokument erstellt: $destfile", "Erfolg", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information) }) $search_csvtool.Controls.Add($PrintButton) # 取消按钮 $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = New-Object System.Drawing.Size(560,420) $CancelButton.Size = New-Object System.Drawing.Size(75,23) $CancelButton.Text = "Abbrechen" $CancelButton.Name = "Abbrechen" $CancelButton.DialogResult = "Cancel" $CancelButton.Add_Click({$search_csvtool.Close()}) $search_csvtool.Controls.Add($CancelButton) [void] $search_csvtool.ShowDialog()
关键修改说明
- 新增
$script:selectedData变量实现跨事件数据共享 - 打印按钮添加空值检查,避免无数据时执行出错
- 直接使用对象属性替换模板占位符,无需拆分字符串
- 使用
Join-Path优化路径拼接,提升代码可靠性 - 新增操作结果提示框,增强用户体验
内容的提问来源于stack exchange,提问作者Raindrop197
相关产品推荐
相关产品推荐

