how to detect merged cells in c# using MS interop excel

时间:2015-06-26 09:37:59

标签: c# excel excel-interop

I want to detect merged cells either in a row/entire sheet(preferable).Here is my code

Microsoft.Office.Interop.Excel.Application xl = new Microsoft.Office.Interop.Excel.Application(); 
Microsoft.Office.Interop.Excel.Workbook workbook = xl.Workbooks.Open(source);
//Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets[sheetNumber];
Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[objInMemory._sheetName];
xl.ScreenUpdating = false;
ws.Columns.ClearFormats();
ws.Rows.ClearFormats();
int colCount = ws.UsedRange.Columns.Count;
int rowCount = ws.UsedRange.Rows.Count;
int strtRow = ws.UsedRange.Rows[1].Row;
int strtCol = ws.UsedRange.Columns[1].Column;


 Microsoft.Office.Interop.Excel.Range objRange = null;

Neither this piece of code

if (ws.Cells.MergeCells)
{

}

Nor this piece of code(only for row1)

for (int j = strtCol; j < strtCol + colCount; j++)
{
    objRange = ws.Cells[strtRow, j];

    if (ws.Cells[strtRow, j].MergeCells)
    {
        message = "The Sheet Contains Merged Cells";
        break;
    }  
}

seem to work..Kindly let me know how to check if a sheet/specific range contains merged cells.

4 个答案:

答案 0 :(得分:6)

MergeCells不是单元格函数,它是范围函数,因此不是:

if (ws.Cells[strtRow, j].MergeCells)

你需要:

_Excel.Range range = (_Excel.Range) ws.Cells[strtRow, j];
if(range.MergeCells) //returns true if cell is merged or false if its not

答案 1 :(得分:4)

If you want to check if a Range contains merged cells, then the MergeCells property is what you're after.

If a range is merged, it will return true. If a range contains merged cells (i.e. some are merged, some aren't), it will return DBNull.Value.

So, this should work for your entire sheet:

object mergeCells = ws.UsedRange.MergeCells;
var containsMergedCells = mergeCells == DBNull.Value || (bool)mergeCells;

答案 2 :(得分:0)

请删除overflow-y: scrollws.Columns.ClearFormats();,以使ws.Rows.ClearFormats();属性起作用。

答案 3 :(得分:0)

查尔斯·马格(Charles Mager)的答案的一个学究版如下:对于包含所有合并区域的单元格但范围不同的单元格的区域,MergeCells的行为似乎被破坏了。因此,实际的建议是遵循Charle对MergeCells结果进行“或”运算并检查是否为Null的答案,因为不能真正相信“ True”值的含义。为了证明我的观点,请尝试以下实验:

首先,合并单元格A1和B1。合并单元格A2和B2。然后从VBA编辑器的立即窗口中运行以下命令。对于各种选择,这将是MergeCells的结果:

  • ?ActiveSheet.Range("A1:B1").MergeCells:是的。正如我们期望的那样,因为它是整个合并区域。
  • ?ActiveSheet.Range("A1:A2").MergeCells:是的。没料到。该范围跨越两个合并区域。但是,所有单元格都合并到 some 区域,所以也许这就是函数要测量的?不。请参阅以下实验。
  • ?ActiveSheet.Range("A1:B2").MergeCells:空。这与最后的结果不一致。因此,这两种含义都不适合实验:“所有单元格都合并到某个区域”或“所有单元格都合并到同一区域”。

结论:

该行为有些零散。在上述实验的基础上,这是我最好的猜测。

  • 如果this的值为True,我们知道所有单元格都合并到 some 区域。我们不能保证这是同一地区。
  • 如果this的值为Null,则说明某些或所有单元格已合并到某个区域。
  • 如果此值为False,则根本不会合并任何单元格。

因此,您可以编写混乱的,分散的逻辑来检查所有三种情况。或者,您可以做Charles所做的事情,将其围绕起来,并以更明智的方式构建某些东西:

  • 如果this的值为True或null,则说明某些单元格已合并到某个区域。
  • 如果此值为False,则根本不会合并任何单元格。

从那里,您可以使用Range.MergeArea来更精确地确定合并的位置。

某些代码

就此而言,假设您使用的是具有Excel Interop Range类型的RawRange属性的包装对象,这是Charles的另一种变体,它具有更安全的转换。

public bool SomeCellsMerged()
{
    object mergeCells = RawRange.MergeCells;
    if(mergeCells is bool someCellsMerged)
    {
        if (someCellsMerged) return true;
    }
    return mergeCells == DBNull.Value;
}