Allgemeiner Codecheck

Alle Fragen zur Programmierung, die nicht in die speziellen Themen passen
vb6oldie
Foriker
Beiträge: 129
Registriert: Mo 17. Apr 2017, 12:51
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von vb6oldie » Di 30. Mai 2017, 08:12

Hallo 4tionov,
danke für den Tipp, jetzt geht's endlich wieder weiter.
Liebe Grüße

vb6oldie
Foriker
Beiträge: 129
Registriert: Mo 17. Apr 2017, 12:51
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von vb6oldie » Di 30. Mai 2017, 09:37

Hallo 4tionov,
und schon wieder bin ich lästig:
Ich habe die nächste Form erstellt. fAdrListen.
Wie bekomme ich das Result dahin?
Die CAdresse:

Code: Alles auswählen

Property sSQL As String
Private $sSQL As String

Property Res As Result
Private $Res As Result

Public Sub Suche() As Boolean

  Dim fm As New FAdrSuchen

  fm.adresse = Me
  fm.Persistent = True 'bleibt nach dem Schließen unsichtbar, wird nicht wirklich geschlossen
  fm.ShowModal() 'Modal anzeigen, der Benutzer kann nun suchen
  ' Nun hat der Benutzer das Form geschlossen, es ist aber noch persistent

  ' CAdresse kann sich das Result abholen:
  $Res = fm.DbResult 'FAdrSuchen  liefert in der Property Res (As Result) das Result
  fm.Persistent = False 'Persistenz ausschalten, damit es wirklich geschlossen werden kann
  fm.close ' Schließen

  Verzweigung()

End

Private Sub Verzweigung()

  Select Case $res.Count
    Case 0 '           Keine Adresse vorhanden
      Message.Info("Die Anzahl der selektierten Datensätze ist Null!")
      Return
    Case 1 '           Adresse anzeigen (fAdr)
      Message.Info("Es wurde ein Record gefunden!")
      Return
    Case Else '
      AdrListe()
      Return
  End Select

End

Private Sub AdrListe()			'<=====

  Dim fm As New FAdrListe		'<=====

  fm.adresse = Me
  fm.Persistent = True 
  fm.ShowModal()
  
  fm.Persistent = False
  fm.close

End

Private Function adrno_Read() As Integer
Und die Form:
Bildschirmfoto vom 2017-05-30 10-27-10.png
Bildschirmfoto vom 2017-05-30 10-27-10.png (36.33 KiB) 4919 mal betrachtet
Liebe Grüße

Benutzeravatar
tionov
Site Admin
Beiträge: 286
Registriert: So 18. Mai 2014, 22:40
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von tionov » Di 30. Mai 2017, 10:32

Mach in fAdrListen eine Property DbResult. Und in DbResult_write füllst du das Grid.

Dann kannst du im CAdresse das fAdrListen mit New als Objekt erstellen, danach fAdrListen.DbResult = $Res und danach fAdrListen.Show.

Das wars.
Alles Gute,

4tionov

vb6oldie
Foriker
Beiträge: 129
Registriert: Mo 17. Apr 2017, 12:51
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von vb6oldie » Mi 31. Mai 2017, 06:45

Hallo 4tionov,
ich habe in der Form fAdr eigentlich alles so gemacht wie in der Form fAdrListe.
Nur ich bekomme keine Daten aus dem Result.

Da Res ein Result ist, muss ich irgend etwas anderes machen als "Res.adrno" zu suchen.

In fAdrListe gab es dazu den GridView_Data.
In den ValueBoxen bzw. den TextBoxe gibt es kein _Data.

Was kann ich dagegen nehmen?
Oder gibt es irgend eine Routine, die mir die Daten liefert?

Liebe Grüße

Benutzeravatar
tionov
Site Admin
Beiträge: 286
Registriert: So 18. Mai 2014, 22:40
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von tionov » Mi 31. Mai 2017, 08:02

Liefert deine SQL-Query Daten? Ist bei dem Result Count = 1?
Dann (ich gehe davon aus, dass im Result die Spaltennamen so heißen) und dass die entsprechenden Controls existieren, dann könnte das so gehen:
gambas code

Private Sub DbResult_write(Value as Result)

  $Res = Value
  FillAdresse()

