简体   繁体   English

在范围Excel C#中编写对象的2D数组

[英]Write a 2D array of objects in range Excel C#

I created a new user defined function in excel using c#, excelDna Add-In,what i want to get is when a user open an excel file, clic on a cell and write =myFunction() press enter, data should be displayed in the excel file. 我使用c#,excelDna加载项在excel中创建了一个新的用户定义函数,我要获得的是用户打开excel文件,在单元格上按clic并写入= myFunction()并按Enter,数据应显示在Excel文件。 these data are retrieved from sql server database and stocked in a 2D array of object, my problem is when i try to display this array in excel range i got this exception Exception de HRESULT : 0x800A03EC Below is my code : 这些数据是从sql server数据库中检索的,并存储在对象的2D数组中,我的问题是,当我尝试在excel范围中显示此数组时,出现了此异常Exception de HRESULT:0x800A03EC下面是我的代码:

public static void LoadViewData()
  {
      var target = (ExcelReference)XlCall.Excel(XlCall.xlfCaller);
      var sheetName = (string)XlCall.Excel(XlCall.xlSheetNm, target);
      var application = (Microsoft.Office.Interop.Excel.Application)ExcelDnaUtil.Application;
      var sheet = application.Sheets[Regex.Replace(sheetName, @"\[[^]]*\]", string.Empty)];
      object[,] result = LoadFromDbData();
      var startCell =sheet.Cells[target.RowFirst + 1, target.ColumnFirst];
      var endCell =sheet.Cells[target.RowFirst+ result.GetUpperBound(0) - result.GetLowerBound(0) + 1,
          target.ColumnFirst+ result.GetUpperBound(1) - result.GetLowerBound(1) + 1];
      var writeRange = sheet.Range[startCell, endCell];

      writeRange.Value2 = result;

  }

target returns the correct value of the cell where the user has written the formula (=myFunction()) sheetName returns the correct activeSheet in which the user writes the formula result contains the data retrieved from sql server, it is an array of object[854,8] startcell and endcell represents the range from which cell to which cell data will be displayed when debugging, all variables contain the correct values, the exception appears in this instruction : target返回用户已在其中写入公式的单元格的正确值(= myFunction())sheetName返回正确的activeSheet,用户在其中写入公式结果的结果包含从sql server检索到的数据,它是对象数组[854] ,8] startcell和endcell表示调试时从其显示单元格数据的范围,所有变量均包含正确的值,此指令中出现例外:

writeRange.Value2 = result;

Anyone has already worked with this or can help please ? 任何人都已经为此工作或可以帮助吗? Thanks 谢谢

I think your "LoadFromDbData()" is returning the data as typed. 我认为您的“ LoadFromDbData()”正在返回键入的数据。 Try converting each value to a string. 尝试将每个值转换为字符串。 Here is a sample (and I can recreate that error code if I do not convert to string): 这是一个示例(如果不转换为字符串,我可以重新创建该错误代码):

void Main()
{
  var tbl = new System.Data.DataTable();
  new SqlDataAdapter(@"
  WITH  tally ( OrderNo, UniqueId, RandNumber )
        AS (
             SELECT TOP 50000
                    ROW_NUMBER() OVER ( ORDER BY t1.object_id ), 
                    NEWID(),
                    CAST(CAST(CAST(NEWID() AS VARBINARY(4)) AS INT) AS DECIMAL) / 1000
             FROM   master.sys.all_columns t1
             CROSS JOIN master.sys.all_columns t2
           )
  SELECT  OrderNo, 
    DATEADD(DAY, -OrderNo, GETDATE()) as OrnekDate, 
    UniqueId, RandNumber, 
    abs(RandNumber)%100 / 100 as pct
  FROM [tally];", @"server=.\SQLExpress;Database=master;Trusted_Connection=yes;").Fill(tbl);

  object[,] arr = new object[tbl.Rows.Count + 1, tbl.Columns.Count];
  for (int i = 0; i < tbl.Columns.Count; i++)
  {
    arr[0, i] = tbl.Columns[i].Caption;
  }
  for (int i = 0; i < tbl.Rows.Count; i++)
  {
    for (int j = 0; j < tbl.Columns.Count; j++)
    {
      arr[i + 1, j] = tbl.Rows[i][j].ToString(); // without .ToString() you should have the error
    }
  }

  // Excel dosya yarat ve arrayi koy
  Microsoft.Office.Interop.Excel.Application xl = new Microsoft.Office.Interop.Excel.Application();
  var workbook = xl.Workbooks.Add();
  xl.Visible = true;

 Worksheet sht = ((Worksheet)workbook.ActiveSheet);
 Range target = (Range)sht.Range[ (Range)sht.Cells[1,1], (Range)sht.Cells[arr.GetUpperBound(0)+1,arr.GetUpperBound(1)+1] ];
 target.Value2 = arr;

}

Note: As a side note, why would you transfer the data as a 2D array? 注意:作为旁注,为什么要将数据作为2D数组传输? That is one of the ways, but beware it is limited (I don't know a good value for the upper limit - try a high number like 200K rows). 这是方法之一,但是请注意,它是有限的(我不知道上限的合适值-尝试使用200K行这样的高数字)。 Getting data into excel is best done via QueryTables.Add or CopyFromRecordSet to my experience. 最好通过QueryTables.Add或CopyFromRecordSet将数据导入excel。 Depending on your needs you might also directly use the Excel file itself as a data table and do inserts. 根据您的需要,您也可以直接将Excel文件本身用作数据表并进行插入。 There is also EPPlus library on Nuget but that would be a little bit slow + may not contain all the capabilities you need. Nuget上也有EPPlus库,但是它有点慢+可能不包含您需要的所有功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM