使用 VBA (Excel) 规范化数据的快速方法
Fast Way to Normalize Data with VBA (Excel)
我目前正在尝试使用 Excel 中的 VBA 规范化数据。所以,我的工作簿导入了几个csv文件,写在不同的工作表中,都是这样构建的。
- 第一行:页眉
- 第一列:x 轴(用于绘图)
- 第二列到第 n 列:y 值
现在我想将所有列从 2 标准化为 n(除以每列的最大值)。这是我目前使用的功能:
Sub NormalizeData(dataName)
cs = Worksheets(dataName).UsedRange.SpecialCells(xlCellTypeLastCell).Column
rs = Worksheets(dataName).UsedRange.SpecialCells(xlCellTypeLastCell).Row
For col = 2 To cs
maxValue = Application.WorksheetFunction.Max(Worksheets(dataName).Columns(col))
For r = 2 To rs
Worksheets(dataName).Cells(r, col) = Worksheets(dataName).Cells(r, col) / maxValue
Next r
Next col
End Sub
这种方法可行,但由于数据量大,速度很慢。有什么办法可以提高速度吗?我已经关闭了屏幕更新。
非常感谢您的帮助!!!
使用另一个 sheet 和 PasteSpecial。
假设 ws1 包含您的数据而 ws2 当前未使用:
with ws2.Range(.Cells(2,2), .Cells(rs, cs))
.value = maxValue
.copy
end with
ws1.Range(.Cells(2,2), .Cells(rs, cs)).PasteSpecial _
Operation:=xlPasteSpecialOperationDivide
Application.CutCopyMode = False
这是一个将矩形范围内的数字归一化的子程序。您可以决定要标准化的范围,然后将该范围传递给此子:
Sub NormalizeRange(R As Range)
'assumes that R is a rectangular range
'will throw an error if any column has max 0
Dim vals As Variant, maxes As Variant
Dim i As Long, j As Long, m As Long, n As Long
m = R.Rows.Count
n = R.Columns.Count
ReDim maxes(1 To n)
With Application.WorksheetFunction
For i = 1 To n
maxes(i) = .Max(R.Columns(i))
Next i
End With
vals = R.Value
For i = 1 To m
For j = 1 To n
vals(i, j) = vals(i, j) / maxes(j)
Next j
Next i
R.Value = vals
End Sub
这将比您目前拥有的更有效,因为它以批量传输的方式在电子表格和 VBA 之间移动值,而不是通过大量单独的 read/writes。它还避免了屏幕更新问题和根据这些值重新计算函数等问题。
我目前正在尝试使用 Excel 中的 VBA 规范化数据。所以,我的工作簿导入了几个csv文件,写在不同的工作表中,都是这样构建的。
- 第一行:页眉
- 第一列:x 轴(用于绘图)
- 第二列到第 n 列:y 值
现在我想将所有列从 2 标准化为 n(除以每列的最大值)。这是我目前使用的功能:
Sub NormalizeData(dataName)
cs = Worksheets(dataName).UsedRange.SpecialCells(xlCellTypeLastCell).Column
rs = Worksheets(dataName).UsedRange.SpecialCells(xlCellTypeLastCell).Row
For col = 2 To cs
maxValue = Application.WorksheetFunction.Max(Worksheets(dataName).Columns(col))
For r = 2 To rs
Worksheets(dataName).Cells(r, col) = Worksheets(dataName).Cells(r, col) / maxValue
Next r
Next col
End Sub
这种方法可行,但由于数据量大,速度很慢。有什么办法可以提高速度吗?我已经关闭了屏幕更新。
非常感谢您的帮助!!!
使用另一个 sheet 和 PasteSpecial。 假设 ws1 包含您的数据而 ws2 当前未使用:
with ws2.Range(.Cells(2,2), .Cells(rs, cs))
.value = maxValue
.copy
end with
ws1.Range(.Cells(2,2), .Cells(rs, cs)).PasteSpecial _
Operation:=xlPasteSpecialOperationDivide
Application.CutCopyMode = False
这是一个将矩形范围内的数字归一化的子程序。您可以决定要标准化的范围,然后将该范围传递给此子:
Sub NormalizeRange(R As Range)
'assumes that R is a rectangular range
'will throw an error if any column has max 0
Dim vals As Variant, maxes As Variant
Dim i As Long, j As Long, m As Long, n As Long
m = R.Rows.Count
n = R.Columns.Count
ReDim maxes(1 To n)
With Application.WorksheetFunction
For i = 1 To n
maxes(i) = .Max(R.Columns(i))
Next i
End With
vals = R.Value
For i = 1 To m
For j = 1 To n
vals(i, j) = vals(i, j) / maxes(j)
Next j
Next i
R.Value = vals
End Sub
这将比您目前拥有的更有效,因为它以批量传输的方式在电子表格和 VBA 之间移动值,而不是通过大量单独的 read/writes。它还避免了屏幕更新问题和根据这些值重新计算函数等问题。