End

Private Sub FillAdresse()
  
  TxtVorname.Text = $Res!vorname
  TxtVorname.Text = $Res!vorname
  ' usw ...

End

Du könntest auch noch was anders machen (das wäre viel gescheiter!):

Wenn CAdresse ein Result mit 1 Zeile enthält (= eine Adresse), dann füllt CAdresse vorname, nachname, etc. bei sich (wie oben) und übergibt an fAdr sich selbst (Über die Property Adresse As CAdresse bei fAdr).

Dann füllt fAdr sich so:
gambas code
Private Sub FillAdresse()
  With $Adresse
    TxtVorname.Text = .vorname
    TxtVorname.Text = .vorname
    ' usw ...
  End With
End

Alles Gute,

4tionov

vb6oldie
Foriker
Beiträge: 129
Registriert: Mo 17. Apr 2017, 12:51
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von vb6oldie » Mi 31. Mai 2017, 09:44

Hallo 4tionov,
habe den ersten Teil probiert, funktioniert einwandfrei.

Für den zweiten Teil benötige ich wahrscheinlich in CAdresse einige zusätzliche propertys, die ich aber noch nicht alle habe, den die Propertys von der Suche entsprechen nicht alle dem Inhalt des Records. Ich denke ich bleibe trotzdem bei Variante 1.

Liebe Grüße

Benutzeravatar
tionov
Site Admin
Beiträge: 286
Registriert: So 18. Mai 2014, 22:40
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von tionov » Mi 31. Mai 2017, 10:53

Ok, alles klar. Schön langsam verstehst Du, nicht? Die zweite Variante wäre besser, weil du dann die Daten in CAdresse kapselst. Das Result zu übergeben, mag vielleicht in dem einen Fall leichter sein, aber insgesamt ist es schlecht, weil du wirst noch öfter im Leben deines Programmes die Adresse benötigen für verschiedenen Zwecke ... und da wirst du dann immer an verschiedenen Stellen einen Result-auseinanderdrösel-und-datenrausfisch-Code implementieren müssen. Und wenn du an einer Stelle was änderst ist es wahrscheinlicher, dass du damit andere Stellen brichst.

