Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0104: MSFlexGrid mit Texteingabe für einzelne Zellen

 von 

Beschreibung 

Das eigentlich sehr praktische MSFlexgrid-Control hat einen entschiedenen Nachteil: Es läßt von Hause aus keine direkte Zelleneingabe zu. Mit einem kleinen Trick, nämlich dem einblenden einer ungebundenen Textbox über der jeweils aktiven Zelle, gehts aber trotzdem.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

keine

Download:

Download des Beispielprojektes [2,6 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei PROJEKT1.VBP -------------
' Die Komponente 'Microsoft FlexGrid Control 6.0 (MSFLXGRD.OCX)' wird benötigt.

'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Textfeld "Text1"
' Steuerelement: Flexible Tabelle "MSFlexGrid1"


'Vielen Dank an Daniel Koehli

Option Explicit

Private Sub MSFlexGrid1_Click()
  Call SizeText
  Text1.Visible = True
  Text1.SetFocus
End Sub

Private Sub MSFlexGrid1_GotFocus()
  MSFlexGrid1_RowColChange
End Sub

Private Sub MSFlexGrid1_LeaveCell()
  MSFlexGrid1.Text = Text1.Text
End Sub

Private Sub MSFlexGrid1_RowColChange()
  Static OldRow%, OldCol%, Change As Boolean
   
    If Change Then Exit Sub
    Change = True
     
    With MSFlexGrid1
      If .Col <> OldCol Or .Row <> OldRow Then
        OldRow = .Row
        OldCol = .Col
        
        Call SizeText
        Text1.Visible = True
        Text1.SetFocus
      End If
    End With
  Change = False
End Sub

Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer)
  With MSFlexGrid1
    Select Case KeyCode
    
      Case vbKeyRight
        If .Col + 2 > .Cols And .Row + 1 < .Rows Then
          .Col = 1
          .Row = .Row + 1
        ElseIf .Col + 1 < .Cols And .Row < .Rows Then
         .Col = .Col + 1
        End If
      
      Case vbKeyUp
        If .Row - 1 > 0 Then .Row = .Row - 1
      
      Case vbKeyDown, vbKeyReturn
        If .Row + 1 < .Rows Then .Row = .Row + 1
      
      Case vbKeyLeft
        If .Col - 1 = 0 And .Row - 1 <> 0 Then
          .Col = .Cols - 1
          .Row = .Row - 1
        ElseIf .Col - 1 <> 0 Then
          .Col = .Col - 1
        End If
      End Select
    End With
    MSFlexGrid1_RowColChange
End Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)
  If KeyAscii = vbKeyReturn Then KeyAscii = 0
  If KeyAscii = vbKeyTab Then
    Call Text1_KeyDown(vbKeyRight, 0)
    KeyAscii = 0
  End If
End Sub

Private Sub Text1_LostFocus()
  Text1.Visible = False
  Call MSFlexGrid1_RowColChange
End Sub

Private Sub SizeText()
  With MSFlexGrid1
    Text1.Text = .Text
    Text1.FontSize = .Font.Size
    Text1.Height = .CellHeight
    
    If .CellLeft + .CellWidth > .Width Then
     Text1.Width = .Width - .CellLeft
    Else
      Text1.Width = .CellWidth
    End If
    
    Text1.Left = .CellLeft + .Left
    Text1.Top = .CellTop + .Top
  End With
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'-------------- Ende Projektdatei PROJEKT1.VBP --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 22 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von nicht_mehr_n00b am 10.03.2010 um 15:05

Nicht ganz die triviale Lösung für das Problem des Verzögerten Aufrufs von LeaveCell:

Eine Variable gridedit (Boolean) einführen. Diese immer beim Bearbieten des Grids auf True setzen:

Private Sub MSFlexGrid1_Click()
gridedit = true
...
End Sub

entsprechend die Änderung der Zellen anpassen:

Private Sub MSFlexGrid1_LeaveCell()
If gridedit = True Then
MSFlexGrid1.Text = Text1.Text
End If
End Sub

Beim Anklicken anderer Steuerungselemente wird gridedit auf False gesetzt.

Kommentar von n00b am 10.03.2010 um 14:07

Arbeite jetzt schon eine Weile damit und bin prinzipiell sehr zufrieden! Ausser dass ich über das gleiche Problem stolpere wie schon Jürgen Caspar vor mir:

- Wenn man nach dem Programmstart nicht die linke obere Zelle anklickt, sondern in eine andere springt, wird der Zelleninhalt mit dem ursprünglichen Text aus dem Textfeld überschrieben.

=> d.h. immer wenn ich ins Flexgrid klicke wird durch die Sub MSFklexGrid_LeaveCell der letzte Inhalt aus Text1 eingefügt. Das muss ich ihm noch austrieben.

Kommentar von Harald am 11.09.2009 um 21:25

funktioniert schon sehr gut - nur noch ein Problem:
habe vorher das Flexgrid mit Zeilen- und Spaltenüberschriften versehen, die dann verschwunden sind, während die Spaltenbreite übernommen wurde.
Wer kennt eine Lösung...
Danke

Kommentar von n00b am 25.05.2009 um 16:35

Wer lesen kann ist klar im Vorteil...

' Steuerelement: Textfeld "Text1"

Bitte die überstürzte Frage einfach ignorieren und vielen Dank für den guten Quellcode!

Kommentar von n00b am 25.05.2009 um 16:03

Öhm, zugegeben, ich habe keine Ahnung von VB und hatte gehofft den Text einfach Copy&Paste übernehmen zu können für eine bestehende MSFlexGrid-Tabelle - aber da kommt immer "Variable nicht definiert" mit Verweis auf "Text1". Wo muss ich das denn definieren?
Oder um nicht ganz so unselbstständig zu sein: wo lese ich am besten nach wies gemacht wird?

Kommentar von wewa am 16.09.2008 um 10:46

Danke!
Hat wunderbar funktioniert.

Nur muss man darauf achten, dass die Textbox vor dem MSFlexlist Element liegt.

Kommentar von TR am 11.05.2006 um 16:14

um den Text in der Textbox automatisch zu markieren, fügt man bei SizeText zum Schluss folgendes ein:

text1.SelStart = 0
text1.SelLength = Len(.Text)

und beim Schluss von Text1_KeyDown

KeyCode = 0

Kommentar von ISIcom am 26.08.2005 um 09:46

Hey Jürgen Caspar,
da bin ich wieder....Tja, das ding kann aber echt viel...sehr toll gemacht. Wollte allerdings einige Änderungen vornehmen im Controler, z.b. möchte einzelen Zellen schon bei ankommen in die Zelle editieren könne, standart ist, wenn ich erst "ENTER" eingebe; erst dann ist es möglich was neues einzu geben...Naja, wie dem auch sei, leider ist der Source code beschädigt. Ich kann Benutzersteuerelement nicht auf machen. Habe mich mal an den Author gewand. Diese Feature ist für das Projekt so ausschlag geben, das ich im negativem Falle, alles selber machen muss... Naja..abwarte...Vielen dank noch mal!

Kommentar von ISIcom am 26.08.2005 um 08:49

Hallo Jürgen Caspar,
danke für den Tip, dann schaue ich mir mal das ganze an. Wenn ich nicht damit klar komme, melde ich mich noch einmal ;-) ..also vielen Danke.

Kommentar von Jürgen Caspar am 25.08.2005 um 22:55

ISIcom, spar Dir die Arbeit. Das Ding funktioniert so zwar halbwegs, aber es fehlen noch viele Funktionen.

Es geht viel einfacher: lade Dir das kostenlose SGrid2-Control von www.vbaccelerator.com runter. Das hat unglaublich viele Funktionen. Z.B. kann man den Inhalt mit einem Click auf den Spaltenkopf sortieren, und und und ...

Das Beispielprogramm auf der Website zeigt die Leistungsfähigkeit und wie es benutzt wird. Ist wirklich einfach. Ich kann es nur empfehlen. Seither gibt es bei mir keine Flexgrids mehr!

Kommentar von ISIcom am 25.08.2005 um 16:41

Hey....Super...echt ganz klasse....ganz tolle idee, so einfach von der Idee, so genial ist es auch...

Allerdings habe ich es mal versucht, den Text markieren zu lassen, wenn was drin steht und ein "fockus" auf die Textbox erzeugt wird:

Private Sub Text1_GotFocus()
Text1.SelStart = 0
Text1.SelLength = Len(Text1.Text)
End Sub

aber leider funktioniert das nicht so...kann mir da jemand helfen...???

Kommentar von Jürgen Raue am 08.08.2005 um 13:26

Hat mit kleinen Änderungen sehr gut funktioniert.
Die Idee ist bestechend einfach, aber sehr gut.

Vielen Dank

Jürgen

Kommentar von Jürgen Caspar am 05.06.2005 um 22:33

Hallo Jens,

der Tipp mit dem SGrid Control ist Gold wert! Danke!
Hier der link:
http://vbaccelerator.com/home/VB/Code/Controls/S_Grid_2/index.asp

Habe mir von vbAccelerator auch gleich noch einige andere Controls besorgt.

MfG
Jürgen

Kommentar von JensR am 04.06.2005 um 11:34

Änderung:

