3

我有一个大型 Excel 表(591 列,2645 行),其基本格式如下所示:

| Time | Data 1 | Data 2 | Data 3 | Data 4 | Data 5 | Data 6 | Data 7 |
|======+========+========+========+========+========+========+========|
| 0.01 |  0.35  |        |        |        |        | 0.1351 | 0.2398 | 
| 0.02 |        |  0.42  |        |        |        | 0.4314 | 0.4342 | 
| 0.03 |        |        |  0.99  |        |        | 0.3414 | 0.4321 |
| 0.04 |        |        |        |  0.12  |        | 0.4351 | 0.4256 |
| 0.05 |        |        |        |        |  0.66  | 0.7894 | 0.9874 |

这基本上是数据流的记录,其中某些字段在每个时间步仅采样一次,而其他字段在每个单独的时间步上采样。然后,一旦循环完成,就会记录完整的“记录”(即,再次写入“数据 1”)。

出于数据处理和分析的目的,最终的数据记录如下所示:

| Time | Data 1 | Data 2 | Data 3 | Data 4 | Data 5 | Data 6 | Data 7 |
|======+========+========+========+========+========+========+========|
| 0.05 |  0.35  |  0.42  |  0.99  |  0.12  |  0.66  | 0.7894 | 0.9874 | 

请注意,时间戳等于在表中找到的时间戳,重复数据字段等于当时的数据值,周期性数据字段等于每个字段的最后报告值。

然后,单个循环的记录基本上将包括在给定时间范围内为任何字段记录的最终值。我可以轻松完成这一步,但每个数据集有 2600 多行数据要处理,还有六个数据集要处理。

是否有一种干净/简单/实用的方法可以在整个数据文件中执行此操作?我可以通过多种方式强制执行此操作,但我希望不必重新发明轮子。如果我可以将输出写入新工作表,那就太好了。

4

4 回答 4

2

欢迎来到 SO。

我有一个基于长度为 5 的循环的小解决方案。它使用该indirect功能,您应该能够根据需要对其进行扩展。

首先,我在您的示例中添加了一些行,以达到 0.15 的时间。这占用了 a1 到 h16。然后我将 i17 添加到 j19,以告知要检查哪些行。我做了这些:

 2  6
 7 11
12 16

这意味着 i17 和 j17 代表第 2 到第 6 行(或数据中的第 1 行)。我建议你让 j17 = i17+4 和 j18=i17+1。

好的,间接函数来了。在 a17,=INDIRECT("A"&$J17)中,这意味着,给我 col A,第 2 行(因为单元格 i17 中有一个 2。该$方法使用绝对列,并继续在公式中使用 I)。

在 b17 中=SUM(INDIRECT("b"&$I17&":b"&"$"&$J17)),表示 b2 到 b6 的总和。

在 c17 中,=SUM(INDIRECT("c"&$I17&":c"&"$"&$J17)).

对 d17、e17 和 f17 重复该模式。

在 g17 中,您只想将 g6 中的内容复制到=INDIRECT("g"&$J17).

在 h17 中,您将 h6 中的内容复制到=INDIRECT("h"&$J17).

然后,您可以将 a17:h17 中的公式向下复制三行。

于 2012-04-19T20:45:03.800 回答
2

像这样的东西可能对你有用

Sub tester()
    SummarizeRows ThisWorkbook.Sheets("Sheet1").Range("A1"), _
                  ThisWorkbook.Sheets("Sheet2").Range("A1")
End Sub


Sub SummarizeRows(rngIn As Range, rngOut As Range)

Const MASTER_COL As Long = 2 'summarize when new value here (except first row)

Dim vals(), data
Dim numRows As Long, numCols As Long
Dim r As Long, c As Long, r_out As Long
Dim c2 As Long, v

    r_out = 1
    'get all the input data
    data = rngIn.CurrentRegion.Value
    numRows = UBound(data, 1)
    numCols = UBound(data, 2)
    ReDim vals(1 To numCols)

    For r = 2 To numRows
        For c = 1 To numCols
            v = data(r, c)
            If Len(v) > 0 Then
                If c = MASTER_COL And r > 2 Then
                    'new value in "master" column...
                    r_out = r_out + 1
                    For c2 = 1 To numCols
                        data(r_out, c2) = vals(c2)
                        vals(c2) = ""
                    Next c2
                End If
                vals(c) = v
            End If
        Next
    Next r

    'write any last values
    r_out = r_out + 1
    For c2 = 1 To numCols
        data(r_out, c2) = vals(c2)
    Next c2

    rngOut.Resize(r_out, numCols).Value = data

End Sub
于 2012-04-19T20:49:27.163 回答
1

这是我最终使用的解决方案...

首先,我创建了第二张表(表 2),复制了标题行,并将第一行中的每条记录设置为等于第一张表(表 1)第一行中的第一条记录。如果工作表 1 中的第一行有一个空值,我将其替换为零。例如:

=IF(Sheet1!A2="",0,Sheet1!A2)

然后我使用公式有条件地将值从工作表 1 复制到工作表 2,或者使用工作表 2 中当前单元格上方的值。例如,在 B3 中(第二条记录,第一个字段):

=IF(Sheet1!B3="",B2,Sheet1!B3)

然后,我将其复制到工作表 2 中具有工作表 1 中可用源值的每个单元格。结果如下所示:

| Time | Data 1 | Data 2 | Data 3 | Data 4 | Data 5 | Data 6 | Data 7 |
|======+========+========+========+========+========+========+========|
| 0.01 |  0.35  |  0     |  0     |  0     |  0     | 0.1351 | 0.2398 | 
| 0.02 |  0.35  |  0.42  |  0     |  0     |  0     | 0.4314 | 0.4342 | 
| 0.03 |  0.35  |  0.42  |  0.99  |  0     |  0     | 0.3414 | 0.4321 |
| 0.04 |  0.35  |  0.42  |  0.99  |  0.12  |  0     | 0.4351 | 0.4256 |
| 0.05 |  0.35  |  0.42  |  0.99  |  0.12  |  0.66  | 0.7894 | 0.9874 |

由此,我能够生成相关的图表来有效地分析数据。

于 2012-10-10T21:16:48.117 回答
0

将其粘贴到数据下方行的单元格中。A 是您要粘贴到的列

=LOOKUP(2,1/(A1:A5<>""),A:A)
于 2012-04-19T19:28:29.423 回答