VBA-Codierungsmuster: Bereichsschleife - Schreiben

Sehen Sie sich unter den VBA-Codierungsmustern den Inhalt von Range Loop-Write an.

Zusammenfassung

Codierungsmuster, die die Leistung beim Schreiben vieler Daten in Excel-Tabellen mit Variant Arrays verbessern, werden eingeführt.

Der folgende Artikel hat bereits behandelt, wie Sie die Leistung verbessern können, wenn Sie viele Daten aus einer Excel-Tabelle lesen.

VBA-Codierungsmuster: Bereichsschleife - Lesen

Einzeilige Zusammenfassung: Das Lesen in Variant Array ist unvergleichlich schneller als Loop.

Im Gegensatz dazu werden wir uns dieses Mal ansehen, wie Daten innerhalb des VBA-Codes in eine Excel-Tabelle geschrieben werden. Die Leistung jeder Methode wird unten verglichen.

Testmethode

Führen Sie den Test folgendermaßen durch.

  • Werte werden in jede Zelle geschrieben, während Zeilen und Spalten basierend auf Range („B2“) erhöht werden.
  • Der in der Zelle aufgezeichnete Wert hat das Format „Zeilennummer, Spaltennummer“.
  • Die Anzahl der Spalten bleibt fest (10 Spalten).
  • Wiederholen Sie den Vorgang, während Sie die Anzahl der Zeilen von 10, 100, 500, 1000 auf 100.000 erhöhen.
  • Da die Anzahl der Zellen gleich der Anzahl der Zeilen x 10 ist, testen Sie bis zu 1 Million Zellen.

Der Testcode kann von github heruntergeladen werden.

Link zur Github-Datei: DAToolset/VBACode/VBA Coding Patterns-Range Loop(Write).xlsm

Grundmuster – verschachtelte Schleife

Das Grundmuster erhöht den Offset der Zeile und Spalte basierend auf der Startzelle und verwendet die Loop-Anweisung für die Spalte innerhalb der Loop-Anweisung für die Zeile.

Der detaillierte Code lautet wie folgt. vorherigen Post VBA-Codierungsmuster: Bereichsschleife - Lesen und der Code ist fast derselbe, und Lesen wurde in Schreiben geändert. (Zeile 10)

Da der Text des Range-Objekts eine schreibgeschützte Eigenschaft ist, können Sie keinen Wert eingeben, also geben Sie den Wert direkt in das Range-Objekt ein.

'* 기본 패턴(Nested Loop)
Public Sub NestedLoop(aTargetRowCnt As Long)
    Dim lRowOffset As Long, lColOffset As Long, oBaseRange As Range, sVal As String
    Set oBaseRange = Range("B2")
    lRowOffset = 0
    For lRowOffset = 0 To aTargetRowCnt '읽는 행의 수(충분히 큰 수로 지정하고 Loop 내부에서 종료 조건 설정)
        If Trim(oBaseRange.Offset(lRowOffset, 0).Value) = "" Then Exit For 'Loop 종료 조건
        For lColOffset = 0 To 9 '읽는 열의 수
            'cell 단위로 쓰는 코드 예시
            oBaseRange.Offset(lRowOffset, lColOffset) = CStr(lRowOffset + 1) + "," + CStr(lColOffset + 1)
        Next lColOffset
    Next lRowOffset
End Sub

Muster mit Einzelschleife-Einzelschleife(1)

Die interne Schleifenanweisung für die Spalten wurde durch so viele Anweisungen ersetzt, wie es Spalten gibt (Zeilen 11 bis 20). Ebenso haben wir Werte direkt in das Range-Objekt eingegeben.

