Hello Everyone,
I need your help. As with the Subject written. I want to insert data into a UltraWinGrid (at the beginning was empty) at runtime.
Then save these data from the UltraWinGrid to a XML-File. How can I do this? Should I produce a DataTable in Database or could I directly save these data to XML without database?
Here is my solution.
It generates exact XML like DataSet.WriteXml() does, but includes only visible rows and columns.
Public Class BaseGrid Inherits UltraWinGrid.UltraGrid
Public Sub WriteXml(XmlPath As String) Dim tbl As DataTable Dim nameSpaceTag As String = ""
If TypeOf Me.DataSource Is DataTable Then tbl = CType(Me.DataSource, DataTable) ElseIf TypeOf Me.DataSource Is DataSet Then tbl = CType(Me.DataSource, DataSet).Tables(Me.DataMember) ElseIf TypeOf Me.DataSource Is BindingSource Then Dim bs As BindingSource = CType(Me.DataSource, BindingSource) tbl = CType(bs.DataSource, DataSet).Tables(bs.DataMember) End If
If tbl Is Nothing Then Message.Msg(My.Resources.nsGrid_NijeMoguceUtvrditiIzvorPodataka, MsgBoxStyle.OkOnly, MsgBoxType.Warning) Exit Sub End If nameSpaceTag = System.IO.Path.GetFileNameWithoutExtension(tbl.DataSet.Namespace.ToString())
If Me.ActiveRow Is Nothing Then Message.Msg(My.Resources.nsGrid_NitiJedanRedakNijeOznacen, MsgBoxStyle.OkOnly, MsgBoxType.Warning) Exit Sub End If
MainFormDomino.SaveStatus() MainFormDomino.ShowStatus(My.Resources.ShowStatus_FilterPreparing)
Dim j As Integer = 0 Dim totRows As Integer = Me.Rows.GetFilteredInNonGroupByRows.Length
MainFormDomino.ShowProgress(Decimal.Truncate((j + 1) / totRows * 100))
Dim ms As New System.IO.MemoryStream Dim Xml As New System.Xml.XmlTextWriter(ms, System.Text.Encoding.UTF8)
' Set writter formatting With Xml .Indentation = 1 .Formatting = Formatting.Indented .IndentChar = ControlChars.Tab End With
Xml.WriteStartDocument() Xml.WriteStartElement(nameSpaceTag)
' Write shema ' <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> Xml.WriteStartElement("xs:schema")
Xml.WriteStartAttribute("id") Xml.WriteValue(nameSpaceTag) Xml.WriteEndAttribute()
Xml.WriteStartAttribute("xmlns") Xml.WriteValue("") Xml.WriteEndAttribute()
Xml.WriteStartAttribute("xmlns:xs") Xml.WriteValue("http://www.w3.org/2001/XMLSchema") Xml.WriteEndAttribute()
Xml.WriteStartAttribute("xmlns:msdata") Xml.WriteValue("urn:schemas-microsoft-com:xml-msdata") Xml.WriteEndAttribute()
' <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> Xml.WriteStartElement("xs:element")
Xml.WriteStartAttribute("name") Xml.WriteValue(nameSpaceTag) Xml.WriteEndAttribute()
Xml.WriteStartAttribute("msdata:IsDataSet") Xml.WriteValue(True) Xml.WriteEndAttribute()
Xml.WriteStartAttribute("msdata:UseCurrentLocale") Xml.WriteValue(True) Xml.WriteEndAttribute()
' <xs:complexType> Xml.WriteStartElement("xs:complexType")
' <xs:choice minOccurs="0" maxOccurs="unbounded">
Xml.WriteStartElement("xs:choice")
Xml.WriteStartAttribute("minOccurs") Xml.WriteValue("0") Xml.WriteEndAttribute()
Xml.WriteStartAttribute("maxOccurs") Xml.WriteValue("unbounded") Xml.WriteEndAttribute()
' <xs:element name="Table">
Xml.WriteStartElement("xs:element")
Xml.WriteStartAttribute("name") Xml.WriteValue("Table") Xml.WriteEndAttribute()
' <xs:sequence> Xml.WriteStartElement("xs:sequence")
For Each dc As UltraGridColumn In Me.ActiveRow.Band.Columns
If Not dc.Hidden Then Dim col As DataColumn = tbl.Columns(dc.Key)
' <xs:element name="PRIORITET" type="xs:int" minOccurs="0" />
Xml.WriteStartAttribute("name") Xml.WriteValue(col.ColumnName) Xml.WriteEndAttribute()
Xml.WriteStartAttribute("type")
Select Case col.DataType Case GetType(String) Xml.WriteValue("xs:string") Case GetType(Integer) Xml.WriteValue("xs:int") Case GetType(Decimal) Xml.WriteValue("xs:string") Case GetType(Boolean) Xml.WriteValue("xs:string") Case GetType(DateTime) Xml.WriteValue("xs:dateTime")
' Unsupported data type (byte etc) Case Else Xml.WriteValue("xs:string") End Select Xml.WriteEndAttribute()
Xml.WriteStartAttribute("minOccurs") Xml.WriteValue("0") Xml.WriteEndAttribute() Xml.WriteEndElement() End If Next
' </xs:sequence> ' </xs:complexType> ' </xs:element> ' </xs:choice> ' </xs:complexType> ' </xs:element> '</xs:schema> Xml.WriteEndElement() Xml.WriteEndElement() Xml.WriteEndElement() Xml.WriteEndElement() Xml.WriteEndElement() Xml.WriteEndElement() Xml.WriteEndElement()
' Now Data
For Each dr As UltraGridRow In Me.Rows.GetFilteredInNonGroupByRows
Xml.WriteStartElement(tbl.TableName)
For Each dc As UltraGridColumn In Me.ActiveRow.Band.Columns If dc.Hidden = False Then Xml.WriteStartElement(dc.Key) Dim colType As Type = tbl.Columns(dc.Key).DataType
Select Case colType Case GetType(String) Xml.WriteValue(CStr(dr.Cells(dc.Index).Value)) Case GetType(Integer) Xml.WriteValue(CInt(dr.Cells(dc.Index).Value)) Case GetType(Decimal) Xml.WriteValue(CDec(dr.Cells(dc.Index).Value)) Case GetType(Boolean) Xml.WriteValue(CBool(dr.Cells(dc.Index).Value)) Case GetType(DateTime) Xml.WriteValue(CDate(dr.Cells(dc.Index).Value))
' Unsupported data type (byte etc) Case Else Xml.WriteValue("") End Select
Xml.WriteEndElement() End If Next Xml.WriteEndElement() Next
' End document Xml.WriteEndDocument()
Xml.Flush() ms.Flush()
Dim xmlBytes() As Byte = ms.ToArray() Dim xmlString As String = System.Text.Encoding.UTF8.GetString(xmlBytes)
Xml.Close() ms.Close() ms.Dispose() ms = Nothing Xml = Nothing
VFPToolkit.VFPToolkit.strings.StrToFile(xmlString, XmlPath)
MainFormDomino.ShowProgress(0) MainFormDomino.RestoreStatus()
End SubEnd Class
If your data source is a DataTable, then there is a much easier way:
dt1.WriteXml(fileName);
This, of course, would not include any unbound columns in the grid and it also would not account for any sorting or filtering of the grid data. So your method is better in that regard. :)