文件夹下文件名正确排序问题



有时候需要将文件名按照数字大小排序,而不是按照字母顺序排序,例如:


Traditional Sort
Alphanum
1000X Radonius Maximus
10X Radonius
200X Radonius
20X Radonius
20X Radonius Prime
30X Radonius
40X Radonius
Allegia 50 Clasteron
Allegia 500 Clasteron
Allegia 50B Clasteron
Allegia 51 Clasteron
Allegia 6R Clasteron
Alpha 100
Alpha 2
Alpha 200
Alpha 2A
Alpha 2A-8000
Alpha 2A-900
Callisto Morphamax
Callisto Morphamax 500
Callisto Morphamax 5000
Callisto Morphamax 600
Callisto Morphamax 6000 SE
Callisto Morphamax 6000 SE2
Callisto Morphamax 700
Callisto Morphamax 7000
Xiph Xlater 10000
Xiph Xlater 2000
Xiph Xlater 300
Xiph Xlater 40
Xiph Xlater 5
Xiph Xlater 50
Xiph Xlater 500
Xiph Xlater 5000
Xiph Xlater 58
        

10X Radonius
20X Radonius
20X Radonius Prime
30X Radonius
40X Radonius
200X Radonius
1000X Radonius Maximus
Allegia 6R Clasteron
Allegia 50 Clasteron
Allegia 50B Clasteron
Allegia 51 Clasteron
Allegia 500 Clasteron
Alpha 2
Alpha 2A
Alpha 2A-900
Alpha 2A-8000
Alpha 100
Alpha 200
Callisto Morphamax
Callisto Morphamax 500
Callisto Morphamax 600
Callisto Morphamax 700
Callisto Morphamax 5000
Callisto Morphamax 6000 SE
Callisto Morphamax 6000 SE2
Callisto Morphamax 7000
Xiph Xlater 5
Xiph Xlater 40
Xiph Xlater 50
Xiph Xlater 58
Xiph Xlater 300
Xiph Xlater 500
Xiph Xlater 2000
Xiph Xlater 5000
Xiph Xlater 10000
        
使用:

private void button1_Click_1(object sender, EventArgs e)
        {
            this.treeView1.Nodes.Clear();
            
           if( this.folderBrowserDialog1.ShowDialog()==DialogResult.OK )
           {
               this.label6.Text =this.folderBrowserDialog1.SelectedPath;
               workpath = this.folderBrowserDialog1.SelectedPath;
               DirectoryInfo dir = new DirectoryInfo(workpath);
               FileInfo[] arrFi = dir.GetFiles("*.*");
               //FileInfo[] files = dir.GetFiles();
               SortAsFileName(ref arrFi);
               for (int i = 0; i < arrFi.Length; i++)
               {
                   this.treeView1.Nodes.Add(arrFi[i].Name);
               }
               
           }
        }
        private void SortAsFileName(ref FileInfo[] arrFi)
        {
            AlphanumComparator alph = new AlphanumComparator();
            //Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return x.Name.CompareTo(y.Name); });
            Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return alph.Compare(x.Name, y.Name); });
        }
智能排序类:

/*
 * The Alphanum Algorithm is an improved sorting algorithm for strings
 * containing numbers.  Instead of sorting numbers in ASCII order like
 * a standard sort, this algorithm sorts numbers in numeric order.
 *
 * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
 *
 * Based on the Java implementation of Dave Koelle's Alphanum algorithm.
 * Contributed by Jonathan Ruckwood <jonathan.ruckwood@gmail.com>
 *
 * Adapted by Dominik Hurnaus <dominik.hurnaus@gmail.com> to
 *   - correctly sort words where one word starts with another word
 *   - have slightly better performance
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
using System;
using System.Collections;
using System.Text;
/*
 * Please compare against the latest Java version at http://www.DaveKoelle.com
 * to see the most recent modifications
 */
namespace AlphanumComparator
{
    public class AlphanumComparator : IComparer
    {
        private enum ChunkType {Alphanumeric, Numeric};
        private bool InChunk(char ch, char otherCh)
        {
            ChunkType type = ChunkType.Alphanumeric;
            if (char.IsDigit(otherCh))
            {
                type = ChunkType.Numeric;
            }
            if ((type == ChunkType.Alphanumeric && char.IsDigit(ch))
                || (type == ChunkType.Numeric && !char.IsDigit(ch)))
            {
                return false;
            }
            return true;
        }
        public int Compare(object x, object y)
        {
            String s1 = x as string;
            String s2 = y as string;
            if (s1 == null || s2 == null)
            {
                return 0;
            }
            int thisMarker = 0, thisNumericChunk = 0;
            int thatMarker = 0, thatNumericChunk = 0;
            while ((thisMarker < s1.Length) || (thatMarker < s2.Length))
            {
                if (thisMarker >= s1.Length)
                {
                    return -1;
                }
                else if (thatMarker >= s2.Length)
                {
                    return 1;
                }
                char thisCh = s1[thisMarker];
                char thatCh = s2[thatMarker];
                StringBuilder thisChunk = new StringBuilder();
                StringBuilder thatChunk = new StringBuilder();
                while ((thisMarker < s1.Length) && (thisChunk.Length==0 ||InChunk(thisCh, thisChunk[0])))
                {
                    thisChunk.Append(thisCh);
                    thisMarker++;
                    if (thisMarker < s1.Length)
                    {
                        thisCh = s1[thisMarker];
                    }
                }
                while ((thatMarker < s2.Length) && (thatChunk.Length==0 ||InChunk(thatCh, thatChunk[0])))
                {
                    thatChunk.Append(thatCh);
                    thatMarker++;
                    if (thatMarker < s2.Length)
                    {
                        thatCh = s2[thatMarker];
                    }
                }
                int result = 0;
                // If both chunks contain numeric characters, sort them numerically
                if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
                {
                    thisNumericChunk = Convert.ToInt32(thisChunk.ToString());
                    thatNumericChunk = Convert.ToInt32(thatChunk.ToString());
                    if (thisNumericChunk < thatNumericChunk)
                    {
                        result = -1;
                    }
                    if (thisNumericChunk > thatNumericChunk)
                    {
                        result = 1;
                    }
                }
                else
                {
                    result = thisChunk.ToString().CompareTo(thatChunk.ToString());
                }
                if (result != 0)
                {
                    return result;
                }
            }
            return 0;
        }
    }
}
参考:http://www.davekoelle.com/alphanum.html

### 回答1: 以下是完成此任务的 VBA 代码: ``` Sub MergeExcelSheets() Dim wbDest As Workbook Dim wbSrc As Workbook Dim wsSrc As Worksheet Dim strPath As String Dim strFile As String Dim strFiles As String '设置目标文件夹的路径 strPath = "C:\Users\YourName\Documents\Excel Files\" '获取该文件夹内所有 Excel 文件的名称 strFiles = Dir(strPath & "*.xl*") '创建一个新的工作簿作为合并后的目标文件 Set wbDest = Workbooks.Add '循环遍历每一个源文件 Do While strFiles <> "" strFile = strPath & strFiles Set wbSrc = Workbooks.Open(strFile) Set wsSrc = wbSrc.Sheets(1) '将每一个源文件的第一张工作表复制到目标工作簿的最后一个工作表 wsSrc.Copy After:=wbDest.Sheets(wbDest.Sheets.Count) wbSrc.Close False '继续遍历下一个源文件 strFiles = Dir Loop End Sub ``` 在运行此代码前,请确保替换 `strPath` 变量为您自己的文件夹路径,以确保代码可以正确访问该文件夹内的 Excel 文件。 ### 回答2: 以下是一个将同一文件夹内按文件名排序Excel的第一张工作表合并的VBA代码: ```vba Sub 合并工作表() Dim 文件夹路径 As String Dim 文件名 As String Dim wb合并 As Workbook Dim wb源 As Workbook Dim ws源 As Worksheet Dim 行号 As Long ' 设置文件夹路径 文件夹路径 = "C:\你的文件夹路径\" ' 替换为你的文件夹路径 ' 创建一个新工作簿用来合并数据 Set wb合并 = Workbooks.Add ' 循环遍历文件夹中的所有文件 文件名 = Dir(文件夹路径 & "*.xls*") ' 只考虑Excel文件(xls和xlsx) Do Until 文件名 = "" ' 打开源工作簿 Set wb源 = Workbooks.Open(文件夹路径 & 文件名) ' 将源工作簿的第一张工作表复制到合并工作簿 Set ws源 = wb源.Sheets(1) ws源.Copy After:=wb合并.Sheets(wb合并.Sheets.Count) ' 关闭源工作簿,不保存更改 wb源.Close False ' 继续下一个文件 文件名 = Dir Loop ' 删除合并工作簿的第一个空白工作表 Application.DisplayAlerts = False ' 禁止显示删除警告 wb合并.Sheets(1).Delete Application.DisplayAlerts = True ' 激活合并工作簿的第一张工作表 wb合并.Sheets(1).Activate ' 设置合并后的工作簿的名称和保存路径 文件名 = 文件夹路径 & "合并工作表.xlsx" ' 替换为你想要的文件名称和保存路径 ' 保存合并后的工作簿 wb合并.SaveAs 文件名 ' 关闭合并工作簿 wb合并.Close ' 清理内存 Set wb合并 = Nothing Set wb源 = Nothing Set ws源 = Nothing MsgBox "合并完成!合并后的工作簿路径为:" & 文件名, vbInformation End Sub ``` 请将上述代码中的`C:\你的文件夹路径\`替换为你要合并文件的文件夹路径,并将`文件夹路径 & "合并工作表.xlsx"`替换为你想要合并工作表保存的文件名和路径。执行此代码后,将会在指定的文件夹路径下生成一个合并后的工作簿。 请注意,在执行代码之前,确保没有其他Excel工作簿处于打开状态,以便代码能够正确运行。 ### 回答3: 以下是一个VBA代码,用于将同一文件夹内所有按文件名排序Excel的第一张工作表合并。 ```VBA Sub 合并工作表() Dim 文件夹路径 As String Dim 文件名 As String Dim 文件类型 As String Dim 目标工作簿 As Workbook Dim 源工作簿 As Workbook Dim 目标工作表 As Worksheet Dim 源工作表 As Worksheet Dim i As Long '设置要合并的文件夹路径 文件夹路径 = "C:\你的文件夹路径\" '设置要合并的文件类型(这里假设为.xlsx文件) 文件类型 = "*.xlsx" '创建一个新的目标工作簿 Set 目标工作簿 = Workbooks.Add '打开目标工作簿的第一个工作表 Set 目标工作表 = 目标工作簿.Sheets(1) '获取指定文件夹内的所有文件名 文件名 = Dir(文件夹路径 & 文件类型) '循环遍历每个文件 Do While 文件名 <> "" '打开源工作簿 Set 源工作簿 = Workbooks.Open(文件夹路径 & 文件名) '复制源工作簿的第一个工作表到目标工作簿的末尾 Set 源工作表 = 源工作簿.Sheets(1) 源工作表.UsedRange.Copy 目标工作表.Cells(目标工作表.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1) '关闭源工作簿 源工作簿.Close False '获取下一个文件名 文件名 = Dir Loop '保存目标工作簿 目标工作簿.SaveAs 文件夹路径 & "合并工作表.xlsx" '关闭目标工作簿 目标工作簿.Close '显示一个完成消息 MsgBox "已将所有工作表合并到一个文件中。", vbInformation End Sub ``` 在代码中,你需要修改`文件夹路径`变量的值为实际的文件夹路径,以及修改`文件类型`变量的值为要合并的文件类型。然后,运行代码即可将同一文件夹内所有按文件名排序Excel的第一张工作表合并到一个新的工作簿中,并保存为名为"合并工作表.xlsx"的文件。 请注意,此代码假设你的Excel文件没有密码保护,并且所有的工作表都是以第一张工作表开始的。如果有特殊情况,你需要根据实际需求进行相应的修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值