PDA

Vollständige Version anzeigen : Mehrere Datensätze in eine Spalte???


MasterLR
20.03.2004, 12:12
ich hab folgendes problem:

tabelle1:
ID name nachname gebdatum

tabelle2:
ID (von tabelle1) telnummer

nun hat eine person mehre telefonnummern. nun möchte ich einen bericht mit allen personen erstellen mit der extra spalte in der allen telefonnummern enthalten sind. beispiel:

Hans | Mustermann | 31.01.80 | 0123456 012347 0234515

wie mach ich das?

zweites problem: ich möchte mehrere personen löschen INCL. aller dazu telefonnummern der personen die in ein bestimmten jahr geboren sind...

DANKE schon mal :)

Scrap
20.03.2004, 12:40
die id's beider tabellen sollten identisch sein, also ID 1 sollte auch zusammengehörige datensätze in beiden tabellen treffen. (das ist ja klar, denk ich)

dann musst du per formular, auswahl vom nutzer oder vb code (halt wie es für dich passt) die id bestimmen, zu der du den bericht erstellen willst

die SQL aufrufe würden dann so sein:

"SELECT [telnummer] From tabelle2 WHERE [ID] = " & deineIDVariable
"SELECT [name], [nachname], [gebdatum] from tabelle1 WHERE [ID] = " & deineIDVariable


beim löschen bin ich mir grad nicht sicher (bin nicht so sql fest), aber da hilft google.
es müsste etwas in der art sein:

deineIDVariable = "SELECT [id] from tabelle1 WHERE [gebdatum] = " & deineDatumsVariable
(das = klappt so nicht, da vb den sql befahl so nicht erkennt, da war irgendwas mit docmd.sql oder so nötig)
"DELETE [telnummer] From tabelle2 WHERE [ID] = " & deineIDVariable
"DELETE [name], [nachname], [gebdatum] from tabelle1 WHERE [ID] = " & deineIDVariable


ich hoffe jemand korrigiert meine unvollständigkeiten, oder google hilft dir weiter. ich wollte dir nu erstmal einen ansatz geben.

mfg stone

[edit 1]
rechtschreibfehlerkorrektur

MasterLR
20.03.2004, 13:02
ich möchte nicht nur EINE id (=Person) auswählen sondern einen bericht erstellen lassen welcher ALLE personen enthält plus eine spalte in der alle zu der person passenden telefonnummern....

reinir
20.03.2004, 13:15
abfrage, die Dir alle TelNr der jeweiligen personen ermittelt:

<div><link href="http://www.ms-office-forum.net/forum/externals/codeconv.css" rel="stylesheet"><pre>SELECT Tabelle1.vorname, Tabelle1.nachname, Tabelle2.Telefonnummer
FROM Tabelle1 INNER JOIN Tabelle2 ON Tabelle1.id = Tabelle2.NID;
&nbsp;</pre></div>
Code eingefügt mit dem MOF Code Converter (http://www.ms-office-forum.net/forum/codeconverter.php)

die abfrage ist dann datenherkunft deines berichtes...
da es aber detaildatensätze sind, wird's wohl nur untereinander fkt., wenn Du nur boardmitteln einsetzen willst
eine spalte kann ja auch sehr lange sein, was machst Du, wenn Du 20 telefonnummern für eine person hast ??

es ginge schon, dass in einer "spalte" darzustellen, wenn Du das ganze über vba ausliest, und "zusammenfügst" - ob sich der aufwand lohnt sei dahingestellt....

Scrap
20.03.2004, 13:22
[edit]
ok, reinir hat dir den besseren tip gegeben

MasterLR
20.03.2004, 13:50
Original geschrieben von reinir
es ginge schon, dass in einer "spalte" darzustellen, wenn Du das ganze über vba ausliest, und "zusammenfügst" - ob sich der aufwand lohnt sei dahingestellt....

ja ist richtig... kannst du mir die vb lösung (oder ansatz) für folgende ausgabe geben:


Hans | Mustermann | 31.01.80 | 0123456
| | | 012347
| | | 0234515
Hans2 | Mustermann2 | 01.01.80 | 6543210
| | | 9876543


das wäre super... kann ich mit dein inner join mit einmal sowohl person als auch die verbundenen telefonnummern löschen?

danke für eure hilfe...

Scrap
20.03.2004, 14:03
also für den bericht würde ich eine query (abfrage) in access selber erstellen
das macht viel weniger arbeit als mit vb
der bericht wertet dann die abfrage aus
(du musst nur das sql statement von feinir kopieren)

zm löschen sagst du einfach:
DoCmd.RunSQL ="DELETE FROM Tabelle1 INNER JOIN Tabelle2 ON id = " & deineIDVariable & ";"

wenn das so nicht klappt, dann machst du 2 befehle draus:
DoCmd.RunSQL ="DELETE FROM Tabelle1 id = " & deineIDVariable & ";"
DoCmd.RunSQL ="DELETE FROM Tabelle2 id = " & deineIDVariable & ";"

(http://www.w3schools.com/sql/sql_delete.asp)

MasterLR
20.03.2004, 14:28
Original geschrieben von Scrap
also für den bericht würde ich eine query (abfrage) in access selber erstellen
das macht viel weniger arbeit als mit vb
der bericht wertet dann die abfrage aus
(du musst nur das sql statement von feinir kopieren)


nein kann ich nicht benutzen da ich sonst ein resultat ala:

Hans | Mustermann | 31.01.80 | 0123456
Hans | Mustermann | 31.01.80 | 654321
Hans | Mustermann | 31.01.80 | 82734345

bekomm und ich aber

Hans | Mustermann | 31.01.80 | 0123456
| | | 654321
| | | 82734345

haben möchte... :-D

Scrap
20.03.2004, 14:45
ich hab noch keinen bericht erstellt, aber es müsste auf jeden fall per vb gehen:
du gehst die liste deiner gefunden werte durch und schaust, ob namen mehrfach vorkommen:
also immer den ersten fund nehmen (zb tempvariabele) mit dem nächsten datansatz vergleichen
identisch: alles ausser telnummer löschen
nicht identisch: temp auf neuen namen (besser: kombinations name, vorname, am allerbesten: tabelle1.id ist eineindeutig) setzen
3.zeile nehmen: temp mit id vergleichen
.
.
.


ist sicher keine elegante lösung, würde aber deine abfrage auf dein wunschformat bringen

um ehrlich zu sein: bin gespannt ob jemand eine besser lösung hat *G*
aber erfolg hättest du mit meiner auch

Nouba
20.03.2004, 15:17
Folgende Funktion sollte im richtigen Bereich aufgerufen die Telefonnummern aneinanderreihen.
Private Function HoleTelNr( _
Feldname As String, _
Tabellenname As String, _
Schluesselfeldname As String, _
Schluesselfeldwert As Long, _
Optional Trennzeichen As String = "; ") As Variant

Dim rs As DAO.Recordset
Dim i As Long
Dim sResult As String

On Error Resume Next

Set rs = CurrentDb().OpenRecordset( _
"SELECT [" & Feldname & "] FROM " _
& Tabellenname & " WHERE [" _
& Schluesselfeldname & "] = " & Schluesselfeldwert, _
dbOpenForwardOnly)

Do While Not rs.EOF
sResult = sResult & rs(0) & Trennzeichen
rs.MoveNext
Loop

If Len(sResult) Then
sResult = Left$(sResult, Len(sResult) - Len(Trennzeichen))
HoleTelNr = sResult
End If

If Not rs Is Nothing Then rs.Close

Set rs = Nothing

End Function

Scrap
20.03.2004, 15:25
danke für die umsetzung der idee..

MasterLR
20.03.2004, 15:57
DANKE... vorallem an Nouba, das er sich die arbeit gemacht hat -> thx!!!

nur noch ein "prob" -> wie kann ich am einfachsten nun alle personen in ein bestimmten geburtsjahr löschen INCL. aller zugehörigen telefonnummern?
wie ich die personen löschen würde ist klar... interessant wäre es nur auf einfachste art personen UND telefonnummern zu löschen...

gibt es eine elegantere lösung als einzeln per vb script die id's der personen zu nehmen und die entsprechenden telefonnummern einträge nacheinander zu löschen?

MasterLR
20.03.2004, 16:10
noch eine frage: wie binde ich diese funktion in eine normale abfrage ein? oder kann ich diese vb funktion eine sql anweisung benutzen (denke ja eher nicht)

Scrap
20.03.2004, 16:14
als vb gehts mit:

DoCmd.RunSQL = "UPDATE..."

denk ich

für löschen muss ich nochmal nachdenken

Nouba
20.03.2004, 16:20
Wenn Du daraus eine Public Funktion machst und in ein globales Modul stellst, kannst Du das Teil global in der Anwendung verwenden.

Wenn das Datum in der Personentabelle steht kannst Du in der Beziehung zur Telefontabelle die Löschwertweitergabe einstellen. Dann fügst Du die Personentabelle in die Abfrage ein und schreibst in eine Spalte Jahr(Datumsfeld) und als Parameter gibst Du das gewünschte Jahr ein. Dann, wenn noch ein Backup gefertigt wurde, sollte nach Umstellen der Abfrage in eine Löschabfrage diese Dir die Daten aus beiden Tabellen rausfegen.

MasterLR
20.03.2004, 16:27
funktioniert folgendes?

select *.tabelle1, HoleTelNr(....) from tabelle1

Nouba
20.03.2004, 16:29
Ich denke schon, dass es funktioniert - ich weiß aber jetzt im Moment nicht genau, was Du machhen willst?

MasterLR
20.03.2004, 16:33
ganz normale abfrage erstellen mittels oben stehenden befehl...

MasterLR
20.03.2004, 16:55
funktioniert.... wie bekomm ich das trennzeichen so hin das es ein zeilenumbruch wird? "\n" ist es leider nicht :-D

Nouba
20.03.2004, 17:10
<i>Zchn(13) & Zchn(10)</i> sollten einen Zeilenumbruch einfügen.

MasterLR
20.03.2004, 17:34
Nouba: wenn du mir jetzt noch sagen kannst wie ich mit vb in einen bestimmten zeit bereich des geburtsdatum alle personen UND ihre telefonnummern löschen kann, habe ich dann nur noch eine einzige fragen an dich: wie kann ich das wieder gut machen (danke!!!!!!) :rolleyes:

MasterLR
20.03.2004, 18:32
hab es selbst gefunden -> DANKE AN ALLE

Nouba
20.03.2004, 19:07
Hallo stone,

getestet habe ich die Funktion nicht.
Function LoescheZeitraum( _
MainTab As String, _
SubTab As String, _
FKSubTab As String, _
PKMainTab As String, _
DateField As String, _
StartDate As Variant, _
EndDate As Variant) As Boolean

'// bei Erfolg wird Wahr zurückgegeben.

Const ISODateFmt As String = "\#yyyy--mm-dd\#;;;\N\u\l\l"

'// verwEndDatet Objekte der DAO-Biblithek
Dim ws As DAO.Workspace
Dim db As DAO.Database

Dim sSQL As String
Dim sMsg As String

'// wir wollen nur Datumswerte akzeptieren
If Not IsDate(StartDate) Or Not IsDate(EndDate) Or EndDate < StartDate Then Exit Function

'// erste Löschabfrage zusammenstellen
sSQL = sSQL & "DELETE" & vbCrLf
sSQL = sSQL & "FROM " & SubTab & vbCrLf
sSQL = sSQL & "WHERE [" & FKSubTab & "] In (" & vbCrLf
sSQL = sSQL & " SELECT" & vbCrLf
sSQL = sSQL & " [" & PKMainTab & "]" & vbCrLf
sSQL = sSQL & " FROM " & MainTab & vbCrLf
sSQL = sSQL & " WHERE [" & DateField & "] BETWEEN " _
& Format(StartDate, ISODateFmt) & " AND " _
& Format(EndDate, ISODateFmt) & ")"

sMsg = sMsg & "Lösche zuerst Daten der abhängigen Tabelle mit folgender Abfrage:"
sMsg = sMsg & vbCrLf & vbCrLf & sSQL & vbCrLf & vbCrLf
sMsg = sMsg & "Bitte Vorgang bestätigen."
If MsgBox(sMsg, vbQuestion + vbYesNo, "Löschbestätigung...") <> vbYes Then Exit Function

On Error GoTo Fehlerbehandlung

Set db = CurrentDb()

'// wir gehen Nummer sicher und löschen nur, wenn Alles «fluppt».
Set ws = DBEngine(0)
ws.BeginTrans

'// wir werden zuerst die Daten der SubTab los
db.Execute sSQL, dbFailOnError

'// für die MainTab erstellen wir eine neue Löschabfrage
sSQL = ""

sSQL = sSQL & "DELETE" & vbCrLf
sSQL = sSQL & "FROM " & MainTab & vbCrLf
sSQL = sSQL & "WHERE [" & DateField & "] BETWEEN " _
& Format(StartDate, ISODateFmt) & " AND " _
& Format(EndDate, ISODateFmt) & ")"

sMsg = ""
sMsg = sMsg & "Lösche jetzt Daten der Haupttabelle mit folgender Abfrage:"
sMsg = sMsg & vbCrLf & vbCrLf & sSQL & vbCrLf & vbCrLf
sMsg = sMsg & "Bitte Vorgang bestätigen."
If MsgBox(sMsg, vbQuestion + vbYesNo, "Löschbestätigung...") <> vbYes Then
'// ist vielleicht nicht ganz so schön - besser wäre einen Error zu «raisen»
ws.Rollback
GoTo RausHier
End If

'// löscht die Daten der MainTab
db.Execute sSQL, dbFailOnError

'// alles Roger
ws.CommitTrans
LoescheZeitraum = True

RausHier:
On Error GoTo 0

Set db = Nothing
Set ws = Nothing

Fehlerbehandlung:
ws.Rollback
MsgBox "Beim Löschen der Daten ist ein Fehler aufgetreten." & vbCrLf & vbCrLf _
& "Fehler: #" & Err.number & vbCrLf & vbCrLf & Err.Description, vbInformation + vbOKOnly, "Fehler beim Löschen..."
Resume RausHier
End Function