PDA

Vollständige Version anzeigen : Datensätze einfügen mit Schleife


bobst
21.01.2008, 09:44
Hallo Forum

Ich habe mich wohl etwas übernommen, aber ich muss mein Problem irgendwie lösen.

In der angehängten Datenbank muss ich zu einem Produkt definierte Risiken zuweisen. Zu jedem Material in der Tabelle Artikelpos gibt es mehrere Risiken.
Die Risiken sind in der Tabelle T_Risiko abgespeichert. Sie bilden sozusagen den Risikostamm.
Die Artikelrisiken sind dem Artikel über die Artikelnummer zugeordnet.
Ich muss nun mit einem Befehl alle Risiken aus dem Risikostamm zu einem Material in Artikelpos in die Tabelle ArtikelRisk einfügen. Bei einem erneuten Klick auf den Button, dürfen die Risiken aber nicht ein zweites mal angefügt werden. Nur wenn neue Risiken zu einem Material definiert wurden, sollen die neuen hinzugefügt werden. Dazu kann man irgendwie Schleifen verwenden...

Alle Themen die ich dazu gefunden habe, helfen mir leider nicht weiter.
Ich wäre euch sehr dankbar, wenn ihr mir hierbei unterstützen könnt.

Freundliche Grüsse
Bobst

peterffw
21.01.2008, 10:16
Hi Bobst,

warum verwendest Du nach dem Button-Click auf Risiken importieren das Feld "Mat" und nicht das Feld "Artikel" ?

Nur zum Verständnis um Dir eine Schleife zu Programmieren!!

Servus
Peter

bobst
21.01.2008, 10:20
Hallo Peter

Die Risiken in der Tabelle Risiko beziehen sich auf das Feld Material, welches in der ArtikelPos-Tabelle vorhanden ist.
Die Risikotabelle T_Artikelrisiko bezieht sich auf den Artikel. Ich muss also alle Risiken zu dem Artikel effektiv auf den Artikel verweisen.

Ein anderer Artikel kann Materialien enthalten, welche schon in einem vorhandenen Artikel sind, deshalb muss zu jedem Artikel die Risiken neu zusammengestellt werden, je nach Aufbau. Weisst Du was ich meine?

peterffw
21.01.2008, 11:10
Hi bobst,

ich hoffe ich habe Dein Problem richtig verstanden!!. Anbei ein Lösungsansatz mit Recordsets. Das ganze wäre natürlich viel effektiver, wenn entsprechende Indizies auf den Tabellen liegen würden.

Wenn ich daneben liege, dann melde Dich nochmals.

Servus
Peter

bobst
21.01.2008, 12:42
Hallo Peter

Vielen Dank für Deine Lösung. Sieht sehr gut aus! :-)

Allerdings habe ich noch ein kleines Problem...
Wenn ich im Artikel 1 auf das Material KF-033 gehe, fügt der Code ein Risiko ein. Im Risikostamm (T_Risiko) sind für dieses Material 2 Risiken vorgesehen. Das heisst, es müssen alle Risiken zu einem Material eingefügt werden.

Der Code funktioniert auch nur dann, wenn ein Material im Unterformular markiert ist. Ist es möglich, dass durch einmaliges Betätigen des Buttons alle Risiken zu allen Materialien eingefügt werden?

Was meinst Du genau mit Indizies?

Könntest Du mir bitte nochmals helfen?

Gruss
Bobst

peterffw
21.01.2008, 13:05
Hi Bobst,

anbei nochmals eine Version, die das Problem löst, mit den 2 oder mehr Risiken!

Der Code funktioniert auch nur dann, wenn ein Material im Unterformular markiert ist. Ist es möglich, dass durch einmaliges Betätigen des Buttons alle Risiken zu allen Materialien eingefügt werden?


Das versuch ich Dir als Beispiel zu lösen - Verständnisfrage soll sich das dann auf den ganzen Artikel beziehen?

So wie die Lösung jetzt ist, muss immer z.B. die komplette Risiko-Tabelle durchgelesen werden, um zu prüfen ob noch ein gleiches Material wie das ausgewählte kommt. Wenn aber z.B. in der Risikotabelle auf dem Feld MAT ein Index liegt, dann kann die Suche eingeschränkt werden. Bei der geringen Anzahl von Datenästzen in den Tabellen kein Problem, aber wenn Du im Risiko mal 10000 Datensätze gespeichert hast, oder über ein Netzlaufwerk arbeitest, dann wirst Du die Zeit merken!!

Servus
Peter

