Share via


Adatok másolása InfoPath-adatforrások között

FRISSÍTÉS: Bizonyos körülmények között baj van az AppendChild() függvénnyel. Készítettem egy megkerülő megoldást, amely az InsertAfter() függvényt használja, és némiképpen lerövidítettem a kódot. Mostantól ez olvasható a cikkben.


Érdekes kérdést kaptam az egyik ügyfelünktől. Egy InfoPath-űrlap egy webszolgáltatást hív, és ismétlődő adatokat kap vissza. Szeretné további mezőkkel kiegészíteni a sémát, majd űrlaptárba menteni a kitöltött űrlapot. Egyszerűnek hangzik, de nem az.

A feladat

Tegyük fel, hogy a külső adatforrás egy projektlista, amely minden projekthez megadja annak megnevezését és a felelős nevét. Ha másodlagos adatforrásként hozzáadjuk az InfoPath-űrlapsablonhoz, kb. a következőt kapjuk:

clip_image001

A kis lakatok azt jelzik, hogy sem az adatforrás szerkezetét, sem az egyes mezők tulajdonságait nem változtathatjuk meg. Pedig nekünk valami olyasmi kellene, mint a következő ábrán:

clip_image001[4]

Az ismétlődő ProjectReport rekordok valójában a külső adatforrás Project rekordjaira épülnek, de tartalmaznak egy plusz mezőt (ProjectStatus) és egy teljes ismétlődő csomópontot (Task) is annak extra mezőivel egyetemben. Mivel a másodlagos adatforrást nem tudjuk módosítani, az a megoldás, hogy adatait beolvassuk, majd átmásoljuk az elsődleges adatforrás megfelelő mezőibe.

Ezt a feladatot már nem tudjuk az InfoPath negyedik generációs eszközeivel (pl. szabályok) elvégezni, programoznunk is kell. Ebben segít, hogy a 2007-es InfoPath a VBScript/JScript mellett tartalmazza a Visual Studio Tools for Applications (VSTA) környezetet, ami a Visual Basic for Applications (VBA) utódja, és teljes körű programozási lehetőséget biztosít Visual Basic .NET és C# nyelveken egyaránt.

A VSTA a .NET Framework 2.0-ra és a Core XML Services 6.0-ra épül, és helyből ki van kapcsolva az Office-telepítőben, ezeket tehát célszerű előre ellenőrizni.

A megoldás
  1. Hozzuk létre a fent látható első (sárga hátterű) szerkezettel rendelkező külső adatforrást. A webszolgáltatás helyett az egyszerűség kedvéért használhatunk egy XML adatfájlt is, kb. a következő tartalommal:

    <?xml version="1.0" encoding="utf-8" ?>
    <Projects>
    <Project>
    <ProjectName>P001</ProjectName>
    <ProjectOwner>Kőnig Tibor</ProjectOwner>
    </Project>
    <Project>
    <ProjectName>P002</ProjectName>
    <ProjectOwner>Kőnig Tibor</ProjectOwner>
    </Project>
    <Project>
    <ProjectName>P003</ProjectName>
    <ProjectOwner>Csermák Zsolt</ProjectOwner>
    </Project>
    </Projects>

  2. Nyissunk meg egy új InfoPath-űrlapsablont, és hozzuk benne létre a fent látható második (fehér hátterű) adatszerkezetet.

  3. Adjuk a sablonhoz az XML fájlt mint másodlagos adatkapcsolatot. (Legyünk negatívak: ne erőforrásfájlként vegyük fel, ne engedélyezzük a kapcsolat nélküli használatot, és ne kérjük a beolvasását az űrlap megnyitásakor.)

  4. Alakítsuk ki az űrlap felhasználói felületét. Itt látható egy lehetőség a megvalósításra (ismétlődő szekciókkal és elrendezéstáblázatokkal):clip_image001[10]

  5. Mentsük el az űrlapsablont a biztonság kedvéért, pl. ProjectReport.xsn néven.

  6. Nyissuk meg a Betöltés gomb tulajdonságait, majd kattintsunk az Űrlapkód módosítása... gombra. Ha a VSTA telepítve van a gépünkön, megjelenik a Visual Studionál már megszokott fejlesztőkörnyezet, benne egy InfoPath-kódprojekt az InfoPathban beállított nyelven (VB vagy C#; nálam VB). A kurzor a Betöltés gomb (én btnLoad-nak neveztem el) eseménykezelőjében villog, ami kb. így néz ki:

    Public Sub btnLoad_Clicked(ByVal sender As Object, _
    ByVal e As ClickedEventArgs)
    ' Ide írhatja a kódot.
    End Sub

  7. Ezt az eseménykezelőt fogjuk most elkészíteni. A fő és a másodlagos adatforrás XML adatain dolgozunk majd, az XPath technológia használatával. Először olvassuk be a (nálam Projects névre keresztelt) forrásadatokat a következő kóddal:

    ' A forrásadatok beolvasása
    Me.DataConnections("Projects").Execute()

  8. Tegyük elérhetővé a projektek listáját:

    ' Az adatforrás és a projektek gyűjteményének megcímzése
    Dim projectRoot As XPathNavigator = Me.DataSources _
    ("Projects").CreateNavigator()
    Dim projectList As XPathNodeIterator = _
    projectRoot.Select("//Project", NamespaceManager)

  9. Egy kis értelmezés: az XPathNavigator (amit itt a CreateNavigator állít elő) az űrlap adatszerkezetének egy csomópontját (Node), míg az XPathNodeIterator csomópontok egész gyűjteményét címezi meg, a NamespaceManager objektum pedig nyilvántartja a különböző adatkapcsolatokban használt névtereket.

  10. Játsszuk el ezt a projektjelentések listájával is:

    ' Az űrlapadatok megcímzése
    Dim reportRoot As XPathNavigator = _
    Me.MainDataSource.CreateNavigator()

  11. Az űrlapsablonban helyből van egy (üres) ProjectReport csomópont vagy rekord. Ezt sokszorosítjuk, hogy pont annyi legyen belőle, mint amennyi Project csomópont van a projektek listájában:

    ' A szükséges számú üres jelentés létrehozása
    Dim firstReport As XPathNavigator = _
    reportRoot.SelectSingleNode _
    ("//my:ProjectReport[1]", NamespaceManager)
    Dim projectIndex As Integer
    For projectIndex = 2 To projectList.Count
    Dim clonedReport As XmlReader = _
    firstReport.ReadSubtree
    clonedReport.ReadInnerXml()
    firstReport.InsertAfter(clonedReport)
    Next

  12. Most pedig ciklusban átmásoljuk a projektlistából a projektjelentés-listába a projektek megnevezését és felelősét:

    ' A projektek és felelősök nevének átmásolása
    For projectIndex = 1 To projectList.Count
    reportRoot.SelectSingleNode _
    ("//my:ProjectReport[" & projectIndex.ToString _
    & "]/my:ProjectName", _
    NamespaceManager).SetValue _
    (projectRoot.SelectSingleNode _
    ("//Project[" & projectIndex.ToString & _
    "]/ProjectName", NamespaceManager).Value)
    reportRoot.SelectSingleNode _
    ("//my:ProjectReport[" & projectIndex.ToString _
    & "]/my:ProjectOwner", _
    NamespaceManager).SetValue _
    (projectRoot.SelectSingleNode _
    ("//Project[" & projectIndex.ToString & _
    "]/ProjectOwner", NamespaceManager).Value)
    Next

Kész az űrlapsablon, tegyük közzé, és kezdjük el használni! A forrásadatok és a kézzel bevitt új adatok egy új, közös sémában egyesülnek.