Как назначить значение соответствующему заголовку после извлечения данных из файла DAT (текстового файла) с использованием VBA? - PullRequest
1 голос
/ 30 января 2020

У меня есть 2 столбца значений в моем DAT-файле, первый - время, а другой - напряжение вместе с ним. Например, 1 2 3 4 5 (время) и 18 20 22 25 26 (напряжение) соответственно.

Время указано в первом столбце файла DAT, а напряжение отделено запятой рядом с ним. Я хотел бы прикрепить значения напряжения к соответствующим значениям времени (от 18 В до 1 с, от 20 В до 2 с и т. Д. c). Мне уже удалось извлечь время и напряжение, но я не знаю, как подать напряжение на соответствующее время.

Причина, по которой мне нужно это сделать, заключается в том, что существует много файлов DAT, из которых мне нужно извлечь данные, а не каждый из файлов DAT имеет одинаковое время (некоторые из них 1 2 3 5 6 7). Следовательно, мой план состоит в том, чтобы объединить время для всех файлов DAT (эта часть выполнена), а затем приложить их соответствующее напряжение ко времени соответственно их файлу DAT. Ниже приведен пример, иллюстрирующий мою проблему, чтобы сделать вопрос еще яснее.

DAT file(alpha)  
time voltage 
1, 18
2, 20
3, 22
4, 25
5, 26

DAT file(beta)
time voltage 
1, 180
2, 201
5, 222
6, 253
7, 265

DAT file(charlie)
time voltage 
1, 11
2, 23
6, 28
9, 22
10, 6

To be printed on excel - 
time alpha beta charlie
1     18    180   11
2     20    201   23
3     22    0     0
4     25    0     0
5     26    222   0
6     0     253   28
7     0     265   0
9     0     0     22
10    0     0     6

Спасибо!

Ответы [ 3 ]

0 голосов
/ 31 января 2020

Здесь в качестве образца:

Sub test()
    Dim a As Integer
    Dim Pos As Long
    Dim RowBegin As Long
    Dim myRange As Range
    For a = 1 To 3
        Pos = 2
        RowBegin = 2
        Do While True
           If a = 1 Then CelCol = "A"
           If a = 2 Then CelCol = "C"
           If a = 3 Then CelCol = "E"
           RsltCol = "H"
           If IsEmpty(Range("Sheet1!" & CelCol & Pos).Value) = True Then Exit Do
           Set myRange = Range("Sheet1!" & RsltCol & Range("Sheet1!" & CelCol & Pos).Value + RowBegin - 1)
           myRange.Offset(0, 0).Value = Range("Sheet1!" & CelCol & Pos).Value
           If IsEmpty(myRange.Offset(0, 1).Value) Then myRange.Offset(0, 1).Value = 0
           If IsEmpty(myRange.Offset(0, 2).Value) Then myRange.Offset(0, 2).Value = 0
           If IsEmpty(myRange.Offset(0, 3).Value) Then myRange.Offset(0, 3).Value = 0
           myRange.Offset(0, a).Value = Range("Sheet1!" & CelCol & Pos).Offset(0, 1).Value
           Pos = Pos + 1
        Loop
    Next
End Sub

Источник и результат в sheet1 в виде изображения:

enter image description here

0 голосов
/ 31 января 2020

Это реализация моего предложения. Пожалуйста, попробуйте это. Ключевым является то, что данные записываются на выходной лист, оставляя оригинал без изменений. Вы можете заменить входные листы и добавить их в существующий выходной лист. Однако полученный новый выходной лист не будет иметь отсортированных строк и столбцов, поскольку сортировка выполняется до создания исходного выходного листа. Пожалуйста, попробуйте мой код и посмотрите, как вам это понравится.

Option Explicit

Enum Nws                            ' Worksheet navigation
    NwsCapRow = 1
    NwsFirstDataRow                 ' no value assigned means previous + 1
    NwsBatch = 1                    ' 1 = column A
    NwsTime
    NwsVolt
    NwsTTime = 1                    ' Output sheet:
    Nws1stBatch = 5                 ' could be any column on the right
End Enum

