Access-o-Mania

Access-Forum (Deutsch/German) => Access Programmierung => Thema gestartet von: datekk am Januar 23, 2017, 16:10:26

Titel: Formular mit ADODB Recordset aktualisieren
Beitrag von: datekk am Januar 23, 2017, 16:10:26
Hallo,

ich habe ein Formular, welches ich an ein ADODB Recordset binde. Die Datenquelle besteht allerdings aus einer Abfrage, die mehrere Felder anderer Tabellen abfragt.

Der Datensatz wird im Formular richtig angezeigt, jedoch kann ich keine Daten ändern. Wenn ich das Formular schließe, werden alle Daten auf den Urzustand zurück gesetzt.

Der ADODB Recordset holt sich die Daten von einem SQL Server, wo eine gespeicherte Prozedur aufgerufen wird, die wiederum den Datensatz liefert.

Wie kann ich also so einen Datensatz aktualisieren der auf mehreren Tabellen beruht?
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: ebs17 am Januar 23, 2017, 17:47:33
Eine Aktualisierbarkeit erreicht man, wenn man sich auf Datensätze in Tabellen konzentriert (da liegen sie nämlich wirklich).

Also sollte man aus dem zu ändernden Feld auf den Datensatz der beteiligten Tabelle schließen können und auf diesen dann die Änderung anwenden,
- per gesondertem Änderungsformular zur Tabelle,
- per Aktionsabfrage
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: datekk am Januar 23, 2017, 17:53:34
Ist es denn eigentlich möglich einem Steuerelement seine Herkunft zu entlocken? Also kann man z.B. bei Me.Textfeld irgendwie herausfinden, woher es seine Daten bezieht?

Also so z.B.: debug.print me.textfeld.herkunftstabelle.name?

Denn irgendwie muss ja im Recordset die Herkunft auch hinterlegt sein.

Meine Idee ist, die Steuerelemente via Do Loop zu durchlaufen, die Datenherkunft abzufragen und somit für jedes Feld eine Aktualisierungsabfrage durchzuführen. Ggf. lässt sich dies ja noch auf geänderte Felder reduzieren...

Ist das möglich?
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: PhilS am Januar 23, 2017, 18:01:36
Zitat von: datekk am Januar 23, 2017, 16:10:26Wie kann ich also so einen Datensatz aktualisieren der auf mehreren Tabellen beruht?
Mal davon abgesehen, dass diese Formulierung in sich schon widersprüchlich ist, kannst du mehrere Tabellen auf einmal nur dann aktualisieren, wenn du die Logik der Aktualisierung selbst ausprogrammierst. - Das wird mit gebundenen Formularen evtl. schwierig, könnte aber mit einem komplett ungebundenem Recordset gehen.

In der Regel ist die einfachste, und meist auch beste Option, die dem Rat von ebs17 zu folgen und sich auf eine Tabelle zu konzentrieren.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: datekk am Januar 23, 2017, 18:03:18
Jo, bin schon am ändern und versuche die Felder der anderen Tabelle via Unterformular einzufügen.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: PhilS am Januar 23, 2017, 18:08:50
Zitat von: datekk am Januar 23, 2017, 17:53:34
Ist es denn eigentlich möglich einem Steuerelement seine Herkunft zu entlocken? Also kann man z.B. bei Me.Textfeld irgendwie herausfinden, woher es seine Daten bezieht?
[...]
Denn irgendwie muss ja im Recordset die Herkunft auch hinterlegt sein.
Ein ADODB.Field hat in seiner Properties-Auflistung eine Property BASETABLENAME. - Ob dort etwas brauchbares drin steht, hängt natürlich von der Logik in der SP ab, die die Daten liest und an den Client liefert.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: Beaker s.a. am Januar 23, 2017, 18:35:01
Hallo,
ZitatIst es denn eigentlich möglich einem Steuerelement seine Herkunft zu entlocken? Also kann man z.B. bei Me.Textfeld irgendwie herausfinden, woher es seine Daten bezieht?
Vielleicht indem man die RecordSource des Formulars und die ControlSource des
Textfeldes ausliest?
gruss ekkehard
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: markusxy am Januar 23, 2017, 23:38:56
Zitat von: datekk am Januar 23, 2017, 16:10:26
Wie kann ich also so einen Datensatz aktualisieren der auf mehreren Tabellen beruht?

Das ist normalerweise kein Problem. Im Gegenteil, grade in diesem Punkt ist ADO wesentlich besser wie DAO. Nur Felder mit berechneten oder aggrigierten Werten kann man nicht ändern. Die restlichen Felder können normal immer aktualisiert werden.

