PDA

Vollständige Version anzeigen : Werte aus ListBox editieren


Suwarin
18.04.2009, 03:13
Hallo zusammen,
nu weiss ich nicht mehr weiter...
Ich möchte eine markierte zeile in der listbox (terminübersicht) in die datenmaske (termineingabe) bringen und anschliessend wieder zurück in die tabelle.
...hab nur leider keine ahnung wie ich dass anstellen soll.
Ich hoffe also nochmals auf eure hilfe !!!
MfG

jinx
18.04.2009, 08:10
Moin, Suwarin,

da ich Deine VBA-Kenntnisse nicht einschätzen kann, zuerst nur der Anriss meines Lösungsvorschlages: hinter der Schaltfläche Bearbeiten eine weitere UserForm aufrufen, die die Daten aus der UF Terminübersicht für den ausgewählten Datensatz in Textboxen einfügt und zusätzlich in ein nicht angezeigtes Feld die Angabe ListIndex für den Datensatz übergibt (kann dann zum Schreiben in die Tabelle verwendet werden, beginnt bei 0 und muss zum Zurückschreiben um 2 erhöht werden für die Angabe der Zeile). Nach dem Öffnen der neuen UF würde ich die alte aus dem Speicher entfernen und ggf. über eine Schaltfläche danach wieder aufrufen. Solltest Du Probleme mit der Umsetzung haben - bitte Info.

Ein organisatorischer Hinweis von meiner Seite: ich würde es bevorzugen, angehängten Beispielmappen unterschiedliche Namen zu geben, auch wenn sie einem Projekt und dessen Problemen angehören.

Suwarin
18.04.2009, 10:59
Hallo Jinx,
danke für Deine Antwort-
Meine vba kenntnisse sind mehr als bescheiden, sind meine ersten Gehversuche. Über Bearbeiten öffnet sich eine userform, aber weiter komm ich leider nicht. Die gefundenen codes kann ich nicht wirklich nachvollziehen. Wäre nett wenn Du mir ein kurzes Beispiel mit einer entsprechenden Erklärung posten würdest.
MfG

jinx
18.04.2009, 12:24
Moin, Suwarin,

Ansatz - bitte überlege Dir vielleicht einmal, wie Du in einem halben Jahr bei nicht umbenannten Steuerelementen bei einer Anpassung ins Schwitzen gerätst...

'Allgemeines Modul
Option Explicit

Public glngZeile As Long
'Form Terminübersicht, Schaltfläche Bearbeiten
Private Sub BearbeitenCB_Click()

'Prüfen, ob eine Auswahl im Listenfeld gemacht wurde
If ListBox1.ListIndex = -1 Then Exit Sub
'Zuweisung der Zeilenangabe an globale Variabel
glngZeile = ListBox1.ListIndex + 2
'aktuelles Formular ausblenden
Unload Terminübersicht
'Anderes Formular aufrufen
Termineingabe.Show

End Sub
'Formular Termineingabe
Option Explicit
'Sprechende Namen für die Steuerelemente verwenden oder die Aufgabe im Code als Kommentar hinterlegen
'Ohne diese Angaben ist es sehr mühsam, anhand des Codes zu erkennen, was denn dort gemacht werden soll

Private Sub CommandButton3_Click()
'Leert die Eingaben der UserForm
'Mein Vorschlag: cmdLeeeren

ComboBox4 = ""
TextBox1 = ""
TextBox2 = ""
'TextBox3 = ""
'TextBox4 = ""
ComboBox3 = ""
ComboBox2 = ""
TextBox5 = ""
TextBox3.Value = 1
TextBox4.Value = 1
CheckBox1.Value = False
End Sub

Private Sub CommandButton4_Click()
'Schreibt die Daten in die Tabelle Termine in Zeile 2 - warum statisch?

Dim lngCounter As Long

With Worksheets("Termine")
For lngCounter = 12 To 15
.Cells(2, lngCounter).Value = Controls("Textbox" & lngCounter - 11).Value
Next lngCounter
' .Range("K2").Value = TextBox1.Value
' .Range("L2").Value = TextBox2.Value
' .Range("M2").Value = TextBox3.Value
' .Range("N2").Value = TextBox4.Value
TextBox5.Value = .Range("O2")
End With

End Sub

