【问题标题】:Fastest Way To Iterate On Range Of Excel References ("C20:F22")迭代 Excel 引用范围的最快方法 ("C20:F22")
【发布时间】:2013-02-01 05:27:53
【问题描述】:

假设这个字符串变量是 Excel 中的一个单元格区域:

string RangeReference = "C20:F22";

所以我需要RangeReference 中的引用列表,如下所示:

List<string> GetAllReferencesInRange(string RangeReference) { }

对于这种情况,我们将有:

GetAllReferencesInRange(RangeReference);
//=
//C20
//D20
//E20
//F20
//C21
//D21
//E21
//F21
//C22
//D22
//E22
//F22

如果RangeReference = "AG9:AI11"; 那么:

GetAllReferencesInRange(RangeReference);
//=
//AG9
//AH9
//AI9
//AG10
//AH10
//AI10
//AG11
//AH11
//AI11

那么最快的方法是什么?

更新:

我知道这个问题根本与 Excel 无关,但我使用 OpenXML SDK 2.5 来获取 Excel 文件和元素,所以也许 OpenXML 中有一个我不知道的简单方法。

【问题讨论】:

    标签: c# excel range loops


    【解决方案1】:

    我发现了一些东西,但我不知道这是不是最快的方法。

    起初我建立了一个存储列名和相关数字的字典:

    Dictionary<string, ulong> ColumnsInNumber = new Dictionary<string, ulong>();
    string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    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++);
    

    在 Excel 2010 中,最后一列名称是“XFD”,在上面我们将数字设置为从“A”到“ZZZ”的列

    所以我们可以迭代行和列:

    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));
       }
    }
    

    【讨论】:

      【解决方案2】:

      首先检查它的格式是否正确,然后:

          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;
              }
          }
      

      目前适用于单字母,我正在努力让更多行发生。

      【讨论】:

      • 输出是什么,看看我能不能修复它?
      • 我用"AX10:BC12" 测试它,但在LongRangesecond 是一个负数。
      • 这很奇怪。我去看看:)
      • 我已经让它工作得更好了,但还不够:pastebin.com/uWUbHAPy Alphabet upper 是字母表的大写版本。
      • 我仍然不知道您要做什么,但是您的新解决方案不起作用,例如检查“AX10:BC12”,为列名选择两个或多个字符。
      猜你喜欢
      • 1970-01-01
      • 2015-01-06
      • 2014-02-16
      • 2016-07-19
      • 2019-04-08
      • 2023-04-11
      • 2017-11-28
      • 1970-01-01
      • 2018-10-07
      相关资源
      最近更新 更多