Bol*_*ltz 9 powershell type-conversion
我在 PowerShell 中有一个脚本,用于从 CSV 导入数据。我收到错误
无法将值“日记帐金额”转换为类型“System.Double”。错误:“输入字符串的格式不正确。” 在 C:\TestPowerShell\TestPowerShell1.ps1:98 char:1 + $JournalAmount = [double] $_.PSObject.Properties['Journal Amount'].Va ... + ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~ + CategoryInfo:InvalidArgument:(:) [],RuntimeException + ExcellentQualifiedErrorId:InvalidCastFromStringToDoubleOrSingle
Get-Content "config.txt" | foreach-object -begin {$h=@{}} -process { $k = [regex]::split($_,'='); if(($k[0].CompareTo("") -ne 0) -and ($k[0].StartsWith("[") -ne $True)) { $h.Add($k[0], $k[1]) } }
$FileBrowserInitialDir = $h.FileBrowserInitialDir
$Header = 'Terminal','Company','Journal Account Code','Project','Task','Line of Business','Date','Journal Amount','Report Entry Vendor Description'
$TIDataFilePath = $h.TIDataFilePath
$TIDataFileBaseName = $h.TIDataFileBaseName
$TIScreenID = $h.TIScreenID
$TIControlFile = $h.TIControlFile
$TIErrLog = $h.TIErrLog
$ResultsFilePath = $h.ResultsFilePath
$ResultsFileBaseName = $h.ResultsFileBaseName
$dt = Get-Date -Format "MMddyyyyHHmmss"
$TIDataFile = "$($TIDataFileBaseName)$($dt).txt"
$ResultsFile = "$($ResultsFileBaseName)$($dt).txt"
Add-Type -AssemblyName System.Windows.Forms
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
InitialDirectory = $FileBrowserInitialDir
Filter = 'CSV (*.csv)|*.csv'
Title = "Select Expense csv file"
}
$null = $FileBrowser.ShowDialog()
if($FileBrowser.FileName -eq ""){
exit
}
$EXPENSECSV = Import-CSV $FileBrowser.FileName -Header $Header
New-Item -path $TIDataFilePath -name $TIDataFile -type "file"
$EXPENSECSV |foreach-object{
$Terminal = $_.PSObject.Properties['Terminal'].Value
$Terminal = $Terminal.Insert(0,'0')
$CompanyTemp = $_.PSObject.Properties['Company'].Value
$CompanyTemp = $CompanyTemp.Insert(0,'0')
#$Company= [String]::Concat($_.Terminal,$CompanyTemp)
$Company= [String]::Concat($Terminal,$CompanyTemp)
$LineofB = $_.PSObject.Properties['Line of Business'].Value
#$JournalAmount = [double] $_.PSObject.Properties["Journal Amount"].Value
$LineofB = $LineofB.Insert(0,'0')
$Account = $_.PSObject.Properties['Journal Account Code'].Value
$Sub = $LineofB
$TranDateStr = $_.PSObject.Properties['Date'].Value
$JournalAmount = [double] $_.PSObject.Properties['Journal Amount'].Value
$Description = $_.PSObject.Properties['Report Entry Vendor Description'].Value
$row = ""
$row += "`"Level1`","
$row += "`"$($Company)`","
$row += "`"$($Account)`","
$row += "`"$($Sub)`","
$row += "`"$($TranDateStr)`","
# Convert Concur Amount to Credit/Debit Amount
# Postive Amount --> Debit Amount
# Negative Amount --> Credit Amount
if($JournalAmount -lt 0){
$JournalAmount*= -1
$row += "`"$($JournalAmount)`"," #Credit Amount
$row += "`"`"," #Debit Amount
}
else {
$row += "`"`"," #Credit Amount
$row += "`"$($JournalAmount)`"," #Debit Amount
}
$row += "`"$($Description)`""
Add-Content -Path "$($TIDataFilePath)$($TIDataFile)" -Value $row
}
#Results
New-Item -path $ResultsFilePath -name $ResultsFile -type "file"
$ResultsStr = "----------------------------------------------------------------------------------`n"
$ResultsStr += " Concur to Dynamics SL `n"
$ResultsStr += "----------------------------------------------------------------------------------`n"
$ResultsStr += "Copy and paste the following into the Transaction Import screen.`n"
$ResultsStr += "Line 1: Data File Name`n"
$ResultsStr += "Line 2: Screen ID`n"
$ResultsStr += "Line 3: Control File Name`n"
$ResultsStr += "Line 4: Output Log File`n`n`n"
$ResultsStr += "$($TIDataFilePath)$($TIDataFile)`n"
$ResultsStr += "$($TIScreenID)`n"
$ResultsStr += "$($TIControlFile)`n"
$ResultsStr += "$($TIErrLog)"
Add-Content -path "$($ResultsFilePath)$($ResultsFile)" -value $ResultsStr
Start-Process "$($ResultsFilePath)$($ResultsFile)"
Run Code Online (Sandbox Code Playgroud)
mkl*_*nt0 14
回答所提出的问题:
将字符串转换为[double]- 正如您自己尝试过的那样 -确实有效,但前提是该字符串被识别为(浮点)数字。
警告:由于PowerShell 的强制转换是区域性不变的,因此仅.被识别为小数点,并且,始终被解释为千位分组分隔符。
要以文化敏感的方式进行解析,请使用[double]::Parse($string)基于当前文化的规则进行解析(如 中所反映的$PSCulture);传递一个实例作为第二个参数,以根据给定[cultureinfo]文化的规则进行解析(例如,要根据法国文化的规则进行解析,请使用)[double]::Parse($string, [cultureinfo] 'fr-FR')
如果无法识别字符串值,您可以使用以下方法之一来处理这种情况:
至于你尝试过的:
正如Mathias R. Jessen指出的那样,问题的可能原因是您的 CSV 文件本身具有标题行,但您还通过参数提供了标题-Header。
这会导致 CSV 文件的标题行被误读为第一个数据行,因此返回的第一个对象将列(标题)名称Import-Csv包含为属性值 - 这会导致转换失败,因为您正在有效地执行以下操作:[double]
[double] 'Journal Amount'
所以:
省略-Header调用中的参数Import-Csv。
作为优化,通过使用普通的点表示法简化属性值检索;只需使用引号来指定属性名称Journal Amount,因为它包含空格:
Import-CSV $FileBrowser.FileName | # !! No -Header argument
ForEach-Object {
# Simpler and more efficient than:
# $JournalAmount = [double] $_.PSObject.Properties['Journal Amount'].Value
$JournalAmount = [double] $_.'Journal Amount'
}
# ...
Run Code Online (Sandbox Code Playgroud)
这解决了这个问题:
$JournalAmount = $JournalAmount -as [double]
$JournalAmount = $_.PSObject.Properties['Journal Amount'].Value
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21659 次 |
| 最近记录: |