Memofeld und Text einlesen

Moderator: ModerationP

Re: Memofeld und Text einlesen

Beitragvon knobbi38 » 20. Nov 2020, 17:41

Hallo Hubert,

ich weiß jetzt nicht, wo die Probleme mit der Beschreibung sind, deshalb hier nochmal das Ganze zum mitschreiben.

im UF:
Code: Alles auswählen
Option Compare Database
Option Explicit

Private m_strSelectedText As String

Private Sub txtMemo_GotFocus()
  m_strSelectedText = vbNullString
End Sub

Private Sub txtMemo_LostFocus()
  m_strSelectedText = txtMemo.SelText
End Sub

Public Property Get SeletectedText() As String
  SeletectedText = m_strSelectedText
End Property

Public Property Let SeletectedText(ByVal NewValue As String)
  m_strSelectedText = NewValue
End Property

und dann im HF:
Code: Alles auswählen
Private Sub btnGetSelectedText_Click()
  Debug.Print Me.subContainer.Form.SeletectedText
  Me.subContainer.Form.SeletectedText = vbNullString
End Sub

"subContainer" ist dabei der Name des SubForm-Steuerelements.

Gruß Ulrich
knobbi38
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 2798
Registriert: 02. Jul 2015, 14:23

Re: Memofeld und Text einlesen

Beitragvon Hubert$ » 22. Nov 2020, 10:31

Hallo,
vielen Dank, ich habe es verwendet. Aber es läuft leider nicht. Zuerst dachte ich, es läge an den Formularen, dann an der Datenbank. Habe daraufhin eine neue erstellt. Dasselbe Problem.
Es liegt wohl daran, wie ich schon schrieb, dass das LostFocus-Ereignis eines Controls nicht ausgelöst wird, wenn man aus einem Control des Ufos in ein Control des Hafos wechselt. Das GotFocus-Ereignis für den umgekehrten Fall, also vom Hafo zu einem Control des Ufo dagegen gibt es. Und wechselt man nur die Datensätze innerhalb des Ufos, wird LostFocus, gefolgt von GotFocus, ausgelöst.
Ganz kurios wird es, wenn man vom Ufo ins Hauptformular und dann zurück ins Unterformular geht. Da gibt es einen Unterschied: zurück auf den Ausgangsdatensatz kommt nur GotFocus; zurück auf einen anderen als den Ausgangsdatensatz kommt GotFocus, was noch erklärlich ist, aber dann auch noch LostFocus, GotFocus.
Ich habe mal eine Datenbank beigefügt, wo man das nachvollziehen kann. Die Property habe ich wegen der LostFocus-Besonderheit nicht eingebracht.
Das exit-event des Ufo-Controls soll ja unpassend sein, aber was bleibt dann noch oder kann man es doch mit der Property verwenden?
Gruß Hubert
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Hubert$
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 90
Registriert: 04. Dez 2019, 21:32

Re: Memofeld und Text einlesen

Beitragvon knobbi38 » 22. Nov 2020, 15:18

Hallo Hubert,

die Fokussteuerung ist nicht "kurios" - möglicherweise kennt man nur noch nicht alle Zusammenhänge. Da die Fokussteuerung nicht verändert werden kann, müssen eventuell mehr Aspekte für eine Problemlösung berücksichtigt werden.

Du hast schon wieder die Rahmenbedingungen komplett geändert, in dem du von einer Einzelformularansicht auf die Endlosansicht mit mehrern DS gewechselt hast. Das sind wieder nochmal komplett anderen Verhältnisse.

Das Hilfskonstrukt mit dem Textbox-Fokus Ereignis ist nur notwendig, wenn der Fokus innerhalb eines Formulars auf ein anderes Steuerelement gesetzt wird, z.B. durch den Klick auf einen Button. Deshalb wurde die Zwischenspeicherung zunächst notwendig.
Nach deiner letzen Änderung mit dem Button auf dem HF, habe ich das leider nicht mehr weiter beachtet und auch nicht wieder herausgenommen. Deshalb konnte das Beispiel so auch leider nicht mehr richtig funktionieren. Sorry für die damit gestiftete Verwirrung.

Wenn du also vom HF aus mit einem Klick auf einen Button den aktuell selektierenten Text auslesen möchtest, reicht im UF folgendes:
Code: Alles auswählen
Public Property Get SelectedText() As String
  On Error Resume Next
  SelectedText = Me!txtFirma.SelText
  On Error GoTo 0
End Property

und im HF dann:
Code: Alles auswählen
Private Sub btnGetSelectedText_Click()
  Me!txtSelectedText.Value = Me!subContainer.Form.SelectedText
End Sub

Ich frage mich jetzt allerdings, wofür das überhaupt gut sein soll. Meistens resultieren solche Anforderungen aus der Suche für die Behandlung eines anderen Symptoms, anstatt der eigentlichen Ursache auf den Grund zu gehen.

Das scheinbar "komische" Fokusverhalten ist vielleicht damit am Einfachsten zu erklären, daß die Fokussteuerung für jedes Formular getrennt ist und aus Sicht des HF nur das SubForm-Steuerelement selbst den Fokus erhält. Dieses erst gibt den erhaltenen Fokus an das eingebettet Formular weiter und selektiert nochmal das zuletzt fokusierte Steuerlement. Deshalb tritt auch kein Lost-Fokus Ereignis im UF auf, weil aus Sicht des UF beim Wechsel auf das HF dieses den Fokus scheinbar nicht verliert, sondern der Fokusverlust ist "nur" im HF beim SubForm-Steuerelement aufgetreten. Dort hat ein anderes Steuerelement den Fokus erhalten.

Zwei Dinge solltest du noch bei deinen Versuchen beachten:
1. Sollte ein Subform-Steuerelement immer eine anderen Bezeichner bekommen, als das geladene Formular. Das wird vom Access-Assistenten leider nicht berücksichtigt.
2. Anzeigen, wie Msgbox oder Debug-Ausgaben können die Fokussteuerung beeinflussen. Debug-Ausgaben sind dabei noch das harmlosere Mittel, funktionieren aber auch nicht exakt. Eine Lösung dafür wären Logausgaben in eine Datei oder per Debug-Schnittstelle von Windows.

Gruß Ulrich
knobbi38
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 2798
Registriert: 02. Jul 2015, 14:23

Re: Memofeld und Text einlesen

Beitragvon Hubert$ » 22. Nov 2020, 23:55

Hallo Ulrich,
danke. Das passt und läuft so.
Übrigens ist es egal, ob das Ufo ein Einzel- oder Endlosformular ist.
Zur Property:
ist es eigentlich individueller Stil statt einer Function die Property Get bei fehlendem Let zu nehmen? Ich sehe den Sinn bisher darin, dass man die Let- und Get-Property wählt, um einen gemeinsamen Namen verwenden zu können. In dieser Kombination wird sie ja auch durch das Einfügen-Menü ausgegeben.
Gruß Hubert
Hubert$
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 90
Registriert: 04. Dez 2019, 21:32

Re: Memofeld und Text einlesen

Beitragvon knobbi38 » 23. Nov 2020, 02:11

Hallo Hubert,

Properties werden üblicherweise für einzelne Eigenschaften, Methoden hingegen eher für Aktionen und Berechnungen verwendet. Es müssen nicht immer alle LET/GET/SET Eigenschaftsprozeduren implementiert werden. Bei nur GET ist die Eigenschaft readonly, bei nur LET entsprechend writeonly und es gibt auch Mischimplementierungen, wie z.B. WriteOnce usw.
Natürlich könnte eine Property immer durch eine Methode ersetzt werden, wobei sich dann u.U. die Art der Zuweisung ändert.
Letztendlich ist eine Frage des Programmierstils und das ist dann auch eine subjektive Entscheidung. Der Stil sollte aber schon lesbar und nachvollziehbar für Außenstehende sein, genauso wie einheitlich und durchgängig, mindestens innerhalb eines Projekts.

Eigentlich für dotnet gedacht, kann aber auch analog für VBA angewendet werden:
https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms229054(v=vs.100)?redirectedfrom=MSDN

Gruß Ulrich
knobbi38
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 2798
Registriert: 02. Jul 2015, 14:23

