Home » excel » c# – Fastest Way To Iterate On Range Of Excel References ("C20:F22")

c# – Fastest Way To Iterate On Range Of Excel References ("C20:F22")

Posted by: admin April 23, 2020 Leave a comment


Assume this string variable is a range of cells in Excel:

string RangeReference = "C20:F22";

So I need a list of references in RangeReference Like this:

List<string> GetAllReferencesInRange(string RangeReference) { }

For this case we will have:


And if RangeReference = "AG9:AI11"; Then:


So what is the fastest way to get this?


I Know this question could not related to Excel at all, but I use OpenXML SDK 2.5 to Get Excel File and Elements, so Maybe there is an easy way in OpenXML that I don’t Know.

How to&Answers:

I found some thing but I don’t know is it the fastest way or not.

At first I buid a dictionary that stores a column name and a related number:

Dictionary<string, ulong> ColumnsInNumber = new Dictionary<string, ulong>();
ulong SpecialNumber = 0;

foreach (char FirstChar in Alphabet)
   ColumnsInNumber.Add(FirstChar.ToString(), SpecialNumber++);

foreach (char FirstChar in Alphabet)
   foreach (char SecondChar in Alphabet)
      ColumnsInNumber.Add(string.Format("{0}{1}", FirstChar, SecondChar), SpecialNumber++);

foreach (char FirstChar in Alphabet)
   foreach (char SecondChar in Alphabet)
      foreach (char ThirdChar in Alphabet)
          ColumnsInNumber.Add(string.Format("{0}{1}{2}", FirstChar, SecondChar, ThirdChar), SpecialNumber++);

In Excel 2010 the last column name is “XFD”, in above we set numbers to Columns from “A” to “ZZZ”

So We Can iterate on rows and Columns:

string FirstColumn = GetColumnName(GetFirstCellReference(RangeReference));
string LastColumn = GetColumnName(GetLastCellReference(RangeReference));
uint FirstRow = GetRowNumber(GetFirstCellReference(RangeReference));
uint LastRow = GetRowNumber(GetLastCellReference(RangeReference));

List<string> Result = new List<string>();

for (uint row = FirstRow; row <= LastRow; row++)
   for (ulong column = ColumnsInNumber[FirstColumn]; column <= ColumnsInNumber[LastColumn]; column++)
     string ColumnName = ColumnsInNumber.Where(kv => kv.Value == column).FirstOrDefault().Key;
     Result.Add(string.Format("{0}{1}", ColumnName, row));


First check that it’s in the right format, then:

    static readonly List<char> alphabetUpper = new List<char> { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
    static public IEnumerable<string> GetRange(string arg)
        arg = arg.ToUpperInvariant();
        string[] ranges = arg.Split(':');
        ulong range0 = ulong.Parse((new string((from char c in ranges[0] where char.IsDigit(c) select c).ToArray())));
        ulong range1 = ulong.Parse ((new string((from char c in ranges[1] where char.IsDigit(c) select c).ToArray())));
        ranges[0] = new string((from char c in ranges[0] where !char.IsDigit(c) select c).ToArray());
        ranges[1] = new string((from char c in ranges[1] where !char.IsDigit(c) select c).ToArray());
        IEnumerable<int> arrayindexes0 = from c in ranges[0] select alphabetUpper.IndexOf(c);
        IEnumerable<int> arrayindexes1 = from c in ranges[1] select alphabetUpper.IndexOf(c);
        foreach (IEnumerable<int> f in (from i in arrayindexes0 from e in arrayindexes1 select new List<int>() {i, e}))
            foreach (int i in f)
                foreach (ulong o in LongRange(range0, range1))
                    yield return alphabetUpper[i] + o.ToString();
    static IEnumerable<BigInteger> LongRange (BigInteger first, BigInteger second)
        BigInteger difference = second - first;
        for (BigInteger i = 0; i <= difference; i++)
            yield return first + i;

Works for single letter ones for the moment, I’m working on letting more rows happen.