User Passwort
 Passwort speichern Passwort vergessen?
 
 
 
 Alle Foren
 PDA-Dev :: Windows Mobile
 VB.NET
 Wie mehrdimensionales Array füllen?
Autor Vorheriges Thema Thema Nächstes Thema  

UweK

PDA-Programmierer


37 Beiträge

Erstellt am: 30.06.2010 :  15:27:11 Uhr  Profil anzeigen  Autor eine Email senden  Besuche UweK's Homepage  Antwort mit Zitat
Hallo Leute,
ich plage mich seit Tagen mit einem Problem, für das ich einfach keine Lösung finde.
Vielleicht habe ich mich auch nur verrant oder stehe total auf dem Schlauch :-/
Ich arbeite mit VS2008 (VB.NET) und dem CF 3.5.
Ich habe einen String mit z.B. folgendem Wert:
Dim Datensatz As String
Datensatz = "Musterort,Musterstraße,1"
Diesen String zerlege ich mit der Split-Funktion in seine Einzelteile und speichere diese
in einem Array:
Dim Ebene() As String
Ebene = Datensatz.Split(",")
Nun möchte ich die einzelnen Elemente des Arrays Ebene in einer weiteren aber mehrdimensionalen Tabelle bzw. Array, in Relation zueinander ablegen. Wie muss ich dazu das Array dimensionieren?
Und wie kann ich feststellen, ob das Element "Musterort" bereits in der ersten Dimension und das Element "Musterstraße" in der zweiten Dimension des Arrays enthalten ist, wenn der Wert "Hausnummer" im String Datensatz ändert und ich nur die 3. Dimension des Arrays erweitern will?
Was ist wenn sich der Wert "Musterort" im String in z.B. "Musterort-1" ändert? Oder sich die Straße ändert? Soweit ich weiß kann man mit ReDim immer nur die Dimension ganz rechts verändern.
Bin ich überhaupt auf dem richtigen Weg?
Ich hoffe, ich habe mich einigermaßen verständlich ausgedrückt und es kann mir jemand von
Euch mit einem kleinen Beispiel helfen.
Vielen Dank im Voraus!
Gruß,
Uwe.
   

Useless user

PDA-Spezialist


465 Beiträge

Erstellt  am: 30.06.2010 :  22:31:21 Uhr  Profil anzeigen  Besuche Useless user's Homepage  Antwort mit Zitat
Also:
Es gibt mehrdimensionale Arrays z.B. Arr(3,2) UND es gibt Arrays von Arrays. Das ist zwei verschiedene Dinge bei den man sich immer im Klaren sein sollte was gerade verwendet wird.
Ein Mehrdimensionales Array hat immer einen gleichmäßigen Aufbau. Das heißt wenn du Dimension 1 mit 3 angibst und Dimension 2 mit 5 hast du ein Array 3x5.
Wenn du ein Array von Arrays anlegst kann jedes Array eine beliebige Länge haben - auch 0 und das Array im Array kann auch Nothing sein!
Mehrdimensionale Arrays verwende ich so gut wie nie. Ich bin eher ein Freund vom Array im Array - am besten in Verbindung mit der generischen Liste. Siehe hier:
Dim Datensatz As String
Datensatz = "Musterort,Musterstraße,1"
Dim Ebene() As String
Ebene = Datensatz.Split(",")
Dim objList as New List(of String())
objList.Add(Ebene)
objList.ToArray gibt dann das Array eines Arrays zurück.
Noch besser ist natürlich der Ansatz die Daten etwas strukturierter in einem Objekt abzuspeichern:
Dim objList as New List(of Adresse())
Dim adr as New Adresse()
If Ebene.Length > 0 then adr.Ort = Ebene(0)
If Ebene.Length > 1 then adr.Strasse = Ebene(1)
If Ebene.Length > 2 then adr.Hausnr = Ebene(2)
Um eine Liste mit Adressen anzulegen:
objList.Add(adr)
Zum Anfang der Seite

Useless user

PDA-Spezialist


465 Beiträge

