如何通过PowerShell动态更新Crystal Reports的数据库连接?
动态修改Crystal Report数据库连接的PowerShell脚本优化方案
要实现根据工厂参数切换报表的数据库连接,仅修改SetLogon是不够的,还需要调整数据库名称(以及必要的服务器信息),同时要考虑主报表和子报表的所有数据源连接。以下是优化后的完整脚本:
Param( [string]$ProductID, [string]$Factory ) # 定义工厂与数据库的映射关系,可根据实际需求扩展 $dbMappings = @{ "Factory01" = "DBFACTORY_01" "Factory02" = "DBFACTORY_02" "Testing" = "DBFACTORY_TESTING" } # 验证Factory参数是否在映射表中 if (-not $dbMappings.ContainsKey($Factory)) { Write-Error "无效的工厂名称:$Factory,请检查参数输入" exit } # Crystal Reports assemblies $assemblyPath1 = "C:\Program Files (x86)\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Common\SAP BusinessObjects Enterprise XI 4.0\win64_x64\dotnet\crystaldecisions.crystalreports.engine.dll" $assemblyPath2 = "C:\Program Files (x86)\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Common\SAP BusinessObjects Enterprise XI 4.0\win64_x64\dotnet\crystaldecisions.shared.dll" if (-not (Test-Path $assemblyPath1)) { Write-Error "Assembly CrystalDecisions.CrystalReports.Engine does not exist." exit } if (-not (Test-Path $assemblyPath2)) { Write-Error "Assembly CrystalDecisions.Shared does not exist." exit } # Load assemblies Add-Type -Path $assemblyPath1 Add-Type -Path $assemblyPath2 # ReportDocument $report = New-Object CrystalDecisions.CrystalReports.Engine.ReportDocument # load report $reportPath = "C:\template\ToolboxV4.rpt" $report.Load($reportPath) # -------------------------- 核心修改:动态切换数据库连接 -------------------------- $targetDb = $dbMappings[$Factory] $dbUsername = "your_sql_username" # 替换为实际数据库用户名 $dbPassword = "your_sql_password" # 替换为实际数据库密码 # 修改主报表的所有数据源连接 foreach ($conn in $report.DataSourceConnections) { # SetConnection参数说明:服务器名, 数据库名, 是否使用Windows集成验证 $conn.SetConnection($conn.ServerName, $targetDb, $false) $conn.SetLogon($dbUsername, $dbPassword) } # 修改子报表的所有数据源连接(如果报表包含子报表) foreach ($subreport in $report.Subreports) { foreach ($subConn in $subreport.DataSourceConnections) { $subConn.SetConnection($subConn.ServerName, $targetDb, $false) $subConn.SetLogon($dbUsername, $dbPassword) } } # ------------------------------------------------------------------------------- # Parameters $report.SetParameterValue("ProductID",$ProductID) $report.SetParameterValue("Factory",$Factory) # Export $exportPath = "C:\Result\Refill $ProductID.pdf" $exportOptions = New-Object CrystalDecisions.Shared.ExportOptions $pdfFormatOptions = New-Object CrystalDecisions.Shared.PdfRtfWordFormatOptions $exportOptions.ExportFormatType = [CrystalDecisions.Shared.ExportFormatType]::PortableDocFormat $exportOptions.FormatOptions = $pdfFormatOptions $exportOptions.ExportDestinationType = [CrystalDecisions.Shared.ExportDestinationType]::DiskFile $exportOptions.DestinationOptions = New-Object CrystalDecisions.Shared.DiskFileDestinationOptions $exportOptions.DestinationOptions.DiskFileName = $exportPath $report.Export($exportOptions) $report.Close() $report.Dispose() Write-Output "报表导出完成,目标路径:$exportPath"
关键优化点说明:
- 工厂-数据库映射表:通过
$dbMappings字典实现参数与数据库名的绑定,新增工厂时只需添加新的键值对,无需修改核心逻辑。 - 遍历所有数据源连接:避免仅修改第一个连接导致部分数据仍使用旧数据库的问题。
- SetConnection方法:该方法用于修改数据库连接的核心信息(服务器、数据库名、验证方式),配合
SetLogon完成完整的凭据更新。 - 子报表处理:如果报表包含子报表,必须同步修改子报表的数据源,否则子报表会使用原连接导致数据不一致。
使用说明:
- 替换
$dbUsername和$dbPassword为实际的数据库登录凭据。 - 调整
$dbMappings中的工厂名称与对应数据库名,匹配你的业务场景。 - 执行脚本时传入正确的
ProductID和Factory参数,例如:.\Export-Report.ps1 -ProductID "PROD001" -Factory "Factory02"
内容的提问来源于stack exchange,提问作者Wehrmicel
相关产品推荐
相关产品推荐

