从Powershell查询excel时如何强制返回数据类型?

时间:2015-05-26 21:19:45

标签: excel powershell oledb

我使用Powershell使用OLEDB连接查询Excel电子表格。我有一列有多个值。我注意到当4个单元格中的1个包含字母时,查询将返回NULL,数据类型将为System.DBNull。见下文:

Excel Spreadsheet 1

脚本输出:

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。例如:

Excel Spreadsheet 2

脚本输出:

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()

1 个答案:

答案 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)