Erstellt  am: 30.06.2010 :  22:33:49 Uhr  Profil anzeigen  Besuche Useless user's Homepage  Antwort mit Zitat
Achso:
Auf ein mehrdimensionales Array greift du über arr(index1, index2) zu.
Auf ein Array im Array so: arr(index1)(index2)
(weil Arr(index1) selbst ein Array zurückgibt:
Dim innerArr as String() = arr(index1)
Dim element as String = innerArr(index2)
Zum Anfang der Seite

UweK

PDA-Programmierer


37 Beiträge

Erstellt  am: 01.07.2010 :  11:47:07 Uhr  Profil anzeigen  Autor eine Email senden  Besuche UweK's Homepage  Antwort mit Zitat
Hallo Useless user,
danke für Deine Mühe und die schnelle Antwort!
Ich werd mir die beiden Wege jetzt mal anschauen bzw. ausprobieren, denn so wirklich habe ich das noch nicht verstanden bzw. weiß ich nicht ob diese beiden Wege für meine Zwecke geeignet sind. Vielleicht sollte ich mal den Hintergrund ein wenig beschreiben.
Die Daten kommen ursprünglich aus einer SQL compact Datenbank und die einzelnen Ebenen die ich mit Split aus dem übergebenen String filtere sollen in EINER ListBox (Ich arbeite
mit der TouchListBox von Mirabyte) dargestellt werden. Die ListBox wird zur Laufzeit
dynamisch anhand der übergebenen Ebenen erzeugt. Ich weiß also vorher nicht wieviele Ebenen dargestellt werden sollen.
Werden z.B. in einer Schleife alle Straßen und Hausnummern eines (oder mehrerer) Orte(s) übergeben, sollen erst alle Daten in Relation zueinander in Tabellen, Arrays oder was auch immer (vielleicht kommt auch ein DataSet in Frage?) im Arbeitsspeicher abgelegt werden. Zunächst soll nur die erste Ebene (in dem Falle alle Orte) in der ListBox angezeigt werden. Wird ein Element angetippt, soll der Inhalt der Listbox gelöscht und mit derzu dem Ort gehörenden Straßen gefüllt werden. Wird eine Straße angetippt, sollen die Straßenelemente wieder gelöscht und die ListBox mit den zur angetippten Straße gehörenden Hausnummern gefüllt werden usw.
Das Ganze solle eine Treeview ersetzen, die man ja schlecht mit den Fingern bedienen kann.
Welche Methode denkst Du, ist dafür am besten geeignet? Es soll ja auch performant sein.
Ich denke mal dass, das Beispiel indem die Daten in einem Objekt abgespeichert werden schonmal weg fällt, da ich nie weiß wieviele Ebenen übergeben werden und weil es sich nicht unbedingt um eine Adresse handeln muss sondern es kann sich zum Beispiel auch um ein Lager mit Regalen und Artikeln/Artikelnummern handeln.
Nochmals vielen Dank für Deine Hilfe im Voraus!!
Gruß,
Uwe.

Bearbeitet von: UweK am: 01.07.2010 12:00:41 Uhr
Zum Anfang der Seite

Useless user

PDA-Spezialist


465 Beiträge

Erstellt  am: 04.07.2010 :  22:39:04 Uhr  Profil anzeigen  Besuche Useless user's Homepage  Antwort mit Zitat
Im Grund ist es doch folgendes Problem - ganz abstrakt und ohne Details der Implementierung. Du hast eine Reihe von Eingabewerten (Adressdaten), einen Zustand (die Ebene auf der du dich bei deiner Suche befindest) und eine Operation die in Abhängigkeit des Zustandes immer die Items für die ListBox suchen, auswählen und zurückgeben muss.
Dein aktueller Zustand sollte ein Array, eine generische Liste oder ein Queue (System.Collection.Specialized. ... ) vom Datentyp String sein. Jedes Element des Arrays ist das was der auf seinem "Pfad" ausgewählt hat. Da musst du dich zuerst drum kümmern, dass dein Zustand immer angepasst wird sobald der Benutzer die Ebene wechselt.
Danach brauchst du die Suchfunktion. Dein Suchalgorithmus sollte die Addessdaten anhand der aktuellen Ebene filtern. Wie du hierbei vorgehst hängt davon ab wie viele Adressen zu verarbeiten sind. Bei einem DataSet kannst du dir einen Filter zusammenbauen und auf die DataTable anwenden oder du kannst selbst die Suche in einer Schleife programmieren oder du kannst dir eine SQL-Abfrage bauen und diese auf die Datenbank loslassen.
Das Objekte ausscheiden weil du die Anzahl der Ebenen nicht kennst ist Unfug. Du musst nur die Objekte entsprechend flexibel definieren.
Zum Anfang der Seite

UweK

PDA-Programmierer


37 Beiträge

Erstellt  am: 14.07.2010 :  17:15:25 Uhr  Profil anzeigen  Autor eine Email senden  Besuche UweK's Homepage  Antwort mit Zitat
Hallo Useless User,
ich muss das Thema nochmal aufgreifen...
Ich habe in der Zwischenzeit verschiedene Anläufe unternommen das Problem zu lösen, leider bislang noch immer ohne Erfolg...
Ich bin allerdings zu dem Schluss gekommen, dass ich die übergebenen Werte in einem DataSet und den entsprechenden DataTables abspeicher. Aber da fängt das Problem schon an.
Ich bekomme einfach keine sauberen Relationen über entsprechende ID's zur Vorgängertabelle hin :-/
Ich habe zum Test folgende Daten, die ich ich in Schleifen kunterbunt verändere, die aber in den Tabellen in Relation zueinander stehen sollen.
Beispiel:
Dim Werte As String
For i = 1 To 5
Werte = "Ort, Straße, Haus-Nr, Kunde, Abnahmestelle-Strom, Zaehler-" & i
ListBox.Fuellen(Werte)
Next
For i = 1 To 4
Werte = "Ort, Straße, Haus-Nr, Kunde-" & i & ", Abnahmestelle-Strom, Zaehler-" & i
ListBox.Fuellen(Werte)
Next
For i = 1 To 3
Werte = "Ort" & i & ", Straße, Haus-Nr, Kunde-" & i & ", Abnahmestelle-Strom, Zaehler-" & i
ListBox.Fuellen(Werte)
Next
ListBox.Anzeigen()
In ListBox.Fuellen werden die Werte gesplittet, ein DataSet und die entsprechende Tabellen mit Ihren Feldern angelegt, sofern noch nicht vorhanden.
In Tabelle1 sollen alle Orte stehen, in Tabelle2 alle Straßen u.s.w
ListBox.Anzeigen soll dann die Tabelle Orte ohne doppelte Einträge enthalten, also im
Beispielfall "Ort/Ort-1/Ort-2/Ort-3".
Wenn ich nun auf "Ort" klicke wird die ListBox gelöscht und anhand der im Tag des Lisboxelementes gespeicherten Tabellen-ID soll nun die ListBox mit den Straßen gefüllt werden, im Beispielfall gibt's dort nur 1 Element nämlich "Straße"., dann käme "Haus-Nr",
dann kämen "Kunde/Kunde-1/Kunde-2/Kunde-3/Kunde-4". Wenn nun "Kunde" angeklickt wird sollen die 5 Zähler die zu "Kunde" gehören in der ListBox angezeigt werden, wird "Kunde-1" angeklickt sollen die 4 zugehörigen Zähler angezeigt werden. u.s.w
Aber wie gesagt schaffe ich es schon nicht die Relationen anhand entsprechnder ID's sauber hinzubekommen.
Wie schaffe ich es nun, dass die Daten aus den 3 Schleifen in Relation zu einander stehen?
Ich bekomme es einfach nicht hin.
Kannst Du oder sonst wer hier, mir vielleicht mit einem Stück Quellcode weiterhelfen, dass die Daten sauber in Relation zu einander die Tabellen schreibt. Das auslesen und
in die ListBox schreiben bekomme ich sicher hin.
Vielen Dank!
Ich hoffe ich habe mich einigermaßen verständlich ausgedrückt aber ich weiß nicht wie ich das Problem sonst beschreiben soll :-/
Gruß,
Uwe.
Zum Anfang der Seite

Useless user

PDA-Spezialist


465 Beiträge

Erstellt  am: 14.07.2010 :  21:41:48 Uhr  Profil anzeigen  Besuche Useless user's Homepage  Antwort mit Zitat
Ich denke der Ansatz ist schon nicht besonders elegant. Von der Sache her genügt EINE Tabelle mit den Spalten Ort, Straße, Hausnr, usw. - die beschreibt sozusagen einen Zähler und darum geht es wenn ich das richtig verstanden hab.
Wenn du deine Ebene "Ort" haben willst nimmst du eben nur die Orte um die Listbox zu füllen. Wenn du sowieso eine SQL-Compact-Datenbank hast ist es naheliegen das mit einer einfachen SQL-Abfrage zu realisieren. Für jede Ebene musst du dann die entsprechende Abfrage um ein WHERE-Kriterium erweitern.
Zum Anfang der Seite

UweK

PDA-Programmierer


37 Beiträge

Erstellt  am: 15.07.2010 :  10:01:12 Uhr  Profil anzeigen  Autor eine Email senden  Besuche UweK's Homepage  Antwort mit Zitat
Hi,
danke für den Tipp!
Das ist zwar wahrscheinlich die einfachste Methode das Problem in den Griff zu bekommen aber auch nicht die eleganteste und vor allem nicht die performanteste. Denn man führt ja in jedem Satz doppelte Einträge.
An jedem Ort hängen beliebig viele Straßen, an jeder Straße hängen beliebig viele Hausnummern, an jeder Hausnummer hängen beliebig viele Kunden, An jedem Kunden hängen beliebig viele Abnahmestellen, an jeder Abnahmestelle hängen beliebig viele Zähler...
Gerade diese Redundanz wollte ich vermeiden und um diese zu vermeiden gibt es ja auch Relationen und Beziehungen.
Ich habe auch keine SQL-Compact Datenbank beim füllen sondern halte die Daten im Speicher in einem Dataset. Lediglich die Ursprungsdaten, der String der mir übergeben wird kommt aus einer SQL-Compact Datenbank, auf die ich selbst aber keinen Zugriff habe.
Hat vielleicht sonst noch jemand eine Idee wie man das Problem am besten in den Griff bekommen kann?
Vielen Dank im Voraus.
Gruß,
Uwe.
Zum Anfang der Seite

Useless user

PDA-Spezialist


465 Beiträge

Erstellt  am: 15.07.2010 :  22:44:08 Uhr  Profil anzeigen  Besuche Useless user's Homepage  Antwort mit Zitat
Du müsstest deine Abfrage-Funkion dann so gestalten dass du in einer Schleife alle Werte durchläufst und bei jedem Wert nachschaust ob du diesen schon in deiner Liste hast(Stichwort HashTable). Wenn du die Redundanz vermeiden willst musst du deine Datenstrukturen normalisieren, d.h. dein Datensatz für den Zählen besteht nicht aus Ort, Straße sondern aus OrtID und StraßeID hinter der sich dann in einer seperaten Tabelle hinterlegte Klartextbezeichnungen verbergen. Das ist zwar ein Datendesign nach Lehrbuch aber sich auch nicht so optimal für die Performance.
Zum Anfang der Seite

UweK

PDA-Programmierer


37 Beiträge

Erstellt  am: 16.07.2010 :  10:40:38 Uhr  Profil anzeigen  Autor eine Email senden  Besuche UweK's Homepage  Antwort mit Zitat
Ja, das ist ja genau das Problem, das können unter umständen zwischen 1000 und 1500 Datensätze sein! Deshalb wollte ich ja die Relation, über die ID's, was ich ja nicht sauber hin bekomme. Alle Datensätze zu durchlaufen und zu prüfen dauert zu lange, das hab' ich ja schon versucht. :-/
Zum Anfang der Seite

Useless user

PDA-Spezialist


465 Beiträge

Erstellt  am: 16.07.2010 :  17:27:27 Uhr  Profil anzeigen  Besuche Useless user's Homepage  Antwort mit Zitat
Ich habe Schleifen mit 4000 - 5000 Durchläufe und es funktioniert in akzeptabeler Geschwindigkeit. Vielleicht ist deine Schleife nicht optimal, poste mal den Code dazu.
Vielleicht kann man auch etwas vorsortieren, aber darüber reden wir nochmal. Hattest du nicht geschrieben du hast keine feste Anzahl an Ebenen? Ort, Straße, Hausnr ... klingt für mich eigentlich eher nach einer vordefinierten Hierachie.

Bearbeitet von: Useless user am: 16.07.2010 17:33:40 Uhr
Zum Anfang der Seite

UweK

PDA-Programmierer


37 Beiträge

Erstellt  am: 20.07.2010 :  11:14:16 Uhr  Profil anzeigen  Autor eine Email senden  Besuche UweK's Homepage  Antwort mit Zitat
Hallo Useless User,
ich habe am Wochenende alles bisher in diese Richtung gemachte über den Haufen geworfen und den Vorschlag von Dir als Grundlage genommen und neu umgesetzt. Wirklich glücklich bin ich zwar mit der unnötigen datenredundanz nicht aber besser als gar keine Lösung! :-/
Nein, es gibt keine feste Anzahl von Ebenen, das mit Ort, Straße, Hausnummer etc. war nur ein Beispiel. Es könnte auch Lager, Regal, Charge, Artikel etc... sein oder eine Menüstruktur. Das ganze liegt in einer DLL und soll einigen Programmen bzw. Modulen dienen
um eine (oder mehrere) TouchListbox (das ist ein fingerfreundlches Control von MiraByte)
anhand der übergebenen Daten zu füllen, auszuwerten und entsprechendes zurückzugeben.
Hier mal ein Auszug aus dem Code, vielleicht kann man daran ja noch was optimieren:
Hier wird die Tabelle im DataSet gefüllt.
 
Public Sub Fuellen(ByVal WerteListe() As String, ByVal MeinSteuerelement As EnumSteuerElemente)
Select Case MeinSteuerelement
Case EnumSteuerElemente.TouchListBox
Dim Ebene() As String
Ebene = WerteListe(0).Split(",")
'Im Array Ebene steht dann zum Beispiel Ort, Straße, HausNummer, Kunde, Abnahmestelle, Zähler
If Datensatz.Tables.Contains("Tabelle") = False Then
Tabelle = New System.Data.DataTable("Tabelle")
Tabelle.Columns.Add("ID", GetType(Integer))
Datensatz.Tables.Add(Tabelle)
End If
Dim TabellenZeile As System.Data.DataRow = Datensatz.Tables.Item("Tabelle").NewRow()
TabellenZeile("ID") = Datensatz.Tables.Item("Tabelle").Rows.Count + 1
For i = 0 To Ebene.Count - 1
If Tabelle.Columns.Contains("Ebene" & i) = False Then
Tabelle.Columns.Add("Ebene" & i, GetType(String))
End If
TabellenZeile("Ebene" & i) = Trim(Ebene(i))
Next i
Datensatz.Tables.Item("Tabelle").Rows.Add(TabellenZeile)
End Select
End Sub
 
Zu Anfang wird die Listbox mit den Werten aus dem Feld Ebene0 gefüllt.
Danach wird die Listbox mit der jeweils nächsten Ebene in Relation zum zurvor
gewählten Listbox-Eintrag gefüllt. Ist die Listebox mit der letzten Tabelle im Dataset gefüllt, werden die Schlüsselwerte des gewählten Elements im entsprechenden Click-Event zur weiteren Verarbeitung zurückgegeben.
Hier noch der Code mit dem die Listbox entsprechend der Ebene gefüllt wird:
 
Private Sub FuelleTouchListBoxEbene()
If Not TouchListBox.IsDisposed Then
Dim view As System.Data.DataView = New System.Data.DataView
Dim MyTabellenZeile As System.Data.DataRow
Dim UeberschriftElement As New TouchListHeaderItem(TouchListBox)
Dim Ebene As String = TouchListBox.Tag
Cursor.Current = Cursors.WaitCursor
With view
.Table = Datensatz.Tables.Item("Tabelle")
If CInt(Ebene) > 0 Then
Dim ZeilenFilter As String = ""
tlbElementRelationTabelle = tlbElementRelation.Split(",")
For i = 0 To tlbElementRelationTabelle.Count - 1
ZeilenFilter &= "Ebene" & i & " LIKE '" & Trim(tlbElementRelationTabelle(i)) & "'"
If i < tlbElementRelationTabelle.Count - 1 Then
ZeilenFilter &= " AND "
End If
Next
.RowFilter = ZeilenFilter
End If
End With
Dim tmpTabelle As System.Data.DataTable = view.ToTable("tmpTabelle", True, New String() {"Ebene" & Ebene})
If CInt(Ebene) = 0 Then
tlbAnimationsRichtung = AnimationDirection.adBottom
Else
tlbAnimationsRichtung = AnimationDirection.adLeft
End If
TouchListBox.PrepareAnimation()
TouchListBox.Items.Clear()
If CInt(Ebene) > 0 Then
UeberschriftElement.Text = tlbElementRelation
End If
UeberschriftElement.Height = tlbItemHeight2
UeberschriftElement.TextFont = New Font(UeberschriftElement.TextFont.Name, tlbFontSize3, UeberschriftElement.TextFont.Style)
UeberschriftElement.IsSelectable = False
TouchListBox.Items.Add(UeberschriftElement)
For Each MyTabellenZeile In tmpTabelle.Rows
TouchListBox.Tag = (CInt(Ebene) + 1).ToString
ListBoxElement = New TouchListDefaultItem(Me.TouchListBox)
ListBoxElement.Text = MyTabellenZeile.Item("Ebene" & Ebene).ToString
ListBoxElement.Height = tlbItemHeight
ListBoxElement.TextFont = New Font(ListBoxElement.TextFont.Name, tlbFontSize2, ListBoxElement.TextFont.Style)
ListBoxElement.TextPosition.LeftSpace = 64
ListBoxElement.BackgroundImage = AlphaImage.FromByteArray(My.Resources.ElementHintergrundBlauWeissBlau480)
ListBoxElement.BackgroundSelected = AlphaImage.FromByteArray(My.Resources.ElementHintergrundGrauWeissGrau480)
ListBoxElement.BackgroundImage2 = AlphaImage.FromByteArray(My.Resources.ElementHintergrundBlauWeissBlau480)
ListBoxElement.BackgroundSelected2 = AlphaImage.FromByteArray(My.Resources.ElementHintergrundGrauWeissGrau480)
ListBoxElement.RightIcon = AlphaImage.FromByteArray(My.Resources.NaechsteEbene480)
ListBoxElement.TextFontSelected = New Font(ListBoxElement.TextFont.Name, tlbFontSize2, ListBoxElement.TextFont.Style)
ListBoxElement.TextFontColorSelected = Color.Firebrick
If tlbNaechsteEbeneIcon = True Then
ListBoxElement.ShowRightIcon = True
Else
ListBoxElement.ShowRightIcon = False
End If
TouchListBox.Items.Add(ListBoxElement)
Next
End If
TouchListBox.UpdateList(tlbAnimationsRichtung, tlbAnimationsTyp, False)
Cursor.Current = Cursors.Default
End Sub
 
LG,
Uwe.
Zum Anfang der Seite
  Vorheriges Thema Thema Nächstes Thema  
Springe nach:
 
  Bookmark & Share  
 
 
 
  Tags  
 
Keine Tags gefunden
 
 

 



pda-dev.de

Quicklinks: Foren-Übersicht | Developer-News | Suche | Impressum

© just-works! Software

Zum Anfang der Seite

Snitz Forums 2000