sqlms-wordvstocomobjecticonvertible

VSTO: Store __ComObject (Microsoft.Office.Interop.Word.Table) in Database


I would like to store a Microsoft.Office.Interop.Word.Table object in a T-SQL Database. And get the object again from the database to paste in a word document. Its mandatory that all the information, like tag, index, format keep consistent.

On the database side I created a [Object] (varbinary(max)) byte[] field.

Directly assigning the word object to the paramized query results in an serialization error. I tells me that I need to explicit create a conversion function (iConvertible):

System.InvalidCastException
  HResult=0x80004002
  Nachricht = Parameterwert konnte nicht von LoomTable in Byte[] umgewandelt werden.
  Quelle = offer
  Stapelüberwachung:
   bei offer.Classes.TextBlock.WriteTextBlockToDB() in C:\Temp\code\text\Classes\TextBlock.cs: Zeile215
   bei offer.ManageBlockTexts.ButtonLeft_Click(Object sender, EventArgs e) in C:\Temp\code\text\InsertNewText.cs: Zeile691

Innere Ausnahme 1:
InvalidCastException: Ein Objekt muss IConvertible implementieren.

Code:

SqlConnection cn = new SqlConnection(cn_string);
            string sql_Text = @"INSERT INTO LOOM.Text(Description, TextLong, TextBlock, Language, Approved, Object) VALUES(@DES, @TEL, @TEB, @LAN, @APP, @OBJ);
                            SELECT SCOPE_IDENTITY()";
...
using (SqlCommand sqlCommand = new SqlCommand(sql_Text, cn))
{
...
    sqlCommand.Parameters.Add("@OBJ", SqlDbType.VarBinary, Int32.MaxValue);
    sqlCommand.Parameters["@OBJ"].Value = this.loomTable;

    cn.Open();
    object returnObj = sqlCommand.ExecuteScalar();
...
}

using Microsoft.Office.Interop.Word;

namespace offer.Classes
{
    class LoomTable
    {
...
        private Table table;
...
    }
}

I already wraped the word object in my own LoomTable Class to build some kind of ToString converter. But this seems to be alot of hustle and is prone to errors when the user inserts pictures diagrams, oleobjects in the table.

Any suggestions? Help would be highly appreciated!


Solution

  • Word objects aren't independent of the document in which they reside; they aren't "serializable", nor do they consist of just text.

    As far as I know, there are two possible approaches:

    1. Remove all other information from the document. Save that version of the document to disk (temporarily). Import the document into the database (at which point you should be able to remove the temporary file). To re-use the content, save the document as a file and insert the file into the target document OR open the file in Word and transfer the content.

    2. Retrieve the table range's WordOpenXML property, which is plain text - the Office Open XML that describes the table in the context of a document in the OPC flat-file format - and store that. It can later be retrieved (written into another document) using the Range.InsertXML method.

    Note, however, in both cases (or any other approach you may find) that an exact copy of how the information appeared in the original document is not guaranteed. This is due to how Word handles formatting (styles) and page layout. The content will adapt to the style definitions in the target document and the layout to the margin settings.