在不替换所有文本的情况下,使用VBscript替换CSV文件中的数字

3

我正在处理这段代码

Dim strFirm,soNumber,strValues,arrStr,strCitrix,NewText,text

strFirm = "Gray"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("cloud.csv",1,True)

Do while not objTextFile.AtEndOfStream
    arrStr = Split(objTextFile.ReadLine, ",")
If arrStr(0) = strFirm Then
    soNumber = arrStr(1)
Exit Do
End If
Loop

objTextFile.Close

strCitrix = soNumber + 1

MsgBox "Cloud Client " & strFirm & " is now using " & strCitrix & " Citrix licenses."

NewText = Replace(soNumber, soNumber, strCitrix)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("cloud.csv",2,True)
objTextFile.Writeline NewText
objTextFile.Close

然而,当我运行代码时,替换会清除我的文件上的所有文字,除了我写的数字。

我希望它只更改指定变量,保留其他所有文本。

示例:

Client1,5
Client2,7
Client3,12
Gray,6
Client4,9
Client5,17
Client6,8

运行脚本后

Client1,5
Client2,7
Client3,12
Gray,7
Client4,9
Client5,17
Client6,8

有人能指出我做错了什么吗?

提前感谢您的帮助。

2个回答

5

你的输出文件仅包含你要更改的数字,因为你从读取的文本中仅提取了该数字:

soNumber = arrStr(1)

将其增加一:

strCitrix = soNumber + 1

soNumber中的数字(该字段仅包含数字)替换为递增的数字:

NewText = Replace(soNumber, soNumber, strCitrix)

然后只将新数字写回文件中:

objTextFile.Writeline NewText

为了保留原始内容的部分,您需要将它们写回文件中,而不仅仅是修改后的内容。
如果您逐行阅读源文件(当处理大型文件时,这是一个好主意,因为它避免了内存耗尽),则应该在进行操作时将输出写入临时文件中。
Set inFile  = objFSO.OpenTextFile("cloud.csv")
Set outFile = objFSO.OpenTextFile("cloud.csv.tmp", 2, True)

Do while not objTextFile.AtEndOfStream
  line = inFile.ReadLine
  arrStr = Split(line, ",")
  If arrStr(0) = strFirm Then
    soNumber = CInt(arrStr(1))
    outFile.WriteLine arrStr(0) & "," & (soNumber + 1)
  Else
    outFile.WriteLine line
  End If
Loop

inFile.Close
outFile.Close

然后用修改过的文件替换原始文件:

objFSO.DeleteFile "cloud.csv", True
objFSO.MoveFile "cloud.csv.tmp", "cloud.csv"

然而,如果您的输入文件很小,直接读取整个文件、处理它并覆盖原内容会更容易:
text = Split(objFSO.OpenTextFile("cloud.csv").ReadAll, vbNewLine)

For i = 0 To UBound(text)
  If Len(text(i)) > 0 Then
    arrStr = Split(text(i), ",")
    If arrStr(0) = strFirm Then
      soNumber = CInt(arrStr(1))
      text(i) = arrStr(0) & "," & (soNumber + 1)
    End If
  End If
Next

objFSO.OpenTextFile("cloud.csv", 2, True).Write Join(text, vbNewLine)

Len(text(i)) > 0的检查是为了跳过空行(包括文件末尾的换行符),因为空字符串会被分割成空数组,这将导致检查arrStr(0) = strFirm失败,并出现索引越界错误。


1
@AnsgarWiechers +1 针对诊断和逐行处理的方法;Split() on .ReadAll() 策略可以通过至少提到尾随 EOL/空最后数组项的问题来改进。 - Ekkehard.Horner

1

对于短文件,我更喜欢使用.ReadAll()/RegExp策略:

  Dim oFS    : Set oFS   = CreateObject("Scripting.FileSystemObject")
  Dim sFirma : sFirma    = "Gray"
  Dim sFSpec : sFSpec    = "..\data\cloud.csv"
  Dim sAll   : sAll      = oFS.OpenTextFile(sFSpec).ReadAll()
  Dim reCut  : Set reCut = New RegExp
  reCut.Global    = True
  reCut.Multiline = True
  reCut.Pattern   = "^(" & sFirma & ",)(\d+)"
  Dim oMTS   : Set oMTS  = reCut.Execute(sAll)
  If 1 = oMTS.Count Then
     oFS.CreateTextFile(sFSpec).Write reCut.Replace(sAll, "$1" & (CLng(oMTS(0).SubMatches(1)) + 1))
  Else
     ' handle error
  End If
  WScript.Echo oFS.OpenTextFile(sFSpec).ReadAll()

输出:

Client1,5
Client2,7
Client3,12
Gray,7
Client4,9
Client5,17
Client6,8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接