'단일 Loop를 사용하는 패턴: Single Loop(1)
Public Sub SingleLoop1(aTargetRowCnt As Long)
    Dim lRowOffset As Long, lColOffset As Long, oBaseRange As Range, sVal As String
    Set oBaseRange = Range("B2")
    lRowOffset = 0
    Dim lRowCount As Long, lColCount As Long, oHeaderRange As Range
    Set oHeaderRange = oBaseRange.Offset(-1, 0)
    lRowCount = aTargetRowCnt
    lColCount = Range(oHeaderRange, oHeaderRange.End(xlToRight)).Columns.Count
    For lRowOffset = 0 To lRowCount - 1 '읽는 행의 수 (Offset은 0부터 시작하므로 Count -1 까지 Loop 실행해야 함)
        oBaseRange.Offset(lRowOffset, 0) = CStr(lRowOffset + 1) + ",1"
        oBaseRange.Offset(lRowOffset, 1) = CStr(lRowOffset + 1) + ",2"
        oBaseRange.Offset(lRowOffset, 2) = CStr(lRowOffset + 1) + ",3"
        oBaseRange.Offset(lRowOffset, 3) = CStr(lRowOffset + 1) + ",4"
        oBaseRange.Offset(lRowOffset, 4) = CStr(lRowOffset + 1) + ",5"
        oBaseRange.Offset(lRowOffset, 5) = CStr(lRowOffset + 1) + ",6"
        oBaseRange.Offset(lRowOffset, 6) = CStr(lRowOffset + 1) + ",7"
        oBaseRange.Offset(lRowOffset, 7) = CStr(lRowOffset + 1) + ",8"
        oBaseRange.Offset(lRowOffset, 8) = CStr(lRowOffset + 1) + ",9"
        oBaseRange.Offset(lRowOffset, 9) = CStr(lRowOffset + 1) + ",10"
    Next lRowOffset
End Sub

Muster mit Einzelschleife-Einzelschleife(2)

Value2 wurde verwendet, um die Single-Loop-Syntax beizubehalten und Werte in den Bereich einzugeben.

'단일 Loop를 사용하는 패턴: Single Loop(2), Value2 사용
Public Sub SingleLoop2(aTargetRowCnt As Long)
    Dim lRowOffset As Long, lColOffset As Long, oBaseRange As Range, sVal As String
    Set oBaseRange = Range("B2")
    lRowOffset = 0
    Dim lRowCount As Long, lColCount As Long, oHeaderRange As Range
    Set oHeaderRange = oBaseRange.Offset(-1, 0)
    lRowCount = aTargetRowCnt
    lColCount = Range(oHeaderRange, oHeaderRange.End(xlToRight)).Columns.Count
    For lRowOffset = 0 To lRowCount - 1 '읽는 행의 수 (Offset은 0부터 시작하므로 Count -1 까지 Loop 실행해야 함)
        oBaseRange.Offset(lRowOffset, 0).Value2 = CStr(lRowOffset + 1) + ",1"
        oBaseRange.Offset(lRowOffset, 1).Value2 = CStr(lRowOffset + 1) + ",2"
        oBaseRange.Offset(lRowOffset, 2).Value2 = CStr(lRowOffset + 1) + ",3"
        oBaseRange.Offset(lRowOffset, 3).Value2 = CStr(lRowOffset + 1) + ",4"
        oBaseRange.Offset(lRowOffset, 4).Value2 = CStr(lRowOffset + 1) + ",5"
        oBaseRange.Offset(lRowOffset, 5).Value2 = CStr(lRowOffset + 1) + ",6"
        oBaseRange.Offset(lRowOffset, 6).Value2 = CStr(lRowOffset + 1) + ",7"
        oBaseRange.Offset(lRowOffset, 7).Value2 = CStr(lRowOffset + 1) + ",8"
        oBaseRange.Offset(lRowOffset, 8).Value2 = CStr(lRowOffset + 1) + ",9"
        oBaseRange.Offset(lRowOffset, 9).Value2 = CStr(lRowOffset + 1) + ",10"
    Next lRowOffset
End Sub

So schreiben Sie Daten in den Speicher auf einmal in Range - Verwenden von Variant Array