Falls die Mindestanforderungen für das Update erfüllt sind, bleibt noch das Formular.
Auch wenn sich das Recordset aktualisieren lässt, spielt das Formular manchmal nicht mit. Die Implementierung in Access Forms ist sehr mangelhaft. Ich verwende daher bei ADO RS für Endlosformulare in der Regel ein Datagrid.
Die Frage ist jetzt, ob sich das Recordset ohne Bindung an ein Formular aktualisieren lässt.
Wenn nein, dann poste einfach mal die Abfrage aus der SP und zeige den Code wie du das Recordset öffnest.

LG Markus
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: PhilS am Januar 24, 2017, 10:53:20
Zitat von: markus888 am Januar 23, 2017, 23:38:56Falls die Mindestanforderungen für das Update erfüllt sind, bleibt noch das Formular.
Auch wenn sich das Recordset aktualisieren lässt, spielt das Formular manchmal nicht mit.
Wenn ein Aktualisierungsproblem nur aus dem Formular resultiert, lässt sich das in vielen Fällen durch Setzten der UniqueTable- und/oder ResyncCommand-Property beheben.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: datekk am Januar 24, 2017, 10:58:24
Danke Markus und PhilS. Ich habe noch weitere Fragen zu Euren Antworten:

ZitatFalls die Mindestanforderungen für das Update erfüllt sind, bleibt noch das Formular.
Was sind die Mindestanforderungen? Also in der "normalen" Access Umgebung basiert das Formular auf einer Abfrage von mehreren Tabellen und hier ist das Formular aktualisierbar. Ich habe einfach die Abfrage .. also die SELECT Anweisung in die Open Einstellungen des RS genommen, bzw. auf Basis der Abfrage eine gespeicherte Prozedur erstellt, die ich via EXEC aufrufe.

ZitatDie Frage ist jetzt, ob sich das Recordset ohne Bindung an ein Formular aktualisieren lässt.
Wie finde ich das heraus?

Zitatlässt sich das in vielen Fällen durch Setzten der UniqueTable- und/oder ResyncCommand-Property beheben.
Wie mache ich das und wo?


Die Ursprüngliche Abfrage ist:
SELECT Kundenliste.ID_Kunde, Kundenliste.Type, Firma.Firmenname, Firma.Straße, Firma.PLZ, Firma.Ort, Ansprechpartner.Anrede, Ansprechpartner.Vorname, Ansprechpartner.Nachname, Kundenliste.Nachverfolgung, Kundenliste.Uhrzeit, Kundenliste.VertriebsID, Kundenliste.Erstellungsdatum, Kundenliste.Status_1, Kundenliste.Vertriebsphase, Kundenliste.Titel, Kundenliste.Quelle, Kundenliste.[geschlossen am], Kundenliste.Neukunde, Firma.ID_Kunde AS ParentID, Kundenliste.GrandParentContactServiceID, Kundenliste.Type, Kundenliste.IrisSubType, Ansprechpartner.WorkPhoneNum, Ansprechpartner.MobilePhoneNum, Ansprechpartner.EmailAddress1, Kundenliste.KundenIdRef, Kundenliste.VorgangsFarbe, Kundenliste.AutoPilotOn, Kundenliste.AutoPilotArt, Kundenliste.AutoPilotDatumLetzteAktion

FROM (Kundenliste LEFT JOIN Kundenliste AS Firma ON Kundenliste.ParentIDNeu = Firma.ID_Kunde) LEFT JOIN Kundenliste AS Ansprechpartner ON Kundenliste.GrandParentContactServiceID = Ansprechpartner.ID_Kunde

WHERE (((Kundenliste.Type)=3));


Code in gespeicherter Prozedur:


SELECT Kundenliste.ID_Kunde, Kundenliste.Type, Firma.Firmenname, Firma.Straße, Firma.PLZ, Firma.Ort, Ansprechpartner.Anrede, Ansprechpartner.Vorname, Ansprechpartner.Nachname, Kundenliste.Nachverfolgung, Kundenliste.Uhrzeit, Kundenliste.VertriebsID, Kundenliste.Erstellungsdatum, Kundenliste.Status_1, Kundenliste.Vertriebsphase, Kundenliste.Titel, Kundenliste.Quelle, Kundenliste.[geschlossen am], Kundenliste.Neukunde, Firma.ID_Kunde AS ParentID, Kundenliste.GrandParentContactServiceID, Kundenliste.Type, Kundenliste.IrisSubType, Ansprechpartner.WorkPhoneNum, Ansprechpartner.MobilePhoneNum, Ansprechpartner.EmailAddress1, Kundenliste.KundenIdRef, Kundenliste.VorgangsFarbe, Kundenliste.AutoPilotOn, Kundenliste.AutoPilotArt, Kundenliste.AutoPilotDatumLetzteAktion
FROM (Kundenliste LEFT JOIN Kundenliste AS Firma ON Kundenliste.ParentIDNeu = Firma.ID_Kunde) LEFT JOIN Kundenliste AS Ansprechpartner ON Kundenliste.GrandParentContactServiceID = Ansprechpartner.ID_Kunde
WHERE (((Kundenliste.ID_Kunde)=@intID) AND ((Kundenliste.Type)=3));





Aufruf im Klassenmodul:

Private Sub Form_Open(Cancel As Integer)

    Set Me.Recordset = SQLRecordset("EXEC dbo.spVerkaufschanceHolen " & Me.OpenArgs)
   
End Sub


Funktion SQLRecordset:


Public Function SQLRecordset(sql As String) As ADODB.Recordset
On Error Resume Next

    Set SQLRecordset = New ADODB.Recordset
    With SQLRecordset
        .ActiveConnection = Connection
        .CursorLocation = adUseServer
        .CursorType = adOpenKeyset
        .LockType = adLockOptimistic
        .Source = sql
        .Open
    End With

Private Function Connection() As ADODB.Connection

    Set Connection = New ADODB.Connection
    With Connection
        .ConnectionString = "DATA PROVIDER=SQLOLEDB.1;Server=**************;DATABASE=*******;UID=******;PWD=*********"
        .CursorLocation = adUseServer
        .Provider = "MSDataShape"
        .Open
    End With
   

End Function




Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: markusxy am Januar 24, 2017, 16:01:26

ZitatDie Frage ist jetzt, ob sich das Recordset ohne Bindung an ein Formular aktualisieren lässt.

Wie finde ich das heraus?


Einfach testen.

Zitatlässt sich das in vielen Fällen durch Setzten der UniqueTable- und/oder ResyncCommand-Property beheben.  Wie mache ich das und wo?


Die VBA Hilfe wäre da ganz ein heißer Tipp.

LG Markus
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: markusxy am Januar 24, 2017, 16:05:13
Zitat von: PhilS am Januar 24, 2017, 10:53:20
Wenn ein Aktualisierungsproblem nur aus dem Formular resultiert, lässt sich das in vielen Fällen durch Setzten der UniqueTable- und/oder ResyncCommand-Property beheben.

Meine Angaben zur Aktualisierbarkeit haben sich auf einen Client Cursor bezogen (gewöhnlich die erste Wahl bei Access - da dieser bei allen Steuerelementen erforderlich ist). Da kann es vorkommen, das nur ein Teil der Felder aktualisierbar ist. Da ich auch kein Access Form mehr für ADO einsetzte, interessiert es mich auch nicht wahnsinnig ob das funktioniert. Verfügst du da über Erfahrung?

LG Markus
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: PhilS am Januar 25, 2017, 09:08:11
Zitat von: datekk am Januar 24, 2017, 10:58:24
Zitatlässt sich das in vielen Fällen durch Setzten der UniqueTable- und/oder ResyncCommand-Property beheben.
Wie mache ich das und wo?
In einem ADP ganz normal in den Formulareigenschaften. In einer MDB/ACCDB sind diese Eigenschaften im Formulardesigner ausgeblendet, aber sie können auch dort per VBA-Code gesetzt werden.
Sinnvollerweise machst du das nachdem du das Recordset des Formulars zugewiesen hast.

Ich glaube dein Hauptproblem ist aber die Cursor-Einstellung deines Recordsets. Du brauchst einen clientseitigen (adUseClient) Cursor, damit deine Recordsets, an ein Formular gebunden, aktualisierbar sind.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: datekk am Januar 25, 2017, 09:28:14
Alles klar, ich werde das mal probieren. Ein Problem habe ich noch: Datumsfelder. Der SQL Server liefert mir das Datum so: 2017-01-23

Wie kann ich das Datum in einem Textfeld ganz normal darstellen (23.01.2017) UND auch aktualisieren? optimaler Weise mit der Datumsauswahl (also wo sich das kleine Kalenderfenster öffnet).

Ich hatte es schon mit dem Microsoft Steuerelement DatePicker versucht. Dieses stellt das Datum richtig dar, bei Änderung erhalte ich jedoch die Fehlermeldung, dass das Feld zu klein wäre für die Datenmenge. Datentyp im SQL ist Date. Ich nehme an, das Steuerelement liefert DateTime.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: markusxy am Januar 25, 2017, 11:13:58
Zitat von: datekk am Januar 25, 2017, 09:28:14
Der SQL Server liefert mir das Datum so: 2017-01-23

Welchen Datentyp zeigt das Recordset für das Datum?
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: PhilS am Januar 25, 2017, 11:26:18
Zitat von: datekk am Januar 25, 2017, 09:28:14Datentyp im SQL ist Date. Ich nehme an, das Steuerelement liefert DateTime.
Der Date-Datentyp ist relativ neu im SQL-Server. Ältere Treiber kennen den Datentyp nicht und übermittelt die Daten als Text. Ich würde besser DateTime als Datentyp verwenden. Mit neueren Treibern sollte aber auch Date funktionieren. - Dazu kann ich aber mangels eigener Erfahrungen keine genaueren Informationen liefern.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: datekk am Mai 12, 2017, 18:23:08
Hallo an Alle,

ich muss das Thema nochmal rauskramen. Ich habe immer noch keine Lösung für ein ungebundenes Formular, welches seine Daten aus deinem ADO -  Recordset beziehen soll. Zur Erinnerung: Das Formular holt seine Daten nicht aus EINER Tabelle, sondern aus einer SELECT Anweisung mit verknüpften Tabellen.

Ich kann das Formular nicht allein aus der Tabelle mit Daten füllen, da es so nicht leserlich wäre.

Hier wurde ja auch schon was mit der Unique Table Eigenschaft und Resync gepostet. Vielleicht kann mir hier jemand nochmal weiterhelfen. Die Beispiele die ich online finde, beziehen sich nicht auf ein ADO Recordset als Grundlage eines (Endlos)Formulars.

msql = "SELECT tblEins.*, tblZwei.* From tblEins INNER JOIN tblZwei ON tblEins.ID = tblZwei.RefId"



With rs
    .Source = msql
    .ActiveConnection = con
    .CursorType = adOpenKeyset
    .LockType = adLockOptimistic
    .Properties("Unique Table") = "tblEins"
    .Properties("Resync Commanc") = "Select * From (" & msql & ") Where tblEins.Id = ?"
    .Open
End With



Hier komme ich nicht weiter. Das Formular lässt sich nach wie vor nicht bearbeiten. Wo sind die ADO Profis hier im Forum?  ;)
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: MzKlMu am Mai 12, 2017, 21:49:53
Hallo,
Zitatsondern aus einer SELECT Anweisung mit verknüpften Tabellen.
das ist kein Grund ein ungebundenes Formular zu verwenden.
Abfragen mit INNER JOIN können fast immer auch in gebunden Formularen verwendet werden.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: datekk am Mai 12, 2017, 22:00:18
Meine Tabellen liegen aber auf einem SQL Server und ich möchte keine Tabellen in Access einbinden. Es soll alles nur noch über ADO Recordsets laufen.

Damit kann ich das Form nicht binden.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: DF6GL am Mai 13, 2017, 09:20:44
Hallo,


https://msdn.microsoft.com/de-de/library/office/ff835419.aspx
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: datekk am Mai 13, 2017, 10:52:18
Hallo DF6GL,

das Problem ist, dass meine Abfrage nicht altualisierbar ist per ADO. Siehe Beispiel. Ich würde sie aber gern aktualisierbar haben.

Der genannte Code läuft nur, wenn die Datenquelle eine Tabelle ist.
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: DF6GL am Mai 13, 2017, 12:06:23
Hallo,

Zitatmeine Abfrage nicht altualisierbar ist


naja, dann muss eben genau dies geändert werden...  Wenn die Abf. nicht aktualisierbar ist, dann kann irgendein Recordset darauf auch nichts ausrichten..
Titel: Re: Formular mit ADODB Recordset aktualisieren
Beitrag von: PhilS am Mai 13, 2017, 15:56:36
Zitat von: datekk am Mai 12, 2017, 18:23:08Hier wurde ja auch schon was mit der Unique Table Eigenschaft und Resync gepostet.
UniqueTable und ResyncCommand sind Eigenschaften des Formulars.

Deine Abfrage muss aber für sich genommen mit den gewünschten Änderungen aktualisierbar sein. Wenn sie das nicht ist, helfen auch alle clientseitigen Einstellungen nichts.
Du kannst das Prüfen, indem du eine View mit deiner Abfrage erstellst und dann auf der SQL-Server-Seite das gewünschte UPDATE-Statement darauf ausführst. - Wenn das nicht möglich ist, musst du das SQL anders gestalten.