非线性Excel范围C#的独特列表

时间:2017-05-04 17:51:53

标签: c# excel vsto office-interop

我遇到以下问题。第一部分代码的工作原理是将所有不同的值拉入一个列表框供用户查看。但是,当数据被过滤时,它仍然会提取所有不是我想要的隐藏值。当我试图仅将可见单元格拉入范围时,它将我的范围转换为不同的列表。关于为什么打破范围的任何想法打破了这个? System.Array myvalues行上的代码中断错误" Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:无法转换类型'字符串'到' System.Array'"。对我来说似乎很奇怪。

工作代码:

Range values = sht.Range[cell1, cell2];
System.Array myvalues = (System.Array)values.Cells.Value;
string[] listValues = myvalues.OfType<object>().Select(o => o.ToString()).ToArray();
string[] listValues2 = listValues.Distinct().ToArray();

打破代码:

Range values = sht.Range[cell1, cell2].SpecialCells(XlCellType.xlCellTypeVisible);
System.Array myvalues = (System.Array)values.Cells.Value;
string[] listValues = myvalues.OfType<object>().Select(o => o.ToString()).ToArray();
string[] listValues2 = listValues.Distinct().ToArray();

编辑:

工作代码可以处理隐藏范围的时间以及何时不包含

var extractedFromSheet = new List<object>();
            foreach (Range area in values.Areas)
            {
                var areaValue = area.Value;
                if (areaValue is Array) // The area contains multiple cells
                {
                    var arr = (Array)areaValue;
                    extractedFromSheet.AddRange(arr.OfType<object>().Select(o => o .ToString()));
                }
                else // The area contains one cell
                {
                    extractedFromSheet.Add(areaValue);
                }
            }
            var distinct = extractedFromSheet.Distinct();

1 个答案:

答案 0 :(得分:2)

xlCellTypeVisible返回非连续的Range。该范围具有.Areas属性,每个属性也是Range。尝试迭代values.Areas并从每个范围中获取值。

您还需要检查每个值,因为它可能是单值或数组,具体取决于区域是包含一个单元格还是多个单元格。这可能是你所看到的错误。它从一个单元格中读取一个字符串,因此它不会返回一个数组。

应该这样做或接近:

var extractedFromSheet = new List<object>();
foreach(Range area in values.Areas)
{
    var areaValue = area.Value;
    if(areaValue is Array) // The area contains multiple cells
    {
        extractedFromSheet.AddRange((System.Array)areaValue);
    }
    else // The area contains one cell
    {
        extractedFromSheet.AddRange(areaValue);
    }
}
var distinct = extractedFromSheet.Distinct();

有点搞砸了属性可以返回任何类型的对象或数组。我甚至不记得你要做的所有事情,以确保清理对COM对象的引用。

https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.areas.aspx