Home » excel » c# – Excel.Worksheet.Cells has reversed behavior?

c# – Excel.Worksheet.Cells has reversed behavior?

Posted by: admin April 23, 2020 Leave a comment

Questions:

Hey all, I’m experiencing transposed behavior when working the Excel.Worksheet.Cells array.

My first cell needs to be at [row = 10, column = 3]
My second cell needs to be at [row = 11, column = 17]

Then using these two cells as boundaries, I create a range and merge it.
As you can tell from the values noted above, the range should be mostly horizontal.

So, to help me out, I created a simple helper function that merges cells:

    public static void MergeRange(Excel.Worksheet worksheet, int startRowIdx, 
        int startColIdx, int endRowIdx, int endColIdx, bool across = false)
    {   //Get range boundaries.
        Excel.Range cells = worksheet.Cells;

        //commented out, resolved code is directly below - N. Miller, 9-24-2013
        //Excel.Range topleftCell = cells[startColIdx][startRowIdx];
        //Excel.Range bottomrightCell = cells[endColIdx][endRowIdx];
        Excel.Range topleftCell = cells[startRowIdx, startColIdx];
        Excel.Range bottomrightCell = cells[endRowIdx, endColIdx];

        //Merge range.
        Debug.WriteLine(String.Format("({0}, {1}) to ({2}, {3}).", startRowIdx, startColIdx, endRowIdx, endColIdx)); 
        Excel.Range range = worksheet.get_Range(topleftCell, bottomrightCell);
        Excel.Interior interior = range.Interior;
        interior.ColorIndex = XLColor.PERIWINKLE; //JUST HIGHLIGHTS RANGE FOR NOW.
        //range.Merge(across);

        //Cleanup
        Marshal.ReleaseComObject(interior);
        Marshal.ReleaseComObject(range);
        Marshal.ReleaseComObject(bottomrightCell);
        Marshal.ReleaseComObject(topleftCell);
        Marshal.ReleaseComObject(cells);
    }

In the code above, I select the cells I want by swapping the columns and rows. This, contrary to what I expected, results in the desired behavior, but it contradicts the MSDN documentation:

MSDN Worksheet.Cells

In the MSDN documentation they give an example where the row is listed first, then the column follows after.

So my question is this… which is correct?
Should the row be first, or should the column be first?
When I modify my code to be consisten with the MSDN documentation, the highlighted cells are transposed.

How to&Answers:

If I understand you correctly then when you use say cells[1][2] then it means A2 In such a case, Column comes first and then the row. If you write it as cells[1,2] then you will get B2. In this case, Row comes first and then the Column.

It’s the same in Excel-VBA. ?Cells(1)(2).address in immediate window gives $A$2 and ?Cells(1,2).address gives $B$1 If you feel that I have not understood your query then please re-phrase it for me…

Here is the complete code to test it.

NOTE: Tested using VS 2010 Ultimate + Excel 2010

using System;
using System.Windows.Forms;
using System.IO;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;

Namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        Public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            Excel.Application xlexcel;
            Excel.Workbook xlWorkBook;
            Excel.Worksheet xlWorkSheet;

            object misValue = Missing.Value;
            xlexcel = new Excel.Application();
            xlexcel.Visible = true;

            //~~> Open a File (Change filename as applicable)
            xlWorkBook = xlexcel.Workbooks.Open("C:\SomeFile.xlsx",
                         0, true, 5, "", "", true,

            Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,
            "\t", false, false, 0, true, 1, 0);

            //~~> Set Sheet 1 as the sheet you want to work with
            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

            Excel.Range cells = xlWorkSheet.Cells;
            Excel.Range topleftCell = cells[1][2];

            MessageBox.Show(topleftCell.Address);

            topleftCell = cells[1,2];

            MessageBox.Show(topleftCell.Address);

            //~~> Once done close and quit Excel
            xlWorkBook.Close(false, misValue, misValue);
            xlexcel.Quit();

            //~~> CleanUp
            releaseObject(xlWorkSheet);
            releaseObject(xlWorkBook);
            releaseObject(xlexcel);
        }

        private void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                MessageBox.Show("Unable to release the Object " + ex.ToString());
            }
            finally
            {
                GC.Collect();
            }
        }
    }
}

ScreenShot

enter image description here

enter image description here