Dies ist eine Methode, um die im 2D Variant Array gespeicherten Daten auf einmal in den Bereich zu schreiben.Der detaillierte Code ist wie folgt.

' 한번에 쓰는 패턴
Public Sub VariantArray(aTargetRowCnt As Long)
    Dim vRngArr As Variant, oBaseRange As Range, oHeaderRange As Range, lColCount As Long, sVal As String
    Set oBaseRange = Range("B2")
    Set oHeaderRange = oBaseRange.Offset(-1, 0)
    lColCount = Range(oHeaderRange, oHeaderRange.End(xlToRight)).Columns.Count
    ReDim vRngArr(1 To aTargetRowCnt, 1 To lColCount)
    Dim lCol As Long, lRow As Long
    For lRow = LBound(vRngArr, 1) To UBound(vRngArr, 1)
        For lCol = LBound(vRngArr, 2) To UBound(vRngArr, 2)
            vRngArr(lRow, lCol) = CStr(lRow) + "," + CStr(lCol)
        Next lCol
    Next lRow
    oBaseRange.Resize(aTargetRowCnt, lColCount).Value2 = vRngArr
End Sub

Der Kerncode besteht aus 14 Zeilen. Ersetzen Sie Range direkt durch das Variant-Array, um Daten zu schreiben.

    oBaseRange.Resize(aTargetRowCnt, lColCount).Value2 = vRngArr

VBA-Codierungsmuster: Bereichsschleife - Lesen Wenn Sie es mit dem folgenden abgelesenen Code vergleichen, können Sie sehen, dass nur die linke und rechte Seite geändert wurden und sie gleich sind.

    vRngArr = oBaseRange.Resize(aTargetRowCnt, lColCount).Value2

Leistungsvergleich

Bereichsschreibleistungsvergleich

VBA-Codierungsmuster: Bereichsschleife - Lesen Ebenso wurde die Ausführungszeit jeder Methode zusammengefasst und gleichzeitig die Zeilenanzahl von 10 auf 100.000 erhöht.
(Ausführungsumgebung: 2019 LG Gram, CPU i5, Ram 16 GB, 256 GB SSD)

표1. Row Count, Cell Count와 각 방법의 쓰기(Write) 소요시간(초)
Tabelle 1. Zeilenanzahl, Zellenanzahl und Schreibzeit (Sekunden) jeder Methode
그림1. Row Count, Cell Count와 각 방법의 쓰기(Write) 소요시간(초)
Abbildung 1. Zeilenanzahl, Zellenanzahl und Schreibzeit (Sekunden) jeder Methode

Die Bereichsschreibleistung kann wie folgt zusammengefasst werden.

  • Es gibt fast keinen Unterschied zwischen der Eingabe eines Werts mit Value2 und der direkten Eingabe eines Werts in das Range-Objekt.
  • Verschachtelte Schleifen erzeugten etwas schnellere Ergebnisse als einzelne Schleifen. Es ist das Gegenteil von Read, also ist es schwer zu sagen, dass es immer schneller ist.
  • Das Schreiben von Daten mit Variant Array ist unvergleichlich schneller (mindestens 10 Mal mehr).

Reichweiten-Leseleistungsvergleich

So können Sie die Lese- und Schreibleistung direkt vergleichen. Leistungsvergleich lesen Kopieren Sie den Inhalt unten.

표2. Row Count, Cell Count와 각 방법의 읽기(Read) 소요시간(초)
Tabelle 2. Zeilenanzahl, Zellenanzahl und Lesezeit jeder Methode (Sekunden)
그림1. Row Count, Cell Count와 각 방법의 읽기(Read) 소요시간(초)
Abbildung 1. Zeilenanzahl, Zellenanzahl und Lesezeit jeder Methode (Sekunden)

Variant Array kann die Leistung beim Lesen und Schreiben einer großen Datenmenge in einer Excel-Tabelle mit VBA-Code erheblich verbessern, verwenden Sie es daher bei Bedarf entsprechend.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

de_DEDeutsch