Visual Basic - Technik, FAQ, Tricks, Beispiele

Home / Objekte / Controls / FlexGrid

FlexGrid-Inhalt ins Clipboard kopieren

Einführung

Motivation

Der einfachste Weg, den Inhalt eines FlexGrids z.B. in Excel zur Verfügung zu stellen, ist die Nutzung der Zwischenablage. Die unten vorgestellte Grid2Clipboard-Routine macht genau dies.

Es werde zwei völlig verschiedene Lösungsmöglichkeiten gezeigt. Es zeigt sich, dass manchmal die erste Idee auch die beste ist...

Beispiele

Die folgende Code-Zeile zeigt den kompletten Inhalt des Datenbereichs eines FlexGrids in einer MsgBox an, wobei die Spalten zur besseren Lesbarkeit durch ein Pipe-Symbol getrennt werden:

MsgBox Grid2Text(grd, " | ")

Im folgenden Beispiel wird das komplette FlexGrid in die Zwischenablage kopiert, wobei so ganz nebenbei eine HTML-Tabelle generiert wird:

Grid2Clipboard grd, _
    "</td><td>", _
    "</td></tr>" & vbNewLine & "<tr><td>", _
    "<table>" & vbNewLine & "<tr><td>", _
    "</td></tr>" & vbNewLine & "</table>"

Code / Quelltext

Erster Ansatz: Iteration über alle Zellen (Schleifendurchläufe)

Mit Hilfe der darunter gezeigten Grid2Text-Funktion kann die Zwischenablage ganz einfach mit dem Grid-Inhalt gefüllt werden. Vorher wird mit der Clear-Methode das Clipboard gelöscht, so dass eventuell schon vorhandene Inhalte überschrieben werden können, und damit der Grid-Inhalt auch außerhalb der VB-Anwendung zur Verfügung steht.

Public Sub Grid2Clipboard(ByRef grd As MSFlexGrid, _
    Optional ByRef ColSep As String = vbTab, _
    Optional ByRef RowSep As String = vbNewline, _
    Optional ByRef BeginText As String, _
    Optional ByRef EndText As String)

  Clipboard.Clear
  Clipboard.SetText BeginText _
                  & Grid2Text(grd, ColSep, RowSep) _
                  & EndText
End Sub

Die folgende Routine geht einfach alle Zeilen und Spalten durch, um via TextMatrix-Eigenschaft die Feld-Inhalte aneinanderzuhängen. Standardmäßig werden die Spalten durch Tabulatoren getrennt, die Zeilen durch Zeilenumbrüche.

' ©2002 by Jost Schwider, http://vb-tec.de/
Public Function Grid2Text(ByRef grd As MSFlexGrid, _
    Optional ByRef ColSep As String = vbTab, _
    Optional ByRef RowSep As String = vbNewline _
  ) As String

  'Deklarationen:
  Dim Row As Long
  Dim Col As Long
  Dim RowText As String
  
  With grd
  
    'Alle Zeilen durchlaufen:
    For Row = .FixedRows To .Rows - 1
    
      'Alle Spalten durchlaufen:
      RowText = .TextMatrix(Row, .FixedCols)
      For Col = .FixedCols + 1 To .Cols - 1
        RowText = RowText & (ColSep & .TextMatrix(Row, Col))
      Next Col
      
      'Zeile anhängen:
      Grid2Text = Grid2Text & (RowText & RowSep)
    
    Next Row
  
  End With 'grd
  
  'Ergebnisstring abschneiden:
  Grid2Text = Left$(Grid2Text, Len(Grid2Text) - Len(RowSep))
End Function

Man beachte, wie durch geschickte Klammerung des &-Operators (sowohl beim Spalten- als auch beim Zeilen-Anhängen) VB dazu gezwungen wird, erst die kürzeren Strings miteinander zu verknüpfen. Außerdem werden erst komplette Zeilen zusammengebaut, bevor sie dem Gesamtstring hinzugefügt werden. Dies erhöht die Performance der Funktion deutlich.

