Hi All,
I'm developing an Excel add-in (using C#) which will call a web service to get a "data record" from the company's SQL Server 2014 database and write that data out onto a set of worksheets. "Data record" is deliberately in quotes as you will see in a moment. There is a bunch of ancillary information in the record (the usual date/time stamp, person who last edited the record, etc.). However, the core of the data is held in an XML database field. The XML breaks out into two child sections under the root: a "ProcessingDefaults" child section and a "DTDataMembers" child section. The child sections are basically just tables of data. I will put each child section on its own worksheet.
And yes, the backend developer did include an "XML Schema" as part of the "data record"; again held in an XML database field type.
The 'core' data shows up on my end of the web service as simply a 'string' type. The 'schema' is held in a custom data type (class) that is essentially a collection, the members of which basically define the characteristics of individual columns.
Now, I could traverse the XML and write data into individual cells on the sheets. Ugly, but possible as a last resort.
What I'm looking for is a more elegant solution that leverages the XML facilities available in .NET and Excel.
I looked at the documentation for XMLMapping and thought that ImportXML might work, but when I tried to invoke it in my code:
Microsoft.Office.Interop.Excel.XmlMap myMap = new Microsoft.Office.Interop.Excel.XmlMap();
response = myMap.ImportXML(XMLData)
I get an "Cannot create an instance of the abstract class or interface" error when defining 'myMap'. (And yes, I have a Reference to 'Microsoft.Office.Interop.Excel'. And yes, I have 'using Excel = Microsoft.Office.Interop.Excel; '. And yes, I should also be able to write the code as 'Excel.XmlMap'.) Going back and reading the MSDN documentation, I get the impression that XmlMap might be deprecated with v2013, but hey, what do I know?
A hack would be to write the XML to a temporary file and import it. When I broached this idea to my boss, he had a decidedly negative response (something along the lines of "Let's do this right."; can't say I disagree with him.)
So, in lieu of tearing my hair out, I'm turning to you guys (guys being used in a unisex manner). Anybody have any suggestions? Linq? Something else?
Here's some additional info:
The web service was originally targeted for a Silverlight control. The idea for the add-in is to expand the options available to the user (not to mention that Silverlight is deprecated).
In theory, the database and web service could be modified. In practice: no. (And it really is a "No".)
Excel versions 2007 and later are the targets. As a result, 4.0 is the target .Net version.
This is my first add-in.
I have the most basic understanding of XML. After that, it's all a learning experience (which I'm willing -- just wanted to let you know that I have enough knowledge to be dangerous to myself).
I have included samples of the schema and the data XML. These samples are based on the "real" versions. However, in mocking them up, I might have made a minor error (or two ...); please view them as 'mostly' correct.
As always, your help is greatly appreciated.
Richard
<DTProcessingSchema>
<ColumnDefinitions>
<ColumnDefinition>
<ColumnName>Source</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>0</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>SourceDC</ColumnName>
<TypeName>AProcessingStyle</TypeName>
<RelativeRank>1</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>Destination</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>2</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>DestinationDC</ColumnName>
<TypeName>AProcessingStyle</TypeName>
<RelativeRank>3</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>UCode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>4</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>AlternateCode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>5</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>DCode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>6</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>OCode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>7</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>PCode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>8</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>Name</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>9</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>ACode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>10</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>FACode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>11</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>OACode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>12</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>VCode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>13</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>BCode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>14</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>LR</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>15</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>LD</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>16</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>Comment</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>17</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>RCode</ColumnName>
<TypeName>System.String</TypeName>
<RelativeRank>18</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>X1</ColumnName>
<TypeName>System.Decimal</TypeName>
<RelativeRank>19</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>X2</ColumnName>
<TypeName>System.Decimal</TypeName>
<RelativeRank>20</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>X3</ColumnName>
<TypeName>System.Decimal</TypeName>
<RelativeRank>21</RelativeRank>
</ColumnDefinition>
<ColumnDefinition>
<ColumnName>X4</ColumnName>
<TypeName>System.Boolean</TypeName>
<RelativeRank>22</RelativeRank>
</ColumnDefinition>
</ColumnDefinitions>
</DTProcessingSchema>
<DTProcessing>
<ProcessingDefaults>
<ProcessingDefault>
<Code>1234-AB-CD-56-EFG-78</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Sample</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>102</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Sample</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>103</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Sample</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>104</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Sample</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>105</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Sample</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>201</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Review</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>202</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Review</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>203</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Review</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>204</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Review</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>205</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>Review</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>301</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>None</CodeType>
</ProcessingDefault>
<ProcessingDefault>
<Code>302</Code>
<ProcessingStyle>Normal</ProcessingStyle>
<CodeType>None</CodeType>
</ProcessingDefault>
</ProcessingDefaults>
<DTDataMembers>
<DTData>
<Source>1234-AB-CD-56-EFG-78</Source>
<SourceDC>Normal</SourceDC>
<Destination>123456</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode>Z1234</UCode>
<AlternateCode>XVYT</AlternateCode>
<DCode>5678</DCode>
<OCode>99990</OCode>
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode>01</VCode>
<BCode>A</BCode>
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>102</Source>
<SourceDC>Normal</SourceDC>
<Destination>102</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>103</Source>
<SourceDC>Normal</SourceDC>
<Destination>103</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>104</Source>
<SourceDC>Normal</SourceDC>
<Destination>104</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>105</Source>
<SourceDC>Normal</SourceDC>
<Destination>105</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>201</Source>
<SourceDC>Normal</SourceDC>
<Destination>201</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>202</Source>
<SourceDC>Normal</SourceDC>
<Destination>202</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>203</Source>
<SourceDC>Normal</SourceDC>
<Destination>203</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>204</Source>
<SourceDC>Normal</SourceDC>
<Destination>204</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>205</Source>
<SourceDC>Normal</SourceDC>
<Destination>205</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>301</Source>
<SourceDC>Normal</SourceDC>
<Destination>301</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
<DTData>
<Source>302</Source>
<SourceDC>Normal</SourceDC>
<Destination>302</Destination>
<DestinationDC>Normal</DestinationDC>
<X1>0</X1>
<X2>0</X2>
<X3>0</X3>
<X4>true</X4>
<UCode />
<AlternateCode />
<DCode />
<OCode />
<PCode />
<Name />
<ACode />
<FACode />
<OACode />
<VCode />
<BCode />
<LR />
<LD />
<Comment />
<RCode />
</DTData>
</DTDataMembers>
</DTProcessing>