peterffw
21.01.2008, 13:53
Hi Bobst,

anbei eine Beispiel, in dem alle Materialien mit Ririko eingefügt werden. Ich habe dazu einen neuen Button auf die Form gelegt!!.

Servus
Peter

bobst
21.01.2008, 14:44
Hallo Peter

Hey, sieht echt super aus. Vielen Dank!!
Sorry dass ich mich erst jetz melde. Musste noch an 2 Sitzungen teilnehmen...

Darf ich Dich noch belästigen?

Um Deine Frage aus Nr. #6 noch zu beantworten.... ...ja, die Daten müssen immer artikelbezogen eingefügt werden.

Jetzt besteht noch ein Problem... (letzte Version)
Wenn ich alle Daten aus T_ArtikelRisk lösche und anschliessend für Artikel 1 die Abfrage ausführe, funktioniert alles bestens. (echt geil...)

Geh ich dann zu Artikel Nr4 so fügt er nicht mehr alle Risiken ein, die er eigentlich sollte. Kann es sein, dass der Befehl schaut, ob zu einem bestimmten Material schon Daten in T_ArtikelRisk vorhanden sind und falls ja, diese deshalb nicht mehr einfügt?

Gruss
Bobst

peterffw
21.01.2008, 16:16
Hi Bobst,

ja da hast Du vollkommen recht, es muss natürlich auch noch die Prüfung auf den gleichen Artikel hinzu - kommt vom kopieren, da ich oft zu faul zum schreiben bin.

Anbei die Lösung, die nun funktioniert!

Servus
Peter

bobst
22.01.2008, 12:50
Hallo Peter

Vielen vielen Dank. Der Code funktioniert. Ist wirklich toll!

Hmm, ich habe schon ein wahnsinnig schlechtes Gewissen, aber bei der Übernahme in meine Applikation trat Folgendes auf:

3251 Operation is not supported for this type of Object.

Ich habe das Problem auch ausfindig machen können.

SP.Index = "Primarykey"
SP.Seek ">=", Me!SpeziNr
If SP.NoMatch Then
Exit Sub
End If


Setze ich diesen Teil des Codes auf inaktiv (setze ein " ' " vor die Befehlszeilen) funktioniert alles. Ich habe nur das Gefühl, dass ich damit einen Fehler mache.

Welchen Zusammenhang hat dieser Code-ausschnitt mit der Tabelle und auf die gesamte Code-Struktur?

Magst Du überhaupt noch mir zu helfen?? :confused:

peterffw
22.01.2008, 15:00
Hi,

sorry, dass ich mich jetzt erst melde, aber ich war beim Kunden.

Diese Code-Splitter kommen in dem was ich Dir geschickt habe überhaupt nicht vor!!

Sorry woher hast Du denn das?

Servus
Peter

bobst
22.01.2008, 15:12
Hallo Peter

Absolut kein Problem. Die Arbeit ging mir deshalb nicht aus...
Ich kann ja froh sein, schreibst Du mir überhaupt noch!

Dein Code war:

Private Sub RISIKO_Click()
Dim TREFFER As Long


On Error GoTo FehlerRISIKO
If IsNull(Me!Artikel) Or Me!Artikel = "" Then
Exit Sub
End If
Set DB = CurrentDb
Set RS = DB.OpenRecordset("T_Risiko")
Set TA = DB.OpenRecordset("T_Artikelrisk")
Set AP = DB.OpenRecordset("T_Artikelpos")
AP.Index = "Primarykey"
AP.Seek ">=", Me!Artikel
If AP.NoMatch Then
Exit Sub
End If
Do Until AP.EOF
If AP!Artikel > Me!Artikel Then
Exit Do
End If
If AP!Artikel = Me!Artikel Then
RS.MoveFirst
Do Until RS.EOF
If RS!mat = Trim(AP!mat) Then
TREFFER = 0
TA.MoveFirst
Do Until TA.EOF
If TA!mat = RS!mat Then
If TA!Artikel = Me!Artikel Then
If TA!merkmal = RS!merkmal Then
If TA!problem = RS!problem Then
TREFFER = 9
Exit Do
End If
End If
End If
End If
TA.MoveNext
Loop
If TREFFER = 0 Then
OhneArtikelrisiko1:
TA.AddNew
TA!Artikel = AP!Artikel
TA!mat = RS!mat
TA!merkmal = RS!merkmal
TA!problem = RS!problem
TA.Update
End If
End If
RS.MoveNext
Loop
End If
AP.MoveNext
Loop
Forms!f_artikel.F_Artikelrisk.Form.Requery

EndeRISIKO:
Exit Sub
FehlerRISIKO:
If Err = 3021 Then
Resume OhneArtikelrisiko1
End If
MsgBox Err.Number & " " & Err.Description
Resume EndeRISIKO
End Sub



Ich musste die Variablen umbenennen, da ich den ganzen Code in angepasster Form 2mal verwende....

Somit sieht der Problemteil folgendermassen aus:

SP.Index = "Primarykey"
SP.Seek ">=", Me!SpeziNr
If SP.NoMatch Then
Exit Sub
End If


In meiner Applikation sieht der Code so aus:


Private Sub btnGenerateRisks_Click()
Dim TREFFER As Long
Dim TREFFERSA As Long

Dim DB As DAO.Database
Dim RS As DAO.Recordset
Dim TA As DAO.Recordset
Dim SP As DAO.Recordset
Dim SA As DAO.Recordset

On Error GoTo Err_btnGeneateRisks_Click

If IsNull(Me!SpeziNr) Or Me!SpeziNr = "" Then
Exit Sub
End If

Set DB = CurrentDb
Set RS = DB.OpenRecordset("T_Risiko")
Set TA = DB.OpenRecordset("T_Spezirisk")
Set SP = DB.OpenRecordset("T_SPEZIFIKATIONPOS")
Set SA = DB.OpenRecordset("T_SPEZIARBEITSPLAN")

' ****Risiken zu den Materialien anlegen****

'SP.Index = "Primarykey"
'SP.Seek ">=", Me!SpeziNr
'If SP.NoMatch Then
' Exit Sub
'End If

Do Until SP.EOF
If SP!SpeziNr > Me!SpeziNr Then
Exit Do
End If
If SP!SpeziNr = Me!SpeziNr Then
RS.MoveFirst
Do Until RS.EOF
If RS!S_EIGENSCHAFT = Trim(SP!S_EIGENSCHAFT) Then
TREFFER = 0
TA.MoveFirst
Do Until TA.EOF
If TA!S_EIGENSCHAFT = RS!S_EIGENSCHAFT Then
If TA!SpeziNr = Me!SpeziNr Then
If TA!MERKMAL = RS!MERKMAL Then
If TA!Problem = RS!Problem Then
TREFFER = 9
Exit Do
End If
End If
End If
End If
TA.MoveNext
Loop
If TREFFER = 0 Then
OhneArtikelrisiko1:
TA.AddNew
TA!SpeziNr = SP!SpeziNr
TA!S_EIGENSCHAFT = RS!S_EIGENSCHAFT
TA!Risikokat = RS!Risikokat
TA!MERKMAL = RS!MERKMAL
TA!Problem = RS!Problem
TA!Abteilung = RS!Abteilung
TA!Maschine = RS!Maschine
TA!OPCODE = RS!OPCODE
TA!Ursache = RS!Ursache
TA!NegativEffekt = RS!NegativEffekt
TA!Ausmass = RS!Ausmass
TA!Wahrscheinlichkeit = RS!Wahrscheinlichkeit
TA!Detektierbarkeit = RS!Detektierbarkeit
TA!Insdate = Now()
TA!Insuser = EmplID
TA.Update
End If
End If
RS.MoveNext
Loop
End If
SP.MoveNext
Loop

' ****Risiken zu den Arbeitschritten anlegen****

Do Until SA.EOF
If SA!SpeziNr > Me!SpeziNr Then
Exit Do
End If
If SA!SpeziNr = Me!SpeziNr Then
RS.MoveFirst
Do Until RS.EOF
If RS!Maschine = SA!Maschine Then
TREFFERSA = 0
TA.MoveFirst
Do Until TA.EOF
If TA!Maschine = RS!Maschine Then
If TA!SpeziNr = Me!SpeziNr Then
If TA!OPCODE = RS!OPCODE Then
If TA!MERKMAL = RS!MERKMAL Then
If TA!Problem = RS!Problem Then
TREFFERSA = 9
Exit Do
End If
End If
End If
End If
End If
TA.MoveNext
Loop
If TREFFERSA = 0 Then
OhneArtikelrisiko2:
TA.AddNew
TA!SpeziNr = SA!SpeziNr
TA!Maschine = RS!Maschine
TA!OPCODE = RS!OPCODE
TA!Risikokat = RS!Risikokat
TA!MERKMAL = RS!MERKMAL
TA!Problem = RS!Problem
TA!Abteilung = RS!Abteilung
TA!Ursache = RS!Ursache
TA!NegativEffekt = RS!NegativEffekt
TA!Ausmass = RS!Ausmass
TA!Wahrscheinlichkeit = RS!Wahrscheinlichkeit
TA!Detektierbarkeit = RS!Detektierbarkeit
TA!Insdate = Now()
TA!Insuser = EmplID
TA.Update
End If
End If
RS.MoveNext
Loop
End If
SP.MoveNext
Loop

Forms!F_SPEZIEINGABE.F_SPEZIRISKSUB.Form.Requery


Exit_btnGenerateRisks_Click:
Exit Sub
Err_btnGeneateRisks_Click:
If Err = 3021 Then
Resume OhneArtikelrisiko1
Resume OhneArtikelrisiko2
End If
MsgBox Err.Number & " " & Err.Description
Resume Exit_btnGenerateRisks_Click
End Sub


Der erste Teil (Materialien), (somit dein Code ohne das "SP.Index-Ding" )funktioniert. Mit dem zweiten Teil (Arbeitsschritte) hab ich noch so meine Probleme...

peterffw
22.01.2008, 16:14
Hi,
hast Du ein Problem damit deine Lösung nochmals raufzuladen?
Ansonsten kannst Du mir auch eine PN senden, dann gibts meine Mailadresse!

Zu dem Problem-kann es sein, dass Du in der Tabelle "T_Spezifikationspos" keinen Primaryindex definiert hast?

Servus
Peter

bobst
22.01.2008, 16:27
Ich hab bald den Durchblick nicht mehr. Hier nochmals die DB

peterffw
22.01.2008, 16:40
Hi,
na der Fehler mit dem SP wie in Beitrag #10 und #12 beschriebn ist doch weg?
Du hast noch ein undefiniertes Element im Code stehen.

Bei
if RS!Maschine = SA!Maschine findet er SA!Maschine nicht!!

Ich schau mal!!

Servus
Peter

bobst
22.01.2008, 16:45
hey!

Ich bedank mich jetzt schon mal im voraus!

Wenn ich das nur gut machen könnte... :-)

peterffw
22.01.2008, 16:47
Hi,

der Vergleich muss vermutlich lauten

if RS!Maschine = SA!MAGR

allerdings sind die Feldtypen der beiden Felder nicht gleich.
RS!Maschine ist ein Long-Field, und SA!MAGR ein Textfeld

Du kannst das z.B. umgehen mit
if RS!Maschine = val(SA!MAGR)

Dann läuft er weiter - allerding gerade anscheinend in einer Endlosschleife, und ich muss ihn abwürgen.
Also bis später

bobst
22.01.2008, 17:06
Ist schon merkwürdig. Das SP-Dings funktioniert in der letzten Version die ich Dir geschickt habe. Auf meiner Originalversion funktioniert es nicht.
Die Verweise sind jedoch die gleichen....

Auf jeden Fall werde ich die Version vervollständigen, auf der es Funktioniert.
Wegen der unterschiedlichen Felddatentypen. Habe alles nacht Text (7) geändert. Macht am meisten Sinn für später... Ist wieder mal ein dofer Anfängerfehler.

