1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
function Out-SplittingCSV {
<#
.SYNOPSIS
Ecrit dans un fichier des objets au format CSV.
Cette fonction peut générer plusieurs fichiers regroupant un nombre limité d'objets.
#>
[CmdletBinding()]
Param(
#Objet à convertir.
[ValidateNotNull()]
[Parameter(Mandatory=$True,ValueFromPipeline=$True)]
$InputObject,
#Nom de base du fichier.
#Chaque nom de fichier est incrémenté à partir de zéro.
#Si le fichier existe il est écrasé.
[ValidateNotNullOrEmpty()]
[Parameter(Position=0,Mandatory=$True)]
$Path,
#Nombre d'objet maximum à écrire dans un fichier.
#Voir le paramètre -Validation
[Parameter(Position=1,Mandatory=$True,ParameterSetName="Count")]
[ValidateScript({$_ -ge 1})]
[int]$Count,
#Noms des propriétés d'un objet à convertir.
#Peut être une hashtable normalisé, consulter la documentation du paramètre -Property du cmdlet Select-Object.
[ValidateNotNullOrEmpty()]
[Parameter(Position=2)]
[Object[]]$Property='*',
#Code de validation des clés permettant de 'regrouper' les objets reçu du pipeline.
#Son usage retarde la création d'un nouveau fichier tant que le code de validation renvoi $true alors que la valeur maximum de Count est atteinte ou dépassée.
#On évite ainsi de disperser des informations dont la clé est identique.
[ValidateNotNullOrEmpty()]
[Parameter(Position=3)]
[ScriptBlock] $Validation,
#Spécifie un délimiteur pour séparer les valeurs de propriété.
#Par défaut contient la valeur de la clé de registre suivante :
# hkcu:\Control Panel\International\sList
#Si cette clé n'existe pas la valeur par défaut sera la virgule ','
[ValidateNotNullOrEmpty()]
[Parameter(Position=4)]
[char] $Delimiter,
#Spécifie le type d'encodage pour le fichier cible.
#Les valeurs valides sont ASCII, UTF8, UTF7, UTF32, Unicode, BigEndianUnicode, Default et OEM.
#La valeur par défaut est UTF8.
[Parameter(Position=5)]
[Text.Encoding]$Encoding = [Text.Encoding]::UTF8,
#Omet l'en-tête d'informations de type de la sortie.
#Par défaut, la chaîne de la sortie contient « #TYPE », suivi du nom complet du type de l'objet .NET Framework.
#Le type inséré par ConvertTo-Csv correspond au premier objet reçu dans le pipeline.
#Si les objets reçus ne sont pas du même type, le typename affiché par Get-Member peut ne pas correspondre.
[switch] $NoTypeInformation
)
Begin {
$isValidateKey=$PSBoundParameters.ContainsKey('Validation')
if (!$isValidateKey)
{ $Validation= {$true} }
[Switch] $isVerbose= $null
[void]$PSBoundParameters.TryGetValue('Verbose',[REF]$isVerbose)
if ($isVerbose)
{ $VerbosePreference='Continue' }
$_EA= $null
[void]$PSBoundParameters.TryGetValue('ErrorAction',[REF]$_EA)
if ($_EA -eq $null) #todo
{
#Récupère la valeur du contexte de l'appelant
$ErrorActionPreference=$PSCmdlet.SessionState.PSVariable.Get('ErrorActionPreference').Value
}
else
{
#Priorité: On remplace sa valeur
$ErrorActionPreference=$_EA
}
if (!$PSBoundParameters.ContainsKey('Delimiter'))
{
try {
$Delimiter=(Get-ItemProperty 'hkcu:\Control Panel\International' sList -ea Stop).sList
} catch {
#inexistent key or null value
$Delimiter=','
Write-Warning "Use delimiter '$Demlimiter'."
}
}
function OpenStream {
Write-debug "Increment=$Increment" #<%REMOVE%>
$FileName='{0}\{1}{2}{3}' -F $FileInfo.Directory,$FileInfo.BaseName,((Get-Variable Increment -scope 1).Value++),$FileInfo.Extension
Write-Debug "OpenStream $FileName" #<%REMOVE%>
try {
$Writer=New-Object IO.StreamWriter $FileName, $false, $Encoding
}
catch {
$Er= New-Object System.Management.Automation.ErrorRecord(
$_.Exception,
"IOError",
"OpenError",
$FileName
)
#Stop the pipeline now !
$PSCmdlet.ThrowTerminatingError($Er)
}
try {
if ($TYPEInformation -ne [string]::Empty)
{ $Writer.WriteLine($TYPEInformation) }
if ($HeaderInformation -ne [string]::Empty)
{ $Writer.WriteLine($HeaderInformation) }
}
catch {
$Er= New-Object System.Management.Automation.ErrorRecord(
$_.Exception,
"IOError",
"WriteError",
$FileName
)
$PSCmdlet.ThrowTerminatingError($Er)
}
Write-Output $Writer
}#OpenStream
function CloseStream {
if ($Writer -ne $null)
{
Write-Verbose "Out-SplittingCSV : $($Writer.BaseStream.Name)"
try {
$Writer.Close()
}
catch {
$Er= New-Object System.Management.Automation.ErrorRecord(
$_.Exception,
"IOError",
"CloseError",
$FileName
)
$PSCmdlet.ThrowTerminatingError($Er)
}
}
}#CloseStream
$TYPEInformation=$HeaderInformation=[string]::Empty
$Increment=$Number=0
$PreviousObject=$null
$isAssignHeader=$true
$Writer = $Null
$FileInfo=New-object System.IO.FileInfo $Path
}
Process {
Write-Debug "${Number}/$Count" #<%REMOVE%>
if ($isAssignHeader)
{
$Csv=$InputObject|Select-Object -Property $Property|ConvertTo-Csv -Delimiter $Delimiter -NoTypeInformation:$NoTypeInformation
if ($NoTypeInformation)
{
$HeaderInformation =$Csv[0]
Write-Debug "HeaderInformation= $InputObject" #<%REMOVE%>
}
else
{
$TYPEInformation=$Csv[0]
Write-Debug "TYPEInformation= $InputObject" #<%REMOVE%>
$HeaderInformation =$Csv[1]
Write-Debug "HeaderInformation= $InputObject" #<%REMOVE%>
}
$isAssignHeader=$false
$PreviousObject=$InputObject
$Writer = OpenStream
}
Write-debug "$($Number -ge $Count) $(&$Validation -Current $InputObject -Previous $PreviousObject)" #<%REMOVE%>
if (($Number -ge $Count) -and (&$Validation -Current $InputObject -Previous $PreviousObject))
{
Write-Debug "Split CSV file" #<%REMOVE%>
CloseStream
$Writer = OpenStream
$Number=0
}
if ($isValidateKey)
{ $PreviousObject=$InputObject }
try {
$Writer.WriteLine((($InputObject|Select-Object -Property $Property|ConvertTo-Csv -Delimiter $Delimiter -NoTypeInformation)[1]) )
}
catch {
$Er= New-Object System.Management.Automation.ErrorRecord(
$_.Exception,
"IOError",
"WriteError",
$Writer.BaseStream.Name
)
$PSCmdlet.ThrowTerminatingError($Er)
}
$Number++
}
End {
#Close Current stream
CloseStream
}
} #Out-SplittingCSV |