【问题标题】:insert data object array which contains Excel formula's into existing Excel sheet on a given range将包含 Excel 公式的数据对象数组插入给定范围内的现有 Excel 工作表中
【发布时间】:2017-12-26 03:02:38
【问题描述】:

我有一个数据对象数组 object[,] 来自通过 SqlDataAdapter 加载的 SQL 数据库表,它包含 Excel 公式。

我想将对象粘贴到已打开的 Excel 文件中的某个范围内。

我应该补充一点,当数据表包含诸如“这是一个测试”之类的字符串而不是诸如“=SUM(A1:A5)”之类的 Excel 公式时,一切正常

但我不断遇到对我来说毫无意义的异常。请指教!

这就是我所拥有的。我忽略了什么?

    private void InsertBridgeCalcBlock()
    {
        Excel.Application xlApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");

        try
        {
            xlActiveCell = xlApp.ActiveCell;
            DataTable dt = new DataTable();

            try
            {
                using (SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM " + sDBBridgeCalcTable, conn))
                {
                    da.Fill(dt);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error Message:" + Environment.NewLine + ex);
            }

            object[,] BridgeCalcTable = new object[dt.Rows.Count + 1,dt.Columns.Count];
            for (var i = 0; i < dt.Rows.Count; i++)
                for (var j = 1; j < dt.Columns.Count; j++)
                {
                    BridgeCalcTable[i, j-1] = dt.Rows[i][j];
                }

            Excel.Range insertBridgeCalcTableRange = xlApp.Range[xlApp.ActiveSheet.Cells[xlActiveCell.Row-2, 11], xlApp.ActiveSheet.Cells[xlActiveCell.Row-2 + dt.Rows.Count - 1, 11 + dt.Columns.Count]]; // set insertrange
            xlApp.ActiveSheet.EnableCalculation = true;
            insertBridgeCalcTableRange.Value = BridgeCalcTable; // fill range with data

        }
        catch (Exception ex)
        {
            MessageBox.Show("Error Message:" + Environment.NewLine + ex);
        }
    }

异常如下:

    System.Runtime.InteropServices.COMException (0x800A03EC): 
    Exception from HRESULT: 0x800A03EC at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWarpperTypes, MessageData& msgData)
    at Microsoft.Office.Interop.Excel.Rage.ser_Value(obejct value) at LookApp2016.Form1.InsertBridgeCalcBlock() in ~~myfilelocation~~ line 2886

【问题讨论】:

  • 您遇到了哪些例外情况?
  • 好问题,我已经在我的问题中编辑了它们。
  • 检查这是否对您有帮助 stackoverflow.com/questions/4408336/…
  • 谢谢。但我以前读过那个答案。我的 winform 是一个 clickonce 应用程序。我没有将任何内容保存到服务器。
  • 您在哪一行得到您的例外?

标签: c# excel winforms excel-interop


【解决方案1】:

虽然我还是想知道为什么Interop在数据表中使用Excel公式时会抛出异常,

我通过 Excel.Range.CopyFromRecordSet 输入找到了可能的答案。像这样:

        ADODB.Recordset BridgeCalcRecordset = ConvertToRecordset(dt);
        insertBridgeCalcTableRange.CopyFromRecordset(BridgeCalcRecordset);

但是,现在我的公式不会被自动识别为公式。我必须在计算开始之前编辑并退出每个单元格,公式变为结果...

我解决了这个问题:

     insertBridgeCalcTableRange.Formula = insertBridgeCalcTableRange.Value;

我的代码是相同的,但我使用此代码将我的 DataSet 转换为 ADODB RecordSet(他们说这样也更快): 归功于http://www.nullskull.com/q/10057748/hi-all.aspx的网络之星

    static public ADODB.Recordset ConvertToRecordset(DataTable inTable)
    {
        ADODB.Recordset result = new ADODB.Recordset();
        result.CursorLocation = ADODB.CursorLocationEnum.adUseClient;

        ADODB.Fields resultFields = result.Fields;
        System.Data.DataColumnCollection inColumns = inTable.Columns;

        foreach (DataColumn inColumn in inColumns)
        {
            resultFields.Append(inColumn.ColumnName
                , TranslateType(inColumn.DataType)
                , inColumn.MaxLength
                , inColumn.AllowDBNull ? ADODB.FieldAttributeEnum.adFldIsNullable :
                                         ADODB.FieldAttributeEnum.adFldUnspecified
                , null);
        }

        result.Open(System.Reflection.Missing.Value
                , System.Reflection.Missing.Value
                , ADODB.CursorTypeEnum.adOpenStatic
                , ADODB.LockTypeEnum.adLockOptimistic, 0);

        foreach (DataRow dr in inTable.Rows)
        {
            result.AddNew(System.Reflection.Missing.Value,
                          System.Reflection.Missing.Value);

            for (int columnIndex = 0; columnIndex < inColumns.Count; columnIndex++)
            {
                resultFields[columnIndex].Value = dr[columnIndex];
            }
        }

        return result;
    }

    static ADODB.DataTypeEnum TranslateType(Type columnType)
    {
        switch (columnType.UnderlyingSystemType.ToString())
        {
            case "System.Boolean":
                return ADODB.DataTypeEnum.adBoolean;

            case "System.Byte":
                return ADODB.DataTypeEnum.adUnsignedTinyInt;

            case "System.Char":
                return ADODB.DataTypeEnum.adChar;

            case "System.DateTime":
                return ADODB.DataTypeEnum.adDate;

            case "System.Decimal":
                return ADODB.DataTypeEnum.adCurrency;

            case "System.Double":
                return ADODB.DataTypeEnum.adDouble;

            case "System.Int16":
                return ADODB.DataTypeEnum.adSmallInt;

            case "System.Int32":
                return ADODB.DataTypeEnum.adInteger;

            case "System.Int64":
                return ADODB.DataTypeEnum.adBigInt;

            case "System.SByte":
                return ADODB.DataTypeEnum.adTinyInt;

            case "System.Single":
                return ADODB.DataTypeEnum.adSingle;

            case "System.UInt16":
                return ADODB.DataTypeEnum.adUnsignedSmallInt;

            case "System.UInt32":
                return ADODB.DataTypeEnum.adUnsignedInt;

            case "System.UInt64":
                return ADODB.DataTypeEnum.adUnsignedBigInt;

            case "System.String":
            default:
                return ADODB.DataTypeEnum.adVarChar;
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 1970-01-01
    相关资源
    最近更新 更多