在Excel引用的范围上迭代的最快方法(“C20:F22”)
本文关键字:C20 F22 方法 引用 Excel 范围 迭代 | 更新日期: 2023-09-27 17:59:50
假设此字符串变量是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中可能有一种我不知道的简单方法。
我发现了一些东西,但我不知道这是否是最快的方法。
起初,我创建了一个存储列名和相关数字的字典:
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++);
在Excel2010中,最后一个列名是"XFD",在上面我们将数字设置为Columns from"A"to"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));
}
}
首先检查它的格式是否正确,然后:
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;
}
}
目前适用于单字母的,我正在努力让更多的行发生。