【问题标题】:Excel: Values from Ranges With Multiple AreasExcel:来自具有多个区域的范围的值
【发布时间】:2014-02-06 05:02:36
【问题描述】:

我想使用 C# 在 excel 中获取非连续的多区域范围的值。我看到another SO question 说我可以这样做:

obj[,] data = sheet.get_Range("B4:K4,B5:K5").get_Value();

但是,当我检查结果时,我发现我只从第一个区域获取数据:"B4:K4"

进一步测试,我发现如果我通过以下方式请求数据:

obj[,] data = sheet.get_Range( "B4:K4","B5:K5").get_Value();

我得到了这两个领域的数据...

那么,我的问题是,有没有办法以编程方式组合区域地址,例如 "B4:K4,B5:K5",以便获取它们所引用的所有数据?

谢谢

【问题讨论】:

  • 使用分号而不是逗号时会起作用吗?有时 excel 对这些事情很有趣......但这只是一种预感/猜测!
  • @pnuts:我忘了说这些区域可以是不连续的。以上编辑。
  • @Floris:尝试了你的建议,但没有运气......
  • @pnuts: 已经很接近了,但仍然无法解决以编程方式创建联合的问题

标签: c# excel com-interop


【解决方案1】:

我想出的解决方案并不像我希望的那样优雅,但它仍然可以解决问题:

public List<List<object>> 
GetNonContiguousRowValue(Excel.Worksheet ws, string noncontiguous_address)
{
    var addresses = noncontiguous_address.Split(','); // e.g. "A1:D1,A4:D4"
    var row_data = new List<List<object>>();

    // Get the value of one row at a time:
    foreach (var addr in addresses)
    {
        object[,] arr = ws.get_Range(addr).Value;
        List<object> row = arr.Cast<object>)
                              .Take(arr.GetLength(dimension:1))
                              .ToList<object>();
        row_data.Add(row);
    }
    return row_data;
}

希望这对其他人有所帮助...

【讨论】:

    【解决方案2】:

    如果您尝试从具有隐藏行的范围表中获取数据,另一种技术是抓取可见单元格,并将它们复制到新工作表中。粘贴时,它们会形成一个连续的区域,并且可以检索到正常的 object[,] 数组。

    public object[,] GetNonContiguousVisibleRowsData(Excel.Worksheet sheet, string noncontiguous_address)
    {
        // Add a new worksheet
        Excel.Workbook book = (Excel.Workbook)sheet.Parent;
        Excel.Sheets sheets = book.Sheets;
        Excel.Worksheet tempSheet = (Excel.Worksheet)sheets.Add();
        Excel.Range cellA1 = tempSheet.get_Range("A1");
    
        // Get only the visible cells
        Excel.Range nonContiguousRange = sheet.get_Range(noncontiguous_address);
        Excel.Range visibleSourceRange = nonContiguousRange.SpecialCells(Excel.XlCellType.xlCellTypeVisible);
    
        // Copying the visible cells will result in a contiguous range in tempSheet
        visibleSourceRange.Copy(cellA1);
    
        // Get the contiguous range and copy the cell value.
        Excel.Range contiguousRange = tempSheet.UsedRange;
        object[,] data = (object[,])contiguousRange.get_Value(Excel.XlRangeValueDataType.xlRangeValueDefault);
    
        // Release all COM objects from temp sheet, e.g.:
        // System.Runtime.InteropServices.Marshal.ReleaseComObject(contiguousRange);
        // contiguousRange = null;
    
        tempSheet.Delete();
    
        // release all other COM objects
    
        return data;
    }
    

    【讨论】:

      【解决方案3】:

      另一种方法是将非连续区域组合成一个命名范围,并在 C# 代码中引用该命名范围。这是一种方法(将此公式分配给 Excel 名称管理器中的命名范围):

      =CHOOSE({1;2;3},Sheet1!$A$1,Sheet2!$A$3,Sheet3!$A$5)
      

      这种方法的缺点是每个区域只能是 1 行高。

      【讨论】:

        猜你喜欢
        • 2023-03-29
        • 1970-01-01
        • 2016-08-27
        • 2014-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多