Also: für DRY (don't repeat yourself), Wartungsfreundlichkeit, Eleganz und gutes Design ist 2 besser.

Allerdings auch noch nicht ganz, noch besser wäre eine ORM mit einer Modelklasse (die den einzelnen Datensatz mit seinen Daten, und nur die, hält), einer CAdresse als Controller und vielen fAdrXYZ... als Views.

Und dann wären wir bei MVC.

P.S.: Ich habe für unseren Betrieb ein ORM geschrieben, für Postgresql und habe vor, das Open Source zu machen. Das dauert aber noch ein paar Monate, weil ich dazu ein paar private Libs rausschneiden muss. Bis dahin kannst du dir mal das ansehen:

https://github.com/Deganius/gb.deg.form

Das ist eine Komponente um Results in in einem Tableview und in Comboboxen zu zeigen/zu editieren. Kannst du vielleicht brauchen.
Alles Gute,

4tionov

vb6oldie
Foriker
Beiträge: 129
Registriert: Mo 17. Apr 2017, 12:51
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von vb6oldie » Mi 31. Mai 2017, 13:35

Hallo 4tionov,
1. alles klar, ich werde mich bemühen, die fehlenden propertys in CAdresse nachzutragen und die zweite Version verwirklichen.
Es ist sicher OK, wenn ich Propertys von Adrsuchen und von Adr mische, es wird ja nur auf die aktuell relevanten Felder zugegriffen.

2. Eine andere Frage dazu: wenn ich aus einer Liste eine Adresse auswähle und einzeln anzeige, ev. ändere und dann zur Liste zurückkehre, sind die Änderungen dann in der Liste sichtbar, und kommen die Daten beider Seiten nicht durcheiander?
Ich denke NEIN, da das eine in den propertys (aus der Suche) steht, das andere jedoch im result, ist das richtig?
Wen ich aber nun das Result in die Propertys stelle, stimmt das nicht mehr!
Ich werde daher Nummer 1 noch nicht durchführen, sondern auf deine Antwort warten.

3. Dein ORM ist mir im Moment noch zu hoch, vielleicht verstehe ich es später.
Obwohl ich Daten (nicht die aus der Tabelle adr, aber aus anderen Tabellen, die etwas mit den Adressen zu tun haben, z.B.: Texte zu Code) haben werde, die in eine Combobox zu stellen sind.

Liebe Grüße

Benutzeravatar
tionov
Site Admin
Beiträge: 286
Registriert: So 18. Mai 2014, 22:40
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von tionov » Do 1. Jun 2017, 11:45

Zu 1. Ich weiß nicht, was du meinst mit Properties mischen. zeige mit ein Codebeispiel.

Zu 2: Ich mache das normalerweise so, wie ich schon mal früher gezeigt habe, dass es CAdresse.Edit() gibt. Bei Klick auf die Liste (im Form FAdrListe) wird ein neues Adressobjekt erstellt, da der Primarykey übergeben (Adrno), daraufhin füllt sich das Adressobjekt mit seinen Daten, die es selbstständig von DB holt. Dann ruft man seine Funktion Edit() auf, die das Editierform anzeigt (und bei Bedarf die Adresse speichert). Edit() gibt Boolean Cancel zurück und wenn Cancel = False dann wird die Liste einfach neu von DB geladen, fertig. Bei Cancel = True hat sich nichts geändert.

Hier siehst du auch schon sofort, warum es blöd wäre, das Ganze nicht in CAdresse zu kapseln, weil du müsstest nun gleich in FAdrListe ein Result erstellen und an FAdr übergeben, hättest also identischen Code an zwei Stellen zu pflegen. Das will man nicht.

Sich den Krempel immer wieder von DB zu holen, ist, solange es nur um einen Datensatz geht, auch bei Multiuserbetrieb nicht so sehr teuer. Dafür aber sicher.

Zu 3. Das ist jetzt eh nicht öffentlich, du müsstest es dir selbst schreiben. Und ohne ORM musst du eben SQL-Strings schreiben, das kannst du ja.
Alles Gute,

4tionov

vb6oldie
Foriker
Beiträge: 129
Registriert: Mo 17. Apr 2017, 12:51
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von vb6oldie » Do 1. Jun 2017, 15:43

Hallo 4tionov,
hier eine Liste der Felder von der Suche:
.adrno = ValueBox1.Value
.name = TextBox1.Text
.strasse = TextBox2.Text
.land = TextBox3.Text
.plz = ValueBox2.Value
.ort = TextBox4.Text
.telefon = TextBox5.Text
.email = TextBox6.Text
.branche = TextBox7.Text
.selno = ValueBox3.Value
.perno = TextBox8.Text
.kndno = ValueBox4.Value
.faktjahr = ValueBox5.Value
.faktno = ValueBox6.Value
.bezugmail = TextBox9.Text
und hier die Felder der Adressanzeige bzw vom Result:
ValueBox1.Value = $res!adrno
TextBox1.Text = $res!name
TextBox2.Text = $Res!strasse
TextBox3.Text = $Res!nr
TextBox4.Text = $Res!postadr
TextBox5.Text = $Res!land
ValueBox2.Value = $res!plz
ValueBox3.Value = $Res!lfd
TextBox6.Text = $Res!ort
TextBox7.Text = $Res!geocode
CheckBox1.Value = $res!gestoppt
TextBox8.Text = $Res!rd
TextBox9.Text = $Res!rma
TextBox10.Text = $Res!ud
TextBox11.Text = $Res!uma
Es sind also nur die ersten drei Feldnamen ident, alles andere weicht von einander ab. Ja, es gibt noch vereinzelt andere idente Felder.
Das kommt daher, weil die Suche teilweise Tabellen überschreitend erfolgt/erfolgen soll.
Vielleicht soll ich die Gruppen je durch einen vorangestellten Buchstaben unterscheiden.
"sadrno" für Suche und "aadrno" für Anzeige, oder so ähnlich.

Im Moment bin ich gerade dabei, (eine Menge) Daten in diverse Tabellen der DB zu füllen.

Liebe Grüße

Benutzeravatar
tionov
Site Admin
Beiträge: 286
Registriert: So 18. Mai 2014, 22:40
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von tionov » Do 1. Jun 2017, 17:46

Also so was ist immer unglücklich:
gambas code
.name = TextBox1.Text
.strasse = TextBox2.Text
Besser ist .name = TxtName.Text usw. Dann siehst du (später) gleich, wer für was zuständig ist.

Wenn du verschiedene Arten von Adressen mit verschiedenen Feldern in verschiedenen Tabellen hast, dann ist es unter Umständen sinnvoll, eine generische CAdresse zu haben und dann weitere Klassen davon erben zu lassen und in jenen dann weitere Felder einzuführen oder auch die Funktionen zu überschreiben. Das sind aber Designentscheidungen, die angesichts eines spezifischen Problems getroffen werden müssen und mit Bedacht.

So, insgesamt weiß ich nicht genau, was du mir mit deinem Codebeispiel sagen möchtest. Meine Glaskugel reicht nicht weit genug. Ich muss nicht jedes einzelne Feld wissen, aber du zeigst mit nicht mal, in welcher Klasse oder Form jetzt der Code steht, wie er in welchem Objekt verwendet werden und was er tun soll. "und hier die Felder der Adressanzeige bzw vom Result: " reicht bei weitem nicht.

Die richtige Art zu fragen ist, sein Problem auf die simpelste Form herunter zu brechen und die Frage so zu formulieren, dass sie möglichst eindeutig ist. Möglichst mit einem Beispielprojekt. Wenn du so fragst, kommst du oft schon alleine durch die Beschäftigung mit der Formulierung der Frage von selbst auf die Lösung und brauchst gar nicht mehr fragen.

Inzwischen macht mir die Beschäftigung mit deinem Thema täglich zu viel Arbeit und darum werde ich in diesem Thread nicht mehr schreiben, nichts für ungut, bitte! Ich habe versucht, Dir Grundlagen von Objektorientierung beizubringen, bin mir aber nicht ganz sicher, ob es mir gelungen ist. Ich denke, du solltest dich von hier an selbst fortbilden, deine Versuche machen und dich weiterkämpfen, so wie es jeder machen muss, der eine Programmiersprache lernt. Ich habe dir die Stichworte genannt, dir Grundlagen erklärt und habe dir auch mehrfach beschrieben, wofür Dinge wie OOP, Kapselung, Vererbung usw. gut sind. Ich bin aber nicht dafür da, dir dein Programm zu schreiben und mir Gedanken zu machen, wie du deine speziellen Probleme lösen kannst.

Wenn Du hingegen Grundsatzfragen hast, ordentlich formuliert und zwar so, dass auch andere das grundsätzliche Problem leicht verstehen, dann bin ich gerne bereit zu antworten, was ich kann. Dann können nämlich auch andere daraus lernen, darum geht es nämlich hier im Gambas-Club. Dann machen wir das aber bitte je separatem Grundsatzproblem in einem neuen Thread im Forum, damit später mal andere Leute Probleme suchen und Lösungen finden können.

Und noch etwas: Ich habe Dir jetzt die verschiedenen Elemente erklärt, es gibt Klassen, Objekte, Variablen, Properties, Methoden, usw. Wenn du eine Frage stellst, dann verwende bitte auch die passenden Bezeichnungen, so im Stil "Ich habe hier ein Objekt der Klasse CXYZ mit diesen internen Variablen, jenen Properties, einer Funktion Soundso() und das soll dasunddas tun, was es nicht tut. Beispielprojekt hängt an." Dann kann das jeder verstehen und du kriegst gute Antworten, die dich weiter bringen und alle anderen auch.

So, und jetzt: Frohes Schaffen und gutes Gelingen! :-)
Alles Gute,

4tionov

vb6oldie
Foriker
Beiträge: 129
Registriert: Mo 17. Apr 2017, 12:51
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von vb6oldie » Fr 9. Jun 2017, 16:15

Hallo 4tionov,
ich habe mal wieder dein Posting vom Do 25. Mai 2017, 17:39 durchgearbeitet.

Ich versuche mal mir vorzustellen, was ich möchte und was ich habe.
In FMain habe ich u.a.

Code: Alles auswählen

Public Sub mnASuchen_Click() 'A-Suchen

  Dim fAdresse As New CAdresse

  fAdresse.Suchen()

End
und

Code: Alles auswählen

Public Sub mnANeu_Click() 'A-Neu

  Dim $Adresse As New CAdresse

  $Adresse.AdrNeu()

End
Diese rufen beide CAdresse auf.
InCAdresse habe ich:

Code: Alles auswählen

Public Sub Suchen() As Boolean

  Dim fm As New FAdrSuchen	<= Suchen
  Dim $Abbruch As Boolean

  fm.Adresse = Me
  fm.Persistent = True
  fm.ShowModal()
  $DbResult = fm.$res
  $Abbruch = fm.Abgebrochen
  fm.Persistent = False
  fm.close

  If $Abbruch = False Then		<= Wenn abgebrochen wurde, soll keine 
    Verzweigung()						Verzweigung stattfinden!
  End If

End
bzw.

Code: Alles auswählen

Public Sub AdrNeu()

  Dim fm As New FAdrShow	<= Neue (leere Form))

  fm.Adresse = Me
  fm.Persistent = True
  fm.$isNeu = True
  fm.ShowModal()
  fm.Persistent = False
  fm.close

End
In fAdrSuchen wird, wenn etwas eingetragen(geändert) wurde, Adr_Find aufgerufen,
der erstellt den qry-String, dokumentiert den qry und ruft die Datenbank auf.
Wenn nichts eingetraen wurde, und "Suchen" geklickt wurde, wird ein qry zusammengestellt,
der alle Adressen (aus der DB) liefert.
Zurück in CAdresse, wird die "Verzweigung" aufgerufen. (könnte auch in ""Suchen" erledigt werden.
)
In der Verzweigung wird die Anzahl ($DbResult".Count) überprüft.
Bei 0 wird eine Info-Message ausgegeben und Return aufgerufe.
Bei 1 wird Adr_Show aufgerufen und dann mit Return beendet.
Sonst wird Adr_Liste aufgerufen und danach mit Return Beendet.

In Adr_Show und in Adr_Liste wird fAdrListe aufgerufe und fm.$res = $DbResult übergeben.

Code: Alles auswählen

Public Sub AdrShow()

  Dim fm As New FAdrShow

  fm.Adresse = Me
  fm.Persistent = True
  fm.$isNeu = False
  fm.$res = $DbResult
  fm.ShowModal()
  fm.Persistent = False
  fm.close

End
bzw.

Code: Alles auswählen

Private Sub AdrListe()

  Dim fm As New FAdrListe

  fm.Adresse = Me
  fm.Persistent = True
  fm.$res = $DbResult
  fm.ShowModal()
  fm.Persistent = False
  fm.close

End
In fAdrShow habe ich ein "Form_Open", das mir FillAdresse aufruft, falls es nicht $isNeu ist.
Sollte das nicht besser in Res_Write abgehandelt werden?
In FillAdrese werden die TextBoxen etc. gefüllt und dabei die benötigten Ergänzungen und
Änderungen an den Daten vorgenommen.

Dabei wird eine Sub GetPost aufgerufen, welche die benötigten Daten aus der DB holt und entscheidet,
ob die Daten ins Formular oder in eine Cobobox bzw. in ein Array gestellt werden muß.

Andere Functionen habe ich in ein Modul gestellt, weil sie in FAdrListe wieder vorkommen!
Sollten daher diese Daten nicht besser in CAdresse abgeglichen werden?
Damit in den Forms nur die korrigierten Daten vorliegen?

In fAdrListe habe ich die Sub GridView.Data aufgebohrt, damit ich die Daten auch hier ändern kann.
Auch hier habe ich ein Form_Open geschrieben, damit ich die Spalten-Header ausgeben kann.

Da eine Umstrukturierung viel Arbeit macht, möchte ich zuvor deine Meinung dazu wissen.


Die Azeige fAdrShow soll nur der Anzeige der Daten dienen
Es werden hier auch noch Daten aus anderen Tabellen (in Grids) angezeigt, die separat zu editieren sind.
So dass ich zu den eigentlichen Adressdaten ein Editier-Fenster spendieren muss. Aufzurufen aus CAdresse!?

Den Klick auf eine GridZeile habe ich folgend gelöst:

Code: Alles auswählen

Public Sub grdAAdr_Click()

  Dim inx As Integer, sText As String
  Dim fAdresse As New CAdresse

  inx = grdAAdr.Row
  sText = grdAAdr[inx, 0].text ' = adrno

  fAdresse.AdrShow()	<= zeigt nun die Anzeigeform mit den gewählten Daten an.

End

Liebe Grüße

Benutzeravatar
tionov
Site Admin
Beiträge: 286
Registriert: So 18. Mai 2014, 22:40
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von tionov » Sa 10. Jun 2017, 20:53

Hallo vb6oldie,

sorry, komme erst jetzt dazu, zu antworten. Ich sag erst mal, was mir auffällt.

In mnANeu_Click schreibst du "Dim $Adresse" ... das $-Zeichen verwendet man nur für private klassen- oder modulweite Variablen, hier ist sie aber lokal, darum "Dim Adresse As New CAdresse". Das selbe gilt für "$Abbruch As Boolean".

Auch in CAdresse.AdrNeu() sehe ich "fm.$isNeu". Das $ ist da nicht richtig. Du kannst FAdrShow.Neu als Property oder als public Variable machen, beidesmal ohne "$". Du hast das noch in fm.$res (und vielleicht woanders auch).

Ja, Verzweigung könnte auch in Suchen abgehandelt werden, ansonsten muss Verzweigung definitiv eine private Methode von CAdresse sein. Es ist manchmal praktisch, Code auf mehrere Methoden aufzuteilen, dann empfiehlt es sich aber jeweils von den aufgerufenen Unterfunktionen ein cancel zurück geben. So ist man als Programmierer sicher, dass der Programmfluss so funktioniert, wie man sich das vorstellt. So denke ich, hast du dir das auch gedacht.

Nur hier ist es sicher besser (weil es ist ja noch nicht soo viel Code, es in Suchen() selbst abzuhandeln. Da achtest du nur bitte darauf, dass du die Objekte (Forms) erst mit New erstellst, wenn du sie brauchst. Es könnte so gehen:
gambas code
Public Sub Suchen() As Boolean

    Dim fSuche As New FAdrSuchen
    Dim fListe As FAdrListe
    Dim Abbruch As Boolean
    Dim Res as Result

    'Suchen
    fSuche.Adresse = Me
    fSuche.Persistent = True
    fSuche.ShowModal()
    Res = fSuche.$res
    Abbruch = fSuche.Abgebrochen
    fSuche.Persistent = False
    fSuche.close

    'Adzeigen
    If Abbruch = False Then
        If Res.Count = 1 Then
            ' Dazu siehe weiter unten bei Designproblem
            Me.DbResult = Res
            Show()

        Else If Res.Count > 1 Then
            fListe = New FAdrListe
            With fListe
                .DbResult = Res
                .Show()
            End With
        Else
            Abbruch = True
        Endif
    Endif

    Return Abbruch
End

Public Sub Show()
    Dim fAdr As New FAdrShow

    fAdr.Adresse = Me
    fAdr.Show()
End

Hier siehst du, dass dem Form mit dem Grid das Result übergeben wird. Aber zum Anzeigen der Adresse selbst hat CAdresse die eigene Funktion Show() (sie ersetzt AdrShow) . Dazu weiter unten.

Bis hierher sehe ich einen ganz guten, wartbaren objektorientierten Ansatz. Mein Kompliment! Bis hierher bekomme ich auch noch mit, was du meinst, aber nun wird es nebulös und es fängt nun an, mein kleines Hirn zu überfordern. Darum nehme ich erst mal das, was klarer ist:
Den Klick auf eine GridZeile habe ich folgend gelöst:
gambas code
Public Sub grdAAdr_Click()

  Dim inx As Integer, sText As String
  Dim fAdresse As New CAdresse

  inx = grdAAdr.Row
  sText = grdAAdr[inx, 0].text ' = adrno

  fAdresse.AdrShow()	<= zeigt nun die Anzeigeform mit den gewählten Daten an.

End
Das ist zuerst mal nicht so gut geschrieben. Nenne CAdresse nicht fAdresse, sondern "Adresse", ersteres ist verwirrend, weil es ist ja kein Form. UNd dann: "Adresse.AdrShow()" ist doppelt gemoppelt, nenne die Funktion in der Klasse CAdresse Show(), damit ist klar, was gemeint ist. Und dann wird dieser Code nicht funktionieren. Du musst ja der neuen Adresse irgendwie die Adressnummer übergeben, damit diese sich laden kann. Also braucht CAdresse eine Property, mit der Du die Adressnummer übergibst, damit CAdresse im Moment der Übergabe die Adressdaten von der Datenbank laden kann.

Designproblem

Du hast gerade ein grundsätzliches Designproblem (und ich habe dich vielleicht sogar fälschlicherweise dahin gebracht, es ist inzwischen schwierig, dein komplexer gewordenes Programm im Blick zu behalten, vielleicht verstehe ich auch Sachen falsch):

Bis jetzt gingst du davon aus, dass dein FAdrShow ein Result übergeben bekommt und dann dieses irgendwie anzeigt. Das ist aber nicht sehr gescheit. Das wird in dem Moment deutlich, wo FAdrShow in CAdresse.Show() aufgerufen werden soll, wenn du auf das Grid klickst. Wo ist das Result, das bisher der einzige Weg ist, FAdrShow zu geben, was es anzeigen soll? Wie kommst du von dem Index in dem Grid zur Anzeige der Adresse mit dieser Nummer?

Meine Antwort ist folgende:

Du weißt, die Klasse CAdresse stellt mit Properties wie vorname, nachname, strasse ... usw die Daten zur Verfügung. Irgendwie muss man nun CAdresse dazu bringen, diese Daten zur laden, damit sie verwendet werden können. Dazu sollte CAdresse mehrere Möglichkeiten anbieten (die musst du selbst schreiben, das mache ich dir jetzt nicht vor):

1: Mit einer Property CAdresse.DbResult, wenn dieser ein Result übergeben wird, dann füllt CAdresse (wenn das Result eine Zeile hat, ansonsten wird ein Fehler geworfen) die internen Variablen (vorname, nachname, strasse ...) daraus. Nun kann das Objekt Adresse dem Form FAdrShow übergeben werden und dieses kann die Daten anzeigen.

2: Es gibt in CAdresse die Property Nummer As Integer. Wenn hier die Nummer eingegeben wird, macht CAdresse in Nummer_write(Value) einfach selbst eine Suche in der Datenbank und übergibt das Result an sich selbst in Me.Result und der Code von 1. füllt das Adressobjekt.

Nun hast du zwei Möglichkeiten, die Adresse anzuzeigen, einmal lässt du von FAdrSuchen ein Result erstellen, übergibst es dem Adressobjekt und rufst dessen Methode Show() auf.

Oder Du übergibst dem Adressobjekt eine Nummer, dann lädt das Adressobjekt seine Daten von DB und du rufst dann ebenfalls Show() auf.

FAdrShow bekommt seine Daten nun in der Property Adresse As CAdresse übergeben, bei Adresse_write() füllt es seine Textfelder mit den Daten der Adresse. Und zwar so
gambas code
Public Sub Adresse_write(Value as CAdresse)
	With Value
		TxtVorname.Text = .vorname
		TxtNachname.Text = .nachname
		' usw
	End With
End
Und dann kann es angezeigt werden.

Ok? Soweit klar?

Also jetzt muss es erst mal reichen weil mit den nebulösen anderen Daten die du noch anzeigen möchtest ... das ist noch zu kompliziert. Denn die anderen Daten sollten – so mutmaße ich – ebenfalls Objekte sein, die ihre eigenen Arten der Anzeige und Verwaltung mitbringen und erst mal sollte das mit der Adresse stimmen.
Alles Gute,

4tionov

vb6oldie
Foriker
Beiträge: 129
Registriert: Mo 17. Apr 2017, 12:51
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von vb6oldie » So 11. Jun 2017, 08:36

Hallo 4tionov,
jetzt war ich mal vollkommen verwirrt.
Aber mit längerem Studium bekomme ich langsam mit was du mir vorschlägst.
Ich habe versucht die Änderungen durchzuführen: Die Variablen mit $ habe ich geändert...
Ich habe auch wieder
CAdresseAusschnitt.txt
(1.7 KiB) 127-mal heruntergeladen
einen Ausschnitt meiner CAdresse beigefügt, mit einigen kleinen Fragen.
Ich dachte bisher in DbResult /CAdresse werden die Daten so lange aufbewahrt, bis sie überschrieben werden.
Weiters wusste ich nicht, dass in einem Result die Daten in Array-ähnlicher Form vorhanden sind, auch wenn es nur ein Wert ist. In VB war die Ausgabe z.B. ein String, wenn nur ein Text abgerufen wurde.
Ich habe AdrShow() und AdrListe() beibehalten, ist für mich im Moment übersichtlicher.
Wenn ich in der Form fAdrListe eine Grid-Zeile anklicke, soll die Form verlassen werden und mit der ermittelten adrno die Form fAdrShow wieder aufgerufen werden.
Liege ich da irgendwo falsch?

Code: Alles auswählen

Public Sub grdAAdr_Click()

  Dim inx As Integer, sText, sSQL As String
  Dim Adresse As New CAdresse

  inx = grdAAdr.Row
  sText = grdAAdr[inx, 0].text ' = adrno

  Adresse.adrno = sText
  Adresse.AdrShow()

End
Mein Problem mit "Adr_Neu" werde ich noch überdenken, es muss eine Edit-Form aber mit leerem Inhalt angezeigt werden. !?!

Liebe Grüße

vb6oldie
Foriker
Beiträge: 129
Registriert: Mo 17. Apr 2017, 12:51
Kontaktdaten:

Re: Allgemeiner Codecheck

Beitrag von vb6oldie » Mo 12. Jun 2017, 07:06

Hallo 4tionov,
ich habe mir mal Gedanken über die Übergabe von Result zwischen den einzelnen Formen und CAdresse gemacht, da dies bei mir nicht richtig funktioniert.
Von FMain rufe ich Adresse.Suchen (über CAdesse,Dim Adresse As New CAdresse) auf.
In CAdresse rufe ich FAdrSuchen auf und nach dem ShowModal hole ich fSuche.res nach Res (Res ist eine Private Variable As Result, obwohl ich auch eine Property DbResult/$DbResult habe).
In fAdrSuchen werden in Adresse_Write die Daten in die einzelnen Felder übertragen und in Eingabe_Change werden die Eingaben wieder in die Felder der $Adresse geschickt.
In btnASuche_Clck wird Adr_Find (sollte wohl besser MakeAdrQry heissen) ) aufgerufen bzw. bei keiner Eingabe wird eine qry für alle Records zusammengestellt und in beiden Fällen wird die qry durchgeführt und das Result zurückgeliefert $Adresse-DbResult = res.
Zurück in CAdresse wird das Result gespeichert Res = fSuche.res. <= Hier sollte vermutlich $DbResult = fSuche.Res stehen?
Dann wird die Verzweigung durchgeführt.
AdrShow <==> AdrListe.
In AdrShow wird fShow.res = Res vor dem ShowModal durchgeführt - funktioniert.
In AdrListe wird fListe.res = $DbResult vor dem ShowModal durchgeführt - funktioniert nur teilweise:
Die Daten werden normal angezeigt, wenn ich eine Zeile auswähle, bleibt es beim füllen in fAdrShow bei FillAdresse beim ersten Wert mit "NULL Objekt" hängen.
Wenn ich aber die Liste beende (x) bleibt es nach dem ShowModal bei $adrno = fListe.adrno mit "Typenunverträglichkeit..." hängen.

Da habe ich wohl einiges mit DbResult und Res durcheinander gebracht.
Auch die Rückgabe der adrno muss wohl anders lauten.

Eine andere zusätzliche Frage:
Wie funktioniert eigentlich die Erstellung des Records wenn ich die adrno zurückbekomme, sollte da wieder ein DB-Aufruf erfolgen, oder wird das irgendwie automatisch erledigt, bzw. was muss vorhanden sein, damit das automatisch funktioniert.
Die Daten für die Liste sollten ja nicht verändert werden (alle müssen noch vorhanden sein und nicht auf einen Record reduziert worden sein).

Liebe Grüße

Gesperrt

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast