Excel VBA中的动态数据结构
目前,我正在努力提高VBA程序的性能,因为执行某些表操作需要很长时间 在程序运行期间,我尝试将数据存储在工作表中,但写入操作将永远持续,我希望动态存储此数据,而不是将其写入工作表中,以减少运行所需的时间 我曾考虑使用数组而不是工作表来存储数据,但我不确定这是否可行,因为我不知道我的表到底有多少行/列 这里是我的代码,任何帮助都是感激的Excel VBA中的动态数据结构,excel,vba,Excel,Vba,目前,我正在努力提高VBA程序的性能,因为执行某些表操作需要很长时间 在程序运行期间,我尝试将数据存储在工作表中,但写入操作将永远持续,我希望动态存储此数据,而不是将其写入工作表中,以减少运行所需的时间 我曾考虑使用数组而不是工作表来存储数据,但我不确定这是否可行,因为我不知道我的表到底有多少行/列 这里是我的代码,任何帮助都是感激的 Public row As Long Public rowMax As Long Public startRow As Integer Public materi
Public row As Long
Public rowMax As Long
Public startRow As Integer
Public materialType As String
Public filter As String
Public col As Integer
Public colMax As Integer
Public isUsed As Boolean
Public a As Integer
Sub bestimmeObFelderGenutzt()
Debug.Print ("bestimmeObFelderGenutzt:begin" & " " & Now())
With Sheets("Sheet1")
filter = "I"
startRow = 2
rowMax = Sheets("Sheet1").Cells(.Rows.Count, "F").End(xlUp).row
colMax = Sheets("Sheet1").Cells(1, .Columns.Count).End(xlToLeft).Column
materialType = Sheets("Sheet1").Range(filter & startRow).Value
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = "Nutzung"
For col = 1 To colMax
Sheets("Nutzung").Cells(1, col + 2).Value = Sheets("Sheet1").Cells(1, col).Value
Next col
For row = 2 To rowMax
Sheets("Nutzung").Range("A" & row).Value = Sheets("Sheet1").Range("A" & row).Value
Sheets("Nutzung").Range("B" & row).Value = Sheets("Sheet1").Range("I" & row).Value
For col = 1 To colMax
If IsEmpty(Sheets("Sheet1").Cells(row, col)) = False Then
isUsed = True
Sheets("Nutzung").Cells(row, col + 2).Value = 1
Else:
Sheets("Nutzung").Cells(row, col + 2).Value = 0
End If
Next col
Next row
End With
Debug.Print ("bestimmeObFelderGenutzt:end" & " " & Now())
End Sub
Sub findeUngenutzteSpalten(ByVal materialType As String, pos As Integer)
Debug.Print ("findeUngenutzteSpalten:begin" & " " & materialType & " " & Now())
With Sheets(materialType)
rowMax = Sheets(materialType).Cells(.Rows.Count, "F").End(xlUp).row
colMax = Sheets(materialType).Cells(1, .Columns.Count).End(xlToLeft).Column
Sheets("Auswertung").Cells(1, 1).Value = "Spaltenüberschrift:"
Dim a As Integer
For a = 1 To colMax
Sheets("Auswertung").Cells(a + 1, 1).Value = Sheets("Sheet1").Cells(1, a).Value
Next a
Sheets("Auswertung").Cells(1, pos + 1).Value = materialType
For col = 3 To colMax
For row = 2 To rowMax
If Sheets(materialType).Cells(row, col).Value = 1 Then
Sheets("Auswertung").Cells(col - 1, pos + 1).Value = "Ja"
GoTo WeiterCol
Else:
If row = rowMax Then
Sheets("Auswertung").Cells(col - 1, pos + 1).Value = "Nein"
Else:
GoTo WeiterRow
End If
End If
WeiterRow:
Next row
WeiterCol:
Next col
End With
Debug.Print ("findeUngenutzteSpalten:end" & " " & materialType & " " & Now())
End Sub
Sub kopiereZeilen(ByVal materialType As String)
Debug.Print ("kopiereZeilen:begin" & " " & materialType & " " & Now())
With Sheets("Nutzung")
rowMax = Sheets("Nutzung").Cells(.Rows.Count, "F").End(xlUp).row
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = materialType
Sheets("Nutzung").Cells(1, 1).EntireRow.Copy Sheets(materialType).Cells(1, 1)
Dim unusedRow As Long
For row = 2 To rowMax
unusedRow = Sheets(materialType).Cells.SpecialCells(xlCellTypeLastCell).Offset(1, 0).row
If Sheets("Nutzung").Cells(row, 2).Value = materialType Then
Sheets("Nutzung").Cells(row, 2).EntireRow.Copy Sheets(materialType).Cells(unusedRow, 1)
End If
Next row
End With
Debug.Print ("kopiereZeilen:end" & " " & materialType & " " & Now())
End Sub
Sub allesZusammen()
Debug.Print ("Hauptaufruf:begin" & " " & Now())
Dim types(10) As String
Dim element As Variant
Dim pos As Integer
bestimmeObFelderGenutzt
types(0) = "A"
types(1) = "B"
types(2) = "C"
types(3) = "D"
types(4) = "E"
types(5) = "F"
types(6) = "G"
types(7) = "H"
types(8) = "I"
types(9) = "J"
types(10) = "K"
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = "Auswertung"
For Each element In types
kopiereZeilen (element)
pos = Application.Match(element, types, False)
findeUngenutzteSpalten element, pos
Next element
Debug.Print ("Hauptaufruf:end" & " " & Now())
End Sub
您可以声明动态数组。一般语法为:
Dim Values() As Long
要使用该数组,必须首先将其重新标注为所需的大小。例如,这声明了一个基于零的3 x 5值的二维数组:
ReDim Values(2, 4)
如果要根据变量调整大小,请使用以下方法:
ReDim Values(myrowsize, mycolumnsize)
您可以使用以下语法动态增长或收缩阵列:
ReDim Preserve Values(2, mynewsize)
请注意,您只能重新标注数组的最后一个索引。所以这是不允许的:
ReDim Preserve Values(mynewsize, 4)
但这在您的情况下可能是可以的,因为您有固定数量的列
将动态数组声明为UDT完全可以。例如:
Type UDTInfo
valueA As Long
valueB As Long
End Type
Sub test()
Dim Values() As UDTInfo
ReDim Values(2, 4)
ReDim Preserve Values(2, 5)
End Sub
您可以按正常方式访问阵列:
x = Values(1, 2)
您可以直接将一个动态数组复制到另一个,只要维度的类型和数量与大小匹配并不重要:
Dim Values() As Integer
Dim Results() As Integer
Results = Values
最后,您可以通过以下方式在函数之间传递动态数组:
Function SomeFunc(ByRef Values() As Long) As Long()
Dim ReturnValues() As Long
ReturnValues = Values
SomeFunc = ReturnValues
End Function
注意,只传递动态数组ByRef,不传递ByVal。尝试使用Application.ScreenUpdate方法。查看excel帮助使用。是的,这帮助了很多,现在程序运行速度快了29%!但我需要更快的速度,因为即使它运行的时间减少了29%,但您仍要在每个单元格上迭代大约5个小时。首先尝试筛选条件,然后将范围作为一个整体复制。或者使用数据库。很乐意帮忙。希望能快得多。是的,感觉就像时间旅行:D