Private Sub UserForm_Activate()
'Ich empfinde die Zuweisung eines unsortierten Dictionaries an eine CB mit anschließender Sortierung
'als suboptimal - dies sollte beim Einlesen ins Dictionary erledigt werden können.

Dim lngRow As Long
Dim lngCounter As Long

ComboBox4.Clear
lngRow = Sheets("Menu").Cells(Rows.Count, "F").End(xlUp).Row
For lngCounter = 2 To lngRow
ComboBox4.AddItem Sheets("Menu").Cells(lngCounter, 6)
Next lngCounter
ComboBox4.ListIndex = 0

Dim dic As Object
Dim xKey As Variant
Dim iRow As Long, ALetzte As Long

With Sheets("Termine")
ALetzte = IIf(IsEmpty(.Cells(Rows.Count, "F")), .Cells(Rows.Count, "F").End(xlUp).Row, Rows.Count)
Set dic = CreateObject("scripting.dictionary")
For iRow = 2 To ALetzte
If Not IsEmpty(.Cells(iRow, 6)) Then
xKey = .Cells(iRow, 6).Value
dic(xKey) = 0
End If
Next
End With

For Each xKey In dic
ComboBox3.AddItem xKey
Next

dic.RemoveAll
Set dic = Nothing

Call Sortieren
ComboBox3.ListIndex = -1

End Sub

Sub Sortieren()

Dim Letzter As Integer, Naechster As Integer
Dim i As String

With ComboBox3
For Letzter = 0 To .ListCount - 1
For Naechster = Letzter + 1 To .ListCount - 1
If .List(Letzter) > .List(Naechster) Then
i = .List(Letzter)
.List(Letzter) = .List(Naechster)
.List(Naechster) = i
End If
Next Naechster
Next Letzter
End With

End Sub

Private Sub UserForm_Initialize()
Dim lngRow As Long 'Dimensionierung sollte so erfolgen, ansonsten wird Variant als Dimnsionierung angenommen
Dim lngCounter As Long
'Application.EnableEvents = False 'Tabellenereignisse beim Initialisieren einer Userform ausschalten macht meiner Meinung nach
'nicht wirklich Sinn

'Abfrage, ob Formular nach Auswahl Listbox in Terminübersicht aufgerufen wurde
If glngZeile = 0 Then

'Beim Initialisieren ist eine CB immer leer, wenn ihr keine RowSource zugewiesen wurde
'ComboBox1.Clear

'Statt der festen Bezeichnung der letzten Zeile, wie sie bis Excel2003 galt, wird hier flexibler gearbeitet
lngRow = Sheets("Klienten").Cells(Rows.Count, "A").End(xlUp).Row
For lngCounter = 2 To lngRow
ComboBox1.AddItem Sheets("Klienten").Cells(lngCounter, 1)
Next lngCounter
ComboBox1.ListIndex = -1

'ComboBox2.Clear
lngRow = Sheets("Mitarbeiter").Cells(Rows.Count, "A").End(xlUp).Row
For lngCounter = 2 To lngRow
ComboBox2.AddItem Sheets("Mitarbeiter").Cells(lngCounter, 1)
Next lngCounter
ComboBox2.ListIndex = -1
Else
'Teil für den Aufruf aus dem Listenfeld
'Einlesen der Werte bezogen auf die Zeile
With Sheets("Termine")
ComboBox1.Value = .Cells(glngZeile, "G").Value
ComboBox2.Value = .Cells(glngZeile, "H").Value
'weitere Angaben eintragen
End With
End If
'Application.EnableEvents = True

End Sub

Private Sub CommandButton2_Click()
'cmdAbbrechen, cmdBeenden

Unload Me

End Sub
Private Sub CommandButton1_Click()

Dim xZeile As Long, frm As UserForm

If ComboBox1.Value = "" Then Exit Sub
If ComboBox2.Value = "" Then Exit Sub
If ComboBox4.Value = "" Then Exit Sub
If TextBox1.Value = "" Then Exit Sub
If TextBox2.Value = "" Then Exit Sub
If TextBox5.Value = "" Then Exit Sub

Set frm = Termineingabe
Sheets("Termine").Activate
xZeile = Cells(Rows.Count, "A").End(xlUp).Row + 1

