【问题标题】:Importing data from multiple text files into Excel VBA [closed]将多个文本文件中的数据导入 Excel VBA [关闭]
【发布时间】:2016-05-13 22:54:29
【问题描述】:

我可能对 VBA 和 Excel 宏有疑问。我需要做的是从多个文本文件中导入数据(实际上是整数值),这些文本文件具有随机生成的名称(例如 12345678.txt、8654321.txt 等)但存储在同一个文件夹中(让我们调用它数据文件夹)Excel 成一列。

我面临的问题是我在文本文件中一遍又一遍地重复的测量值(称为 MVA)具有相同的名称。我不需要文本文件中的所有数据,只需要这些 MVA 的一些特定行(对于下面的示例,假设我只需要将“LED 01 Intensity”的 MVA 编号(即 6250)存储在新的Excel 中的单元格。我需要从 10 个多个文本文件(我不知道随机名称)中获取 MVA 行中“LED 01 强度”之后的值,并将每个文本文件存储在 Excel 中的单独单元格中(从 A1 到 A10)。

示例_____________________________________________________________________

名称:153588.txt

日期:14.05.2016

产品名称:电子设备01

检查测试

抵抗 101

MVA:2 欧姆

最大:5 欧姆

最小值:0 欧姆

通过

LED 01 强度

MVA:6250

最大:10000

最小:5000

通过


我需要将很多这些 MVA 值存储在 Excel 中以供分析,我需要了解是否可以使用 VBA 解决此问题。如果您能帮我创建一个宏,我将不胜感激(我有编程的基本知识,但我是 VBA 的初学者)。

【问题讨论】:

  • 目录中的文件可以使用 VBA 轻松读取,无论它们的名称是什么 - 使用 filesystemobject 甚至 Dir() 命令。然后有很多不同的方法来解决解析。我可能会将每个文件导入工作表,然后阅读内容以搜索某些文本(LED 01 Intensity),然后选择找到某些文本的值。这都是关于解析的,它可以通过 VBA 和 Excel 工作表结构帮助来实现。只有在看到您如何尝试解决它之后才能给您建议,而且文件结构对于找出如何处理不一致(如果有)很重要。
  • 感谢您的快速回答!有没有可以分享的代码或我可以开始的教程?我是 VBA 新手,可能需要一些帮助来理解解析算法。
  • 请给我一个确切的示例内容,然后我可以在今天晚些时候为您编写示例代码。除非到那时您收到答复,否则开始可能会有所帮助。
  • 好的,正如我在第一个示例中提到的,我需要将“Led 01 Intensity”下的 MVA 值从数百个文本文件中复制到 Excel 中的一个新单元格中。您说您可能会将每个文件导入工作表,然后搜索文本,然后进行解析并将该值复制到新单元格中(您确定此方法适用于数百个文本文件,同时保持井井有条吗?)如果您可以从我到目前为止给您的内容开始,您可以创建代码吗?对于示例内容,假设我们有 5 个文本文件,其结构与我在示例中提到的相同。只是不同的值。

标签: vba excel text


【解决方案1】:

这是我承诺的代码。根据您提供的描述,它实际上不仅是示例代码,而且是您需要的实际代码。

请注意,我是根据您提供的示例文件编写的 - 这意味着它可能因不同的文本文件结构而失败。

您会注意到开头有一个设置部分。这就是您设置需要为代码提供的内容的地方。

考虑到示例文件,它不会对您的系统仅数百个文本文件产生重大影响 - 可能会在几秒钟内工作并完成。但是,在代码执行期间,可能会在代码中禁用屏幕更新。如果您发现系统确实非常缓慢,请参阅 Excel 应用程序对象的 ScreenUpdating 属性。

我希望能给你一个VBA一个好的开始,所以我尝试了很多方法并评论了很多来解释我们在每个步骤中所做的事情。例如,在新创建的工作簿中使用第一个工作表作为结果工作表,但为临时工作表创建一个新工作表。这是有原因的:每个新工作簿都是用至少一个工作表创建的,但根据该计算机中的 Excel 设置,它也可能是唯一的一个工作表。但是,即使是那些部分也可以通过首先获取工作表的数量并删除不必要的工作表并仅保留 2 个然后使用这些而不是创建一个新的来设计不同的部分。

简而言之 - 有许多不同的方法可以完成相同的任务 - 就像在许多其他编程语言中一样。例如,我使用 QueryTable 将数据导入工作表,然后使用 Find 方法找出它是否具有我需要的值。我不必这样做,我可以将所有信息放在字符串变量中并在字符串中进行搜索!或通过使用另一种方法,或另一种。

最后这应该是你所需要的。我希望它能给你一个好的开始。要使此代码工作:创建一个新工作簿 -> 转到 VBA -> 使用菜单和插入 -> 模块 -> 将以下代码复制并粘贴到编辑器中打开的右侧窗格中。在子过程的开头更改设置区域中的必要变量(可能只有路径变量),然后按 F5 运行代码。

Sub ImportData()

Dim wrk As Workbook
Dim shtSource As Worksheet
Dim shtResult As Worksheet
Dim rng As Range
Dim fndSection As Range
Dim fndValue As Range
Dim data As QueryTable

Dim strFile
Dim strPath As String
Dim strExt As String
Dim strSection As String
Dim strValue As String

    ' ======== BEGIN SETTINGS ========
    ' Define the files path - note there is a last backslash
    strPath = "C:\Users\smozgur\Desktop\files\"
    ' Define file extension
    strExt = "*.txt"

    ' Section to be find
    strSection = "Led 01 Intensity"
    ' Cell value to be find after section
    strValue = "MVA:"
    ' ======== END SETTINGS ========


    ' Create a new workbook to not mess with existing
    Set wrk = Application.Workbooks.Add
    With wrk
        ' Use first (or only) worksheet to store results
        Set shtResult = .Worksheets(1)
        ' Create temp worksheet for reading text files
        Set shtSource = .Worksheets.Add
    End With

    ' Name the Results worksheet
    ' and put search value to indicate it in results
    With shtResult
        .Cells(1, 1).Value = strValue
        .name = "Results"
    End With

    ' Make file search with the given path & extension information
    strFile = Dir(strPath & strExt, vbNormal)

    ' Dir function returns the first file name
    ' with the given extension in the given path
    ' if it is empty string then it means "no more file returned"
    Do Until strFile = ""
        ' Create a query table buffer by using the file reference
        ' in the temp worksheet starting from cell A1
        Set data = shtSource.QueryTables.Add(Connection:="TEXT;" & strPath & strFile, Destination:=shtSource.Cells(1, 1))
        ' Set up query table import properties
        With data
            .TextFileStartRow = 1
            .TextFileParseType = xlDelimited
            .TextFileTextQualifier = xlTextQualifierDoubleQuote
            .TextFileConsecutiveDelimiter = False
            .TextFileTabDelimiter = False
            .TextFileSemicolonDelimiter = False
            .TextFileCommaDelimiter = False
            .TextFileSpaceDelimiter = False
            .TextFileColumnDataTypes = Array(1)
            .TextFileTrailingMinusNumbers = True

            ' Finally retrieve data from the file
            .Refresh BackgroundQuery:=False
        End With

        ' Now the file content is in the temp worksheet as rows

        ' Find the section string in the data as Cell
        Set fndSection = data.ResultRange.Find(strSection)
        If Not fndSection Is Nothing Then
            ' If section is found then search for the Value Name AFTER found section
            Set fndValue = data.ResultRange.Find(strValue, fndSection)
            If Not fndValue Is Nothing Then
                ' If Value Name is found then put it into the next available cell in Results worksheet
                ' by removing the Value Name, so it will be the value itself
                shtResult.Cells(shtResult.Rows.Count, 1).End(xlUp).Offset(1).Value = Replace(fndValue, strValue, "")
            End If
        End If
        With data
            ' Clear the query table range
            .ResultRange.Delete
            ' Delete the query table so we can recreate it for the next file
            .Delete
        End With

        ' Search for the next file meets the given path and extension criteria
        strFile = Dir
    Loop

    ' Delete the temporary worksheet
    ' Make it silent disabling Application Alerts about deleting the worksheet
    Application.DisplayAlerts = False
    shtSource.Delete
    ' Enable Application Alerts back
    Application.DisplayAlerts = True

End Sub

享受 VBA 编程!

===================================

* 编辑多个部分 *

以下代码处理源文件中的多个部分。

Sub ImportData()

Dim wrk As Workbook
Dim shtSource As Worksheet
Dim shtResult As Worksheet
Dim rng As Range
Dim fndSection As Range
Dim fndNextSection As Range
Dim fndValue As Range
Dim data As QueryTable

Dim strFile
Dim strPath As String
Dim strExt As String
Dim strSection As String
Dim strSections
Dim strValue As String

Dim i As Integer
Dim indFileNames As Boolean

    ' ======== BEGIN SETTINGS ========
    ' Define the files path - note there is a last backslash
    strPath = "C:\Users\smozgur\Desktop\files\"
    ' Define file extension
    strExt = "*.txt"

    ' Sections to be find
    strSections = Array("Led 01 Intensity", _
                        "Led 02 Intensity", _
                        "Led 03 Intensity", _
                        "Led 04 Intensity", _
                        "Led 05 Intensity")

    ' Cell value to be find after section
    strValue = "MVA:"
    ' Indicate file names in the output?
    indFileNames = True
    ' ======== END SETTINGS ========


    ' Create a new workbook to not mess with existing
    Set wrk = Application.Workbooks.Add
    With wrk
        ' Use first (or only) worksheet to store results
        Set shtResult = .Worksheets(1)
        ' Create temp worksheet for reading text files
        Set shtSource = .Worksheets.Add
    End With

    ' Name the Results worksheet
    ' and put section headers to indicate their columns
    With shtResult
        With .Cells(1).Resize(, UBound(strSections) + 1)
            .Value = strSections
            .Resize(, UBound(strSections) + 1).Font.Bold = True
        End With
        If indFileNames = True Then
            With .Cells(1, UBound(strSections) + 3)
                .Value = "NOTES"
                .Font.Bold = True
            End With
        End If
        .name = "Results"
    End With

    ' Make file search with given information
    strFile = Dir(strPath & strExt, vbNormal)

    ' Dir function returns the first file name
    ' with the given extension in the given path
    ' if it is empty string then it means "no more file returned"
    Do Until strFile = ""
        ' Create a query table buffer by using the file reference
        ' in the temp worksheet starting from cell A1
        Set data = shtSource.QueryTables.Add(Connection:="TEXT;" & strPath & strFile, Destination:=shtSource.Cells(1, 1))
        ' Set up query table import properties
        With data
            .TextFileStartRow = 1
            .TextFileParseType = xlDelimited
            .TextFileTextQualifier = xlTextQualifierDoubleQuote
            .TextFileConsecutiveDelimiter = False
            .TextFileTabDelimiter = False
            .TextFileSemicolonDelimiter = False
            .TextFileCommaDelimiter = False
            .TextFileSpaceDelimiter = False
            .TextFileColumnDataTypes = Array(1)
            .TextFileTrailingMinusNumbers = True

            ' Finally retrieve data from the file
            .Refresh BackgroundQuery:=False
        End With

        ' Now the file content is in the temp worksheet as rows

        ' Loop through requested sections
        For i = 0 To UBound(strSections)
            ' Find the section string in the data as Cell
            Set fndSection = data.ResultRange.Find(strSections(i))
            If Not fndSection Is Nothing Then
                ' If section is found then search for the Value Name AFTER found section
                Set fndValue = data.ResultRange.Find(strValue, fndSection)
                If Not fndValue Is Nothing Then
                    ' What if value doesn't exist in this section but it finds the next value in the next section
                    ' We have to avoid that unless we are certainly sure each section MUST have the value
                    If i < UBound(strSections) Then
                        Set fndNextSection = data.ResultRange.Find(strSections(i + 1), fndSection)
                    Else
                        Set fndNextSection = shtSource.Cells(shtSource.Rows.Count)
                    End If

                    ' Next available cell in the Results worksheet
                    Set rng = shtResult.Cells(shtResult.Rows.Count, i + 1).End(xlUp).Offset(1)

                    ' Only use the value if found value belongs to the section
                    If fndValue.Row < fndNextSection.Row Then
                        ' If Value Name is found then put it into the next available cell in Results worksheet
                        ' by removing the Value Name, so it will be the value itself
                        rng.Value = Replace(fndValue, strValue, "")
                    Else
                        rng.Value = "N/A"
                    End If
                End If
            End If
        Next i

        If indFileNames = True Then
            ' Let's indicate which file we got this values
            Set rng = shtResult.Cells(shtResult.Rows.Count, UBound(strSections) + 3).End(xlUp).Offset(1)
            rng.Value = strFile
        End If

        With data
            ' Clear the query table range
            .ResultRange.Delete
            ' Delete the query table so we can recreate it for the next file
            .Delete
        End With

        ' Search for the next file meets the given path and extension criteria
        strFile = Dir
    Loop

    ' Autofit columns in the Results worksheet
    shtResult.Columns.AutoFit

    ' Delete the temporary worksheet
    ' Make it silent disabling Application Alerts about deleting the worksheet
    Application.DisplayAlerts = False
    shtSource.Delete
    ' Enable Application Alerts back
    Application.DisplayAlerts = True

End Sub

【讨论】:

  • 哇!你太棒了!!非常感谢你的代码和详细的解释(它真的对我作为一个初学者很有帮助)。我今天用你的宏玩了一下,我搜索了值,它完全按照我想要的方式工作,但只适用于单个列。我想问一下,如果我需要一次搜索多个 LED 值,是否可以只定义更多 strSections 和 strValues ?而且我还想问您是否可以将具有 MVA 值的列名定义为我正在搜索的对应文本(led01、02、03 等强度)?再次感谢您的帮助!
  • 不客气。请确认一件事:当您说多个时,您并不是在谈论找到相同的值,即同一文档中的第二个 MVA,对吗?因为它需要更改算法,否则我将向您展示如何在相同代码中使用 VBA 中的数组有效地工作。请告诉我。注意:我忘了说一些重要的事情:请不要运行任何从其他人那里获得的代码,因为 VBA(与任何其他宏或编程语言一样)在右手中可能非常危险。
  • @VenomX 向您发送了上述更新,但忘记添加您的姓名。以防万一您没有收到通知。请告诉我。
  • 我会认真对待这个建议。这可能是一个问题,因为当我说多个时,我的意思是文本文件中有多个 LED,每个 LED 都有对应的 MVA 值。我想通过向你展示这个例子,我会让自己更清楚我想要做什么,我不想让它过于复杂。有没有可能通过稍微改变算法来做到这一点?或者你知道用 VBA 和 Excel 更简单的方法吗?我认为您非常了解我遇到的问题,再次感谢您的帮助。
  • postimg.org/image/81ofz0o5t 看看这个,你可以更好地理解它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多