Bei extrem großen Tabellen kann u.U. der Einsatz der in "Strings schnell aneinander hängen" gezeigten Concat-Klasse eine weitere Beschleunigung bringen.

Intelligenter Ansatz: Nutzung der Clip-Eigenschaft

Das FlexGrid bietet mit der Clip-Eigenschaft eine Möglichkeit an, den Inhalt des gesamten gerade selektierten Bereichs abzufragen. Die Spalten werden dabei immer durch Tabulatoren getrennt, die Zeilen durch "Wagenrücklauf".

Dies nutzt die folgende Prozedur: Erst wird die aktuelle Selektierung gespeichert, dann der gesamte Datenbereich markiert und ins Clipboard geschrieben, Anschließend wird die ursprüngliche Selektion wiederhergestellt.

Public Sub Grid2Clipboard_Clip(ByRef grd As MSFlexGrid)
  'Deklarationen:
  Dim Row As Long
  Dim Col As Long
  Dim RowSel As Long
  Dim ColSel As Long
  Dim Visible As Boolean
  
  With grd
    'Einstellungen merken:
    Row = .Row
    Col = .Col
    RowSel = .RowSel
    ColSel = .ColSel
    Visible = .Visible
    
    'Datenbereich selektieren:
    .Visible = False
    .Row = .FixedRows
    .Col = .FixedCols
    .RowSel = .Rows - 1
    .ColSel = .Cols - 1
    
    'In die Zwischenablage kopieren:
    Clipboard.Clear
    Clipboard.SetText .Clip
    
    'Einstellungen wiederherstellen:
    .Row = Row
    .Col = Col
    .RowSel = RowSel
    .ColSel = ColSel
    .Visible = Visible
  End With
End Sub

Vergleich/Bewertung

Es ist offensichtlich: Da die Methode via Clip-Eigenschaft keine umständlichen For-Next-Schleifen benötigt, wird sie sicher schneller sein, als unser erster (bereits optimierter) Ansatz. Dafür bietet aber unsere handgestrickte Lösung mehr Flexibilität (freie Wahl der Spalten- und Zeilentrenner).

Schauen wir uns mal ein paar Testfälle an, um Festzustellen, wie groß der Unterschied tatsächlich ist. Das FlexGrid hatte bei variierender Zeilenanzahl immer 5 Spalten. Es wurde jeweils 1000 mal in die Zwischenablage geschrieben.

ZeilenIterationIter.(opt.)ClipBemerkung
100,63s0,62s1,06sBei kleiner Zeilenanzahl bremst die Selektierung die Clip-Methode aus. Es werden dafür schließlich 15 Zugriffe auf diverse FlexGrid-Eigenschaften benötigt.
503,16s2,86s1,96sAha! Bereits bei 50 Zeilen ist die Clip-Methode deutlich schneller. Haben sich unsere Überlegungen also wirklich gelohnt?
1006,80s5,72s5,32sDie Clip-Methode ist auch hier die Schnellste. Man beachte allerdings, wie sich die String-optimierte Iterations-Methode bereits von der nicht-optimierten Version absetzt.
20016,63s11,82s19,45sNanu? Die String-optimierte Iterations-Methode ist ja deutlich schneller als die "intelligente" Clip-Methode!
1000222,38s77,03s517,79sEin totaler Einbruch der Clip-Methode! Selbst die naive Iterations-Methode ist mehr als doppelt so schnell wie die Clip-Methode.

Das Ergebnis zeigt: Was Microsoft mit seiner Clip-Methode abgeliefert hat, ist absolut nicht optimal. Die handgestrickte nur-VB-Lösung ist nicht nur flexibler, sondern auch wieder mal schneller! Smile!

© Jost Schwider, 23.03.2002-23.03.2002 - http://vb-tec.de/gridclip.htm