我使用Powershell
使用OLEDB连接查询Excel电子表格。我有一列有多个值。我注意到当4个单元格中的1个包含字母时,查询将返回NULL
,数据类型将为System.DBNull
。见下文:
脚本输出:
PS D:\temp> D:\WCC_Powershell\ExcelTypeTest.ps1 test.xls
Ticket Number: 1 | Type: System.Double
Ticket Number: 2 | Type: System.Double
Ticket Number: | Type: System.DBNull
Ticket Number: 4 | Type: System.Double
但是,如果4个单元格中的2个包含字母,则所有单元格数据类型都将返回String
。例如:
脚本输出:
PS D:\temp> D:\WCC_Powershell\ExcelTypeTest.ps1 test.xls
Ticket Number: 1 | Type: System.String
Ticket Number: ZZZZ | Type: System.String
Ticket Number: AAAA | Type: System.String
Ticket Number: 4 | Type: System.String
从Powershell查询时是否有办法强制Excel列的返回类型?我的脚本需要知道1)是否有数据(不返回NULL)和2)知道数据类型
这是我用来解析excel文档的脚本:
########################################################################################################
# This function will test if a string value is numeric
# Parameters:
# $value - String to test
########################################################################################################
function IsNumeric($value) {
return ($($value.Trim()) -match "^[-]?[0-9.]+$")
}
########################################################################################################
# This filter will test if a string value is numeric
# Parameters:
# $value - String to test
########################################################################################################
filter isNumeric2() {
return $_ -is [byte] -or $_ -is [int16] -or $_ -is [int32] -or $_ -is [int64] `
-or $_ -is [sbyte] -or $_ -is [uint16] -or $_ -is [uint32] -or $_ -is [uint64] `
-or $_ -is [float] -or $_ -is [double] -or $_ -is [decimal]
}
# Directory location where we have our excel files
########################################################################################################
$excelFN = "$args"
$ExcelFile = "D:\Temp\$excelFN"
$Sheetname = "Interface$"
########################################################################################################
$OleDbConn = New-Object “System.Data.OleDb.OleDbConnection”
$OleDbCmd = New-Object “System.Data.OleDb.OleDbCommand”
$OleDbAdapter = New-Object “System.Data.OleDb.OleDbDataAdapter”
$DataTable = New-Object “System.Data.DataTable”
$OleDbConn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=`"$ExcelFile`";Extended Properties=`"Excel 12.0 Xml;HDR=YES`";"
$OleDbConn.Open()
$OleDbCmd.Connection = $OleDbConn
$OleDbCmd.commandtext = “Select * from [$Sheetname]”
$OleDbAdapter.SelectCommand = $OleDbCmd
########################################################################################################
$RowsReturned = $OleDbAdapter.Fill($DataTable)
$intRow = 1
ForEach ($DataRec in $DataTable) {
# Reading the first column of the current row
$TicketNumber = $DataRec."ticket number"
write-host "Ticket Number:" $TicketNumber "| Type:" $TicketNumber.GetType()
$intRow++
}
$OleDbConn.Close()
答案 0 :(得分:1)
根据KB Article(强调补充):
关于混合数据类型的警告
如前所述,ADO必须猜测每列的数据类型 在Excel工作表或范围中。 (这不受Excel单元格的影响 格式化设置。)如果您有数字,可能会出现严重问题 值与同一列中的文本值混合。 Jet和the ODBC提供程序 返回多数类型的数据,但返回NULL 少数据数据类型的(空)值。 如果两种类型是 同样在列中混合,提供者选择数字而不是文本。
" safe"选项是通过向连接字符串添加IMEX=1
选项将所有字段视为文本:
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=`"$ExcelFile`";Extended Properties=`"Excel 12.0 Xml;HDR=YES;IMEX=1`";"
然后使用显式强制转换(例如:
)转换PowerShell脚本中的数值[int]$value
# or
$value -as [int]
与一元操作员的软胁迫,例如:
+$value
或使用这样的静态解析:
[int]::Parse($value)
# or
$numericValue = 0
[int]::TryParse($value,[ref]$numericValue)