Private Sub MSFlexGrid1_RowColChange()
.
.
.
MSFlexGrid1_LeaveCell
End Sub


Um noch flexibler zu sein ... nutze das Freeware-Steuerelement : 'vbAccelerator VB6 SGrid Control 2.0'.

Kommentar von Jürgen Caspar am 04.06.2005 um 00:52

Eigentlich wäre es ja die Aufgabe von Microsoft gewesen so eine Funktion mitzuliefern, aber na ja ...
Dafür um so mehr Dank an die Programmierer die ihren Code hier veröffentlichen.

Leider habe ich mit diesem Tipp 2 Probleme:

- Die Eingabe aus dem Textfeld geht verloren, wenn der Nutzer nicht im Flexgrid bleibt, sondern von der Textbox aus ein anderes Steuerelement außerhalb des Flexgrids anklickt. Dann wird nämlich die Sub LeaveCell nicht ausgeführt und somit der Inhalt der Textbox nicht in die Zelle geschrieben.

- Wenn man nach dem Programmstart nicht die linke obere Zelle anklickt, sondern in eine andere springt, wird der Zelleninhalt mit dem ursprünglichen Text aus dem Textfeld überschrieben! Ab dann funktioniert es aber. Komisch ...???

MfG
Clouseau

Kommentar von JensR am 13.08.2004 um 19:27

Meine Änderung zum Beispiel:

Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer)
With MSFlexGrid1
Select Case KeyCode
Case vbKeyRight, (vbKeyTab And Shift = 0), vbKeyReturn
If KeyCode = vbKeyReturn Then
If .Col + 1 = .Cols And .Row + 1 = .Rows Then .Rows = .Rows + 1
End If
If .Col + 2 > .Cols And .Row + 1 < .Rows Then
.Col = 1
.Row = .Row + 1
ElseIf .Col + 1 < .Cols And .Row < .Rows Then
.Col = .Col + 1
End If
Case vbKeyUp
If .Row - 1 > 0 Then .Row = .Row - 1
Case vbKeyDown
If .Row + 1 < .Rows Then .Row = .Row + 1
Case vbKeyLeft, (vbKeyTab And Shift = 1)
If .Col - 1 = 0 And .Row - 1 <> 0 Then
.Col = .Cols - 1
.Row = .Row - 1
ElseIf .Col - 1 <> 0 Then
.Col = .Col - 1
End If
End Select
End With
If KeyCode = vbKeyRight Or KeyCode = vbKeyUp Or KeyCode = vbKeyDown Or KeyCode = vbKeyLeft Or KeyCode = vbKeyReturn Or KeyCode = vbKeyTab Then
KeyCode = 0
Text1.SelStart = 0
Text1.SelLength = Len(Text1.Text)
End If
MSFlexGrid1_RowColChange
End Sub

'<Löschen
'Private Sub Text1_KeyPress(KeyAscii As Integer)
' If KeyAscii = vbKeyReturn Then KeyAscii = 0
' If KeyAscii = vbKeyTab Then
' Call Text1_KeyDown(vbKeyRight, 0)
' KeyAscii = 0
' End If
'End Sub
'Löschen>

Kommentar von gustavo bethanco am 15.07.2004 um 01:18

very good

Kommentar von Jens am 07.11.2002 um 12:58

Interessanter Anfang. leider funktioniert das ganze nicht mehr, wenn man ein FlexGrid hat, in dem man scrollen kann. er findet dann die Zellen nicht wieder.

Kommentar von sven brodowski am 28.12.2001 um 22:25

wie programmiert man
die berechnung für
ein vieleck mit mshflexgrid

Kommentar von carsten Hörr am 17.12.2001 um 12:22

ausdruck aus mshflexgrig

Kommentar von Siegfried am 17.05.2001 um 10:05

hallo!
Im großen und ganze funktioniert der Tip. Hat nur zwei Schönheitsfehler:
1. wähle ich einen relativ großen Font, sind MSFlexgrid-Zelle und Textfeld sehr deutlich sichtbar nicht deckungsgleich
2. vertippe ich mich bei einer Eingabe im Textfeld, so ist ein Positionieren des Eingabecursors im Textfeld an die fehlerhafte Stelle nicht möglich (statt dessen Wechsel der Zelle)
Grüße
Siegfried

Kommentar von DOMINIK am 28.02.2001 um 09:58

hallo,
ich habe diesen tipp gerade versucht, bei einer msh zu benutzen. Leider funktioniert er nicht wirklich. Kann es sein, dass der Aufruf für die leavecell-sub fehlt? auf jeden fall übernimmt er den text nicht, und wenn, dass mit einem zeichen mehr oder so!
komisch
gruss
dominik