With frm
Cells(xZeile, "A").Value = .ComboBox4.Value
Cells(xZeile, "B").Value = .TextBox1.Value
Cells(xZeile, "C").Value = .TextBox2.Value
Cells(xZeile, "D").Value = .TextBox3.Value
Cells(xZeile, "E").Value = .TextBox4.Value
Cells(xZeile, "F").Value = .ComboBox3.Value
Cells(xZeile, "G").Value = .ComboBox1.Value
Cells(xZeile, "H").Value = .ComboBox2.Value
Cells(xZeile, "I").Value = .TextBox5.Value
End With

If CheckBox1.Value = False Then
TextBox1 = ""
TextBox2 = ""
TextBox5 = ""
ComboBox3 = ""
End If

'With ActiveWorkbook.Worksheets("Termine").ListObjects("Tabelle3")
' .Sort.SortFields.Clear
' .Sort.SortFields.Add _
' Key:=Range("Tabelle3[[#All],[Datum]]"), _
' SortOn:=xlSortOnValues, _
' Order:=xlAscending, _
' DataOption:=xlSortNormal
'End With
'With ActiveWorkbook.Worksheets("Termine").ListObjects("Tabelle3").Sort
' .Header = xlYes
' .MatchCase = False
' .Orientation = xlTopToBottom
' .SortMethod = xlPinYin
' .Apply
'End With
With ActiveWorkbook.Worksheets("Termine")
With .ListObjects("Tabelle3")
.Sort.SortFields.Clear
.Sort.SortFields.Add _
Key:=Range("Tabelle3[[#All],[von ]]"), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
With .Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End With

Set frm = Nothing
UserForm_Initialize 'Warum dieses Ereignis, wenn die UF geladen ist? Warum nicht Activate, Repaint,
'Neueinlesen des Feldes, welches betroffen ist?

End Sub

Private Sub UserForm_Terminate()

glngZeile = 0

End Sub

Suwarin
18.04.2009, 12:47
Hallo jinx,

tausend dank für deine mühe, werd mich mal damit auseinandersetzen.

MfG

Suwarin
18.04.2009, 13:38
Hallo nochmal,

hab noch 2 probleme beim einlesen aus der LB, werte aus CB3 werden nicht übernommen und uhrzeiten in TB1 und TB2 werden teilweise nicht als solche angezeigt.

MfG

PS Habe zwar noch lange nicht alles wirklich verstanden, bin aber dank deiner hilfe hoffentlich auf dem richtigen weg. Nochmals danke dafür !!!

jinx
18.04.2009, 14:16
Moin, Suwarin,

die Textboxen dürften sich dabei korrekt verhalten und das anzeigen, was hinter den Zeiten steht - der Nachkommateil eines Tages. Umgehen kann man dies, indem man die Angaben entsprechend formatiert:

With Sheets("Termine")
ComboBox1.Value = .Cells(glngZeile, "G").Value
ComboBox2.Value = .Cells(glngZeile, "H").Value
ComboBox3.Value = .Cells(glngZeile, "F").Value
ComboBox4.Value = .Cells(glngZeile, "A").Value
TextBox1.Value = Format(.Cells(glngZeile, "B").Value, "hh:mm")
TextBox2.Value = Format(.Cells(glngZeile, "C").Value, "hh:mm")
TextBox3.Value = .Cells(glngZeile, "D").Value
TextBox4.Value = .Cells(glngZeile, "E").Value
TextBox5.Value = .Cells(glngZeile, "I").Value
End With
Gleiches gilt dann für das Schreiben in die Zellen, die Alternative wäre, die Zellen anschließend zu formatieren.

Wegen des Verhaltens der CB3, versuche bitte einmal folgendes geändertes Vorgehen:
With frm
Cells(xZeile, "A").Value = ComboBox4.Value
Cells(xZeile, "B").Value = TextBox1.Value
Cells(xZeile, "C").Value = TextBox2.Value
Cells(xZeile, "D").Value = TextBox3.Value
Cells(xZeile, "E").Value = TextBox4.Value
Cells(xZeile, "F").Value = ComboBox3.Text
Cells(xZeile, "G").Value = ComboBox1.Text
Cells(xZeile, "H").Value = ComboBox2.Text
Cells(xZeile, "I").Value = TextBox5.Value
End With
Die With-Anweisung wird zwar nicht eingesetzt, dafür erschien bei mir der gewünschte Wert...

Suwarin
18.04.2009, 15:52
Hallo Jinx,

Alles Bestens bis dahin, nu funzt das soweit.

MfG