有没有一种方法可以使用VBA从ASC文档中导入数据并根据上次修改日期修改时间数据?

时间:2019-08-13 07:14:09

标签: excel vba

我正在寻找VBA代码以将数据从多个ASC文件导入到Excel工作表中。数据包含以秒为单位的时间(第一列)和下一列中的值(因此只有前两列很重要)。

这是文件的外观:

0.550000  -674.465088  0.000000  0.000000  3.620000  60.700005  
1.550000  -674.288147  0.000000  0.000000  3.620000  60.700005  
2.550000  -673.940491  0.000000  0.000000  3.620000  60.700005  
3.550000  -673.702515  0.000000  0.000000  3.620000  60.700005  
4.550000  -673.909851  0.000000  0.000000  3.610000  60.700005  
5.550000  -674.111267  0.000000  0.000000  3.610000  60.700005  
6.550000  -674.038147  0.000000  0.000000  3.610000  60.700005  
7.550000  -674.214966  0.000000  0.000000  3.610000  60.700005  
8.550000  -674.227173  0.000000  0.000000  3.610000  60.700005  
9.550000  -674.001587  0.000000  0.000000  3.630000  60.700005  

0.550000  -621.436279  0.000000  0.000000  3.790000  61.000000  
1.550000  -621.064148  0.000000  0.000000  3.700000  61.000000  
2.550000  -621.424133  0.000000  0.000000  3.700000  61.000000  
3.550000  -621.094666  0.000000  0.000000  3.700000  61.000000  
4.550000  -621.088562  0.000000  0.000000  3.700000  61.000000  
5.550000  -621.204468  0.000000  0.000000  3.700000  61.000000  
6.550000  -621.747437  0.000000  0.000000  3.660000  61.000000  
7.550000  -621.479004  0.000000  0.000000  3.660000  61.000000  
8.550000  -621.387512  0.000000  0.000000  3.660000  61.000000  
9.550000  -620.777161  0.000000  0.000000  3.660000  61.000000  

0.550000  -613.312195  0.000000  0.000000  3.730000  60.900002  
1.550000  -613.232910  0.000000  0.000000  3.730000  60.900002  
2.550000  -613.208435  0.000000  0.000000  3.730000  60.900002  
3.550000  -613.238953  0.000000  0.000000  3.790000  60.900002  
4.550000  -613.293945  0.000000  0.000000  3.790000  60.900002  
5.550000  -613.428101  0.000000  0.000000  3.790000  60.900002  
6.550000  -613.507385  0.000000  0.000000  3.790000  60.900002  
7.550000  -613.324402  0.000000  0.000000  3.790000  60.900002  
8.550000  -613.550110  0.000000  0.000000  3.910000  60.900002  
9.550000  -613.306152  0.000000  0.000000  3.910000  60.900002  

这些是3个文件的开头。 我面临的问题是,对于每个文件,时间都是从开头(0,55)开始的,但是文件所基于的度量标准是持续进行的,并且时间旁的值也是如此-在那里每次测量后都休息了几分钟。因此,我们的想法是导入所有文件的数据,并以第一个文件的DateCreated作为起点,然后通过假设下一个测量从其DateCreated开始来继续时间值。

我的VBA知识真的很基础(包含大约一周的阅读和观看youtube教程的时间)。我尝试了不同的方法,目前有一个代码可以从每个文件导入数据,并在我告诉它开始的excel工作表的单元格中启动它。我已经使用记录器编写了此代码,但是我可以想象有一些方法可以使我以更简单的方式来完成它。

我有一个工作表“数据库”,将数据导入其中;还有一个工作表,称为“ admin”,在其中写入路径,工作表名称(将数据导入到其中)和行(导入的行)中每个文件的数据应从以下位置开始。

我还没有找到导入文件的每个DateCreated的方法来使用它们创建持续时间。我在这里发现的另一个问题是DateCreated只能以hhmmss显示,并且要进行计算,我必须调整导入数据的时间列(仅以秒为单位)以使其生效与DateCreated数据相​​当。

Sub ImportAllFiles()
For rep = 4 To 11

    Dim file_name As String
    Dim row_number As String
    Dim output_sheet As String

    file_name = Sheets("Admin").Range("B" & rep).Value
    output_sheet = Sheets("Admin").Range("C" & rep).Value
    row_number = Sheets("Admin").Range("D" & rep).Value


With Sheets(output_sheet).QueryTables.Add(Connection:="TEXT;" + file_name, Destination:=Sheets(output_sheet).Range("$A$" + row_number))

    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .TextFilePromptOnRefresh = False
    .TextFilePlatform = 850
    .TextFileStartRow = 1
    .TextFileParseType = xlDelimited
    .TextFileTextQualifier = xlTextQualifierDoubleQuote
    .TextFileConsecutiveDelimiter = True
    .TextFileTabDelimiter = False
    .TextFileSemicolonDelimiter = False
    .TextFileCommaDelimiter = False
    .TextFileSpaceDelimiter = True

    .TextFileTrailingMinusNumbers = True
    .Refresh BackgroundQuery:=False
End With

Next rep

MsgBox "Done"

End Sub

对我来说,理想的结果是将包含我所有文件的文件夹的路径放在一个单元格中,并导入该文件夹中我所有文件的数据。 而不是总是从0.55开始,它应该是从第一个文件(测量开始)到最后一个文件结束的持续时间。

1 个答案:

答案 0 :(得分:0)

我理解的目标可以通过多种方式实现。但是由于我有一些偏见(可能是没有道理的),可以直接处理文本文件而不在excel中打开它们,而只使用所需的数据来填充excel单元格,因此我将按照以下方式进行操作

  1. 通过“文件对话框”选择文本文件(有时所有文件都会出现问题)
  2. 按创建日期排序文件
  3. 使用FSO作为文本流打开文件
  4. 通过将经过的时间(文本文件的第1列)与文件创建日期时间相加来计算绝对日期时间,从而处理每一行。
  5. 仅将必需的数据写入Excel单元格。

请添加对“ Microsoft脚本运行时”的引用(VBA项目窗口-工具-参考并添加) 可以修改实际工作表名称,文件夹名称,行和列详细信息等的代码。

Option Explicit
Sub test()
Dim Fso As FileSystemObject, fl As File, Txtfl As TextStream
Dim path As String, Rw As Long, StRow As Long
Dim FNames() As Variant, Arr As Variant
Dim i As Long, j As Long, temp1 As Variant, temp2 As Variant
Dim line As String, tm As Date, ldate As Date
Dim Fdate As Date, Fname As String, Ws As Worksheet
Dim Outputsheet As String
Outputsheet = "Sheet1"
Set Fso = CreateObject("Scripting.FileSystemobject")
path = "C:\users\user\Desktop\Folder1"
Set Ws = ThisWorkbook.Sheets(Outputsheet)
StRow = 2

    With Application.FileDialog(msoFileDialogFilePicker)
    .InitialFileName = path
    .AllowMultiSelect = True
    .Filters.Clear
    .Filters.Add "Text Files", "*.Txt;*.Csv", 1
     If .Show <> -1 Then Exit Sub
     ReDim FNames(1 To 2, 1 To .SelectedItems.Count) As Variant

        For i = 1 To .SelectedItems.Count
        FNames(1, i) = .SelectedItems(i)
        Set fl = Fso.GetFile(FNames(1, i))
        FNames(2, i) = fl.DateCreated
       ' Debug.Print FNames(1, i) & " - " & Format(FNames(2, i), "dd-mmm-yyyy HH:Mm:ss")
        Next
    End With

    'Bubble Sort files list in order of date cteated
     For i = 1 To UBound(FNames, 2)
     temp1 = FNames(1, i)
     temp2 = FNames(2, i)
        For j = i + 1 To UBound(FNames, 2)
        If FNames(2, j) < temp2 Then
        FNames(1, i) = FNames(1, j)
        FNames(2, i) = FNames(2, j)
        FNames(1, j) = temp1
        FNames(2, j) = temp2
        End If
        Next j
     Next i

    ldate = 0
    Rw = StRow
    For i = 1 To UBound(FNames, 2)
    Fname = FNames(1, i)
    Fdate = CDate(FNames(2, i))
    'Open each file in order of creation date
    Set Txtfl = Fso.OpenTextFile(FNames(1, i), ForReading)
        While Not Txtfl.AtEndOfStream ' while we are not finished reading through the file
        line = Txtfl.ReadLine
            ' Convert multiple spaces to single space
            Do While InStr(1, line, "  ") > 0
            line = Replace(line, "  ", " ")
            Loop

        Arr = Split(line, " ")
            'if line have significant data
            If UBound(Arr) >= 0 Then
            'calculate Time by adding second value at column 1 with file creation datetime
            tm = DateAdd("s", CDbl(Arr(0)), Fdate)
            Debug.Print tm, Arr(0)
                'Import data only if its time > than last imported data
                If DateDiff("s", tm, ldate) < 0 Then
                ldate = tm
                'write date to excel cells (modify to your requirement)
                Ws.Cells(Rw, 1).Value = tm
                Ws.Cells(Rw, 2).Value = Arr(0)
                Ws.Cells(Rw, 3).Value = Arr(1)
                'Ws.Cells(Rw, 4).Value = Arr(2)
                '
                '
                Ws.Cells(Rw, 7).Value = Fname
                Ws.Cells(Rw, 8).Value = Fdate
                Rw = Rw + 1
                End If
            End If
        Wend
    Txtfl.Close
    Next i

Set Fso = Nothing
End Sub