Re: Memofeld und Text einlesen

Beitragvon Hubert$ » 23. Nov 2020, 11:36

Hallo Ulrich,
danke für den Link.
bei nur LET entsprechend writeonly

Ein alleiniges Let ohne die Kombination mit Get kann ich mir nicht vorstellen oder kann man noch anders auf die Property zugreifen?
Gruß Hubert
Hubert$
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 90
Registriert: 04. Dez 2019, 21:32

Re: Memofeld und Text einlesen

Beitragvon knobbi38 » 23. Nov 2020, 12:15

Hallo Hubert,

sicherlich gibt es auch Konstellationen, wo eine writeonly Property gebraucht wird, z.B. wenn Objekte initialisiert werden und diese Initialisierungswerte nicht automatisch für andere Objekte sichtbar bzw. im Zugriff sein sollen.
kann man noch anders auf die Property zugreifen

Weiß jetzt nicht, was du damit meinst.

Gruß Ulrich
knobbi38
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 2798
Registriert: 02. Jul 2015, 14:23

Re: Memofeld und Text einlesen

Beitragvon Gast » 23. Nov 2020, 14:39

Hallo Ulrich,
Das
Bei nur GET ist die Eigenschaft readonly, bei nur LET entsprechend writeonly und es gibt auch Mischimplementierungen, wie z.B. WriteOnce usw.
kann man so verstehen, dass z.B. nur LET verwendet wird.
Aber ich meine, dass es dann auch eine GET geben muss, also das "nur" das nicht ausschließen darf.
Es sei denn, man kann das GET durch anderen Code ersetzen.
Das meinte ich mit "kann man noch anders auf die Property zugreifen"
Gruß Hubert
Gast
 

Re: Memofeld und Text einlesen

Beitragvon knobbi38 » 23. Nov 2020, 23:28

Hallo Hubert,
... dass es dann auch eine GET geben muss, also das "nur" das nicht ausschließen darf.

Die Annahme ist nicht richtig. LET/GET können für sich alleine auftreten. Wenn es writeonly sein soll, dann darf es kein weiteres GET geben.
Es sei denn, man kann das GET durch anderen Code ersetzen.

Nein, es gibt keinen Ersatz.

Gruß Ulrich
knobbi38
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 2798
Registriert: 02. Jul 2015, 14:23

Re: Memofeld und Text einlesen

Beitragvon Bitsqueezer » 24. Nov 2020, 10:07

Hallo,

naja, "Ersatz" gibt es schon. Du könntest einerseits die Private-Variable in eine Public verwandeln und so mit Property UND Direktzugriff arbeiten. Ebenso könntest Du eine Function schreiben, die Dir den Wert der Variablen zurückliefert und eine Sub, die einen Wert setzt. Das wäre dann "Wurschtelcode".

Das ist das, was Ulrich oben mit "Programmierstil" meinte. Eine Property sollte man immer dann verwenden, wenn man eine einheitliche Art und Weise des Zugriffs auf etwas gewährleisten will, was nach außen hin nicht sichtbar sein soll oder muß. Das muß auch nicht immer zwingend eine Private-Variable sein.

Man sollte immer daran denken, daß jedes Modul in VBA eigentlich als Objekt gehandhabt wird. Das schließt auch Standardmodule ein, die lediglich die Besonderheit haben, durch VBA automatisch mit genau einer Objektinstanz erzeugt zu werden und die man nicht mehrfach instantiieren kann.

Speziell Formular- und Reportmodule aber sind ganz herkömmliche Klassenmodule. Eine Klasse ist der Bauplan für ein Objekt. Nur mit dem Objekt kann man arbeiten. Ohne Instantiierung kann man den Code im Klassenmodul nicht aufrufen (auch wenn als Public deklariert). Darum kannst Du, ohne z.B. ein Formular zu öffnen, auch nicht einen Code davon aufrufen, denn ohne Objekt (also hier: geöffnetes Formular) kannst Du nicht auf dessen Code zugreifen.