Ich habe jetzt auch alles durchkorrigiert. Das Programm ist auch bei mir in einer Endlosschleife hängengeblieben :-(

peterffw
22.01.2008, 17:08
Warte noch 5 Minuten, dann kommt eine Version die zumindest durchläuft. Ob das Betriebswirtschaftlich korrekt ist musst Du dann beurteilen

Servus

peterffw
22.01.2008, 17:13
Hi,

so nun eine Version die durchläuft. Teste mal ob Du Dir das so vorgestellt hast.
Ich habe meine Änderungen kommentiert, und versucht zu erklären was falsch war. In dieser Version ist SA!MAGR noch ein Textfeld also wenn Du RS!Maschine auch auf Text änderst musst Du "clng" wieder entfernen!!

Viel Spass damit. Ich bin ca. noch 30 Minuten erreichbar.

Servus
Peter

bobst
22.01.2008, 17:25
Hallo Peter

Aus betriebswirtschaftlicher Sicht ist vieles nicht mehr rentabel, was wir alles erledigen müssen, um gewisse Normen und Kundenanforderungen zu erfüllen.
Die Idee dieser Applikation ist die, dass bei Neuprodukten ein Riskassessment durchgeführt werden kann, mit Hilfe von Riskstammdaten.
Meiner Ansicht nach ist das effizienter als bei jedem Neuprodukt die Risikobewertung von neuem manuell zu initieren..

Auf jeden Fall möchte ich Dir ganz herzlich danken.
Ich werde mich jetzt noch mit dem Einbinden dieses Codes beschäftigen.
Sollten noch Fragen auftauchen, melde ich mich vielleicht wieder. Hab nämlich schon ein schlechtes Gewissen

Vielen Dank an dieser Stelle noch einmal

Gruss
Bobst

peterffw
22.01.2008, 18:00
Hi Martin,
ein schlechtes Gewissen brauchst Du nicht zu haben. Habe ich gerne gemacht. Eine schönen Feierabend und wenn Probleme auftauchen, dann melde Dich wieder.

Servus
Peter

bobst
23.01.2008, 07:59
Hallo Peter.

Ich hab den Fehler für mein Problem aus #10 und #12 gefunden (SP.Index-Ding)
Verwende dazu die letzte Version die Du mir geschickt hast. Öffne die DB und Teile sie auf in ein FrontEnd und in ein BackEnd. Dan wird der Fehler "höchstwahrscheinlich" auch bei Dir auftreten. Die Ursache jedoch ist mir unklar...

Ist dieser Code-Teil wichtig so dass man ihn umformulieren muss, oder kann er weggelassen werden?

Gruss
Bobst

Josef P.
23.01.2008, 08:18
Falls du mit SP.Index-Ding die Nutzung der Seek-methode meinst, dann kann ich dir die Ursache nennen: Seek ist nur mit Openrecordset(...., dbOpenTable) möglich. dbOpenTable ist aber bei verknüpften Tabellen nicht möglich.
Anm.: bei Openrecordset(..) ohne Typ-Angabe wird ein passender Standardwert verwendet. (siehe OH)

Abhilfe:
Statt der Seek-Methode die FindFirst/FindNext-Methode nutzen
oder die Tabellen direkt öffnen. (Database-Objekt auf BE statt CurrentDb)

bobst
23.01.2008, 08:27
Hallo Josef

Danke für den Hinweis.
Da werde ich etwas zu kauen haben, bis ich diesen Teil durch die FindFirst/FindNext-Methode ersetzt habe. Bin nämlich noch nicht so fit in VBA

Gruss
Bobst

peterffw
23.01.2008, 09:44
Hi Martin,

mach mal langsam mit dem Umbauen. Es geht schon mit der Seek-Methode, Du musst nur den Set Database auf die Backend-MDB machen. Ich bin gerade mitten in einem Problem, sende Dir aber ein Beispiel wenn ich die DB aufgeteilt habe.

Servus
Peter

bobst
23.01.2008, 09:52
Hoi Peter

Wahnsinn. Danke schon mal. Ich konnte noch nicht beginnen. Habe gerade noch andere Probleme im Geschäft zu erledigen. Ich schau ab und an mal rein und wenn ein neuer Beitrag geschrieben wurde, schaue ich mal nach.

Nimm Dir also Zeit.

Gruss
Martin

peterffw
23.01.2008, 10:25
Hi Martin,

anbei nun das Beispiel!!
Ich habe ein Modul "Allgemein" eingefügt, und dort eine Funktion "open_Anfuegen". In dieser Funktion wird ein Workspace zugewiesen, und diesem Workspace DB als Database aber auf die Backend-Datenbank.

Dies ersetzt den Befehl "Set DB = CurrentDB"

Im Modul Allgemein in der Funktion "Open_Anfuegen" ist der Pfad der Backend-Datenbank fest eingetragen. Im Normalfalle zur Auslieferung der Anwendung mach man sowas natürlich dynamisch, do dass Laufwerksverlagerungen mit damit verbundenem neu einbinden der Backend-Tabellen problemlos vor sich geht. Ändere in diesem Beispiel den Pfad der Backendtabelle von "D:\Testaccess\Anfuegen extDaten.mdb" auf deinen Pfad, und verknüpfe die Tabellen neu, denn sonst sucht Access die Backend-Tabellen da wo ich sie verbunden habe.

Der Seek-Befehl kann generell entfallen, würde die Suche aber beschleunigen, da die Treffermenge eingegrenzt wird. Hab ich aber schon weiter oben irgenwo geschriebn.

Servus
Peter

bobst
23.01.2008, 12:58
Hallo Peter

Vielenvielen Dank. Alles klapt nun einwandfrei. Das Thema kann nun abgeschlossen werden.

In Ebay kann man die Käufer und Verkäufer bewerten. Würde man hier die Profis ebenfalls bewerten können, würdest Du die Höchstpunktzahl erhalten.

Beste Grüsse
Martin