Filtereinstellungen durch ComboBoxen bestimmen

  • VB.NET

Es gibt 42 Antworten in diesem Thema. Der letzte Beitrag () ist von raist10.

    Filtereinstellungen durch ComboBoxen bestimmen

    Also erst mal mein Programm:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim label As New Label
    3. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    4. 'alle Für comboStatKarte und comboStatSpieltyp
    5. comboStatKarte.Items.Add("Alle Karten...")
    6. comboStatKarte.SelectedItem = "Alle Karten..."
    7. comboStatSpiel.Items.Add("Alle Spieltypen...")
    8. comboStatSpiel.SelectedItem = "Alle Spieltypen..."
    9. 'Laden
    10. LadenKarte()
    11. LadenDatumList()
    12. LadenKarteList()
    13. LadenSpielList()
    14. LadenComboStatKarte()
    15. 'comboKarte
    16. Combokarte.Text = " select..."
    17. 'comboSpiel
    18. comboSpiel.Items.Add(CStr("1on1"))
    19. comboSpiel.Items.Add(CStr("2on2"))
    20. comboSpiel.Items.Add(CStr("3on3"))
    21. comboSpiel.Items.Add(CStr("4on4"))
    22. comboSpiel.Items.Add(CStr("5on5"))
    23. comboSpiel.Items.Add(CStr("GunGame"))
    24. comboSpiel.Items.Add(CStr("DeathMatch"))
    25. comboSpiel.Items.Add(CStr("ScoutSknife"))
    26. comboSpiel.Items.Add(CStr("BunnyHop"))
    27. comboSpiel.Items.Add(CStr("Positionen"))
    28. 'comboStatSpiel
    29. comboStatSpiel.Items.Add(CStr("1on1"))
    30. comboStatSpiel.Items.Add(CStr("2on2"))
    31. comboStatSpiel.Items.Add(CStr("3on3"))
    32. comboStatSpiel.Items.Add(CStr("4on4"))
    33. comboStatSpiel.Items.Add(CStr("5on5"))
    34. comboStatSpiel.Items.Add(CStr("GunGame"))
    35. comboStatSpiel.Items.Add(CStr("DeathMatch"))
    36. comboStatSpiel.Items.Add(CStr("ScoutSknife"))
    37. comboStatSpiel.Items.Add(CStr("BunnyHop"))
    38. comboStatSpiel.Items.Add(CStr("Positionen"))
    39. 'comboTag / comboMonat / comboJahr
    40. With comboTag
    41. .Items.Add(1)
    42. .Items.Add(2)
    43. .Items.Add(3)
    44. .Items.Add(4)
    45. .Items.Add(5)
    46. .Items.Add(6)
    47. .Items.Add(7)
    48. .Items.Add(8)
    49. .Items.Add(9)
    50. .Items.Add(10)
    51. .Items.Add(11)
    52. .Items.Add(12)
    53. .Items.Add(13)
    54. .Items.Add(14)
    55. .Items.Add(15)
    56. .Items.Add(16)
    57. .Items.Add(17)
    58. .Items.Add(18)
    59. .Items.Add(19)
    60. .Items.Add(20)
    61. .Items.Add(21)
    62. .Items.Add(22)
    63. .Items.Add(23)
    64. .Items.Add(24)
    65. .Items.Add(25)
    66. .Items.Add(26)
    67. .Items.Add(27)
    68. .Items.Add(28)
    69. .Items.Add(29)
    70. .Items.Add(30)
    71. .Items.Add(31)
    72. End With
    73. With comboMonat
    74. .Items.Add("Januar")
    75. .Items.Add("Februar")
    76. .Items.Add("März")
    77. .Items.Add("April")
    78. .Items.Add("Mai")
    79. .Items.Add("Juni")
    80. .Items.Add("Juli")
    81. .Items.Add("August")
    82. .Items.Add("September")
    83. .Items.Add("Oktober")
    84. .Items.Add("November")
    85. .Items.Add("Dezember")
    86. End With
    87. With comboJahr
    88. .Items.Add(2011)
    89. .Items.Add(2012)
    90. End With
    91. '______________________________________________________________________________________
    92. End Sub
    93. 'Karte Hinzufügen
    94. Private Sub cmdAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAdd.Click
    95. If Combokarte.Items.Contains(Combokarte.Text) = False Then
    96. If Combokarte.Text <> " select..." Then
    97. Combokarte.Items.Add(CStr(Combokarte.Text))
    98. speichernKarte()
    99. End If
    100. End If
    101. Combokarte.SelectedItem = Combokarte.Text
    102. End Sub
    103. '______________________________________________________________________________________
    104. 'Speichern
    105. Private Sub speichernKarte()
    106. Dim sw As New System.IO.StreamWriter(Application.StartupPath & "\Karte.txt")
    107. For Each item As String In Combokarte.Items
    108. sw.WriteLine(item)
    109. Next
    110. sw.Close()
    111. End Sub
    112. Private Sub speichernDatumList()
    113. Dim sw As New System.IO.StreamWriter(Application.StartupPath & "\DatumList.txt")
    114. For Each item As String In ListDatum.Items
    115. sw.WriteLine(item)
    116. Next
    117. sw.Close()
    118. End Sub
    119. Private Sub speichernKarteList()
    120. Dim sw As New System.IO.StreamWriter(Application.StartupPath & "\KarteList.txt")
    121. For Each item As String In ListKarte.Items
    122. sw.WriteLine(item)
    123. Next
    124. sw.Close()
    125. End Sub
    126. Private Sub speichernSpielList()
    127. Dim sw As New System.IO.StreamWriter(Application.StartupPath & "\SpielList.txt")
    128. For Each item As String In ListSpiel.Items
    129. sw.WriteLine(item)
    130. Next
    131. sw.Close()
    132. End Sub
    133. '______________________________________________________________________________________
    134. 'Laden
    135. Private Sub LadenDatumList()
    136. If System.IO.File.Exists(Application.StartupPath & "\DatumList.txt") Then
    137. Dim SR As New System.IO.StreamReader(Application.StartupPath & "\DatumList.txt")
    138. Do Until SR.EndOfStream
    139. ListDatum.Items.Add(SR.ReadLine)
    140. Loop
    141. SR.Close()
    142. End If
    143. End Sub
    144. Private Sub LadenKarte()
    145. If System.IO.File.Exists(Application.StartupPath & "\Karte.txt") Then
    146. Dim SR As New System.IO.StreamReader(Application.StartupPath & "\Karte.txt")
    147. Do Until SR.EndOfStream
    148. Combokarte.Items.Add(SR.ReadLine)
    149. Loop
    150. SR.Close()
    151. End If
    152. End Sub
    153. Private Sub LadenKarteList()
    154. If System.IO.File.Exists(Application.StartupPath & "\KarteList.txt") Then
    155. Dim SR As New System.IO.StreamReader(Application.StartupPath & "\KarteList.txt")
    156. Do Until SR.EndOfStream
    157. ListKarte.Items.Add(SR.ReadLine)
    158. Loop
    159. SR.Close()
    160. End If
    161. End Sub
    162. Private Sub LadenSpielList()
    163. If System.IO.File.Exists(Application.StartupPath & "\SpielList.txt") Then
    164. Dim SR As New System.IO.StreamReader(Application.StartupPath & "\SpielList.txt")
    165. Do Until SR.EndOfStream
    166. ListSpiel.Items.Add(SR.ReadLine)
    167. Loop
    168. SR.Close()
    169. End If
    170. End Sub
    171. Private Sub LadenComboStatKarte()
    172. If System.IO.File.Exists(Application.StartupPath & "\Karte.txt") Then
    173. Dim SR As New System.IO.StreamReader(Application.StartupPath & "\Karte.txt")
    174. Do Until SR.EndOfStream
    175. comboStatKarte.Items.Add(SR.ReadLine)
    176. Loop
    177. SR.Close()
    178. End If
    179. End Sub
    180. 'Map löschen
    181. Private Sub cmdDel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDel.Click
    182. Combokarte.Items.Remove(Combokarte.SelectedItem)
    183. Combokarte.Text = " select..."
    184. speichernKarte()
    185. End Sub
    186. 'Training hinzufügen
    187. Private Sub StartTrain_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartTrain.Click
    188. If comboTag.Text <> "" Then
    189. If comboMonat.Text <> "" Then
    190. If comboJahr.Text <> "" Then
    191. If Combokarte.Text <> "" Then
    192. If Combokarte.Text <> " select..." Then
    193. If comboSpiel.Text <> "" Then
    194. 'Karte hinzufügen
    195. If Combokarte.Text <> " select..." Then
    196. ListKarte.Items.Insert(0, Combokarte.SelectedItem)
    197. End If
    198. 'Spielart hinzufügen
    199. ListSpiel.Items.Insert(0, comboSpiel.SelectedItem)
    200. 'Datum hinzufügen
    201. ListDatum.Items.Insert(0, CStr(comboTag.SelectedItem & ". " & comboMonat.SelectedItem & " " & comboJahr.SelectedItem))
    202. speichernDatumList()
    203. speichernKarteList()
    204. speichernSpielList()
    205. Else
    206. MsgBox("Geb alle Werte richtig ein")
    207. End If
    208. Else
    209. MsgBox("Geb alle Werte richtig ein")
    210. End If
    211. Else
    212. MsgBox("Geb alle Werte richtig ein")
    213. End If
    214. Else
    215. MsgBox("Geb alle Werte richtig ein")
    216. End If
    217. Else
    218. MsgBox("Geb alle Werte richtig ein")
    219. End If
    220. Else
    221. MsgBox("Geb alle Werte richtig ein")
    222. End If
    223. End Sub
    224. '______________________________________________________________________________________
    225. 'Auswahl
    226. Private Sub ListDatum_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListDatum.SelectedIndexChanged
    227. Dim Auswahl As Integer
    228. Auswahl = ListDatum.SelectedIndex
    229. If Auswahl > -1 Then
    230. ListKarte.SelectedIndex = Auswahl
    231. ListSpiel.SelectedIndex = Auswahl
    232. End If
    233. End Sub
    234. Private Sub ListKarte_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListKarte.SelectedIndexChanged
    235. Dim Auswahl As Integer
    236. Auswahl = ListKarte.SelectedIndex
    237. If Auswahl > -1 Then
    238. ListDatum.SelectedIndex = Auswahl
    239. ListSpiel.SelectedIndex = Auswahl
    240. End If
    241. End Sub
    242. Private Sub ListSpiel_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListSpiel.SelectedIndexChanged
    243. Dim Auswahl As Integer
    244. Auswahl = ListSpiel.SelectedIndex
    245. If Auswahl > -1 Then
    246. ListKarte.SelectedIndex = Auswahl
    247. ListDatum.SelectedIndex = Auswahl
    248. End If
    249. End Sub
    250. '______________________________________________________________________________________
    251. 'Training löschen
    252. Private Sub cmdTrainingLoeschen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdTrainingLoeschen.Click
    253. Dim Auswahl As Integer
    254. Auswahl = ListDatum.SelectedIndex
    255. ListKarte.SelectedIndex = Auswahl
    256. ListKarte.Items.Remove(ListKarte.SelectedItem)
    257. ListDatum.SelectedIndex = Auswahl
    258. ListDatum.Items.Remove(ListDatum.SelectedItem)
    259. ListSpiel.SelectedIndex = Auswahl
    260. ListSpiel.Items.Remove(ListSpiel.SelectedItem)
    261. speichernDatumList()
    262. speichernKarteList()
    263. speichernSpielList()
    264. End Sub
    265. 'Statistik anzeigen
    266. Private Sub cmdStatistik_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdStatistik.Click
    267. If GroupBox1.Visible = True Then
    268. GroupBox1.Visible = False
    269. GroupBox3.Visible = True
    270. cmdStatistik.Text = "Verlauf"
    271. Else
    272. GroupBox1.Visible = True
    273. GroupBox3.Visible = False
    274. cmdStatistik.Text = "Statistik"
    275. End If
    276. End Sub
    277. '_______________________________________________________________________________________
    278. Private Sub cmdErstellen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdErstellen.Click
    279. End Sub
    280. 'HeuteButton
    281. Private Sub cmdHeute_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdHeute.Click
    282. comboTag.Text = CInt(My.Computer.Clock.GmtTime.Day)
    283. comboJahr.Text = CInt(My.Computer.Clock.GmtTime.Year)
    284. If CStr(My.Computer.Clock.GmtTime.Month) = 1 Then
    285. comboMonat.Text = "Januar"
    286. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 2 Then
    287. comboMonat.Text = "Februar"
    288. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 3 Then
    289. comboMonat.Text = "März"
    290. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 4 Then
    291. comboMonat.Text = "April"
    292. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 5 Then
    293. comboMonat.Text = "Mai"
    294. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 6 Then
    295. comboMonat.Text = "Juni"
    296. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 7 Then
    297. comboMonat.Text = "Juli"
    298. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 8 Then
    299. comboMonat.Text = "August"
    300. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 9 Then
    301. comboMonat.Text = "September"
    302. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 10 Then
    303. comboMonat.Text = "Oktober"
    304. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 11 Then
    305. comboMonat.Text = "November"
    306. ElseIf CStr(My.Computer.Clock.GmtTime.Month) = 12 Then
    307. comboMonat.Text = "Dezember"
    308. End If
    309. End Sub
    310. End Class

    (Anhang: app.jpg)

    In diesem Programm kann man einen Trainingsverlauf für Counterstrike Source speichern und sich Statistiken anzeigen lassen z.B. Wie oft hab ich die Karte de_dust2 gespielt

    An der Stelle:

    VB.NET-Quellcode

    1. Private Sub cmdErstellen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdErstellen.Click
    2. End Sub


    ...möchte ich die Filtereinstellungen wirken lassen. (Anhang: Stats.jpg)

    Wie oft hab ich de_dust2 gespielt? -> ist kein Problem das in einem Label (in diesem Fall Label9.Text) wiederzugeben
    Wie oft habe ich 3on3 gespielt? -> auch kein Problem darzustellen...

    ... damit komme ich zu meinem Problem:

    Ich will mir anzeigen lassen wie oft ich die Karte "de_dust2" als Spieltyp: "3on3" gespielt hab...

    ...sprich das Programm muss erkennen ob die Karte und die Spielart zutrifft um den "wie oft gespielt" Wert zu ermitteln.

    Ich habe stundenlang rumprobiert, wüsste auch nicht wie ich das googlen soll...

    ...Bitte helft mir
    Bilder
    • Stats.jpg

      320,08 kB, 807×479, 158 mal angesehen
    • app.jpg

      257,79 kB, 806×480, 164 mal angesehen
    Ich hab mir deinen Code nicht genau angeschaut, da er nicht unterteilt ist und auch nicht mit Expandern geteilt wurde, dass machts mir schwer zum lesen.

    Aber nun zum Problem:
    - Jedes Item aus ListKarte auslesen
    - Den Index des aktuellen ListKarte Item auslesen
    - Das Item aus der zweiten Liste (ListModus) mit dem Index bestimmen
    - If Abfrage ob item1 = "bla" And item2 = "blu" ist

    Mfg Dancger
    MESS WITH THE BEST, DIE LIKE THE REST! :evil:
    n'paar Links: DNS Tools, Steal WA DB, Droidsheep...
    mir scheint, das ist eine etwas komplexere Datenverarbeitung (naja, bischen). Da muß man mit Datenmodellierung anfangen, also zunächst mal klären, was wie zusammenhängt.
    Zunächst mal scheintes mehrere Spieltypen zu geben.
    Dann gibtes offsichtlich mehrere Karten.

    Weiters willst du wohl auch nach Monaten gruppieren, also gibt es wohl auch mehrere Monate.

    Mit Listboxen, Listview, und normalen Auflistungen kann man das nicht vernünftig lösen.
    Denn es besteht eine 1:n-Beziehung zwischen Spieltyp und Training, und ebenfalls eine 1:n-Beziehung zw. Karten und Trainings.

    Für Spieltyp->Training benötigst du eine Liste von Spieltypen, und jeder Spieltyp müsste eine Liste von Trainings enthalten.
    Karte->Training ebenso - bräuchte eine Liste von Karten, und jede Karte müsste eine Liste von Trainings enthalten.

    Und wenn du dass dann so machst, hast du ein echtes Problem, denn dieselben Trainings finden sich dann in ganz verschiedenen Listen wieder, mw. im 3. Spieltyp und in der 2. Karte.

    Wenn du das gar ohne Listen versuchst, also nur in Listboxen und Listviews, wirds noch ärger, denn Controls können mit differenzierten Datentypen, wie sie für Spieltyp, Karte und Training zu schaffen wären, gar nicht gescheit umgehen.

    Am einfachsten ist hier mal wieder die Dataset-Technologie - die Struktur könnte so aussehen:

    So ein Dataset würde alle erforderlichen Daten der App beinhalten, und alles zusammen mit je einer Codezeile auf Platte lesen/schreiben können.

    Die Tabellen könnte man beliebig aufbereitet zur Anzeige bringen:
    • Entweder alle Spieltypen in einer Combobox, und alle damit gespielten Trainings im Datagridview
    • Oder alle Trainings insgesamt, unter Angabe von Spieltyp und Karte
    • Oder alle Karten in einer Combo, und alle damit gespielten Trainings im Datagridview
    • Oder auch alle Karten in einem Datagridview, und zu jeder Karte alle damit gespielten Trainings in einem anderen Datagridview
    • etc.
    Man könnte auch Filter setzen für Zeitbereiche, die betrachtet werden sollen.

    Und einiges mehr (Punktstände, aufsummierte Punktstände, etc).

    oh - verschiedene Spieler habich noch garnicht berücksichtigt im Datenmodell - ist im typisierten Dataset problemlos möglich, hingegen ohne dieses kaum zu handhaben.
    Ich hab mir deinen Code nicht genau angeschaut, da er nicht unterteilt ist und auch nicht mit Expandern geteilt wurde, dass machts mir schwer zum lesen.
    Würde den Code gerne lesbarer machen weil ich ihn auch sehr unübersichtlich finde. Habe noch nie etwas größeres geschrieben, deswegen wäre es nett wenn du mir kurz verätst was du mit Expandern meinst.

    - Jedes Item aus ListKarte auslesen
    - Den Index des aktuellen ListKarte Item auslesen
    - Das Item aus der zweiten Liste (ListModus) mit dem Index bestimmen
    - If Abfrage ob item1 = "bla" And item2 = "blu" ist
    Ja genau so hab ich mir das auch erst vorgestellt, nur wenn man bedenkt das evtl. später noch mehr Kriterien beim Filtern des Verlaufs zu berücksichtigen sind wie z.B. (Datum und Ergebnis) Dann hört sich die Lösung mit der Dataset-Technologie schon wirklich sinnvoller an...

    Die Tabellen könnte man beliebig aufbereitet zur Anzeige bringen:
    • Entweder alle Spieltypen in einer Combobox, und alle damit gespielten Trainings im Datagridview
    • Oder alle Trainings insgesamt, unter Angabe von Spieltyp und Karte
    • Oder alle Karten in einer Combo, und alle damit gespielten Trainings im Datagridview
    • Oder auch alle Karten in einem Datagridview, und zu jeder Karte alle damit gespielten Trainings in einem anderen Datagridview
    • etc.
    Man könnte auch Filter setzen für Zeitbereiche, die betrachtet werden sollen.

    Und einiges mehr (Punktstände, aufsummierte Punktstände, etc).
    Also ist damit gemeint das ich die listboxen durch eine Tabelle ersetzen soll?
    Hast du evtl. ein brauchbares Tutorial für mich oder würdest du es mir anhand meines Programmes ein Beispiel erstellen?

    Danke für eure Aufmerksamkeit und schnelle Hilfe an diesem Projekt

    marcel87 schrieb:

    Also ist damit gemeint das ich die listboxen durch eine Tabelle ersetzen soll?

    neinneinnein. eiglich für jede Anwendung, besonders aber für Datenverarbeitungen isses eminent wichtig, dass man sich angewöhnt, schon im Denken zwischen Controls (listboxen) und Daten (Tabellen) zu trennen.

    Eine Tabelle kann eine Listbox nicht ersetzen (jdfs. wenn du mit Tabelle eine DataTable des Datasets meinst).
    Eine DataTable ist eine Datenstruktur.
    Controls sind etwas zum Anzeigen von Daten.

    Nun könnteman darauf verfallen, Daten in die Controls hineinzutun (Listbox.Items.Add() und sowas). Aber damit kommt man in einer Datenverarbeitung auch nicht weit, denn die Beziehungen zwischen den Daten kann man nicht mit in die Controls hineintun, und deshalb kommt da recht bald Murx heraus.
    Daher muß man die Controls an die Daten binden. Das ist ein fabelhaftes Verfahren, bei dem die Daten in der Datenstruktur bleiben, und gleichzeitig durch die Controls angezeigt werden (inklusive der Möglichkeit, die Daten zu verändern).
    Hast du evtl. ein brauchbares Tutorial für mich oder würdest du es mir anhand meines Programmes ein Beispiel erstellen?
    Für die Datenstruktur habe ich dir ein Beispiel gezeigt. Ist natürlich nur ein unbrauchbares Beispiel, denn ich kenne dein Programm nicht, und kann daher kein korrektes Datenmodell erstellen.

    Letzteres ist erstmal das wichtigste: dass die Anforderungen geklärt sind, die sich daraus als erforderlich ergebenden Datenstrukturen und ihre Beziehungen untereinander.

    Für Datenmodellierung muss man vollkommen abschalten von der Frage "wie zeige ich das an - Listbox, combobox, listview, datagridview...?"

    Das ist zunächst komplett irrelevant - um ein Datenmodell anzuzeigen, hat man alle möglichkeiten, aber man kann den 2. Schritt nicht vor dem ersten tun.

    Also was du machen kannst ist überlegen, ob dir das gezeigte Datenmodell plausibel erscheint, und ob und was alles daran noch fehlt.

    Erst wenn das Datenmodell fertig ist, als typisiertes Dataset, braucht man sich Gedanken über Controls zu machen, und für Einsteiger ists üblicherweise sehr überraschend, wie einfach dieser 2.Schritt ist, wenn man den ersten korrekt ausgeführt hat.
    @ Marcel87

    Das was Du vorhast kannst Du nur mit einer Datenbank im Hintergrund vernünftig ausführen.

    Ob Dataset per OleDB oder ADO-OCDB oder was für ein Zugriffsmodell Du dann auf die DB nutzt ist erstmal völlig latte und auch ein Stück weit abhängig vom gewählten DBMS.

    Für diese Mini-Vorhaben von Dir reicht eine Single-File-DB wie MS-Access oder SQLite als Backend völlig aus.

    Und wenn Du nun Deine App auf eine DB als Backend umstellst, dann ist der erste Punkt den es zu erfüllen gilt ein korrektes Datenmodell zu erstellen (ERM) ... ohne das kannste eh alles in die Tonne treten. Und dabei lässt Du jegliche Überlegungen über Zugriff oder Auswertung aussen vor! Solche Überlegungen haben in einem ERM aber absolut gar nichts zu suchen ... diese Dinge regeln sich nämlich völlig von alleine wenn das ERM passt.

    ErfinderDesRades hat ja schon einen Ansatz gezeigt der meiner Meinung nach aber nur als Grobprinzip dienen kann und noch nicht praxistauglich ist.

    Du musst jetzt also zuerst mal anfangen zu überlegen mit welchen Entitäten Du umgehen willst. Entität in diesem Falle kannst Du stellvertretend mal für reale Dinge nehmen ... die Karten, das Training, die Spieler etc., etc. ... . Dann erstellst Du die Argumente (z.B. Eintität Karten, Argumente: KartenID, KartenName, KartenTyp, KartenWert oder so in der Richtung ^^) für die Entitäten und normalisierst sie bis zur 3ten Normalform (sprich salopp in Kurzform: jedes Agument beinhaltet EINEN Wert der ALLEINE für sich Sinn macht und NICHT mehr).

    Und dann überlegst Du wie die Entitäten zusammen hängen und stellst die Beziehungstypen (m:n, 1:n oder seltener 1:1) her. Z.B. an einem Training können keine bis mehrere Karten gespielt werden, eine Karte kann an keinem oder mehreren Training's gespielt werden ... klassischer Fall einer m:n Beziehung.

    Wenn Du noch nie mit einer DB gearbeitet hast, dann würde ich Dir dringend empfehlen Dir erstmal eine Grundlektüre zu Gemüte zu führen.

    Wenn Du bei einem Schritt Hilfe brauchst einfach hier posten. ;)

    Gruß

    Rainer

    Edit: ErfinderDesRades war schneller. ^^

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „raist10“ ()

    raist10 schrieb:

    ...kannst Du nur mit einer Datenbank im Hintergrund vernünftig ausführen.
    Irrtum.
    In DB-Programmierung ohne Datenbank zeige ich die einfachste Möglichkeit, die es gibt.
    Den ganzen Trara mitte Datenbank kann man sich sparen, und wenn man nicht darauf verzichten möchte oder kann (etwa bei DatenMengen > 50MB, oder bei Multi-User-Datenbanken), braucht man immer noch dasselbe typisierte Dataset, um im Client die Datenverarbeitung vernünftig auszuprogrammieren.
    ...dann ist der erste Punkt den es zu erfüllen gilt ein korrektes Datenmodell zu erstellen (ERM) ... ohne das kannste eh alles in die Tonne treten. Und dabei lässt Du jegliche Überlegungen über Zugriff oder Auswertung aussen vor! Solche Überlegungen haben in einem ERM aber absolut gar nichts zu suchen ... diese Dinge regeln sich nämlich völlig von alleine wenn das ERM passt.
    :thumbsup: genau meine Rede :thumbsup:

    ErfinderDesRades hat ja schon einen Ansatz gezeigt der meiner Meinung nach aber nur als Grobprinzip dienen kann und noch nicht praxistauglich ist.
    wie gesagt: Mein Ansatz geht über "GrobPrinzip" weit hinaus - er beinhaltet die vollständige Lösung.
    Der Dataset-Designer ist ein ERM - Designer (s. bild oben), und ein typisiertes Dataset ist ein relationales Datenmodell.
    Und Dataset.ReadXml/.WriteXml sind bis 50MB Daten schneller als der kleinste DB-Zugriff über einen DB-Provider.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Also hab ich das jetzt richtig verstanden? Ich soll praktisch z.B. mit Access eine Datenbank erstellen in dem mein Programm seine Daten speichern kann und damit arbeiten kann?

    Wie sieht so eine Abfrage in Code denn aus?
    Achtung: Hier haben wir 2 Köche für denselben Brei.
    Nach meinem Ansatz brauchst du nur ein typisiertes Dataset. Nach raist10 brauchst du eine Datenbank und ein typisiertes Dataset.

    Obwohl - möglicherweise wird raist10 die Datenverarbeitung im Client auch anders regeln wollen, mit untypisiertem Dataset oder mit selbstprogrammierten Datenklassen - von beidem rate ich dringend ab.

    Aber im wichtigsten stimme ich mit raist10 vollständig überein: Vergiss erstmal die praktische Umsetzung, und fang endlich mal an, über dein Datenmodell nachzudenken.
    (Ja, das ist sicher ungewohnt und schwierig, sich drauf einzulassen. Aber wie gesagt: man kann nicht den zweiten Schritt vor dem ersten tun)

    Du könntest etwa selbst ein Dataset aufsetzen, gugge "DatasetOnly" auf Movie-Tuts.
    Ist ja egal, was du später damit machst - hauptsache du hast damit ein Instrument, mit dem du ein ERM (Entity-Relationship-Model) modellieren kannst.
    Davon kannste Screenshots posten, und dann hat man eine Basis, über die man diskutieren kann.
    Okay... werde einen Schritt nach dem nächsten tun und das erst mal so hinnehmen wie gesagt... schließlich will ich ja am Ende auch den AHA Effekt haben....

    Nur eins noch bevor ich mich in die Materie stürze... ich will schnell eine Übergangslösung finden um jemandem das Programm vorzuführen und da würde es reichen wenn erst mal dieses eine Problem gefixt ist....

    Habe es Hiermit versucht:

    VB.NET-Quellcode

    1. Private Sub cmdErstellen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdErstellen.Click
    2. ListSpiel.SelectedIndex = 0
    3. ListKarte.SelectedIndex = 0
    4. For Each Item In ListKarte.Items
    5. If Item = comboStatKarte.Text Then
    6. If ListSpiel.SelectedItem = comboStatSpiel.Text Then
    7. Label9.Text += 1
    8. End If
    9. End If
    10. ListSpiel.SelectedIndex += 1
    11. ListKarte.SelectedIndex += 1
    12. Next
    13. End Sub


    Kriege aber bloß

    Die Liste, an die der Enumerator gebunden ist, wurde geändert. Ein Enumerator kann nur verwendet werden, wenn die Liste nicht geändert wird.
    zurück.... mhhhhh

    Es muss doch möglich sein diese 2 Bedingungen zu Prüfen...
    nein, ist nicht möglich.

    VB.NET-Quellcode

    1. If Item = comboStatKarte.Text Then
    2. If ListSpiel.SelectedItem = comboStatSpiel.Text Then
    Item ist ein ListboxItem oder ein ListviewItem oder sonstwas, aber vmtl. kein String. comboStatKarte.Text ist aber ganz sicher ein String.
    Natürlich schlägt so ein Vergleich immer fehl.

    Sowas ist Strict Off - Schrott. Option Strict On!

    Achso - vlt. doch möglich.

    VB.NET-Quellcode

    1. If Item.Text = comboStatKarte.Text Then
    2. 'oder
    3. If Item.ToString() = comboStatKarte.Text Then
    , je nachdem, ob Item eine .Text-Property hat, und ob .ToString einen für den Vergleich sinnvollen String ergibt

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Irrtum.
    In DB-Programmierung ohne Datenbank zeige ich die einfachste Möglichkeit, die es gibt.

    Den ganzen Trara mitte Datenbank kann man sich sparen, und wenn man nicht darauf verzichten möchte oder kann (etwa bei DatenMengen > 50MB, oder bei Multi-User-Datenbanken), braucht man immer noch dasselbe typisierte Dataset, um im Client die Datenverarbeitung vernünftig auszuprogrammieren.


    Einen Datenbankzugriff zu programmieren ist doch mindestens genauso einfach und überhaupt kein Trara. Das sind im besten Falle 10 Zeilen und Feierabend.

    Und um eine Datenbank wie MS-Access zu verwalten braucht man doch kein typisiertes DataSet, das simple ADO-Net-Objektmodell ist mehr als ausreichend.

    Der Dataset-Designer ist ein ERM - Designer (s. bild oben), und ein typisiertes Dataset ist ein relationales Datenmodell.
    Und Dataset.ReadXml/.WriteXml sind bis 50MB Daten schneller als der kleinste DB-Zugriff über einen DB-Provider.


    Ka wie schnell DataSet.ReadXML/.WriteXML ist aber auf ein Access-DB oder eine SQLite-DB habe ich ohne jegliche Verzögerung ein SQL-Statement ausgeführt und die Daten fein säuberlich vorliegen. Ich denke Du verwechselst hier Server-DB's mit Single-File-DB's, bei letzteren ist der Connection-Aufbau genauso schnell wie auf eine XML-Datei und bei Server-DB's stelle ich im Zweifel eine permaneten Verbindung her und halte die für die Dauer der App-Sitzung aktiv.

    Ganz ehrlich, ich habe mich mit dem Behelfsmodell typisierte Datasets nicht auseinander gesetzt ... wofür auch wenn ich einfacher und schneller mit voller SQL-Unterstützung ein Single-File-DB ansprechen kann und dazu noch in der Datenbank Views und Trigger (nicht Access, aber SQlite) ausnutzen kann inkl. Sicherheitsmechanismen wie Passwort-Schutz der ausgelagerten Daten.

    Aber Du kannst mich gerne überzeugen wo die Vorteile eines typisierten Datasets gegenüber einer DB liegen, denn irgendwo hänge ich noch bei der Meinung wieso mit Mäxchen arbeiten wenn ich gleich mit Max arbeiten kann ... man muss natürlich nicht immer mit Big-Max (DB-Server) arbeiten. ^^


    Nach meinem Ansatz brauchst du nur ein typisiertes Dataset. Nach raist10 brauchst du eine Datenbank und ein typisiertes Dataset.


    Eben nein ... wozu ein typisiertes Dataset wenn ich eine komplette DB im Background liegen habe? Meiner Meinung nach völlig unnötig.


    Obwohl - möglicherweise wird raist10 die Datenverarbeitung im Client auch anders regeln wollen, mit untypisiertem Dataset oder mit selbstprogrammierten Datenklassen - von beidem rate ich dringend ab.


    Das musste mir erklären.

    Für eine Access-DB als BE werde ich einen Teufel tun was anderes als einen ADO-NET-Zugriff zu nutzen (okay, der DAO-Zugriff tut es auch ^^).

    Für die Datenverarbeitung gibt es nichts effektiveres als das pure SQL-Statement das serverseitig verarbeitet wird und dem Client nur die gewünschten Ergebnisse zurück wirft, z.B. durch Views. Bei aktiven DBMS ist der Vorteil noch größer als bei passiven DBMS wie Access oder SQLite, aber auch bei den letzten beiden schlagen meines Wissens nach Views jegliche clientseitige Verarbeitung.

    Bei einem XML musst Du erstmal das komplette XML laden wenn Du eine einfach Abfrage über mehrere Tables hinweg durchführst, bei einer DB feuere ich das SQL-Statement und habe die Info die ich brauche und Feierabend. Schnelligkeit habe ich genauso und im Zweifel öffne ich wie schon gesagt die Connection bei Start der App zur DB und halte die konstant aktiv, dann bin ich aber mit der Geschwindigkeit jenseits von Gut und Böse.

    Aber gut ... ich werde mich mal mit dem Thema typisierte DataSets irgendwann näher auseinander setzen und gucken ob es da wirklich eklatante Vorteile geben sollte, aber mir würde gerade wirklich keiner einfallen.

    Gruß

    Rainer
    Habs satt mich mit der zwischenlösung zu befassen... muss aber leider los jetzt zur Arbeit...

    Also in so einem weniger komplexem Programm brauche ich doch nur eine Datenbank mit einer Tabelle die das eingetragene Spiel in sich als Verlauf speichert... die dann die Spalten Karte / Spieltyp / Ergebnis beinhaltet oder... ? Und dann entsprechend eine Abfrage wie oft ich jetzt z.B. die Karte dust im 3on3 Spieltyp gespielt und gewonnen hab... dazu müssten dann ja bloß alle drei Spalten mit den eingegebenen Daten übereinstimmen... sorry für die schlechte Rechtschreibung, habs eilig

    Also Da ich echt nur die hälfte von dem über DB's geschriebenen Sachen hier verstehe sollte ich mich wohl erst mal mit dem Thema DatenBanken beschäfftigen...

    Hat jemand da einen guten Einstieg für mich der sich evtl. auch in Bezug mit VB2010 bringen lässt...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „marcel87“ ()

    raist10 schrieb:

    Einen Datenbankzugriff zu programmieren ist doch mindestens genauso einfach und überhaupt kein Trara. Das sind im besten Falle 10 Zeilen und Feierabend.

    Ich bin nicht sicher, was du mit "einen Zugriff" meinst. Kriegst du den gesamten DB-Zugriff einer Anwendung mit mw. 3 DB-Tabellen, die zB in 3 Views gezeigt und bearbeitet werden sollen, mit laden und speichern in 10 Zeilen hin? (ich in 2 Zeilen ;)).
    Oder brauchst du für jeden Zugriff 10 Zeilen?
    Hast du deine Daten dann auch schon in einer Form, die du in Combos, Datagridviews etc. anzeigen und bearbeiten kannst?
    Also Laden, bearbeiten (löschen, zufügen, editieren, zb im DatagridView), rückspeichern aller Änderungen aller Views, in 10 Zeilen?

    Kannst du mir das mal zeigen?
    Als Beispiel schlage ich die Solution von DB-Programmierung ohne Datenbank vor - die ist gradezu minimalistisch, eigentlich zu simpel, enthält nur eine 1:n-Relation, nichtmal eine m:n.
    Besser wäre, du demonstrierst dein vorgehen an Minikass, aus DataExpressions - dassis immerhin eine m:n.
    Das berechnen der Summen kannste meinetwegen erst noch weglassen - da hat Dataset einen Heimvorteil mit berechneten Spalten.
    Ka wie schnell DataSet.ReadXML/.WriteXML ist aber auf ein Access-DB oder eine SQLite-DB habe ich ohne jegliche Verzögerung ein SQL-Statement ausgeführt und die Daten fein säuberlich vorliegen. Ich denke Du verwechselst hier Server-DB's mit Single-File-DB's, bei letzteren ist der Connection-Aufbau genauso schnell wie auf eine XML-Datei und bei Server-DB's stelle ich im Zweifel eine permaneten Verbindung her und halte die für die Dauer der App-Sitzung aktiv.

    Ich habs mit Access-Files gemessen - Dataset war glaub so 4* schneller.
    SQLite habichnich.
    Der Connection-Aufbau ist ungleich langsamer. Da muß ja iwie ein Dienst angesprochen werden, ein SQL-Dingsbums kompiliert werden, die Datei ausgelesen und die Daten eingesammelt, und das dann wieder an den Dienst (der DBProvider), dassers zurückschickt.
    Ist auch egal, denn ob über Provider oder die Datei direkt eingelesen - beides ist so schnell, dass der User nix davon mitkriegt.

    Mit clientseitiger Verarbeitung meine ich, die Daten, wenn sie beim Client sind, in den Controls anzuzeigen, dass der User da Änderungen vornehmen kann. Hat nix mittm DBProvider oder annerem Data-Access zu tun.

    Mittm Xml hat man bei Dataset.WriteXml/.ReadXml überhaupt nix am Hut. Man gibt die Datei an und das Dataset befüllt sich eben.

    Der eklatante Vorteil eines typisierten Datasets ist seine Typisierung. Ein Datensatz mw mit Datum und Zahl liegt als DataRow vor, mit den Properties Datum As DateTime und Zahl As Integer - man muß keine DataReader-Columns mit String-Schlüsseln abrufen und auf den gewünschten Wert casten oder sowas.

    Da die Datensätze bereits zur Designzeit mit allen korrekt typisierten Properties bekannt sind, kann man im FormDesigner Databindings zu den Anzeige-Controls einstellen - hmm - wenndes nicht kennst, könnte sein, dass dus dir gar nicht vorstellen kannst, wie komfortabel und mächtig das ist.

    Die typisierung ist jdfs. der Grund, warum man Datenbank-Anwendungen nur mit EntityFramework, Linq2Sql - DataClasses, oder eben mit typisierten Datasets programmieren sollte.
    Dass Dataset sich auch ohne DB abspeichern kann, ist eiglich ein NebenFeature (allerdings unerhört nützlich, und EF und L2S hams halt nicht)

    marcel87 schrieb:

    Also in so einem weniger komplexem Programm brauche ich doch nur eine Datenbank mit einer Tabelle die das eingetragene Spiel in sich als Verlauf speichert... die dann die Spalten Karte / Spieltyp / Ergebnis beinhaltet oder... ? Und dann entsprechend eine Abfrage wie oft ich jetzt z.B. die Karte dust im 3on3 Spieltyp gespielt und gewonnen hab... dazu müssten dann ja bloß alle drei Spalten mit den eingegebenen Daten übereinstimmen... sorry für die schlechte Rechtschreibung, habs eilig


    Nicht ganz ... ein ERM ist schon deutlich komplexer als Du es Dir da gerade vorstellst. ;)

    Vor allem bei den Anforderungen die da raus kommen in Deinem Text wird es mit 1 Table mit absoluter Sicherheit nicht getan sein.

    marcel87 schrieb:

    Also Da ich echt nur die hälfte von dem über DB's geschriebenen Sachen hier verstehe sollte ich mich wohl erst mal mit dem Thema DatenBanken beschäfftigen...


    Ist alles halb so wild, einfach mal reinfuchsen und dann verstehst Du auch ganz schnell um was es hier geht ... wir reden hier nur über Basics, in dem Sinne keine Panik. Klingt alles schlimmer als es ist.

    marcel87 schrieb:

    Hat jemand da einen guten Einstieg für mich der sich evtl. auch in Bezug mit VB2010 bringen lässt...


    Einstieg in die Datenbankwelt hat ABSOLUT gar nichts mit einer Programmierumgebung zu tun.

    Um den wirst Du aber so oder so nicht drumherum kommen, egal ob Du Dich für eine echte DB im Hintergrund entscheidest oder über das Behelfsmodell von ErfinderDesRades. Das ERM muss korrekt stehen sonst hast Du nur Ärger im Nachgang ... i.d.R. dahin gehend das Du alles zuvor gemachte in die Tonne hauen kannst und nochmal von vorne anfängst.

    Zum Einstieg ist die Seite gut geeignet: v.hdm-stuttgart.de/~riekert/lehre/db-kelz/

    Wenn Du das alles intus hast dann kannste mit dem Datenmodell anfangen. *g*

    Wenn Du mit einer richtigen DB im Hintergrund arbeitest dann wäre es auch sinnvoll Dich ein wenig in SQL einzufuchsen, aber das ist nicht wirklich schwierig und für Deine Zwecke reichen eh bereits die SQL-Grundzüge aus um alles umzusetzen.

    Gruß

    Rainer
    @ ErfinderDesRades

    So nachdem ich jetzt 30 Minuten warten musste, hier die Antworten. ;)


    Ich bin nicht sicher, was du mit "einen Zugriff" meinst.


    Nur den Part den Du bei Dir mit XMLRead umsetzt, also rein die Connection zur DB aufbauen. Also quasi:

    VB.NET-Quellcode

    1. Dim xxx As New XYZConnection
    2. xxx.ConnString = “Data Source:= … “
    3. xxx.Open()


    Okay … sind halt nur 3 Zeilen.

    Damit ist erstmal das gleiche passiert was bei Dir mit dem einlesen der XML-Datei geschehen ist … man hat nun Zugriff auf alle Daten.


    Kriegst du den gesamten DB-Zugriff einer Anwendung mit mw. 3 DB-Tabellen, die zB in 3 Views gezeigt und bearbeitet werden sollen, mit laden und speichern in 10 Zeilen hin? (ich in 2 Zeilen ).


    Du wirfst hier was durcheinander. Der Zugriff auf die Daten-Inhalte hat erstmal überhaupt nichts mit der Verwendung der Daten-Inhalte in der Anwendung zu tun. Eine Bindung der DataSource an Formulare und Objekte bekommt man auf dem gleichen Wege hin wie Du. Das hat nichts damit zu tun ob man eine DB im Hintergrund hat oder die Daten in einer XML-Datei gespeichert hat.


    Kannst du mir das mal zeigen?


    Brauche ich nicht, funktioniert fast auf dem exakt gleichen Wege, nur mit dem Unterschied das die Basis eben eine Connection auf eine Datenbank darstellt und bei Dir die Basis eine XML-Datei ist. Da wo Du die XML einliesst, stellste mit der DB im Hintergrund einfach eine Db-Connection her und das war’s.


    Mit clientseitiger Verarbeitung meine ich, die Daten, wenn sie beim Client sind, in den Controls anzuzeigen, dass der User da Änderungen vornehmen kann. Hat nix mittm DBProvider oder annerem Data-Access zu tun.


    Das ist was anderes als ich meine. Es ist halt ein Unterschied ob ich komplette 10-20 MB Daten im Speicher vorhalten muss oder ob ich mir nur mal schnell 10 Byte Daten vom Backend anliefern lasse zur Verarbeitung.


    Mittm Xml hat man bei Dataset.WriteXml/.ReadXml überhaupt nix am Hut. Man gibt die Datei an und das Dataset befüllt sich eben.


    Natürlich hat das was mit XML zu tun, bzw. ist das ein reines XML-Handling.

    Das was Du als ERM-Tool ansiehst ist nichts anderes als ein GUI zur Erzeugung eines XSD-Schemas für das typisierte DataSet, aus dem auch gleichzeitig die Informationen für InteliSense und den Compiler zur Typ-Prüfung rauszieht. Jaaa ... habe mich gerade in der Zwischenzeit damit mal kurz beschäftigt. *g*


    Da die Datensätze bereits zur Designzeit mit allen korrekt typisierten Properties bekannt sind, kann man im FormDesigner Databindings zu den Anzeige-Controls einstellen - hmm - wenndes nicht kennst, könnte sein, dass dus dir gar nicht vorstellen kannst, wie komfortabel und mächtig das ist.


    Wie gesagt, für Databinding brauchst Du kein typisiertes DataSet, sondern es reichen auch die normalen DataSets der OleDB-Connection. Einzig und alleine kommt hinzu dass man eine Typisierung vornehmen muss beim DataBinding.

    Und ... doch, jaaa ... ich weiss genau wie komfortabel gebundene Formulare sind … so komfortabel das ich das wie der Teufel das Weihwasser meide. Das ist aber nur meine persönliche Ansicht und beruht hier hauptsächlich auf meinen Erfahrungen aus Access und die Umsetzung von MS bei den gebundenen Fomularen. Wenn ich mal viel Zeit und Laune habe werde ich mal prüfen ob die den gleichen Problemstellen auch nach Net übernommen haben oder ob sie es da besser gelöst haben. Aber richtig … für einfache Eingaben/Bearbeitung reicht es natürlich absolut aus.

    Bloss letztendlich darf man nie vergessen das DataBinding das gleiche ist wie man selber problemlos mit nicht sonderlich vielen Zeilen Code generalisiert hinbekommt, bloss dafür steckt eine gewaltige und oftmals langsame und durchaus nicht fehlerunanfällige Automatisierungmaschinerie dahinter. Ich vermute das daher auch Deine Zeitunterschiede beim Connection-Zugriff her stammen ... alt bekanntes Problem, Bordmittel von MS die direkten Zugriffscode extrem vereinfachen sind meistens um Welten langsamer als der direkt programmierte Zugriff. Die direkte Connection-Öffnung über die altbewährte ADO COM-Dll (Version 2.8 natürlich ^^) ist mit Sicherheit x-mal schneller als Du 10 MB XML eingelesen hast. ^^


    Die typisierung ist jdfs. der Grund, warum man Datenbank-Anwendungen nur mit EntityFramework, Linq2Sql - DataClasses, oder eben mit typisierten Datasets programmieren sollte.
    Dass Dataset sich auch ohne DB abspeichern kann, ist eiglich ein NebenFeature (allerdings unerhört nützlich, und EF und L2S hams halt nicht)


    Genau darauf will ich hinaus … die Abspeicherung als XML von Recordsets ist ja keine Erfindung von typisierten Datasets, dass beherrscht ja schon das einfache ADO-COM-Objektmodell.

    Nachdem ich mich vorhin mal kurz mit dem Thema beschäftigt habe, ist der Vorteil von typisierten Datasets die Typisierung an sich und die IntelliSense-Unterstützung.

    Und eigentlich sind die typisierten DataSets rein dafür gedacht den Datenbankzugriff bequemer zu machen. Aber mit Sicherheit nicht dafür Datenbanken zu vermeiden und sich mit dem DataSet-Designer als ERM-Tool rum zu quälen (guck Dir mal DeZign o.ä. an ... das sind ERM-Tools ... aber nicht sowas *g*). ;)

    Und wenn Du eine DB im Hintergrund hast dann ist die Erstellung eines typisierten DataSets ja wirklich nur noch eine Sache von ein paar Klicks da die kompletten DB-Spezifikationen inklusive Datentypen gleich direkt übernommen werden über den TableAdapter und man sich daher jegliche Erstellungsarbeit im DataSet-Designer erspart. Connection auswählen, Table auswählen und fertisch (auch gerade geprüft).

    In dem Sinne okay gut … ich plädiere für Anfänger in der Datenbanktechnologie ab sofort für Datenbank im Hintergrund und Übernahme als typisiertes DataSet. Ist der gleiche Aufwand wie bei Dir (ob man die DB im DataSet-Designer designed oder in MS-Access ist zeitlich das Gleiche und die Übernahme als typisiertes DataSet ist ja nun wirklich tierisch simple und schnell ... gebe ich ja zu ;) ) nur hat halt eben alle Vorteile einer DB zu bieten und man schleppt weniger Ballast im Memory mit rum.

    Aber ich denke damit können wir das Thema beenden da wir nun langsam wirklich Off-Topic sind, aber war zumindest mal sehr interessant da ich mich dazu aufgerafft habe mir das Thema mal näher anzusehen. *lach*

    Gruß

    Rainer

    raist10 schrieb:

    Mit clientseitiger Verarbeitung meine ich, die Daten, wenn sie beim Client sind, in den Controls anzuzeigen, dass der User da Änderungen vornehmen kann. Hat nix mittm DBProvider oder annerem Data-Access zu tun.
    Das ist was anderes als ich meine.
    eben.
    Und diese von mir gemeinte clientseitige Verarbeitung hat die enorme Unterstützung von Intellisense und Databinding im Designer.
    Da du das meidest, mußt du deine Typisierung selber proggen. Was immer du damit meinst - es ist in jedem Falle sehr aufwändig und fehleranfällig, schon bei 5 Tabellen mit mw. je 7 Spalten sind da 10 Klassen und ca. 40 Properties zu proggen - bzw. für jeden Zugriff auf diese Dinger kannste mittm String-Schlüssel hantieren, und den Wert casten - letzteres ist im Grunde unverantwortlich unsicher.
    Du hast also die Wahl, durch eigene Typisierungs-Klassen das Dataset quasi nachzuproggen (und wirst es nie annähernd gut hinbekommen), oder an hunderten von Stellen immer String-Schlüssel und Cast-Theater - dirty code vom feinsten.
    Es ist halt ein Unterschied ob ich komplette 10-20 MB Daten im Speicher vorhalten muss oder ob ich mir nur mal schnell 10 Byte Daten vom Backend anliefern lasse zur Verarbeitung.
    Dassis wahr. Dazu ist zu bemerken, also mit seinem Counterstrike-Trainerchen wird der TE kaum jemals 10KB vollkriegen ;). Und wie gesagt: Auch 50MB Daten im Speicher sind heutzutage kein Thema - wahrscheinlich fressen die Icons und Images der Anwendung mehr Resource.
    Mittm Xml hat man bei Dataset.WriteXml/.ReadXml überhaupt nix am Hut. Man gibt die Datei an und das Dataset befüllt sich eben.

    Natürlich hat das was mit XML zu tun, bzw. ist das ein reines XML-Handling.
    Der Satz lautet: Man, also der Programmierer hat mit dem Xml nix am Hut - dasses Xml-Handling ist, ist absolut unbestritten, aber für den Progger eben auch absolut schnurz.
    Das was Du als ERM-Tool ansiehst ist nichts anderes als ein GUI zur Erzeugung eines XSD-Schemas für das typisierte DataSet, aus dem auch gleichzeitig die Informationen für InteliSense und den Compiler zur Typ-Prüfung rauszieht.
    Ums korrekt zu erklären: Wie beim FormDesigner auch, generiert der Dataset-Designer einen Haufen Code in die Dataset.Designer.vb. Eben die TypisierungsKlassen, die du lieber von Hand schreibst. Und weil dieser Code da ist, sind die Klassen da, Typisierung, Intellisense etc.
    Sicher gibts aus Sicht von ERM bessere ERM-Tools - aber erstellen die auch fehlerfreie Typisierungs-Klassen? Kann ich die auch aufs Form ziehen und bekomme ein DataGridView mit allen Spalten, wo ich nurnoch die unerwünschten wieder entfernen brauch, und die erwünschten nurnoch nacharbeiten?
    Und vor allem: Den DatasetDesigner hat jeder, integriert in seiner IDE

    Da die Datensätze bereits zur Designzeit mit allen korrekt typisierten Properties bekannt sind, kann man im FormDesigner Databindings zu den Anzeige-Controls einstellen - hmm - wenndes nicht kennst, könnte sein, dass dus dir gar nicht vorstellen kannst, wie komfortabel und mächtig das ist.

    Wie gesagt, für Databinding brauchst Du kein typisiertes DataSet, sondern es reichen auch die normalen DataSets der OleDB-Connection. Einzig und alleine kommt hinzu dass man eine Typisierung vornehmen muss beim DataBinding.
    Ich glaub, du kennst es nicht.
    Ein untypisiertes Dataset kannst du erst zur Laufzeit an Controls binden - ich aber habe bereits im FormDesigner DatagridViews, die alle Spalten anzeigen, und ich kann deren Resizing-Verhalten einstellen, Sortierbarkeit, Formatierung, ich kann ComboboxColumns einfügen, die Relationen auf andere Tabellen repräsentieren, Ich kann 2 DatagridViews zu einem ParentChildView zusammenschalten - alles ohne eine Zeile coden zu müssen
    Aber richtig … für einfache Eingaben/Bearbeitung reicht es natürlich absolut aus.
    Bloss letztendlich darf man nie vergessen das DataBinding das gleiche ist wie man selber problemlos mit nicht sonderlich vielen Zeilen Code generalisiert hinbekommt,
    Also da bitte ich dich inständig, darüber den Beweis anzutreten.
    Minikass habe ich in einer Stunde geschrieben, ohne Vorlage. Du hast es jetzt als Vorlage - wenn deine Vorgehensweise wirklich annähernd ebenbürtig ist, solltest du es schneller hinkriegen, als die Zeit, die wir hier verdiskutiert haben.

    Meine Prognose: Du wirst das 10fache an Code brauchen. (wieviel mehr an Zeit sagich lieber nicht - dann wirst du dich drücken wollen ;))
    Ich fasse nochmal die Minikass-Funktionalität zusammen: Der User kann Artikel anlegen mit Name und Preis. Er kann Bons anlegen, und mit Posten befüllen, die auf den Artikel verweisen und die Kauf-Anzahl aussagen. Er kann sowohl Artikel, als auch Bons, als auch Posten nach Belieben zufügen/löschen/ändern. Und den ganzen Salat persistieren.
    ca. 80 Zeilen Code habich gebraucht, inklusive einer Sicherheitsabfrage beim Schließen, ob man Änderungen speichern möchte, die auch wirklich nur fragt, wenn Änderungen gegeben sind.
    Und eigentlich sind die typisierten DataSets rein dafür gedacht den Datenbankzugriff bequemer zu machen.
    Bitte! Typisierung ist mehr als Bequemlichkeit! Das ist Sicherheit beim Coden. Coden mit im Grunde nur DatenTyp Object ist sowas von dirty - dagegen ist Strict Off wie das Spülbecken von Meister Propper persönlich. (Und bequemer isses auch - richtig ;))
    Aber mit Sicherheit nicht dafür Datenbanken zu vermeiden
    Stimmt. Aber auch dazu kann man sie verwenden :).
    Und wenn Du eine DB im Hintergrund hast dann ist die Erstellung eines typisierten DataSets ja wirklich nur noch eine Sache von ein paar Klicks da die kompletten DB-Spezifikationen inklusive Datentypen gleich direkt übernommen werden über den TableAdapter und man sich daher jegliche Erstellungsarbeit im DataSet-Designer erspart. Connection auswählen, Table auswählen und fertisch (auch gerade geprüft).
    Seehr richtig! Ganz fabelhaftes Feature ;)
    In dem Sinne okay gut … ich plädiere für Anfänger in der Datenbanktechnologie ab sofort für Datenbank im Hintergrund und Übernahme als typisiertes DataSet.
    Jepp - da kommen wir zusammen :)
    ob man die DB im DataSet-Designer designed oder in MS-Access ist zeitlich das Gleiche
    Der Vorteil, zumindest zunächst mal ohne DB zu arbeiten liegt auch für Profis in der größeren Flexiblität. Bei der Entwicklung einer Anwendung kommt es immer zu Änderungen am Datenmodell. Wenn man gleich mit einem hinterlegten DB-Provider fuhrwerkt, muß man dann in Access rumfummeln, und anschließend das Dataset neu generieren. Bei DatasetOnly braucht man die IDE nicht zu verlassen.
    Für Einsteiger liegt ein weiterer Vorteil darin, dass man den DB-Zugriff erstmal überhaupt nicht erlernen muß - das typisierte Dataset und die Datenbinderei daran sind erstmal auch wirklich ausreichend Stoff.

    Also ich schließe nochmal mit meiner Bitte an dich: Trete den Beweis an, dass du Minikass aus DataExpressions oder wenigsten die AddOnDB aus DB-Programmierung ohne Datenbank wenigsten annähernd so einfach, sicher und funktional vergleichbar implementieren, wie ich aufgezeigt habe.

    @marcel87:
    Wie gesagt - 2 Köche für denselben Brei. Entscheide dich für mit oder ohne Datenbank, und für mit oder ohne typisiertes Dataset.
    Wo die Köche einig sind, ist der Punkt, dass du mit der Datenmodellierung anfangen musst, und ich schlage vor, du nimmst einfacherweise ein typisiertes Dataset als ERM-Tool: als Entwurfs- und Kommunikations-grundlage - aber wenn du ein besseres hast, ist das natürlich besser :)

    Achso - noch eine Frage an dich:
    Kannst du meinen Ausführungen hier überhaupt folgen und zustimmen?
    Das zeigt nämlich ein bischen die Denkweise, wie man ein Datenmodell ausbaldowert.
    Verstehst du die Übertragung meiner Überlegungen zu Karte, Spieltyp und Trainingseinheit in das gepostete "ERM-Diagramm"?

    (mein gott - bin ich ein laberkopf ;))

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    Da du das meidest, mußt du deine Typisierung selber proggen. Was immer du damit meinst - es ist in jedem Falle sehr aufwändig und fehleranfällig, schon bei 5 Tabellen mit mw. je 7 Spalten sind da 10 Klassen und ca. 40 Properties zu proggen - bzw. für jeden Zugriff auf diese Dinger kannste mittm String-Schlüssel hantieren, und den Wert casten - letzteres ist im Grunde unverantwortlich unsicher.


    Moment ... da siehste Du was falsch. ;) Man kann problemos den DB-Datentyp eines Fields/Column aus einem Dataset auslesen. Also kurz: Auswerten des DB-Typs und den Field-Value dann an Hand eines simplen Select-Case-Constructes umcasten.

    Das ist inklusive einfüllen des Recordsets in die Form mit einer einzigen Funktion erledigt ... einfach alle Controls der Form durchlaufen und an Hand Kennzeichner (z.B. Inhalt des Tags oder des Control-Namen) die passenden Recordset Fields einfüllen die nach
    Ermittlung des DB-DataTyps passend umgecastet werden und Thema ist erledigt. Vorteil ist man kann das für jede Form in der man Recordset-Inhalte anzeigen will her nehmen ... wenn man immer die gleiche Syntax für den Kennzeichner nutzt.

    Und der Weg funzt genauso perfekt andersrum ... als von Form to Dataset.

    Was meinst Du denn wie man früher vor der Datenbindung in NET ansonsten Datasets in Formulare reingebracht hat? ;)

    Ums korrekt zu erklären: Wie beim FormDesigner auch, generiert der Dataset-Designer einen Haufen Code in die Dataset.Designer.vb. Eben die TypisierungsKlassen, die du lieber von Hand schreibst. Und weil dieser Code da ist, sind die Klassen da, Typisierung, Intellisense etc.


    Siehe oben, eine Typisierungs-Funktion zur Einfügung von DataSets in Formular/ListViews/Grids zu schreiben dafür brauche ich maximal 0,1% Code von dem was der Dataset.Designer da in seine XML reinpackt. Aber klar ... weil ich eine dynamische Typisierung und keine statische Typisierung schreibe.


    Sicher gibts aus Sicht von ERM bessere ERM-Tools - aber erstellen die auch fehlerfreie Typisierungs-Klassen? Kann ich die auch aufs Form ziehen und bekomme ein DataGridView mit allen Spalten, wo ich nurnoch die unerwünschten wieder entfernen brauch, und die erwünschten nurnoch nacharbeiten?


    Wie wir zuvor schonmal richtig feststellten ist bei einem ERM jegliche Zufgriffs-/Auswertungsüberlegung völlig irrelevant da geht es rein darum das ERM korrekt aufzubauen. Genauso könnte ich jetzt dagegen halten ob der Designer Multilayer-Diagramme beherrscht, Reverse-Engineering, Version-Historie des ERM's, automatisches Modell-Update für exisitierende Datenbanken etc., etc. ... das sind wichtige Funktionen für ein ERM-Tool und nicht wie einfach kann ich das in meiner App nutzen. ;)


    Und vor allem: Den DatasetDesigner hat jeder, integriert in seiner IDE


    Das ist allerdings wahr. ^^

    Ich glaub, du kennst es nicht.
    Ein untypisiertes Dataset kannst du erst zur Laufzeit an Controls binden -


    Ja und? Ist für so oder so der Vorteil schlechthin. Damit wird die Verwendung von dynamischen Forms die unterschiedliche Ergebnisse anzeigen ja erst möglich.

    Ich werde einen Teufel tun und für jedes Table/Abfrageergebnis oder sonstwas eine eigene Form entwerfern ... da würde ja der Hund in der Pfanne verrückt werden.

    Ich stelle z.B. in meinem Access-CRM in einem einzigen DataGrid derzeit über 100 verschiedene Abfragen da mit allem Chichi wie Filter-, Berichts- und Exportmöglichkeiten. Der einmalige Aufwand das Teil zu programmieren ist natürlich im Vergleich zu einer gebundenen Version exorbitant hoch, aber bei gebundenen Formulare hätte ich den Rotz dann 100 mal machen müssen und so habe ich ihn nur ein einziges Mal gemacht.

    Kannst ja gerne mal durchrechnen wieviel Zeit Du brauchst um 100 unterschiedliche Abfragen (die jeweils zwischen 8 und 30 Columns/Spalten zurück geben) über 250 Tabellen hinweg in DataGrids darzustellen wenn Du jedes DataGrid per Bindung einzeln erstellen musst.

    Klar, ein Vorteil der erst bei mehrfacher Verwendung zum Tragen kommt. Aber mit einer der Gründe wieso ich ungern/selten auf gebundene Formulare zurück greife. Bei einer Befüllung wie oben beschrieben, tausche ich per Code je nach Bedarf nur die Kennzeichner die z.B. in Control.Tag hinterlegt sind aus und kann die Form nun für die Anzeige eines komplett anderen DataSets nutzen.

    Oder gar gleich Forms/DataGrids dynamisch an Hand des anzuzeigenden Recordsets erzeugen.

    Kannst Du das auch mit gebundenen Forms/DataGrids? ^^


    Also da bitte ich dich inständig, darüber den Beweis anzutreten.
    Minikass habe ich in einer Stunde geschrieben, ohne Vorlage. Du hast es jetzt als Vorlage - wenn deine Vorgehensweise wirklich annähernd ebenbürtig ist, solltest du es schneller hinkriegen, als die Zeit, die wir hier verdiskutiert haben.

    Meine Prognose: Du wirst das 10fache an Code brauchen. (wieviel mehr an Zeit sagich lieber nicht - dann wirst du dich drücken wollen ;))
    Ich fasse nochmal die Minikass-Funktionalität zusammen: Der User kann Artikel anlegen mit Name und Preis. Er kann Bons anlegen, und mit Posten befüllen, die auf den Artikel verweisen und die Kauf-Anzahl aussagen. Er kann sowohl Artikel, als auch Bons, als auch Posten nach Belieben zufügen/löschen/ändern. Und den ganzen Salat persistieren.
    ca. 80 Zeilen Code habich gebraucht, inklusive einer Sicherheitsabfrage beim Schließen, ob man Änderungen speichern möchte, die auch wirklich nur fragt, wenn Änderungen gegeben sind.


    Mal langsam, wenn ich Routinen für Typisierung einbaue und ähnliches brauche ich natürlich mehr Code. Was bei einer einzigen Form nun wirklich keinen Sinn macht, da haste Recht. Aber spätestens wenn es um mehrere Forms geht die dynamisch zu füllen sind oder einer Form die man mehrfach verwenden kann liegt man dann zeitlich wieder vorne oder zumindest gleich auf ... von der Wartungsfreundlichkeit mal ganz abgesehen. ;)

    Der Vorteil, zumindest zunächst mal ohne DB zu arbeiten liegt auch für Profis in der größeren Flexiblität.


    Oh Moment ... im Sinne von Flexibilität ist das typisierte DataSet das absolut Letzte was man verwenden sollte da das Korsett absolut starr ist und während der Laufzeit unmöglich oder extrem schwer zu ändern ist. Daher ist es ja auch im DataSet-Designer nicht möglich eine Query (oder das was man in SQL als View bezeichnet) anzulegen ohne DB-Anbindung.

    Du willst jetzt aber nicht wirklich das typisierte DataSet als Profi-Werkzeug für Datenbank-Entwicklung darstellen? Bitte, dafür ist das Teil völlig ungeeignet. Welchen Sinn sollte es auch haben? o_O


    Für Einsteiger liegt ein weiterer Vorteil darin, dass man den DB-Zugriff erstmal überhaupt nicht erlernen muß - das typisierte Dataset und die Datenbinderei daran sind erstmal auch wirklich ausreichend Stoff.


    Das ist zwar richtig, halte ich aber auch für den größten Nachteil. Genauso wie die ganzen gebundenen Geschichten in Access ... keine Ahnung von der Materie aber dank Bindung und keinerlei Code-Einsatz bekommt man einfache Ergebnis schnell hin. Spätestens wenn es komplexer wird ist dann meistens Feierabend und das Gejammere groß. Sorry, aber gerade Anfängern die ernsthaft vorhaben sich in das Thema einzufuchsen würde ich persönlich empfehlen auf dem klassischen Wege mit einer richtigen DB an das Thema ranzugehen bevor man dann später auf die Vereinfachungen zurück greift.

    Man lernt dadurch viel mehr und ist dann auch später in der Nutzung von Vereinfachungs-Methoden ala typisiertem Dataset wesentlich besser und kann das dann dort wo es sinnvoll ist nutzen.


    Also ich schließe nochmal mit meiner Bitte an dich: Trete den Beweis an, dass du Minikass aus DataExpressions oder wenigsten die AddOnDB aus DB-Programmierung ohne Datenbank wenigsten annähernd so einfach, sicher und funktional vergleichbar implementieren, wie ich aufgezeigt habe.


    Das ich für diese Einfach-Beispiel mehr Code brauche ist doch klar und gebe ich gerne zu. ;)

    Womit ich mich noch nicht beschäftigt habe, was aber in dem Sinne des Topics interessant wäre ... wie würden sich denn z.B. Auswertungen und deren Anzeige in z.B. Deiner Anwendung Minikass per typisiertem DataSet realisieren lassen? Z.B. ganz übliche Geschichten wie Tagesabschluß, Artikel-Renner/Penner-Listen für frei wählbaren Zeitraum, Umsatzstatistiken nach frei wählbaren Zeiträumen, Artikel nach Lieferanten etc., etc.?

    Das wären jetzt alles Geschichten wo nach meinem Old-Shool-Ansatz für alle diese Abfragen nur ein einziges DataGrid vonnöten wäre und keine einzige Zeile Code für die Ergebnis-Ermittlung. SQL-View dafür wird einmalig im Datenbank-Backend angelegt und dann per dynamischer Routine (relativ identisch der obigen Routine für Formulare, bloss das hier für jedes Field im DataSet eine Column im Grid erst erzeugt wird zur Laufzeit) rein gepumpt. Eine einfache Befüllung ohne Schnickschnack ist für so ein DataGrid ja mehr als zügig runterprogrammiert und gilt dann für zig-Abfragen gleichermaßen.

    Nach Deinem Vorgehen müsstest Du pro Abfrage aber jedesmal ein eigenes DataGrid erstellen oder sehe ich da was falsch? Vor allem wie und wo erzeugst Du bei einem typisiertem DateSet eine Abfrage über mehrere Tables hinweg inklusive aller Rechenfunktionen wie Summe, %-Anteile am Gesamt und ähnlichem? Soweit habe ich mich da noch nicht reingefuchst.


    (mein gott - bin ich ein laberkopf ;))


    Ich glaube da kann ich mich vorbehaltlos anschliessen. ^^

    Gruß

    Rainer