首页 > 解决方案 > 有没有办法在不使用 REGEX 的情况下从 VBA 中查找和替换 .txt 或 .xml 文件?

问题描述

我有一个 excel 文件,它从外部 .exe 文件运行模型,并收集其输出以存储在各种工作表上以进行数据分析。

.exe 文件以可访问的基于文本的格式保存其输入文件。我意识到我可以通过直接从 vba 编辑输入文件并在循环中运行来创建批处理运行,但是它需要在 VBA 的 .txt 或 .xml 文件中查找和替换。我需要使用通配符作为我想要查找的字符串的一部分,每次都会更改,并且在第一次迭代时是不可预测的。例如:

我想在基于文本的文件中找到以下文本:

"0.3843 Flow_Rate_Mass kg/s"

并在重新运行我的脚本之前替换数字,以使用这个新的输入文件解决 .exe 以获得新的流速。但是,数字 0.3843 在第一个实例中可以是任何值(格式为"x.xxxx Flow_Rate_Mass kg/s"),因此我需要使用通配符来查找和替换。

在第一次迭代之后,我将在前一次迭代中设置此值,因此我可以使用已知字符串的查找和替换,而无需通配符。

所以以下应该可以工作,但在第一次迭代时不够灵活:

Dim sBuf As String
Dim sTemp As String
Dim iFileNum As Integer
Dim sFileName As String

sFileName = "C:\filelocation"

iFileNum = FreeFile
Open sFileName For Input As iFileNum

Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTemp = sTemp & sBuf & vbCrLf
Loop
Close iFileNum

sTemp = Replace(sTemp, "0.3843 Flow_Rate_Mass kg/s", "0.5000 Flow_Rate_Mass kg/s")

iFileNum = FreeFile
Open sFileName For Output As iFileNum

Print #iFileNum, sTemp

Close iFileNum

没有 REGEX 有什么解决方法吗?

标签: regexexcelvba

解决方案


一个示例正则表达式替换可能是

Option Explicit

Public Sub test()
    Dim i As Long, tests()

    tests = Array("some text here 0.3843 Flow_Rate_Mass kg/s other text", "some text here 0.5000 Flow_Rate_Mass kg/s other text")
    For i = LBound(tests) To UBound(tests)
        Debug.Print ReplaceMatch(tests(i))
    Next
End Sub

Public Function ReplaceMatch(ByVal inputString As String) As String
    Dim re As Object
    Set re = CreateObject("VBScript.RegExp")
    With re
        .Global = True
        .MultiLine = True
        .pattern = "\b[\.0-9]+( Flow_Rate_Mass kg\/s)"

        If .test(inputString) Then
            ReplaceMatch = .Replace(inputString, "$1")
        Else
            ReplaceMatch = inputString
        End If
    End With
End Function

正则表达式解释:

在此处输入图像描述


Instr假设该流量值的长度固定的示例。请注意,字符串函数确实具有可以使用的最大长度

Option Explicit

Public Sub test()
    Dim i As Long, tests()

    tests = Array("some text here 0.3843 Flow_Rate_Mass kg/s other text", "some text here 0.5000 Flow_Rate_Mass kg/s other text")
    For i = LBound(tests) To UBound(tests)
        Debug.Print ReplaceMatch(tests(i))
    Next
End Sub

Public Function ReplaceMatch(ByVal inputString As String) As String
    Dim pos As Long, fixedLength As Long, length As Long, leftPosition As Long, rightPosition As Long
    fixedLength = 6
    pos = InStr(inputString, " Flow_Rate_Mass kg/s")
    If pos > 0 Then
        length = Len(inputString)
        leftPosition = pos - fixedLength - 1
        rightPosition = length - pos
        ReplaceMatch = Left$(inputString, leftPosition) & Right$(inputString, rightPosition)
    Else
        ReplaceMatch = inputString
    End If
End Function

请注意,有更快的方法使用命令行/powershell 以及现有工具来执行此操作:

示例1 , 2


推荐阅读