Question Création d'objets à partir d'un fichier CSV

Plus d'informations
il y a 11 ans 7 mois #17860 par MALGARINI
Bonjour à tous
Voici le contexte
Mon fichier de test l_test.csv est le suivant :

  • NAME;CREATOR
    T001;OWNER
    T002;OWNER
    T003;OWNER
  • Le script test1.ps1 est le suivant :
    [code:1]
    Param(
    [parameter(Mandatory=$true)]
    [alias(\"fco\",\"FichierCouloir\"«»)]
    ${sstr_FichierCouloir})

    [long]$local:llng_NbFichiersCsv=0

    function slng_FusionnerListesCsv( `
    [Parameter(mandatory=$true,ValueFromPipeline=$true)]
    [Alias(\"FichierCouloir\"«»)]
    [string]$pstr_NomFichierCouloir)
    {
    [Array]$local:«»xast_LigneCsvLue=$null
    [psobject]$local:«»xpso_LignesCsvCible=$null
    [array]$local:«»xast_NomFichierCible=$null
    [string]$local:«»xstr_DbnameCible=$null
    [string]$local:«»xstr_NomFichierFusionne=$null
    [long]$local:«»xlng_NbFichiersCsv=$null

    ${xpso_LignesCsvCible} = Get-Content -path ${pstr_NomFichierCouloir} | Where {$_ -notmatch 'NAME;CREATOR'} |
    Foreach-Object {
    ${xast_LigneCsvLue}=$_ -Split ';'
    New-object PSObject -Property @{TableOrigine=${xast_LigneCsvLue}[0];SchemaCible=${xast_LigneCsvLue}[1]}
    }

    ${xast_NomFichierCible} = ([io.fileinfo]${pstr_NomFichierCouloir}).basename.Split(\"_\"«»)
    Switch (${xast_NomFichierCible}.Count)
    {
    1
    {
    ${xstr_DbnameCible} = ${xast_NomFichierCible}[0].ToUpper()
    } # FIN SANS CARACTERE DE SOULIGNEMENT

    2
    {
    ${xstr_DbnameCible} = ${xast_NomFichierCible}[1].ToUpper()
    } # FIN UN SEUL CARACTERE DE SOULIGNEMENT

    default
    {
    ${xstr_DbnameCible} = ${xast_NomFichierCible}[(${xast_NomFichierCible}.Count - 1)].ToUpper()
    } # FIN AU MOINS DEUX CARACTERES DE SOULIGNEMENT
    } # FIN ANALYSE NOMBRE ELEMENTS TABLEAU

    ${xstr_NomFichierFusionne} = ${xstr_DbnameCible} + '.CSV'

    if ($VerbosePreference -eq \"Continue\"«») {
    Write-Verbose -Message \"NOUVELLE LISTE DE TABLES DANS ${xstr_NomFichierFusionne}\"
    ${xpso_LignesCsvCible}
    Write-Verbose -Message \"*******************\"
    }

    ${xlng_NbFichiersCsv}++

    Return ${xlng_NbFichiersCsv}
    }

    ${llng_NbFichiersCsv} = slng_FusionnerListesCsv -FichierCouloir ${sstr_FichierCouloir}
    [/code:1]

    Lors de l'exécution du script via Set-StrictMode -Version latest;$VerbosePreference=\"Continue\";.\test1.ps1 -fco l_Test.csv Aucun affichage du contenu de l'objet créé avec un message d'erreur concernant la récupération du retour de la fonction dans une variable de type [long] :
    COMMENTAIRES : NOUVELLE LISTE DE TABLES DANS TEST.CSV
    COMMENTAIRES : *******************
    Impossible de convertir la valeur « System.Object[] » du type « System.Object[] » en type « System.Int64 ».
    Au niveau de D:\Développements\Outils\Power Shell\ListeItems\test1.ps1 : 58 Caractère : 22
    + ${llng_NbFichiersCsv} <<<< = slng_FusionnerListesCsv -FichierCouloir ${sstr_FichierCouloir}
    + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException


    Si Je supprime l'appel :
    [code:1]${llng_NbFichiersCsv} = slng_FusionnerListesCsv -FichierCouloir ${sstr_FichierCouloir}[/code:1]
    par
    [code:1]slng_FusionnerListesCsv -FichierCouloir ${sstr_FichierCouloir}[/code:1]

    Je n'ai plus l'erreur mais l'affichage indique bien le contenu de l'objet créé :

  • COMMENTAIRES : NOUVELLE LISTE DE TABLES DANS TEST.CSV

    TableOrigine SchemaCible

    T001 OWNER
    T002 OWNER
    T003 OWNER
    COMMENTAIRES : *******************
    1

  • J'ai donc deux questions :
    Pourquoi dans un cas j'obtiens l'affichage du contenu de l'objet, et pas dans l'autre?
    Et comment résoudre l'erreur :
    Impossible de convertir la valeur « System.Object[] » du type « System.Object[] » en type « System.Int64 ».

    Merci d'avance de votre aide

    La pièce jointe test1.ps1 est absente ou indisponible



    Message édité par: Paul_M, à: 23/07/14 12:03

    Message édité par: Paul_M, à: 23/07/14 12:04<br><br>Message édité par: Paul_M, à: 23/07/14 12:08
    Pièces jointes :

    Connexion ou Créer un compte pour participer à la conversation.

    Plus d'informations
    il y a 11 ans 7 mois #17861 par Laurent Dardenne
    Salut,
    Paul_M écrit:

    Pourquoi dans un cas j'obtiens l'affichage du contenu de l'objet, et pas dans l'autre?

    Ta fonction renvoi des PsObject et un entier, donc un tableau d'objets qui ne peut être converti en type long.
    Par défaut PS émet les objets dans le pipeline, ton affectation reçoit donc tous les objets que la fonction émet. Si tu supprimes l'affectation PS l'émet par défaut sur la console. Cf. Write-Host / Write-Output.
    [code:1]
    function Test {
    Write-Warning \&quot;test\&quot;
    \&quot;un\&quot;
    \&quot;deux\&quot;
    Write-Warning \&quot;Fin\&quot;
    return 3
    }
    Write-Warning \&quot;I =\&quot;
    [long]$i= test
    Write-Warning \&quot;J =\&quot;
    $j= test
    $j
    Write-Warning \&quot;no var =\&quot;
    test
    [/code:1]
    Paul_M écrit:

    Et comment résoudre l'erreur :

    Cela dépend de ce que tu veux faire...

    En passant, à mon avis l'usage d'une notation hongroise devrait être évité. Soit la variable est typée(contrainte) et ne peut contenir qu'un type soit elle ne l'est pas et la notation ne sert à rien.

    Par défaut les variables d'une fonction sont locales, à moins de partager la fonction entre + scripts, c'est donc redondant.

    Les string et les entiers ne peuvent être à $Null sous PS.

    Tutoriels PowerShell

    Connexion ou Créer un compte pour participer à la conversation.

    Plus d'informations
    il y a 11 ans 7 mois #17871 par MALGARINI
    Bonjour

    Merci de ta réponse rapide. J’appréhende mieux maintenant le rôle du « pipeline ».
    Merci également de l’information concernant l’assignation erronée de la valeur $null à une variable de type [sting].
    J’ai bien noté la redondance pour les variables à l’intérieur d’une fonction.
    Concernant l’assignation de $null à une variable de type [long], c’est une bévue de ma part.

    Ce que je souhaite obtenir, c’est une fonction qui retourne un nombre et qui, selon la variable $VerbosePreference, affiche le contenu du tableau construit à partir du fichier CSV.

    Concernant l’usage de la notation, Je vais donner quelques explications.

    Lorsque Je débute dans un nouveau langage, Je m’intéresse à ce que je juge, de part ma propre expérience de développement, comment faisant partie des fondamentaux :
  • Le langage est-il fortement typé ou pas ?
  • Quelles sont les différentes portées des variables
  • Quelles sont les différents types de données des variables

  • A partir de mes découvertes, Je définis des règles de codage (un ensemble de « lois » dont la première règle implicite est « ces principes doivent être appliqués » ; et donc en tout premier par moi-même).
    Mon but est de pouvoir, lorsque Je consulte le code, et dans un souci de maintenance plus aisée, avoir l’information de la portée et du type de données.
    Avec « cerise sur le gâteau »,obtenir, lors de développements modulaires (inclus la concaténation de plusieurs sources pour créer un seul script), l’information permettant de connaître au premier coup d’œil dans quel module consulter.

    Ces choix qui entraînent des contraintes sur le développement et peut-être me brident dans l’exploration et l’exploitation de PowerShell, sont destinés à m’obliger à réfléchir sur le choix de tel ou tel type de données pour un besoin précis.

    Même si ces choix peuvent laisser croire à un côté « dogmatique », ils sont plutôt destinés à exprimer mon côté « Je définis ce que je fais et je fais ce que je définis », et ceci dans un souci de mieux maîtriser le sujet. Et j’accepte toute remarque, question ou autre commentaire sur ma méthode.

    Merci encore pour ce forum très riche.

    Connexion ou Créer un compte pour participer à la conversation.

    Plus d'informations
    il y a 11 ans 7 mois #17872 par Laurent Dardenne
    Paul_M écrit:

    Merci également de l’information concernant l’assignation erronée de la valeur $null à une variable de type [sting].

    Ce n'est pas une erreur, mais PS s'autorise des transformations implicites, le contenu ne correspond donc pas à ce qu'on lit.
    Paul_M écrit:

    Ce que je souhaite obtenir, c’est une fonction qui retourne un nombre et qui, selon la variable $VerbosePreference, affiche le contenu du tableau construit à partir du fichier CSV.

    Essaie ceci qui évite l'envoi des objets dans le pipeline:
    [code:1]
    if ($VerbosePreference -eq \&quot;Continue\&quot;«») {
    Write-Verbose -Message \&quot;NOUVELLE LISTE DE TABLES DANS ${xstr_NomFichierFusionne}\&quot;
    ${xpso_LignesCsvCible}| Foreach {Write-Verbose $_ }
    Write-Verbose -Message \&quot;*******************\&quot;
    }
    [/code:1]
    L'affichage sera différent de celui par défaut, mais reste lisible.
    Paul_M écrit:

    Même si ces choix peuvent laisser croire à un côté « dogmatique »,

    Cela impose une rigueur que tout le monde n'a pas.
    Comme dans l'info on n'aime pas trop les contraintes, l'adoption d'une telle règle nommage au sein d'une équipe me semble délicate.
    Paul_M écrit:

    Et j’accepte toute remarque, question ou autre commentaire sur ma méthode.

    Chacun code comme il veut, avec ton approche cela évite de lire les attributs d'une variable et d'appeler la méthode GetType().
    Je préfére que le nom de mes variables portent une information fonctionnelle que technique.
    Du coup je trouve que ce type de nommage rend de prime abord la relecture difficile. Ensuite c'est une question d'habitude.

    Un dernière remarque, l'usage du nommage de variable ${nom} devrait être évité, tu risques de te retrouver avec des noms difficile à manier en dehors de ce nommage, ex : ${$xstr-DbName}<br><br>Message édité par: Laurent Dardenne, à: 28/07/14 16:19

    Tutoriels PowerShell

    Connexion ou Créer un compte pour participer à la conversation.

    Temps de génération de la page : 0.050 secondes
    Propulsé par Kunena