使用VBA调用Wscript.Shell排序文本文件时仅识别前10字符问题
问题:VBA调用WScript.Shell执行sort命令仅按前10个字符排序
现象描述
尝试通过VBA调用WScript.Shell执行Windows的sort命令对文本文件排序,预期按每行前20个字符排序,但实际仅识别前10个字符,排序后的部分文本如下:
59342768471700000028 59342768471300171816 59342768472400038039 59342768472400055526 59342768470900142917 59342768470300108625 59342768472200028114 59342768472200033063 59342768471900014592 59342768471000152827 59342768472500038040 59342768472500055527 59342768471200167530 59342768470100084909 59342768471100157308 59342768471100162422 59342768471700191485
原因分析
这不是正常现象,问题源于Windows自带sort命令的默认行为:
- 默认情况下,
sort可能会截断过长的排序键,仅使用前10个字符作为排序依据; - 若文本文件为UTF-16(Unicode)编码,
sort默认无法正确识别字符长度,也会导致排序键被错误截断。
解决方法
1. 修改sort命令参数
在生成的bat文件中,给sort命令添加/KEY=1,20参数,强制指定使用第1到第20个字符作为排序键。如果是Unicode文件,额外添加/U参数支持Unicode排序。
2. 修正VBA代码中的潜在问题
- 补充未定义的
horario变量,避免bat文件重名; - 移除未使用的
FSO对象及无效的Close语句; - 简化代码逻辑,减少出错概率。
修改后的完整VBA代码
Sub ClassificarSeq() Dim myOutput As String, myOutput2 As String, pastanova As String Dim batFile As String, nomeDoBat As String, horario As String myOutput = "C:\fileunsorted.txt" ' 生成唯一的bat文件名后缀 horario = Format(Now(), "YYYYMMDDHHMMSS") pastanova = Left(myOutput, InStrRev(myOutput, "\")) nomeDoBat = "C:\TEMP\ClassificarTXT2_" & horario & ".bat" myOutput2 = Left(myOutput, Len(myOutput) - 4) & "_Classificado2.txt" ' 写入bat命令 Open nomeDoBat For Output As #1 Print #1, "cd """ & pastanova & """" ' 按前20个字符排序,若为Unicode文件添加/U参数 Print #1, "sort """ & myOutput & """ /KEY=1,20 /O """ & myOutput2 & """" Print #1, "del /f """ & myOutput & """" Close #1 ' 执行bat文件 Dim wsh As Object Set wsh = VBA.CreateObject("WScript.Shell") Dim waitOnReturn As Boolean: waitOnReturn = True Dim windowStyle As Integer: windowStyle = 1 wsh.Run nomeDoBat, windowStyle, waitOnReturn ' 替换原文件 Name myOutput2 As myOutput ' 清理bat文件 Kill nomeDoBat Set wsh = Nothing End Sub
额外说明
/KEY=start,end参数中的start和end是列号,每个字符对应一列,1,20正好覆盖前20个字符;- 若文本文件为UTF-16编码,将
sort命令行改为:sort """ & myOutput & """ /U /KEY=1,20 /O """ & myOutput2 & """"
内容的提问来源于stack exchange,提问作者Jeú Dourado
相关产品推荐
相关产品推荐