Der Sinn der Property ist es, dem Objekt eine Eigenschaft zu verpassen, daher der Name. Die Eigenschaft soll für alle außenstehende Verwender etwas zur Verfügung stellen, was sie verwenden können. Der Autor des Klassenmoduls (hier des Formularcodes) bestimmt, was Außenstehende damit machen dürfen. Daher gibt es eben die Möglichkeit, Lese-/Schreibrechte auf eine Eigenschaft zu vergeben, sowohl beide wie auch getrennt.
Du arbeitest bereits ständig damit, ohne es wahrscheinlich zu bemerken. Wenn Du etwa die Eigenschaft "WindowHeight" eines Formulares nimmst, dann findest Du in der Hilfe "schreibgeschützter Wert". Das ist dann eine Eigenschaft, die nur eine Get-Property hat, aber kein Let-Pendant. Weil der Autor bestimmt hat, daß man WindowsHeight nur auslesen darf, um die aktuelle Fensterhöhe zu erhalten, aber sie nicht verändern darf.

Mit hoher Wahrscheinlichkeit steht hinter dieser Eigenschaft keine Private-Variable im Klassenmodul Access.Form dahinter, weil es nicht notwendig ist, den Wert im Formular zu speichern. Stattdessen wird der Wert aus dem Betriebssystem zurückgegeben, was intern in der Property-Prozedur gemacht wird. Für den Eigenschaften-Verwender ist es aber eine "Variable", die direkt zum Formular gehört. Woher der Wert kommt und wie er ermittelt wird, spielt für den Verwender keine Rolle. Wenn sich der Autor der Eigenschaft irgendwann entschließt, den Wert völlig anders zu ermitteln, kann er das machen, ohne daß der Verwender das mitbekommt. Daher die "Kapselung" über eine Property. Programmierstil eben. Saubere Schnittstellen nach außen.

Ein weiterer Punkt ist, daß man eine Property wie eine Variable verwenden kann, indem man ihr mit "=" einen Wert zuweist. Würde man dazu eine Sub verwenden, wäre der Wert stattdessen ein Parameter der Sub und es wäre nicht genau zu erkennen, was da passiert, wenn nicht der Name der Sub entsprechend gestaltet ist.

Und der nächste wichtige Punkt ist, daß eine Property im Gegensatz zu einer als Public deklarierten Variable auch eine Wertprüfung vornehmen kann. So könnte man einer Property-Prozedur hinterlegen, daß der Wertebereich der Eigenschaft nur von 1 bis 12 als Integer übergeben werden darf, während intern etwa darüber hinaus daraus ein String mit führender 0 erzeugt wird. Das geht mit einer Variablen nicht.

Durch diese Art der Kapselung kann man intern im Objektcode aber frei gestalten. Die Private-Variable, in der der Wert der Property vielleicht gespeichert wird, muß nicht zwingend wie die Property heißen, wenn man sie umbenennen will, paßt man eben den Code der Property an, fertig. Für den Verwender ändert sich nichts, er verwendet ja nur den Property-Namen.

Eine Property erlaubt also das Abgrenzen des internen vom externen Code, wodurch die Codeteile unabhängiger voneinander werden und bessere Wiederverwendbarkeit ermöglichen. Ob man sie verwendet oder nicht, ist dann eben Programmierstil. Man kann halt auch Wurschtelcode schreiben, muß sich dann aber auch nicht wundern, wenn die Anwendung immer wartungsintensiver und fehleranfälliger wird, weil man alles kreuzweise "irgendwie" miteinander verknüpft hat.

Gruß

Christian
Bitsqueezer
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 7911
Registriert: 21. Jun 2007, 12:17

Re: Memofeld und Text einlesen

Beitragvon knobbi38 » 24. Nov 2020, 11:05

@Christian:

Besser kann man das wohl nicht beschreiben. 8-)

Grüße Ulrich
knobbi38
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 2798
Registriert: 02. Jul 2015, 14:23

Re: Memofeld und Text einlesen

Beitragvon Hubert$ » 24. Nov 2020, 23:45

Hallo,
vielen Dank.
Alles interessant zu lesen.
Gruß Hubert
Hubert$
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 90
Registriert: 04. Dez 2019, 21:32

Vorherige

Zurück zu Access Forum (provisorisch)

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste