Källkoden för /anders.enges/xml/xml36.asp

<!--#include file="../inc/navstuff.asp" -->
<p>När vi har formen klar skriver vi in lite kod:</p>
<ol>
   <li>Preparationer<br>
     <br>
     Sätt in följande i <b>General Declarations</b> för formen:<br>
     <div class="code">Option Explicit<br>
       <br>
       Dim C_PROVIDER As String<br>
       Dim C_CONNECTION As String<br>
       Dim C_XML As String<br>
       Dim C_SQL As String<br>
       <br>
       <p>' Globalt Recordset objekt<br>
         Dim rs As ADODB.Recordset<br>
       </p>
     </div>
     <br />
   </li>
   <li>Sätt in följade <b>Form_Load</b> handelseprocedur<br>
     <div class="code">Private Sub Form_Load()<br>
         ' modifiera dessa vid behov<br>
          C_PROVIDER = "Microsoft.Jet.OLEDB.4.0"<br>
          C_CONNECTION = "Data Source=" & App.Path & "\xml.mdb"<br>
          C_XML = App.Path & "\xml.xml"<br>
          C_SQL = "SELECT * FROM DATA"<br>
       <br>
          ' Skapa recordset objektet<br>
          Set rs = New ADODB.Recordset<br>
       <br>
          ' Lite inställningar för knappar mm.<br>
          cmd_SaveXML.Enabled = False<br>
          txt_Texten.Locked = True<br>
          txt_Siffran.Locked = True<br>
          cmd_Navigera(5).Enabled = False<br>
          txt_Texten = ""<br>
          txt_Siffran = ""<br>
       End Sub </div>
     <br />
   </li>
   <li>Sedan skapar vi koden som öppnar databasen och sparar den som xml<br>
     <div class="code">Private Sub cmd_OpenMDB_Click()<br>
          ' Skapa och öppna en Connection till databasen<br>
          Dim conn As ADODB.Connection<br>
          Set conn = New ADODB.Connection<br>
          conn.Provider = C_PROVIDER<br>
          conn.ConnectionString = C_CONNECTION<br>
          conn.Open<br>
       <br>
          ' om recordsetten är öppen så stänger
       vi den<br>
          If rs.State <> adStateClosed Then<br>
             rs.Close<br>
          End If<br>
          <br>
          ' OBS! använd helst klient kursor<br>
          rs.CursorLocation = adUseClient<br>
          rs.CursorType = adOpenKeyset<br>
          rs.ActiveConnection = conn<br>
          rs.LockType = adLockOptimistic<br>
       <br>
          ' öppna recordset med SQL<br>
          rs.Source = C_SQL<br>
          rs.Open<br>
       <br>
          ' Tag bort eventuella tidigare xml-filer<br>
          If Dir(C_XML) <> "" Then<br>
             Kill C_XML<br>
          End If<br>
       <br>
          ' spara som xml<br>
          rs.Save C_XML, adPersistXML<br>
          <br>
          ' stäng allt <br>
          rs.Close<br>
          conn.Close<br>
          Set conn = Nothing<br>
       End Sub <br>
     </div>
     <br>
   </li>
   <li>Starta programmet och klicka på knappen "exportera xml".
     Om allt gått vägen borde du ny ha fått en xml fil sominnehåller
     allt data från databasen. Tag en titt på den...<br>
     <br>
   </li>
   <li>Som nästa så skapar vi koden som öppnar databasen från
     xml filen:<br>
     <div class="code">Private Sub cmd_UseXML_Click()<br>
          Dim I As Integer<br>
          Dim fName As String<br>
       <br>
          ' Om recordset är öppen så stänger
       vi den<br>
          If rs.State <> adStateClosed Then<br>
             rs.Close<br>
          End If<br>
       <br>
          ' måste ha klientkursor<br>
          rs.CursorLocation = adUseClient<br>
          rs.Open C_XML, _<br>
                "Provider=MSpersist;",
       _<br>
                adOpenKeyset, _<br>
                adLockBatchOptimistic,
       _<br>
                adCmdFile<br>
       <br>
          ' Övervaka ändringarna så att ändringar<br>
          ' skrivs till xmlfilen på sådant sätt<br>
          ' att vi ser alla ändringar<br>
          rs.MarshalOptions = adMarshalModifiedOnly<br>
       <br>
       <br>
          ' Nedanstående är ett trick som automatiskt
       ser<br>
          ' till att textboxar kopplas till databasfälten<br>
          ' Gå igenom fälten<br>
          ' Om det finns en kontroll som heter<br>
          ' txt_<Fältets namn> t.ex. txt_Siffran<br>
          ' så kopplar vi detnna textbox till<br>
          ' fältet<br>
          ' vill vi inte loopa kan vi sätta följande rader<br>
          ' för varje fält<br>
          ' Set <i>textboxen</i>.DataSource = <i>recordset</i><br>
          ' <i>textboxen</i>.DataField = "<i>namn på fältet</i>"<br>
          ' ta för guds skull inte och kör med<br>
          ' rs!Fält = Text1.text varianten som ni<br>
          ' kanske använde i VB 5.0<br>
<br>
          On Error Resume Next<br>
          For I = 0 To rs.Fields.Count - 1<br>
             fName = "txt_" & rs.Fields(I).Name<br>
             If fName = Controls(fName).Name Then<br>
                Set Controls(fName).DataSource
       = rs<br>
                Controls(fName).DataField
       = rs.Fields(I).Name<br>
             End If<br>
          Next<br>
          On Error GoTo 0<br>
          cmd_SaveXML.Enabled = True<br>
          Label1.Caption = rs.AbsolutePosition & _<br>
                      "/"
       & rs.RecordCount<br>
       End Sub</div>
     <br>
     <br>
   </li>
   <li>Vi skapar sedan en (enkel) navigering med hjälp av <b>cmd_Navigera</b>
     knapparna<br>
     <div class="code">Private Sub cmd_Navigera_Click(Index As Integer)<br>
          Dim I As Integer<br>
          Select Case Index<br>
             Case 0 ' Första<br>
                rs.MoveFirst<br>
       <br>
             Case 1 ' Föregående<br>
                rs.MovePrevious<br>
                If rs.BOF Then<br>
                   Beep<br>
                   rs.MoveFirst<br>
                End If<br>
       <br>
             Case 2 ' Nästa<br>
                rs.MoveNext<br>
                If rs.EOF Then<br>
                   Beep<br>
                   rs.MoveLast<br>
                End If<br>
       <br>
             Case 3 ' Sista<br>
                rs.MoveLast<br>
       <br>
             Case 4 ' Ändra<br>
                For I = 0 To 3<br>
                   cmd_Navigera(I).Enabled
       = False<br>
                Next<br>
                cmd_Navigera(5).Enabled
       = True<br>
                txt_Texten.Locked
       = False<br>
                txt_Siffran.Locked
       = False<br>
       <br>
             Case 5 ' Spara<br>
                If rs.Status = adRecModified
       Then<br>
                   rs.Update<br>
                End If<br>
                For I = 0 To 3<br>
                   cmd_Navigera(I).Enabled
       = True<br>
                Next<br>
                txt_Texten.Locked
       = True<br>
                txt_Siffran.Locked
       = True<br>
                cmd_Navigera(5).Enabled
       = False<br>
       <br>
             Case 6 ' Radera<br>
                rs.Delete<br>
                rs.MovePrevious<br>
                If rs.BOF Then<br>
                   rs.MoveFirst<br>
                End If<br>
       <br>
             Case 7 ' Ny<br>
                rs.AddNew<br>
                For I = 0 To 3<br>
                   cmd_Navigera(I).Enabled
       = False<br>
                Next<br>
                cmd_Navigera(5).Enabled
       = True<br>
                txt_Texten.Locked
       = False<br>
                txt_Siffran.Locked
       = False<br>
          End Select<br>
          Label1.Caption = rs.AbsolutePosition & _ <br>
                   "/"
       & rs.RecordCount<br>
       End Sub </div>
     <br>
   </li>
   <li>Innan vi kan proköra måste vi även se till att datat sparas
     (det görs inte automatiskt)<br>
     <div class="code">Private Sub cmd_SaveXML_Click()<br>
          If Dir(C_XML) <> "" Then<br>
             Kill C_XML<br>
          End If<br>
          ' Finns en bug i ADO 2.5 som gör att<br>
          ' första posten ibland inte sparas<br>
          ' om man har kontroller kopplade till fälten<br>
          ' en klon funkar bättre<br>
          rs.Clone.Save C_XML, adPersistXML<br>
       End Sub</div>
     <br>
   </li>
   <li>Prova genom att öppna xmlfilen med knappen "öppna xml".
     Gör sedan några ändringar. Se till att ändra, lägga
     till och radera. Spara xml data. Öppna sedan XML filen i ett annat program
     och se på datat. Observera att det inte lagras statiskt resultat, utan
     i xml filen framgår vilka ändringar som gjorts. Detta betyder att
     vi kan ta dessa ändringar och sätta dessa tillbaka till databasen.<br>
     <br>
     Detta kan göras med följande kod:<br>
     <div class="code">Private Sub cmd_UpdateMDB_Click()<br>
        Dim conn As ADODB.Connection<br>
        Set conn = New ADODB.Connection<br>
     <br>
        Dim tmpConn As ADODB.Connection<br>
     <br>
        conn.Provider = C_PROVIDER<br>
        conn.ConnectionString = C_CONNECTION<br>
        conn.Open<br>
     <br>
        If rs.State = adStateClosed Then<br>
           rs.CursorLocation = adUseClient<br>
           rs.Open C_XML, _<br>
                 "Provider=MSpersist;", _<br>
                 adOpenKeyset, _<br>
                 adLockBatchOptimistic, _<br>
                 adCmdFile<br>
        End If<br><br>
        ' spara recordsettens nuvarande connection<br>
        Set tmpConn = rs.ActiveConnection<br>
       <br>
          ' Koppla rs till databasen connection<br>
          rs.ActiveConnection = conn<br>
      <br>
          ' Töm eventuella fel<br>
          conn.Errors.Clear<br><br>
          ' uppdatera allt<br>
        rs.UpdateBatch<br>
      <br>
          ' om ingenting gått fel så   <br>
          ' "nollställer" vi xml filen <br>
         ' tag en titt på xml filen efteråt<br>
         If conn.Errors.Count
       = 0 Then<br>
           rs.ActiveConnection = tmpConn<br>
           rs.UpdateBatch<br>
        End If<br>
         ' spara <br />
        If Dir(C_XML) <> "" Then<br>
           Kill C_XML<br>
        End If<br>
      <br >
     
        ' spara xml<br>
         rs.Clone.Save C_XML, adPersistXML<br>
     <br>
        rs.Close<br>
        conn.Close<br>
        tmpConn.Close<br>
        Set conn = Nothing<br>
        Set tmpConn = Nothing<br>
     End Sub</div><br>
     <br>
   </li>
</ol>
<!--#include file="../inc/footer.asp" -->