C# 在Excel'中对命名范围进行排序;带代码的s名称管理器
我使用VSTO从Excel电子表格中获取命名范围的列表:C# 在Excel'中对命名范围进行排序;带代码的s名称管理器,c#,excel,sorting,vsto,named-ranges,C#,Excel,Sorting,Vsto,Named Ranges,我使用VSTO从Excel电子表格中获取命名范围的列表: public List<Name> GetNamedRanges(Workbook activeWorkbook) { List<Name> namedRanges = new List<Name>(); Name name; for (int i = 0; i < activeWorkbook.Names.Count; i++) { name =
public List<Name> GetNamedRanges(Workbook activeWorkbook)
{
List<Name> namedRanges = new List<Name>();
Name name;
for (int i = 0; i < activeWorkbook.Names.Count; i++)
{
name = activeWorkbook.Names.Item(i + 1);
if (!name.Value.Contains("#REF"))
{
namedRanges.Add(name);
}
}
return namedRanges;
}
公共列表GetNamedRanges(工作簿activeWorkbook)
{
List namedRanges=新列表();
姓名;
对于(int i=0;i=第1页$加元9:$D$172
=第1页$E$41:$F$172在Excel中对它们进行排序,然后再次阅读工作簿。(这是一个简单的方法。)在Excel中对它们进行排序,然后再次阅读工作簿。(这是一个简单的方法。)从中提取代码并对其进行修改,使其按字符串长度排序(按数字拆分后),然后按自然顺序排序。限制是,如果您有不同名称的工作表,您的工作表也将按字符串长度排序,而不是按数字排序
public class ExcelNameComparer<T> : IComparer<IEnumerable<T>>
{
/// <summary>
/// Create a sequence comparer using the default comparer for T.
/// </summary>
public ExcelNameComparer()
{
comp = Comparer<T>.Default;
}
/// <summary>
/// Create a sequence comparer, using the specified item comparer
/// for T.
/// </summary>
/// <param name="comparer">Comparer for comparing each pair of
/// items from the sequences.</param>
public ExcelNameComparer(IComparer<T> comparer)
{
comp = comparer;
}
/// <summary>
/// Object used for comparing each element.
/// </summary>
private IComparer<T> comp;
/// <summary>
/// Compare two sequences of T.
/// </summary>
/// <param name="x">First sequence.</param>
/// <param name="y">Second sequence.</param>
public int Compare(IEnumerable<T> x, IEnumerable<T> y)
{
using (IEnumerator<T> leftIt = x.GetEnumerator())
using (IEnumerator<T> rightIt = y.GetEnumerator())
{
while (true)
{
bool left = leftIt.MoveNext();
bool right = rightIt.MoveNext();
if (!(left || right)) return 0;
if (!left) return -1;
if (!right) return 1;
int lengthResult = leftIt.Current.ToString().Length.CompareTo(rightIt.Current.ToString().Length);
if (lengthResult != 0) return lengthResult;
int itemResult = comp.Compare(leftIt.Current, rightIt.Current);
if (itemResult != 0) return itemResult;
}
}
}
Func<string, object> convert = str =>
{
try { return int.Parse(str); }
catch { return str; }
};
公共类ExcelNameComparer:IComparer
{
///
///使用T的默认比较器创建序列比较器。
///
公共ExcelNameComparer()
{
comp=比较器默认值;
}
///
///使用指定的项比较器创建序列比较器
///对于T。
///
///用于比较每对数据的比较器
///序列中的项目。
公共ExcelNameComparer(IComparer comparer)
{
comp=比较器;
}
///
///用于比较每个元素的对象。
///
私人国际比较公司;
///
///比较两个T序列。
///
///第一个序列。
///第二个序列。
公共整数比较(IEnumerable x,IEnumerable y)
{
使用(IEnumerator leftIt=x.GetEnumerator())
使用(IEnumerator rightIt=y.GetEnumerator())
{
while(true)
{
bool left=leftIt.MoveNext();
bool right=righit.MoveNext();
如果(!(左|右))返回0;
如果(!left)返回-1;
如果(!right)返回1;
int lengthResult=leftIt.Current.ToString().Length.CompareTo(rightIt.Current.ToString().Length);
如果(lengthResult!=0)返回lengthResult;
int itemResult=comp.Compare(leftIt.Current,righit.Current);
如果(itemResult!=0)返回itemResult;
}
}
}
Func convert=str=>
{
尝试{return int.Parse(str);}
catch{return str;}
};
现在运行实际排序:
var lst = new List<string> { "Sheet1!$A$9:$B$172", "Sheet1!$AY$77:$AZ$172", "Sheet1!$E$41:$F$172", "Sheet1!$A$10:$B$172", "Sheet1!$A$1:$B$172" };
var sorted = lst.OrderBy(
str => Regex.Split(str.Replace(" ", ""), "([0-9]+)").Select(convert),
new ExcelNameComparer<object>());
foreach (var sort in sorted)
{
System.Diagnostics.Debug.Print(sort);
}
var lst=新列表{“Sheet1!A$9:$B$172”,“Sheet1!AY$77:$AZ$172”,“Sheet1!E$41:$F$172”,“Sheet1!A$10:$B$172”,“Sheet1!A$1:$B$172”};
var sorted=lst.OrderBy(
str=>Regex.Split(str.Replace(“,”),“([0-9]+)”)。选择(转换),
新的ExcelNameComparer());
foreach(排序中的变量排序)
{
系统.诊断.调试.打印(排序);
}
收益率:
活页1!$A$1:$B$172活页1!$A$9:$B$172
活页1!$A$10:$B$172
活页1!$E$41:$F$172
活页1!$AY$77:$AZ$172
从中获取代码并对其进行修改,使其按字符串长度排序(按数字拆分后),然后按自然顺序排序。限制是,如果您有不同名称的工作表,则工作表也将按字符串长度排序,而不是按数字排序
public class ExcelNameComparer<T> : IComparer<IEnumerable<T>>
{
/// <summary>
/// Create a sequence comparer using the default comparer for T.
/// </summary>
public ExcelNameComparer()
{
comp = Comparer<T>.Default;
}
/// <summary>
/// Create a sequence comparer, using the specified item comparer
/// for T.
/// </summary>
/// <param name="comparer">Comparer for comparing each pair of
/// items from the sequences.</param>
public ExcelNameComparer(IComparer<T> comparer)
{
comp = comparer;
}
/// <summary>
/// Object used for comparing each element.
/// </summary>
private IComparer<T> comp;
/// <summary>
/// Compare two sequences of T.
/// </summary>
/// <param name="x">First sequence.</param>
/// <param name="y">Second sequence.</param>
public int Compare(IEnumerable<T> x, IEnumerable<T> y)
{
using (IEnumerator<T> leftIt = x.GetEnumerator())
using (IEnumerator<T> rightIt = y.GetEnumerator())
{
while (true)
{
bool left = leftIt.MoveNext();
bool right = rightIt.MoveNext();
if (!(left || right)) return 0;
if (!left) return -1;
if (!right) return 1;
int lengthResult = leftIt.Current.ToString().Length.CompareTo(rightIt.Current.ToString().Length);
if (lengthResult != 0) return lengthResult;
int itemResult = comp.Compare(leftIt.Current, rightIt.Current);
if (itemResult != 0) return itemResult;
}
}
}
Func<string, object> convert = str =>
{
try { return int.Parse(str); }
catch { return str; }
};
公共类ExcelNameComparer:IComparer
{
///
///使用T的默认比较器创建序列比较器。
///
公共ExcelNameComparer()
{
comp=比较器默认值;
}
///
///使用指定的项比较器创建序列比较器
///对于T。
///
///用于比较每对数据的比较器
///序列中的项目。
公共ExcelNameComparer(IComparer comparer)
{
comp=比较器;
}
///
///用于比较每个元素的对象。
///
私人国际比较公司;
///
///比较两个T序列。
///
///第一个序列。
///第二个序列。
公共整数比较(IEnumerable x,IEnumerable y)
{
使用(IEnumerator leftIt=x.GetEnumerator())
使用(IEnumerator rightIt=y.GetEnumerator())
{
while(true)
{
bool left=leftIt.MoveNext();
bool right=righit.MoveNext();
如果(!(左|右))返回0;
如果(!left)返回-1;
如果(!right)返回1;
int lengthResult=leftIt.Current.ToString().Length.CompareTo(rightIt.Current.ToString().Length);
如果(lengthResult!=0)返回lengthResult;
int itemResult=comp.Compare(leftIt.Current,righit.Current);
如果(itemResult!=0)返回itemResult;
}
}
}
Func convert=str=>
{
尝试{return int.Parse(str);}
catch{return str;}
};
现在运行实际排序:
var lst = new List<string> { "Sheet1!$A$9:$B$172", "Sheet1!$AY$77:$AZ$172", "Sheet1!$E$41:$F$172", "Sheet1!$A$10:$B$172", "Sheet1!$A$1:$B$172" };
var sorted = lst.OrderBy(
str => Regex.Split(str.Replace(" ", ""), "([0-9]+)").Select(convert),
new ExcelNameComparer<object>());
foreach (var sort in sorted)
{
System.Diagnostics.Debug.Print(sort);
}
var lst=新列表{“Sheet1!A$9:$B$172”,“Sheet1!AY$77:$AZ$172”,“Sheet1!E$41:$F$172”,“Sheet1!A$10:$B$172”,“Sheet1!A$1:$B$172”};
var sorted=lst.OrderBy(
str=>Regex.Split(str.Replace(“,”),“([0-9]+)”)。选择(转换),
新的ExcelNameComparer());
foreach(排序中的变量排序)
{
系统.诊断.调试.打印(排序);
}
收益率:
活页1!$A$1:$B$172活页1!$A$9:$B$172
活页1!$A$10:$B$172
活页1!$E$41:$F$172
活页1!$AY$77:$AZ$172
我只是通过删除数字,然后按长度排序,然后按字母顺序排序,这相当混乱,但可以做到:
static public List<Name> GetNamedRangesInOrder(Workbook activeWorkbook)
{
List<Name> namedRanges = GetNamedRanges(activeWorkbook);
List<string> lstStringNameRanges = new List<string>();
foreach (var item in namedRanges)
{
lstStringNameRanges.Add(RemoveDigits(item.RefersTo.ToString()));
}
IEnumerable<string> results = SortByLengthAndName(lstStringNameRanges);
List<Name> sortedNamedRanges = new List<Name>();
foreach (var item in results)
{
int index = -1;
for (int i=0; i < namedRanges.Count; i++)
{
if (RemoveDigits(namedRanges[i].RefersTo.ToString()) == item.ToString())
{
index = i;
break;
}
}
sortedNamedRanges.Add(namedRanges[index]);
}
return sortedNamedRanges;
}
static public IEnumerable<string> SortByLengthAndName(IEnumerable<string> e)
{
IEnumerable<string> query = e.OrderBy(x => x.Length).ThenBy(x => x).ToList();
return query;
}
static public string RemoveDigits(string e)
{
string str = new string((from c in e
where char.IsLetter(c) || char.IsSymbol(c)
select c).ToArray());
return str;
}
静态公共列表GetNamedRangeSOrder(工作簿activeWorkbook)
{
List namedRanges=GetNamedRanges(活动工作簿);