C# 在Excel'中对命名范围进行排序;带代码的s名称管理器

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 =

我使用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 = activeWorkbook.Names.Item(i + 1);
        if (!name.Value.Contains("#REF"))
        {
            namedRanges.Add(name);
        }       
    }
    return namedRanges;
}
公共列表GetNamedRanges(工作簿activeWorkbook) { List namedRanges=新列表(); 姓名; 对于(int i=0;i 这将以奇怪的顺序返回名称:

有没有人有一个简单的方法按列顺序对名称范围进行排序。例如:

=第1页$A$9:$B$172
=第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(活动工作簿);