Sub SortToColumns()
    ' Variatus @STO 31 Jan 2020

    Dim WsS As Worksheet            ' Source (input)
    Dim WsT As Worksheet            ' Target (output)
    Dim Rng As Range
    Dim Fnd As Range
    Dim Tmp As Variant
    Dim Rls As Long                 ' WsS.last row
    Dim Rs As Long, Rt As Long      ' Source / Target row
    Dim Cs As Long, Ct As Long      ' Source / Target column

    ' This worksheet has your DAT files, in Excel format, appended
    ' below each other (no headers, no blank rows)
    ' A column A was inserted in which a unique identifier
    ' for each DAT file is written.
    ' (all entries from one file have the same identifier)
    Set WsS = ThisWorkbook.Worksheets("Input")          ' change the Ws name to suit

    With ThisWorkbook.Worksheets
        On Error Resume Next
        Set WsT = .Item("Output")                       ' change to suit
        If Err Then
            Set WsT = .Add(After:=.Item(.Count))
            With WsT
                .Name = "Output"                        ' change to suit
                ' add captions & formatting here
            End With
        End If
    End With

    On Error GoTo 0
    With WsS
        Rls = .Cells(.Rows.Count, NwsBatch).End(xlUp).Row
        Cs = .UsedRange.Columns.Count
        Set Rng = .Range(.Cells(NwsFirstDataRow, NwsBatch), .Cells(Rls, Cs))
        With .Sort.SortFields
            .Clear
            .Add Key:=Rng.Columns(NwsTime), SortOn:=xlSortOnValues, _
                 Order:=xlAscending, DataOption:=xlSortNormal
            .Add Key:=Rng.Columns(NwsBatch), SortOn:=xlSortOnValues, _
                 Order:=xlAscending, DataOption:=xlSortNormal
        End With
        With .Sort
            .SetRange Rng
            .Header = xlGuess
            .MatchCase = False              ' change to suit
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
    End With

    With WsT
        For Rs = NwsFirstDataRow To Rls
            Ct = Application.Max(.Cells(NwsCapRow, .Columns.Count).End(xlToLeft).Column, Nws1stBatch)
            Set Rng = .Range(.Cells(NwsCapRow, Nws1stBatch), .Cells(NwsCapRow, Ct))
            Tmp = WsS.Cells(Rs, NwsBatch).Value
            Set Fnd = Rng.Find(Tmp, Rng.Cells(Rng.Cells.Count), xlValues, xlWhole, xlByColumns, xlNext)
            If Fnd Is Nothing Then
                Ct = Rng.Column + IIf(Rng.Cells(1).Value = "", Rng.Cells.Count, 0)
                .Cells(NwsCapRow, Ct).Value = Tmp
            Else
                Ct = Fnd.Column
            End If

            Rt = Application.Max(.Cells(.Rows.Count, NwsTTime).End(xlUp).Row + 1, 2)
            Set Rng = .Range(.Cells(NwsFirstDataRow, NwsTTime), .Cells(Rt, NwsTTime))
            Tmp = WsS.Cells(Rs, NwsTime).Value
            Set Fnd = Rng.Find(Tmp, Rng.Cells(Rng.Cells.Count), xlValues, xlWhole, xlByRows, xlNext)
            If Not Fnd Is Nothing Then Rt = Fnd.Row
            .Cells(Rt, NwsTTime).Value = WsS.Cells(Rs, NwsTime).Value
            .Cells(Rt, Ct).Value = WsS.Cells(Rs, NwsVolt).Value
        Next Rs
    End With
End Sub
0 голосов
/ 31 января 2020

Хорошо, возможно, позвольте мне попробовать другой подход - задать вопрос - извлечение и очистка данных не проблема, поэтому я могу получить следующее в Excel, как показано ниже (используя тот же пример).

1  18  1 180  1 11
2  20  2 201  2 23
3  22  5 222  6 28  
4  25  6 253  9 22
5  26  7 265  10 6   
     

так что теперь мне нужен код для сортировки этих данных, чтобы я мог получить это -

1     18    180   11
2     20    201   23
3     22    0     0
4     25    0     0
5     26    222   0
6     0     253   28
7     0     265   0
9     0     0     22
10    0     0     6

надеюсь, что это станет понятнее и еще раз спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...