我有一个dataobject数组对象[,]来自通过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
答案 0 :(得分:0)
虽然我仍然想知道为什么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
获得Web Star奖励 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;
}
}