/ / Jak zmusić typ danych do powrotu przy wyszukiwaniu w Excelu z Powershell? - excel, powershell, oledb

Jak zmusić typ danych do powrotu podczas kwerendy Excel z Powershell? - excel, powershell, oledb

Używam Powershell zapytać arkusz kalkulacyjny Excel za pomocą połączenia OLEDB. Mam jedną kolumnę z wieloma wartościami. Zauważyłem, że gdy 1 z naszych 4 komórek zawiera litery, zapytanie zwróci a NULL a typem danych będzie System.DBNull. Zobacz poniżej:

Arkusz kalkulacyjny programu Excel 1

Wynik skryptu:

PS D:temp> D:WCC_PowershellExcelTypeTest.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

Jednak jeśli 2 z 4 komórek zawierają litery, wszystkie typy danych komórek powracają jako String. Przykład:

Arkusz kalkulacyjny programu Excel 2

Wynik skryptu:

PS D:temp> D:WCC_PowershellExcelTypeTest.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

Czy istnieje sposób wymusić typ zwracania kolumny programu Excel podczas kwerendy z Powershell? Mój skrypt musi wiedzieć, czy 1) tam są dane (nie zwracają wartości NULL) i 2) znają typ danych

Oto skrypt, którego używam do analizy dokumentu programu 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()

Odpowiedzi:

1 dla odpowiedzi № 1

Według tego KB Artykuł (wyróżnienia dodane):

Przestroga dotycząca mieszanych typów danych

Jak wspomniano wcześniej, ADO musi zgadywać przy danychwpisz dla każdej kolumny w arkuszu lub zakresie programu Excel. (Na tę komórkę Excel nie ma wpływu ustawienia formatowania.) Poważny problem może wystąpić, jeśli masz numeryczne wartości zmieszane z wartościami tekstowymi w tej samej kolumnie. Zarówno Jet, jak i Dostawca ODBC zwraca dane typu większego, ale zwraca NULL (puste) wartości dla typu danych mniejszości. Jeśli oba typy są jednakowo mieszane w kolumnie, dostawca wybiera numerycznie ponad tekst.

Opcja "bezpieczna" traktuje wszystkie pola jako tekst, dodając IMEX=1 opcja do ciągu połączenia:

"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=`"$ExcelFile`";Extended Properties=`"Excel 12.0 Xml;HDR=YES;IMEX=1`";"

a następnie konwertuj wartości liczbowe w skrypcie PowerShell, korzystając z jawnych rzutów, takich jak:

[int]$value
# or
$value -as [int]

Miękka przymus z operatorem jednoargumentowym, takim jak:

+$value

lub przy użyciu parsowania statycznego w ten sposób:

[int]::Parse($value)
# or
$numericValue = 0
[int]::TryParse($value,[ref]$numericValue)