Excel工作表中的结果将类似于this(经过示例数据测试)

不过,最简单的方法可能是使用常规文本处理功能以excel格式导入文本文件,然后最终对时间字段(列)中的数据进行过滤和排序,该时间字段是通过将文件创建时间与第一列数据(即经过的秒数)相加而得出的。也许有人在这方面也应该提供其他答案。我只分享了我喜欢的处理相似数据的方法。

编辑:修改了代码的最后部分以获得更正的时间。添加的功能中包含德语设置代码。

Option Explicit
Sub test2()
Dim Fso As FileSystemObject, fl As File, Txtfl As TextStream
Dim path As String, Rw As Long, StRow As Long
Dim FNames() As Variant, Arr As Variant
Dim i As Long, j As Long, temp1 As Variant, temp2 As Variant
Dim Line As String, tm As Date, ldate As Date
Dim Fdate As Date, Fname As String, Ws As Worksheet
Dim Outputsheet As String
Outputsheet = "Sheet1"
Set Fso = CreateObject("Scripting.FileSystemobject")
path = "C:\users\user\Desktop\Folder1"
Set Ws = ThisWorkbook.Sheets(Outputsheet)
StRow = 2

    With Application.FileDialog(msoFileDialogFilePicker)
    .InitialFileName = path
    .AllowMultiSelect = True
    .Filters.Clear
    .Filters.Add "Text Files", "*.Txt;*.Csv", 1
     If .Show <> -1 Then Exit Sub
     ReDim FNames(1 To 2, 1 To .SelectedItems.Count) As Variant

        For i = 1 To .SelectedItems.Count
        FNames(1, i) = .SelectedItems(i)
        Set fl = Fso.GetFile(FNames(1, i))
        FNames(2, i) = fl.DateCreated
       ' Debug.Print FNames(1, i) & " - " & Format(FNames(2, i), "dd-mmm-yyyy HH:Mm:ss")
        Next
    End With

    'Bubble Sort files list in order of date cteated
     For i = 1 To UBound(FNames, 2)
     temp1 = FNames(1, i)
     temp2 = FNames(2, i)
        For j = i + 1 To UBound(FNames, 2)
        If FNames(2, j) < temp2 Then
        FNames(1, i) = FNames(1, j)
        FNames(2, i) = FNames(2, j)
        FNames(1, j) = temp1
        FNames(2, j) = temp2
        End If
        Next j
     Next i


    Dim Fulltxt As String, LineArr As Variant, TimeOffset As Double
    ldate = 0
    Rw = StRow
    For i = 1 To UBound(FNames, 2)
    Fname = FNames(1, i)
    Fdate = CDate(FNames(2, i))
    'Open each file in order of creation date
    Set Txtfl = Fso.OpenTextFile(FNames(1, i), ForReading)
    Fulltxt = Txtfl.ReadAll
    Txtfl.Close
    LineArr = Split(Fulltxt, vbCrLf)
    TimeOffset = 0

        ' Look for last significant line from last line
        For j = UBound(LineArr) To 0 Step -1
            If Trim(LineArr(j)) <> "" Then
            Line = ClearDoubleSpace(CStr(LineArr(j)))
            TimeOffset = Split(Line, " ")(0)
            Exit For
            End If
        Next

        For j = 0 To UBound(LineArr)
        Line = ClearDoubleSpace(CStr(LineArr(j)))
        If Trim(Line) <> "" Then  'not a blank line
        Arr = Split(Line, " ")
            If UBound(Arr) >= 0 Then  'if line have significant data
            'calculate Time by adding second value at column 1 with file creation datetime
            tm = DateAdd("s", CDbl(Arr(0)) - TimeOffset, Fdate)
            Debug.Print tm, Arr(0), Fdate
                'Import data only if its time > than last imported data
                If DateDiff("s", tm, ldate) < 0 Then
                ldate = tm
                'write date to excel cells (modify to your requirement)
                Ws.Cells(Rw, 1).Value = tm
                Ws.Cells(Rw, 2).Value = Arr(0)
                Ws.Cells(Rw, 3).Value = Arr(1)
                'Ws.Cells(Rw, 4).Value = Arr(2)
                '
                '
                Ws.Cells(Rw, 7).Value = Fname
                Ws.Cells(Rw, 8).Value = Fdate
                Rw = Rw + 1
                End If
            End If
        End If
        Next j

    Next i

Set Fso = Nothing
End Sub
Private Function ClearDoubleSpace(Line As String) As String
 Line = Trim(Line)
 ' Convert multiple spaces to single space
 Do While InStr(1, Line, "  ") > 0
 Line = Replace(Line, "  ", " ")
 Loop
 'Replace decimal Separator with Geramn
 If Application.DecimalSeparator = "," Then Line = Replace(Line, ".", ",") ' , 1, 1)
 ClearDoubleSpace = Line
End Function
相关问题