Conversion xls > xml

Bonjour à tous,

Je me permets de vous contacter dans le cadre de mon boulot. Je suis charpentier et dispose dans mon entreprise d'une tronçonneuse numérique qui lit des listes de pièces à découper au format xml. Le bureau d'études lui les exporte au format excel sous la forme suivante:

N° pièce

Hauteur

Epaisseur

Longueur

Quantité

N° mur

Voici ici un exemple d'excel avec une liste de production brute et une macro qui générerait un tri par section stricte (https://www.cjoint.com/c/HAmwBwePFny ).

Au sein du fichier xml, les pièces sont regroupées par section (hauteur ET épaisseur strictement identiques) sous un en-tête qui liste ensuite les longueurs (variables), le numéro de mur (s'il y en a un) et la quantité de chacune (variable aussi). Voici ci-dessous un exemple de code avec trois section différentes 30x65, 45x240 et 80x240 avec pour chacune, plusieurs longueurs et dans le cas du 45x240, deux longueurs de 555 n'appartenant pas au même mur (MD101 et MD102) et donc codées l'une à la suite de l'autre.

<?xml version="1.0"?>
<Programs fileversion="version 1.0">
    <PrgProgram>02012018_Test_Stromab</PrgProgram>
    <PrgHeadTrimmingLength>0</PrgHeadTrimmingLength>
    <PrgTailTrimmingLength>0</PrgTailTrimmingLength>
    <PrgPrinterField1></PrgPrinterField1>
    <PrgPrinterField2></PrgPrinterField2>
    <PrgPrinterField3></PrgPrinterField3>
    <PrgPreOptimized>0</PrgPreOptimized>
    <PrgProgrammedBarLength>0</PrgProgrammedBarLength>
    <PrgSections>
        <SecSectionID>1</SecSectionID>
        <SecHeight>30</SecHeight>
        <SecMinWidth/>
        <SecMaxWidth/>
        <SecWidth>65</SecWidth>
        <PreOpt/>
        <PrgPieces>
            <PcPage/>
            <PcQuality>1</PcQuality>
            <PcPieceID>1</PcPieceID>
            <PcLength>830</PcLength>
            <PcNumberOfPieces>1</PcNumberOfPieces>
            <PcPriority>0</PcPriority>
            <PcUnloader1>2</PcUnloader1>
            <PcUnloader2>0</PcUnloader2>
            <PcPrinterCode></PcPrinterCode>
            <PcPrinterId></PcPrinterId>
            <PcPrinterField1></PcPrinterField1>
            <PcPrinterField2>2572</PcPrinterField2>
            <PcPrinterField3>MD101</PcPrinterField3>
            <PcPrinterField4></PcPrinterField4>
            <PcPrinterField5></PcPrinterField5>
            <PcPrinterField6></PcPrinterField6>
            <PcPrinterField7></PcPrinterField7>
            <PcPrinterField8></PcPrinterField8>
            <PcPrinterField9></PcPrinterField9>
            <PcPrinterField10></PcPrinterField10>
            <PcNumberOfDonePieces>0</PcNumberOfDonePieces>
            <PcSelected>1</PcSelected>
        </PrgPieces>
        <PrgPieces>
            <PcPage/>
            <PcQuality>1</PcQuality>
            <PcPieceID>2</PcPieceID>
            <PcLength>3980</PcLength>
            <PcNumberOfPieces>1</PcNumberOfPieces>
            <PcPriority>0</PcPriority>
            <PcUnloader1>1</PcUnloader1>
            <PcUnloader2>3</PcUnloader2>
            <PcPrinterCode></PcPrinterCode>
            <PcPrinterId></PcPrinterId>
            <PcPrinterField1></PcPrinterField1>
            <PcPrinterField2>2562</PcPrinterField2>
            <PcPrinterField3>MD101</PcPrinterField3>
            <PcPrinterField4></PcPrinterField4>
            <PcPrinterField5></PcPrinterField5>
            <PcPrinterField6></PcPrinterField6>
            <PcPrinterField7></PcPrinterField7>
            <PcPrinterField8></PcPrinterField8>
            <PcPrinterField9></PcPrinterField9>
            <PcPrinterField10></PcPrinterField10>
            <PcNumberOfDonePieces>0</PcNumberOfDonePieces>
            <PcSelected>1</PcSelected>
        </PrgPieces>
        <SecSectionID>2</SecSectionID>
        <SecHeight>45</SecHeight>
        <SecMinWidth/>
        <SecMaxWidth/>
        <SecWidth>240</SecWidth>
        <PreOpt/>
        <PrgPieces>
            <PcPage/>
            <PcQuality>1</PcQuality>
            <PcPieceID>3</PcPieceID>
            <PcLength>413</PcLength>
            <PcNumberOfPieces>1</PcNumberOfPieces>
            <PcPriority>0</PcPriority>
            <PcUnloader1>2</PcUnloader1>
            <PcUnloader2>0</PcUnloader2>
            <PcPrinterCode></PcPrinterCode>
            <PcPrinterId></PcPrinterId>
            <PcPrinterField1></PcPrinterField1>
            <PcPrinterField2>2546</PcPrinterField2>
            <PcPrinterField3>MD101</PcPrinterField3>
            <PcPrinterField4></PcPrinterField4>
            <PcPrinterField5></PcPrinterField5>
            <PcPrinterField6></PcPrinterField6>
            <PcPrinterField7></PcPrinterField7>
            <PcPrinterField8></PcPrinterField8>
            <PcPrinterField9></PcPrinterField9>
            <PcPrinterField10></PcPrinterField10>
            <PcNumberOfDonePieces>0</PcNumberOfDonePieces>
            <PcSelected>1</PcSelected>
        </PrgPieces>
        <PrgPieces>
            <PcPage/>
            <PcQuality>1</PcQuality>
            <PcPieceID>4</PcPieceID>
            <PcLength>452</PcLength>
            <PcNumberOfPieces>1</PcNumberOfPieces>
            <PcPriority>0</PcPriority>
            <PcUnloader1>2</PcUnloader1>
            <PcUnloader2>0</PcUnloader2>
            <PcPrinterCode></PcPrinterCode>
            <PcPrinterId></PcPrinterId>
            <PcPrinterField1></PcPrinterField1>
            <PcPrinterField2>2544</PcPrinterField2>
            <PcPrinterField3>MD101</PcPrinterField3>
            <PcPrinterField4></PcPrinterField4>
            <PcPrinterField5></PcPrinterField5>
            <PcPrinterField6></PcPrinterField6>
            <PcPrinterField7></PcPrinterField7>
            <PcPrinterField8></PcPrinterField8>
            <PcPrinterField9></PcPrinterField9>
            <PcPrinterField10></PcPrinterField10>
            <PcNumberOfDonePieces>0</PcNumberOfDonePieces>
            <PcSelected>1</PcSelected>
        </PrgPieces>
        <PrgPieces>
            <PcPage/>
            <PcQuality>1</PcQuality>
            <PcPieceID>5</PcPieceID>
            <PcLength>555</PcLength>
            <PcNumberOfPieces>1</PcNumberOfPieces>
            <PcPriority>0</PcPriority>
            <PcUnloader1>2</PcUnloader1>
            <PcUnloader2>0</PcUnloader2>
            <PcPrinterCode></PcPrinterCode>
            <PcPrinterId></PcPrinterId>
            <PcPrinterField1></PcPrinterField1>
            <PcPrinterField2>2534</PcPrinterField2>
            <PcPrinterField3>MD101</PcPrinterField3>
            <PcPrinterField4></PcPrinterField4>
            <PcPrinterField5></PcPrinterField5>
            <PcPrinterField6></PcPrinterField6>
            <PcPrinterField7></PcPrinterField7>
            <PcPrinterField8></PcPrinterField8>
            <PcPrinterField9></PcPrinterField9>
            <PcPrinterField10></PcPrinterField10>
            <PcNumberOfDonePieces>0</PcNumberOfDonePieces>
            <PcSelected>1</PcSelected>
        </PrgPieces>
        <PrgPieces>
            <PcPage/>
            <PcQuality>1</PcQuality>
            <PcPieceID>6</PcPieceID>
            <PcLength>555</PcLength>
            <PcNumberOfPieces>1</PcNumberOfPieces>
            <PcPriority>0</PcPriority>
            <PcUnloader1>2</PcUnloader1>
            <PcUnloader2>0</PcUnloader2>
            <PcPrinterCode></PcPrinterCode>
            <PcPrinterId></PcPrinterId>
            <PcPrinterField1></PcPrinterField1>
            <PcPrinterField2>2534</PcPrinterField2>
            <PcPrinterField3>MD102</PcPrinterField3>
            <PcPrinterField4></PcPrinterField4>
            <PcPrinterField5></PcPrinterField5>
            <PcPrinterField6></PcPrinterField6>
            <PcPrinterField7></PcPrinterField7>
            <PcPrinterField8></PcPrinterField8>
            <PcPrinterField9></PcPrinterField9>
            <PcPrinterField10></PcPrinterField10>
            <PcNumberOfDonePieces>0</PcNumberOfDonePieces>
            <PcSelected>1</PcSelected>
        </PrgPieces>
        <SecSectionID>3</SecSectionID>
        <SecHeight>80</SecHeight>
        <SecMinWidth/>
        <SecMaxWidth/>
        <SecWidth>240</SecWidth>
        <PreOpt/>
        <PrgPieces>
            <PcPage/>
            <PcQuality>1</PcQuality>
            <PcPieceID>12</PcPieceID>
            <PcLength>2945</PcLength>
            <PcNumberOfPieces>1</PcNumberOfPieces>
            <PcPriority>0</PcPriority>
            <PcUnloader1>1</PcUnloader1>
            <PcUnloader2>3</PcUnloader2>
            <PcPrinterCode></PcPrinterCode>
            <PcPrinterId></PcPrinterId>
            <PcPrinterField1></PcPrinterField1>
            <PcPrinterField2>2481</PcPrinterField2>
            <PcPrinterField3>MD101</PcPrinterField3>
            <PcPrinterField4></PcPrinterField4>
            <PcPrinterField5></PcPrinterField5>
            <PcPrinterField6></PcPrinterField6>
            <PcPrinterField7></PcPrinterField7>
            <PcPrinterField8></PcPrinterField8>
            <PcPrinterField9></PcPrinterField9>
            <PcPrinterField10></PcPrinterField10>
            <PcNumberOfDonePieces>0</PcNumberOfDonePieces>
            <PcSelected>1</PcSelected>
        </PrgPieces>
    </PrgSections>
</Programs>

Afin de faciliter la tâche des gars à l'atelier, je souhaiterais un peu d'aide pour développer un fichier excel qui automatiserait la conversion.

Avez-vous des idées sur la conception (la forme que pourrait prendre l'interface) et d'éventuelles idées de fonction, macros etc ?

D'avance merci, bien à vous.

Baptiste.

Bonjour,

Une piste peut être !

En créant un squelette du groupe principal qui nécessite le changement de valeurs avec ces dernières dans un tableau dont tu auras au préalable défini le nombre de dimensions nécessaires (les valeurs pouvant être récupérées dans une feuille de calcul). Une fois tous les paramètres définis, construction de la chaîne complète :

Sub Test()

    Dim Tbl() As String
    Dim XML As String
    Dim ChaineXML As String
    Dim I As Integer

    'créer autant de dimensions que nécessaire !
    ReDim Tbl(1 To 5, 1 To 2)

    Tbl(1, 1) = "M101" 'PcPrinterField3
    Tbl(2, 1) = "830" 'PcLength
    Tbl(3, 1) = "2572" 'PcPrinterField2
    Tbl(4, 1) = "1" 'PcQuality
    Tbl(5, 1) = "1" 'PcPieceID

    Tbl(1, 2) = "M102"
    Tbl(2, 2) = "3980"
    Tbl(3, 2) = "2562"
    Tbl(4, 2) = "1"
    Tbl(5, 2) = "2"

    'Etc...

    For I = 1 To UBound(Tbl, 2)

        XML = "<PrgPieces>" & vbCrLf
        XML = XML & "<PcPage/>" & vbCrLf
        XML = XML & "<PcQuality>" & Tbl(4, I) & "</PcQuality>" & vbCrLf
        XML = XML & "<PcPieceID>" & Tbl(5, I) & "</PcPieceID>" & vbCrLf
        XML = XML & "<PcLength>" & Tbl(2, I) & "</PcLength>" & vbCrLf
        XML = XML & "<PcNumberOfPieces>1</PcNumberOfPieces>" & vbCrLf
        XML = XML & " <PcPriority>0</PcPriority>" & vbCrLf
        XML = XML & "<PcUnloader1>2</PcUnloader1>" & vbCrLf
        XML = XML & "<PcUnloader2>0</PcUnloader2>" & vbCrLf
        XML = XML & "<PcPrinterCode></PcPrinterCode>" & vbCrLf
        XML = XML & "<PcPrinterId></PcPrinterId>" & vbCrLf
        XML = XML & "<PcPrinterField1></PcPrinterField1>" & vbCrLf
        XML = XML & "<PcPrinterField2>" & Tbl(3, I) & "</PcPrinterField2>" & vbCrLf
        XML = XML & "<PcPrinterField3>" & Tbl(1, I) & "</PcPrinterField3>" & vbCrLf
        XML = XML & "<PcPrinterField4></PcPrinterField4>" & vbCrLf
        XML = XML & "<PcPrinterField5></PcPrinterField5>" & vbCrLf
        XML = XML & "<PcPrinterField6></PcPrinterField6>" & vbCrLf
        XML = XML & "<PcPrinterField7></PcPrinterField7>" & vbCrLf
        XML = XML & "<PcPrinterField8></PcPrinterField8>" & vbCrLf
        XML = XML & "<PcPrinterField9></PcPrinterField9>" & vbCrLf
        XML = XML & "<PcPrinterField10></PcPrinterField10>" & vbCrLf
        XML = XML & "<PcNumberOfDonePieces>0</PcNumberOfDonePieces>" & vbCrLf
        XML = XML & "<PcSelected>1</PcSelected>" & vbCrLf
        XML = XML & "</PrgPieces>"

        ChaineXML = ChaineXML & XML

        MsgBox ChaineXML 'n'affichera pas tout au second passage mais c'est pour le test !

    Next I

End Sub

Génial cette réponse Theze !

J'avoue que je me rends compte que la solution dépasse largement mon champs de compétences (je suis charpentier à la base hein !), mais ça me motive d'autant plus après avoir suivi un petit tuto sur le VBA de savoir qu'un cas concret me tend les bras.

Cependant, une légère zone d'ombre concernant ton texte introductif. Tu parles de "groupe principal qui nécessite le changement de valeur avec ces dernières dans un tableau dont j'aurais au préalable défini le nombre de dimensions nécessaires". Cela signifie-t-il de regrouper toutes les pièces par sections identiques, comme le fait la petite macro de tri dans mon exemple ?

Néanmoins, je ne vois pas apparaître les sections dans ta macro, dois-je réfléchir à une macro à part entière qui générerait ce code xml d'en-tête ?

Désolé pour ce manque de discernement, mais je ne m'attendais à une avancée si folle après mon premier post, un énorme merci pour le temps consacré !

Baptiste.

Re,

On peut voir que tu as les balises :

<PrgPieces>
'...
<PrgPieces>

Qui se répètent et qui ont des valeurs variables. Donc j'imagine qu'il est possible de définir les débuts et fin du code, pour le début :

<?xml version="1.0"?>
<Programs fileversion="version 1.0">
    <PrgProgram>02012018_Test_Stromab</PrgProgram>
    <PrgHeadTrimmingLength>0</PrgHeadTrimmingLength>
    <PrgTailTrimmingLength>0</PrgTailTrimmingLength>
    <PrgPrinterField1></PrgPrinterField1>
    <PrgPrinterField2></PrgPrinterField2>
    <PrgPrinterField3></PrgPrinterField3>
    <PrgPreOptimized>0</PrgPreOptimized>
    <PrgProgrammedBarLength>0</PrgProgrammedBarLength>
    <PrgSections>
        <SecSectionID>1</SecSectionID>
        <SecHeight>30</SecHeight>
        <SecMinWidth/>
        <SecMaxWidth/>
        <SecWidth>65</SecWidth>
        <PreOpt/>

pour la fin :

    </PrgSections>
</Programs>

et donc, les différents groupes ou "blocs" dont je parlais dans mon précédent post, comme celui-ci :

        <PrgPieces>
            <PcPage/>
            <PcQuality>1</PcQuality>
            <PcPieceID>1</PcPieceID>
            <PcLength>830</PcLength>
            <PcNumberOfPieces>1</PcNumberOfPieces>
            <PcPriority>0</PcPriority>
            <PcUnloader1>2</PcUnloader1>
            <PcUnloader2>0</PcUnloader2>
            <PcPrinterCode></PcPrinterCode>
            <PcPrinterId></PcPrinterId>
            <PcPrinterField1></PcPrinterField1>
            <PcPrinterField2>2572</PcPrinterField2>
            <PcPrinterField3>MD101</PcPrinterField3>
            <PcPrinterField4></PcPrinterField4>
            <PcPrinterField5></PcPrinterField5>
            <PcPrinterField6></PcPrinterField6>
            <PcPrinterField7></PcPrinterField7>
            <PcPrinterField8></PcPrinterField8>
            <PcPrinterField9></PcPrinterField9>
            <PcPrinterField10></PcPrinterField10>
            <PcNumberOfDonePieces>0</PcNumberOfDonePieces>
            <PcSelected>1</PcSelected>
        </PrgPieces>
        <PrgPieces>

qui je pense, définissent les pièces à usiner et dont il est possible de définir les variables (valeurs qui sont changeantes) comme par exemple :

<PcLength>830</PcLength>

où 830 est une variable que j'ai fais évoluer avec un tableau :

Tbl(2, 1) = "830" 'PcLength

Re-bonsoir Theze,

Et merci pour tant de réactivité et de clarté.

Tu as effectivement raison sur l'architecture du code du fichier, à ce détail près: les pièces de bois sont avant tout réuni sous la balise

<SecSectionID>1</SecSectionID>
        <SecHeight>30</SecHeight>
        <SecMinWidth/>
        <SecMaxWidth/>
        <SecWidth>65</SecWidth>
        <PreOpt/>

qui se répètent pour chaque section (hauteur x épaisseur, ou height et width).

Pour chaque section, il faut donc générer cet "en-tête" de code puis puis le code que tu as déjà rédigé pour les pièces qui possèdent cette section.

Cela change-t-il la structure de ta macro ?

Bonjour,

Je pense que la partie "Section" peut être répétée pour chaque pièce sans que le compilateur de la machine en prenne ombrage

Je suis parti avec un "type Utilisateur" afin de rendre le code plus facile à manipuler et en fin de proc, un fichier XML est créé dans le même dossier que celui du classeur où tu colleras le code ci-dessous. Pour les différentes valeurs, tu peux créer un tableau dans une feuille et ensuite, les récupérer dans le tableau de type Utilisateur dans une boucle avant de l'injecter dans le code xml :

Type Piece

    IDPiece As Integer
    IDSection As Integer
    Mur As String
    Largeur As Double
    Hauteur As Double
    Longueur As Double
    Qualite As Integer
    NBPiece As Integer
    Nombre As Integer
    Champ2 As Long
    'etc...

End Type

Sub Test()

    Dim Tbl() As Piece
    Dim DebutXML As String
    Dim FinXML As String
    Dim XML As String
    Dim ChaineXML As String
    Dim I As Integer

    'créer autant de dimensions que nécessaire !
    'les valeurs pouvant être récupérées dans un tableau sur une feuille
    ReDim Tbl(1 To 2) 'pour le test, deux dimensions

    Tbl(1).IDPiece = 1
    Tbl(1).IDSection = 1
    Tbl(1).Mur = "M101"
    Tbl(1).Hauteur = 30
    Tbl(1).Largeur = 65
    Tbl(1).Longueur = 830
    Tbl(1).NBPiece = 1
    Tbl(1).Qualite = 1
    Tbl(1).Nombre = 1
    Tbl(1).Champ2 = 2572

    Tbl(2).IDPiece = 1
    Tbl(2).IDSection = 1
    Tbl(2).Mur = "M101"
    Tbl(2).Hauteur = 30
    Tbl(2).Largeur = 65
    Tbl(2).Longueur = 830
    Tbl(2).NBPiece = 1
    Tbl(2).Qualite = 1
    Tbl(2).Nombre = 1
    Tbl(2).Champ2 = 2562

    DebutXML = "<?xml version=""1.0""?>" & vbCrLf
    DebutXML = DebutXML & "<Programs fileversion=""version 1.0"">" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgProgram>02012018_Test_Stromab</PrgProgram>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgHeadTrimmingLength>0</PrgHeadTrimmingLength>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgTailTrimmingLength>0</PrgTailTrimmingLength>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgPrinterField1></PrgPrinterField1>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgPrinterField2></PrgPrinterField2>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgPrinterField3></PrgPrinterField3>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgPreOptimized>0</PrgPreOptimized>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgProgrammedBarLength>0</PrgProgrammedBarLength>" & vbCrLf
    DebutXML = DebutXML & vbCrLf

    FinXML = Space(4) & "</PrgSections>" & vbCrLf
    FinXML = FinXML & "</Programs>" & vbCrLf

    For I = 1 To UBound(Tbl)

        XML = XML & vbCrLf
        XML = Space(4) & "<PrgSections>" & vbCrLf
        XML = XML & Space(8) & "<SecSectionID>" & Tbl(I).IDSection & "</SecSectionID>" & vbCrLf
        XML = XML & Space(8) & "<SecHeight>" & Tbl(I).Hauteur & "</SecHeight>" & vbCrLf
        XML = XML & Space(8) & "<SecMinWidth/>" & vbCrLf
        XML = XML & Space(8) & "<SecMaxWidth/>" & vbCrLf
        XML = XML & Space(8) & "<SecWidth>" & Tbl(I).Largeur & "</SecWidth>" & vbCrLf
        XML = XML & Space(8) & "<PreOpt/>" & vbCrLf
        XML = XML & vbCrLf

        XML = XML & Space(8) & "<PrgPieces>" & vbCrLf
        XML = XML & Space(12) & "<PcPage/>" & vbCrLf
        XML = XML & Space(12) & "<PcQuality>" & Tbl(I).Qualite & "</PcQuality>" & vbCrLf
        XML = XML & Space(12) & "<PcPieceID>" & Tbl(I).IDPiece & "</PcPieceID>" & vbCrLf
        XML = XML & Space(12) & "<PcLength>" & Tbl(1).Longueur & "</PcLength>" & vbCrLf
        XML = XML & Space(12) & "<PcNumberOfPieces>" & Tbl(1).Nombre & "</PcNumberOfPieces>" & vbCrLf
        XML = XML & Space(12) & "<PcPriority>0</PcPriority>" & vbCrLf
        XML = XML & Space(12) & "<PcUnloader1>2</PcUnloader1>" & vbCrLf
        XML = XML & Space(12) & "<PcUnloader2>0</PcUnloader2>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterCode></PcPrinterCode>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterId></PcPrinterId>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField1></PcPrinterField1>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField2>" & Tbl(I).Champ2 & "</PcPrinterField2>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField3>" & Tbl(I).Mur & "</PcPrinterField3>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField4></PcPrinterField4>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField5></PcPrinterField5>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField6></PcPrinterField6>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField7></PcPrinterField7>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField8></PcPrinterField8>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField9></PcPrinterField9>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField10></PcPrinterField10>" & vbCrLf
        XML = XML & Space(12) & "<PcNumberOfDonePieces>0</PcNumberOfDonePieces>" & vbCrLf
        XML = XML & Space(12) & "<PcSelected>1</PcSelected>" & vbCrLf
        XML = XML & Space(12) & "</PrgPieces>" & vbCrLf
        XML = XML & vbCrLf

        ChaineXML = ChaineXML & XML

    Next I

    ChaineXML = DebutXML & ChaineXML & FinXML

    CreerXML ChaineXML

End Sub

Sub CreerXML(Chaine As String)

    Dim I As Integer

    Open ThisWorkbook.Path & "\TestXML.xml" For Output As #1

        Print #1, Chaine

    Close #1

End Sub

Re,

Je viens de bosser un peu plus sur mon exemple (et corrigé 2, 3 fautes dues au copier/coller). Je n'avais pas fais attention que tu avais posté un classeur sur cjoint donc, à partir de ce classeur j'ai créé une seconde feuille avec les valeur de la feuille "Feuil1" etg j'ai mis des commentaires de même pour le code. A toi de voir si ça convient !

Re-bonjour,

Génial, ça me semble tout bonnement parfait ! Je dois rajouter deux champs liés au type d'éjection (PcUnloader1 et 2) dans le type utilisateur. Aussi, le fichier sera utilisé par des novices d'Excel, je vais chercher une macro pour trier directement le fichier par ID Section <

Et la macro du début permet de classer les pièces par section pour avoir un oeil sur celle qui est la plus représentée et la longueur en mètre linéaire pour chaque quantité (longueur * quantité), mais je ne l'ai pas abouti, ça n'est donc pas indispensable.

Merci encore,

Baptiste.

Si tu rencontre un problème, n'hésites surtout pas à revenir !

Une idée pour générer automatiquement un ID par section ? Merci d'avance

Edit: le mieux est que j'essaye en bidouillant pour éviter de te déranger et que tu fasses tout le boulot. Je suis au bureau cet aprèm, je t'envoie une esquisse dans la soirée.

Bonne après-midi !

Re,

Je pense qu'après un tri sur la hauteur puis l'épaisseur (ou vice versa) il est possible de créer un IDSection chaque fois que l'une des deux ou les deux valeurs différent des précédentes, je regarde ça demain !

Bonne soirée

Hervé

Bonjour Theze,

Dans ce fichier, j'ai créé la colonne ID Section avec la condition =SI(ET(C3=C2;D3=D2);B2;B2+1) et un filtre croissant pour éviter que la même section porte différents ID Section mais cela ne suffit pas... Je regarde du côté des TCD

Ensuite pour les balises Pc Unloader 1 et 2, j'ai intégré deux colonnes EJ1 et EJ2 avec un remplissage par condition selon la longueur de la pièce. J'ai ainsi créé dans le type Utilisateur, les variables:

[codeEj1 As Byte

Ej2 As Byte][/code]

puis renseigné leur emplacement dans le tableau (colonne 8 et 9):

 Tbl(I).Ej1 = Plage(I, 9).Value
Tbl(I).Ej2 = Plage(I, 10).Value

et enfin dans le corps du code à l'endroit des Pcunloader:

  XML = XML & Space(12) & "<PcUnloader1>" & Tbl(I).Ej1 & "</PcUnloader1>" & vbCrLf
XML = XML & Space(12) & "<PcUnloader2>" & Tbl(I).Ej2 & "</PcUnloader2>" & vbCrLf

Néanmoins, lorsque je lance la macro, il m'affiche un message d'erreur: erreur d’exécution "13" et le débogage m'amène à la ligne

Tbl(I).Ej1 = Plage(I, 8).Value

. J'ai comme l'impression que l'erreur vient de moi...!

Bonjour,

Je poste le code complet avec la Sub de tri et création des IDSection :

Type Piece

    IDPiece As Integer
    IDSection As Integer
    Mur As String
    Epaisseur As Double
    Hauteur As Double
    Longueur As Double
    Qualite As Integer
    Quantite As Integer
    Champ2 As Long 'je ne sais pas ce que c'est ?
    'etc...

End Type

Sub Test()

    Dim Tbl() As Piece
    Dim Plage As Range
    Dim DebutXML As String
    Dim FinXML As String
    Dim XML As String
    Dim ChaineXML As String
    Dim I As Integer
    Dim Section As Integer

    'la plage est définie à partir de A2 sur toute la feuille "Feuil2"
    Set Plage = DefPlage(Worksheets("Feuil2"), 2, 1)

    'tri et création des IDSection
    TriSection Plage

    'les valeurs correspondantes sont entrées dans le tableau
    For I = 1 To Plage.Rows.Count

        ReDim Preserve Tbl(1 To I)

        Tbl(I).IDPiece = Plage(I, 1).Value
        Tbl(I).IDSection = Plage(I, 2).Value
        Tbl(I).Hauteur = Plage(I, 3).Value
        Tbl(I).Epaisseur = Plage(I, 4).Value
        Tbl(I).Longueur = Plage(I, 5).Value
        Tbl(I).Quantite = Plage(I, 6).Value
        Tbl(I).Mur = Plage(I, 7).Value
        Tbl(I).Champ2 = Plage(I, 8).Value
        Tbl(I).Qualite = 1 '<--- valeur identique pour tous les champs

    Next I

    'début du code XML
    DebutXML = "<?xml version=""1.0""?>" & vbCrLf
    DebutXML = DebutXML & "<Programs fileversion=""version 1.0"">" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgProgram>02012018_Test_Stromab</PrgProgram>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgHeadTrimmingLength>0</PrgHeadTrimmingLength>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgTailTrimmingLength>0</PrgTailTrimmingLength>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgPrinterField1></PrgPrinterField1>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgPrinterField2></PrgPrinterField2>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgPrinterField3></PrgPrinterField3>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgPreOptimized>0</PrgPreOptimized>" & vbCrLf
    DebutXML = DebutXML & Space(4) & "<PrgProgrammedBarLength>0</PrgProgrammedBarLength>" & vbCrLf
    DebutXML = DebutXML & vbCrLf

    'fin du code XML
    FinXML = Space(4) & "</PrgSections>" & vbCrLf
    FinXML = FinXML & "</Programs>" & vbCrLf

    'construit le corps do code
    For I = 1 To UBound(Tbl)

        'n'inscrit le bloc de la section que si l'ID change
        '(la variable "Section" étant initialisée à 0, le début du corps comporte d'office le bloc de section)
        If Tbl(I).IDSection <> Section Then

            XML = XML & Space(4) & "<PrgSections>" & vbCrLf
            XML = XML & Space(8) & "<SecSectionID>" & Tbl(I).IDSection & "</SecSectionID>" & vbCrLf
            XML = XML & Space(8) & "<SecHeight>" & Tbl(I).Hauteur & "</SecHeight>" & vbCrLf
            XML = XML & Space(8) & "<SecMinWidth/>" & vbCrLf
            XML = XML & Space(8) & "<SecMaxWidth/>" & vbCrLf
            XML = XML & Space(8) & "<SecWidth>" & Tbl(I).Epaisseur & "</SecWidth>" & vbCrLf
            XML = XML & Space(8) & "<PreOpt/>" & vbCrLf
            XML = XML & vbCrLf

            'pour le contrôle afin de ne pas doublonner
            Section = Tbl(I).IDSection

        End If

        'valeurs propre à chaque pièce
        XML = XML & Space(8) & "<PrgPieces>" & vbCrLf
        XML = XML & Space(12) & "<PcPage/>" & vbCrLf
        XML = XML & Space(12) & "<PcQuality>" & Tbl(I).Qualite & "</PcQuality>" & vbCrLf
        XML = XML & Space(12) & "<PcPieceID>" & Tbl(I).IDPiece & "</PcPieceID>" & vbCrLf
        XML = XML & Space(12) & "<PcLength>" & Tbl(I).Longueur & "</PcLength>" & vbCrLf
        XML = XML & Space(12) & "<PcNumberOfPieces>" & Tbl(I).Quantite & "</PcNumberOfPieces>" & vbCrLf
        XML = XML & Space(12) & "<PcPriority>0</PcPriority>" & vbCrLf
        XML = XML & Space(12) & "<PcUnloader1>2</PcUnloader1>" & vbCrLf
        XML = XML & Space(12) & "<PcUnloader2>0</PcUnloader2>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterCode></PcPrinterCode>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterId></PcPrinterId>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField1></PcPrinterField1>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField2>" & Tbl(I).Champ2 & "</PcPrinterField2>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField3>" & Tbl(I).Mur & "</PcPrinterField3>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField4></PcPrinterField4>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField5></PcPrinterField5>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField6></PcPrinterField6>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField7></PcPrinterField7>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField8></PcPrinterField8>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField9></PcPrinterField9>" & vbCrLf
        XML = XML & Space(12) & "<PcPrinterField10></PcPrinterField10>" & vbCrLf
        XML = XML & Space(12) & "<PcNumberOfDonePieces>0</PcNumberOfDonePieces>" & vbCrLf
        XML = XML & Space(12) & "<PcSelected>1</PcSelected>" & vbCrLf
        XML = XML & Space(12) & "</PrgPieces>" & vbCrLf
        XML = XML & vbCrLf

    Next I

    'construction finale du code...
    ChaineXML = DebutXML & XML & FinXML

    'et création du fichier XML dans le même dossier que celui du classeur
    CreerXML ChaineXML

End Sub

Sub TriSection(Plage As Range)

    Dim I As Integer
    Dim Concat As String
    Dim J As Integer

    'tri la plage du plujs petit au plus grand sur la colonne "Hauteur" puis "Epaisseur"
    Plage.Sort Plage(1, 3), xlAscending, Plage(1, 4), , xlAscending

    'crée les IDSection
    For I = 1 To Plage.Rows.Count

        If Plage(I, 3).Value & Plage(I, 4).Value <> Concat Then

            J = J + 1: Plage(I, 2).Value = J
            Concat = Plage(I, 3).Value & Plage(I, 4).Value

        Else

            Plage(I, 2).Value = J

        End If

    Next I

End Sub

Sub CreerXML(Chaine As String)

    Open ThisWorkbook.Path & "\TestXML.xml" For Output As #1

        Print #1, Chaine

    Close #1

End Sub

Function DefPlage(Fe As Worksheet, Optional L As Long = 1, Optional C As Long = 1) As Range

    On Error GoTo Fin

    With Fe

        Set DefPlage = .Range(.Cells(L, C), _
                       .Cells(.Cells.Find("*", .[A1], -4123, , _
                       1, 2).Row, .Cells.Find("*", .[A1], -4123, , _
                       2, 2).Column))

    End With

    Exit Function

Fin:

    Set DefPlage = Nothing

End Function

Bonjour Theze,

Je regarde ça à l'instant, étant en déplacement sur des chantiers ce we. C'est tout bonnement mieux que ce que j'attendais !

J'ai voulu faire en sorte que les utilisateurs puissent renommer le fichier en entrant le nom dans une cellule de la feuille 1. Pour ça j'ai rajouté une variable en colonne 8 (=la cellule de la feuille 1 en question) puis recopié :

[codeDebutXML = DebutXML & Space(4) & "<PrgProgram>]" & Tbl(I).Epaisseur & "</PrgProgram>" & vbCrLf[/code]

mais ça ne fonctionne pas. De la même façon, est-ce possible que ce titre soit le nom du fichier sauvé dans le répertoire identique à la feuille xls ?

Encore merci ! En échange, si besoin un jour de conseils dans le calcul / fabrication de structure bois (pas tous les jours que ça se présente !), n'hésite pas !

Bonjour,

Si je comprend bien, tu veux avoir la possibilité de donner un nom particulier au fichier qui soit et dans le XML :

DebutXML = DebutXML & Space(4) & "<PrgProgram>" & Replace(NomFichier, " ", "_") & "</PrgProgram>" & vbCrLf '<--- remplace les espaces par des tirets bas

et être le nom du fichier XML sur le disque du genre "21-01-2018 Test de fichier" dans ce cas, au lancement de la macro un InputBox va demander de donner un nom au fichier, si il comporte des espaces, ils seront remplacés par des tirets bas dans le XML comme ceci :

21-01-2018_Test_de_fichier et l'extension ".xml" sera rajoutée au nom du fichier de cette façon :

21-01-2018 Test de fichier.xml

Je reposte le classeur avec le code modifié !

Royal !

Voici l'interface que j'ai mis en forme pour la version finale.

Le petit TCD sur le côté permet d'avoir une synthèse par section des mètre linéaire nécessaire et pour combien de pièces. Une petite macro permet de le rafraîchir.

J'avais mis au point une petite règle de formatage conditionnelle mais en copie-collant les données depuis le tableau du logiciel dont les cellules sont déjà formatées par un style, ça a complètement désordonné mon tri. Tant pis donc pour ce formatage, les infos arriveront comme elles arriveront.

Néanmoins, peux-tu me donner ton avis sur le degré de protection à rajouter pour éviter les fausses manip ? Et d'expériences, des infos qui peuvent s'avérer utiles des travers dans l'interface ?

Merci (encore) !

Bonjour,

Si ton tableau doit rester comme ça, ma fonction "DefPlage()" ne doit pas être utilisée car, si on prend la feuille "Principale", la plage sera définie de A2 à Kx et donc, il y aura plantage au niveau de la machine car le fichier .xml qui va sortir sera n'importe quoi !

Il te faut remplacer la ligne de code suivante :

Set Plage = DefPlage(Worksheets("Feuil2"), 2, 1)

par celle-ci :

With Worksheets("Principale"): Set Plage = .Range(.Cells(6, 1), .Cells(.Rows.Count, 6).End(xlUp)): End With

et tu peux supprimer la fonction "DefPlage()". La plage est définie sur les colonnes de A à F sur la feuille "Principale" à partir de A6 à Fx pour ne pas prendre en compte ton TCD.

Concernant la "protection", le mieux serait de récupérer automatiquement par macro les valeurs depuis le fichier source donné par le BE sans qu'il y est intervention de quelqu'un hormis pour le contrôle des valeurs

Bonsoir Hervé,

Derniers petits bugs avant l'utilisation: Les ID section et EJ dont je conditionne l'affiche avec des SI pose problème à la macro. Je viens de m'en rendre compte juste avant d'envoyer la maquette au BE, alors que ça ne causait pas de problème il y a encore une fois lors d'un autre essai...

Je sais qu'il est tard, mais là je ne pige pas...

Ci-joint le fichier

Merci d'avance pour ton aide, bien à toi.

Baptiste.

Bonjour,

C'est la présence des formules dans la colonne J qui pose problème car la plage est définie jusqu'à J11 alors qu'il n'y a aucune valeur ailleurs. Il ne faut pas utiliser de formule dans la zone, faire ça par macro. Voici ton classeur avec les modifications !

Merci mille fois Hervé !

J'ai juste modifié la cellule de sélection pour l'attribution des EJ, qui se fait selon la longueur de la pièce et non la quantité (colonne 7). Ca a l'air de tourner ! Les gars à l'atelier sont refaits de ne plus avoir à recopier les valeurs une par une dans la machine... !

Sur certaines liste de prod, les longueurs apparaissent sous une forme décimale de type 123,111 pour la longueur. J'ai beau modifier le format de la cellule, il ne s'agit que d'un formatage visuel et la longueur apparaît toujours avec autant de décimales dans le xml, ce qui ne plait pas à la machine (qui affiche tout bonnement 0).

Je te joins le fichier type de liste de prod (à copier coller dans le convertisseur) et le convertisseur avec des données et les décimales qui apparaissent dans la dernière colonne.

A l'avenir, pour limiter les actions "humaines", le mieux de créer une macro de demande de sélectionner le fichier source ou un simple userform sous forme de tableau à copier / coller suffirait ? Merci pour ton avis.

Très bon après-midi,

Baptiste.

Rechercher des sujets similaires à "conversion xls xml"