【问题标题】:Compare Excel spreadsheet values with each line of text file & return output based on the result将 Excel 电子表格值与文本文件的每一行进行比较,并根据结果返回输出
【发布时间】:2026-01-17 10:55:01
【问题描述】:

我需要将电子表格中的值与包含区域传输输出的文本文件进行比较,以根据电子表格中列出的类型获取特定接口的 IP 地址。

  • 我的意见:

    • Excel 电子表格: +------------+------------+ | 姓名 | 整数类型 | +------------+------------+ |开关-1 | | |服务器1 |生产 | |服务器2 |离体 | |开关-2 | | |服务器3 |生产 | |服务器4 |其他 | +------------+------------+
    • 文本文件: server1-prod.fqdn.com 86400 IN A 192.168.0.10 server1-oob.fqdn.com 600 IN A 192.168.0.11 server2-prod.fqdn.com 600 IN A 192.168.0.12 server2-oob.fqdn.com 600 IN A 192.168.0.13 server3-prod.fqdn.com 300 IN A 192.168.0.14 server3-oob.fqdn.com 600 IN A 192.168.0.15 server4-foo.fqdn.com 86400 IN A 192.168.0.16
  • 我想要的输出:

    开关名称:Switch-1 接口名称:server1-prod.fqdn.com - IP 地址:192.168.0.10 接口名称:server2-oob.fqdn.com - IP 地址:192.168.0.11 开关名称:Switch-2 接口名称:server3-prod.fqdn.com - IP 地址:192.168.0.12 server4-foo.fqdn.com 未知接口类型:其他。

我当前的代码:

Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("C:\Server-List-by-Switch.xlsx")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("FQDN-and-IP.txt")

strNextLine = objFile.Readline
arrList = Split(objFile.ReadLIne(),vbCrLf)
intRow = 2

objFile.Close

Do Until objExcel.Cells(intRow,1).Value = ""
    objHostName = objExcel.Cells(intRow,1).Value
    objIntfType = objExcel.Cells(intRow,2).Value

    If InStr(1,objExcel.Cells(intRow,1).Value,"Switch-",1) > 0 Then

        Wscript.Echo vbCrLF & "Switch Name: " & objHostName

    ElseIf InStr(1,objExcel.Cells(intRow, 1).Value,"Switch-",1) = 0 And InStr(1,objExcel.Cells(intRow,2).Value,"Production",1) > 0 then

            For Each line In arrList
                objFQDN = LCase(objHostName & "-prod.fqdn.com.")
                strFQDN = splitRE (strNextLine, "\s+")
                Wscript.Echo strFQDN(0)
                If InStr(Lcase(line),objFQDN) > 0 Then
                    strIPAddress = Right(line, Len(line) - InStrRev(line," ") )
                    Wscript.Echo "Interface name(Production): " & strFQDN & " - IP Address: " & strIPAddress
                End If
            Next

    ElseIf InStr(1,objExcel.Cells(intRow, 1).Value,"Switch-",1) = 0 And InStr(1,objExcel.Cells(intRow,2).Value,"OOB",1) > 0 then

            For Each line In arrList
                objFQDN = LCase(objHostName & "-oob.fqdn.com.")
                strFQDN = splitRE (strNextLine, "\s+")
                Wscript.Echo strFQDN(0)
                If InStr(Lcase(line),objFQDN) > 0 Then
                    strIPAddress = Right(line, Len(line) - InStrRev(line," ") )
                    Wscript.Echo "Interface name(Production): " & strFQDN & " - IP Address: " & strIPAddress
                End If
        Next

    Else 

        Wscript.Echo objHostName & " has an unknown interface type: " & objIntfType

    End If

    intRow = intRow + 1

Loop

Function splitRE(strSource, pattern)
    With CreateObject("vbscript.regexp")
        .Global = True
        .Pattern =pattern
        splitRE = Split(.Replace(strSource, " "), " ")
    End With
End Function 

objExcel.Quit

现在唯一的问题是strFQDN变量只填充了文本文件的第一行,重复,所以比较失败:

server1-prod.fqdn.com.

【问题讨论】:

  • 能否将您的数据示例上传为图片或format like this?我完全不知道你在说什么数据:(
  • 什么比较失败? strFQDN 从来没有与任何东西相比,只是呼应......
  • 我没有尝试过你的代码,但我看到的第一个明显错误是strNextLine = objFile.ReadlinearrList = Split(objFile.ReadLIne(),vbCrLf)。您将第一行读入 strNextLine,然后在主循环中重复使用它。您将第二行读入 arrList。您忽略文本文件的其余部分。试试arrList = Split(objFile.ReadAll(),vbCrLf)
  • 第二个错误:Do Until objExcel.Cells(intRow,1).Value = ""objExcel 是一个 Excel 应用程序。 .Cells(intRow,1).Value 需要一个工作表。

标签: regex excel vbscript text-files


【解决方案1】:

只是一个疯狂的猜测 - 两者都替换

strFQDN = splitRE (strNextLine, "\s+")

strFQDN = splitRE (line, "\s+")


或用其他行更新strNextLine,现在它始终是第一行..

【讨论】:

  • 嗨,deathApril,这只会比较从文本文件中读取的数组结果与从文本文件中读取的数组结果。我需要将电子表格中的主机名与从文本文件中提取的每条记录的第一个数组项进行比较。
  • 我很害怕你的解释,但你这次只更新strNextLine = objFile.Readline,再也不会,所以它总是第一行......
  • 是的,这正是问题所在。如何让它迭代文本文件的所有行,直到找到匹配项?
  • 如果你编辑你的问题来回答我的问题,我也许可以提供更多帮助,现在我不知道你在说什么:(
  • 我想用文本文件中的新行重复更新 strNextLine,直到找到与 objFQDN 中填充的 Excel 电子表格值匹配或到达文件末尾。这些信息够吗?
【解决方案2】:

您的代码很复杂,没有明显的原因。例如,为什么宏打开工作簿“C:\Server-List-by-Switch.xlsx”而不是位于其中?

我不知道Wscript.Echo 做了什么,所以使用 Debug.Print 输出到即时窗口。我不喜欢在每个变量的开头使用三个字符的类型标识符。但如果使用,它们应该是正确的。所以我认为objFile 可以,因为它是一个对象,但objHostName 是错误的,因为它是一个字符串。

我已经简化了您的代码,但保留了结构。这意味着此代码无法创建输出行server4-foo.fqdn.com Unknown interface type: Other.,因为您的代码验证的是 Excel 表格而不是文本文件。代码可以重新排序,但您需要更清楚地了解数据的性质。

我在工作簿中有一个“Server-List-by-Switch”工作表。它包含:

  |   A      |    B      |
1 | Name     | Intf type |
2 | Switch-1 |           |
3 | SERVER1  | Production| 
4 | SERVER2  | OOB       |
5 | Switch-2 |           |
6 | SERVER3  | Production| 
7 | SERVER4  | Other     |

宏的输出是:

Switch Name: Switch-1
Interface name: server1-prod.fqdn.com - IP Address: 192.168.0.10
Interface name: server2-oob.fqdn.com - IP Address: 192.168.0.13
Switch Name: Switch-2
Interface name: server3-prod.fqdn.com - IP Address: 192.168.0.14
SERVER4 has an unknown interface type: Other

在不重新排序代码的情况下尽可能接近。

Option Explicit
Sub GenIPAddressReport()

  Dim arrList() As String
  Dim FQDN As String
  Dim FQDNPart() As String
  Dim HostName As String
  Dim IntfType As String
  Dim intRow As Long
  Dim IPAddress As String
  Dim Line As Variant
  Dim LinePart() As String
  Dim objFile As Object
  Dim objFSO As Object

  Set objFSO = CreateObject("Scripting.FileSystemObject")
  Set objFile = objFSO.OpenTextFile(ActiveWorkbook.Path & "\FQDN-and-IP.txt")

  arrList = Split(objFile.ReadAll(), vbCrLf)

  objFile.Close
  Set objFile = Nothing

  'For Each Line In arrList
  '  Debug.Print Line
  'Next

  intRow = 2
  With Worksheets("Server-List-by-Switch")

  Do Until .Cells(intRow, 1).Value = ""
    HostName = .Cells(intRow, 1).Value
    IntfType = .Cells(intRow, 2).Value
    If InStr(1, HostName, "Switch-") > 0 Then
      Debug.Print "Switch Name: " & HostName
    ElseIf InStr(1, HostName, "Switch-") = 0 And _
           InStr(1, IntfType, "Production") > 0 Then
      For Each Line In arrList
        FQDN = LCase(HostName & "-prod.fqdn.com")
        LinePart = Split(LCase(Line), " ")
        If FQDN = LinePart(0) Then
          Debug.Print "Interface name: " & LinePart(0) & _
                      " - IP Address: " & LinePart(UBound(LinePart))
          Exit For
        End If
      Next
    ElseIf InStr(1, HostName, "Switch-") = 0 And _
           InStr(1, IntfType, "OOB") > 0 Then
      For Each Line In arrList
        FQDN = LCase(HostName & "-oob.fqdn.com")
        LinePart = Split(LCase(Line), " ")
        If FQDN = LinePart(0) Then
          Debug.Print "Interface name: " & LinePart(0) & _
                      " - IP Address: " & LinePart(UBound(LinePart))
          Exit For
        End If
      Next
    Else
       Debug.Print HostName & " has an unknown interface type: " & IntfType
    End If
    intRow = intRow + 1
  Loop

  End With

End Sub

【讨论】:

  • 它标记为 vbscript,而不是 vba,你为什么要谈论宏?并且代码中的一些 cmets 会有所帮助..无论如何,+1 以更接近 OP 的要求;)
  • @deathApril。我通过它的excel 标签提出了这个问题,并没有注意到vbscript 标签。我应该从Echo 命令中猜到它不是vba。我想知道更多的 cmets,但我没有添加任何东西;我认为我的行为更加整洁和正确。
最近更新 更多