VBScript处理12000行CSV去重:Dictionary异常及日志导出求助
VBScript CSV去重:Dictionary对象踩坑指南
嘿,我太懂你处理12000行CSV去重时卡壳的感觉了!先理清楚你的核心需求:基于userid和/或card_number识别重复项,把重复行存进Dictionary,非重复行写入新文件,最后还要把重复项导出到日志对吧?
先明确你的重复场景,比如这种整行完全重复的情况:
userid fistname lastname card_number
1234 toto help 111111
1234 toto help 111111
还有这种不同userid但card_number相同的重复:
1234 toto help 111111
5678 user user2 111111
你说FSO的文件操作都正常,但Dictionary逻辑完全跑不起来,我看了你的代码片段,发现几个致命问题:
核心问题清单
- Dictionary没初始化:你只声明了
dictionary变量,但没通过Set dictionary = CreateObject("Scripting.Dictionary")创建实例——就像拿了个空盒子却没拆封,根本没法装东西! - 重复判断逻辑搞反了:你现在的代码是「不存在就写输出,存在就加Dictionary」,但实际应该是「不存在就加Dictionary并写输出,存在就记到重复日志」。
- 日志写入逻辑混乱:
objTextFile完全没初始化,循环里写Dictionary的方式错误,最后For Each循环的.Item用法也不符合VBScript语法。 - 注释符号用错了:VBScript的注释是单引号
',不是#,虽然有些环境能兼容,但规范写法必须改。
修正后的完整代码
我给你调整了代码,解决了所有问题,还加了详细注释:
' 声明所需变量 Dim objFSO, objTextFile, objFile Dim CurDir, InputFile, OutputFile, LogFile Dim strInput Dim dictionary, key ' 初始化路径(请根据你的实际文件路径修改) Set objFSO = CreateObject("Scripting.FileSystemObject") CurDir = objFSO.GetAbsolutePathName(".") & "\" InputFile = "input.csv" ' 你的原始CSV文件名 OutputFile = "myCSVfile.csv" ' 去重后的输出文件名 LogFile = "duplicates.log" ' 重复项日志文件名 ' 初始化Dictionary对象(这步是关键中的关键!) Set dictionary = CreateObject("Scripting.Dictionary") dictionary.CompareMode = vbTextCompare ' 可选:忽略大小写匹配,不需要就删掉 ' 创建输出文件和日志文件(覆盖模式,UTF-8编码) Set OutputFile = objFSO.CreateTextFile(CurDir & OutputFile, 2, True) Set objTextFile = objFSO.CreateTextFile(CurDir & LogFile, 2, True) ' 打开原始输入文件 Set objFile = objFSO.OpenTextFile(CurDir & InputFile, 1) ' 逐行读取处理 Do Until objFile.AtEndOfStream strInput = objFile.ReadLine() strInput = Trim(strInput) ' 跳过空行 If Len(strInput) = 0 Then Continue Do End If ' 这里是整行去重的逻辑,如果要基于userid+card_number去重,看下面的补充 If Not dictionary.Exists(strInput) Then ' 非重复行:加入Dictionary并写入输出文件 dictionary.Add strInput, strInput OutputFile.WriteLine strInput Else ' 重复行:直接写入日志文件 objTextFile.WriteLine strInput End If Loop ' 在日志末尾添加重复项统计 objTextFile.WriteLine "=====================================" objTextFile.WriteLine "Total duplicated lines: " & objFSO.GetFile(CurDir & LogFile).LineCount - 1 ' 关闭所有文件,释放资源 objFile.Close OutputFile.Close objTextFile.Close Set objFSO = Nothing Set dictionary = Nothing WScript.Echo "去重完成!已生成去重文件和重复项日志。"
补充:基于userid+card_number精准去重
如果你的重复判断不是整行,而是只要userid和card_number相同就算重复,那把循环里的判断逻辑改成下面这样(假设CSV用空格分隔,要是逗号分隔就把Split的分隔符改成","):
' 替换循环内的判断部分 Dim parts parts = Split(strInput, " ") ' 按空格分割每行内容 ' 提取第1列userid和第4列card_number(索引从0开始) Dim keyStr keyStr = parts(0) & "|" & parts(3) ' 用|作为组合键的分隔符,避免冲突 If Not dictionary.Exists(keyStr) Then dictionary.Add keyStr, strInput OutputFile.WriteLine strInput Else objTextFile.WriteLine strInput End If
这样就能精准识别userid和card_number组合的重复项,不管其他字段有没有变化。
额外:怎么单独导出Dictionary内容?
其实上面的代码已经在遇到重复时直接写入日志了,效率更高。如果你非要单独导出Dictionary里存储的内容,可以用这个循环:
' 导出Dictionary所有键到日志(示例) objTextFile.WriteLine "===== Dictionary存储的键 =====" For Each key In dictionary.Keys objTextFile.WriteLine key Next
内容的提问来源于stack exchange,提问作者Overlord
相关产品推荐
相关产品推荐

