PDA

Vollständige Version anzeigen : Aus Textfeld 1. Wort auswählen


Haschi
16.05.2003, 08:59
Hallo zusammen

Ich habe eine Tabelle mit den Feldern "Familienname" sowie "Vorname". Nun habe ich eine Abfrage mit einem Soundex-Funktion erstellt (für ein VBA-Greenhorn eine echte Knacknuss), die mir alle Personen bringt mit einem ähnlich klingenden Familiennamen. Um die Suche noch mehr einzuschränken möchte ich diese Abfrage um das Feld "Vornamen" erweitern. Mein Problem: Es gibt Vornamen, die aus mehreren Wörtern bestehen, z.B. Joseph Andreas Franz. Ich finde keine Lösung [da fehlt mir wohl das Anfängerglück :( ], wie ich z.B. den 1. Vornamen selektionieren kann, bzw. den 2. Vornamen usw. Dann könnte ich für jeden Vornamen eine Soundex-Funktion programmieren usw. ...

Ich bin mir sicher, Ihr habt eine Lösung für mein simples Problem.
Haschi

Pittchen
16.05.2003, 09:24
Moin Haschi,

hier eine Möglichkeit:

<div><link href="http://www.ms-office-forum.net/forum/externals/codeconv.css" rel="stylesheet"><pre><span class="TOKEN">Private Sub</span> Vorname_Exit(Cancel <span class="TOKEN">As</span> <span class="TOKEN">Integer</span>)
<span class="TOKEN">Dim</span> strVorname <span class="TOKEN">As</span> <span class="TOKEN">String</span>
<span class="TOKEN">Dim</span> lngZeichenNr <span class="TOKEN">As</span> <span class="TOKEN">Long</span>
&nbsp;
lngZeichenNr = InStr(Vorname.Value, &quot; &quot;)
strVorname = Left(Vorname.Value, lngZeichenNr)
MsgBox &quot;Der erste Vorname =&quot; &amp; strVorname
&nbsp;
<span class="TOKEN">End</span> <span class="TOKEN">Sub</span>
&nbsp;</pre></div>

Noch Fragen?

Viel Erfolg und Gruß Pittchen

TommyK
16.05.2003, 09:27
Hallo,

kopiere folgende Funktion in Deine DB in ein Modul:

Function GetArg(Text As Variant, Position As Integer, Trennzeichen As String) As Variant
'*******************************************
'Name: GetArg (Function)
'Purpose: Zerstückelt einen String, in dem mehrere - durch TRENNZEICHEN getrennte Argumente
'Author:
'Date:
'Inputs: Text = Text der zerlegt werden soll, POSITION = Pos des Vorkommens des Trennzeichens, Trennzeichen = der String des Trennzeichens
' POSITION = 0 gibt die Anzahl der Argumente zurück
'Output:
'Example:
'*******************************************

Dim Pos As Integer

If IsNull(Text) And Position = 0 Then GetArg = 0: Exit Function
If IsNull(Text) And Position > 0 Then GetArg = Null: Exit Function

If right$(Text, Len(Trennzeichen)) <> Trennzeichen Then
Text = Text & Trennzeichen
End If


If Left(Text, Len(Trennzeichen)) <> Trennzeichen Then
Text = Trennzeichen & Text
End If

If Position = 0 Then

Dim Anzahl As Integer

Anzahl = 0
Pos = InStr(1, Text, Trennzeichen)
While Pos <> 0
Anzahl = Anzahl + 1
Pos = InStr(Pos + 1, Text, Trennzeichen)
Wend

GetArg = Anzahl - 1

Else

Dim i As Integer
Dim EndPos As Integer

Pos = 0

For i = 1 To Position

Pos = InStr(Pos + 1, Text, Trennzeichen)
If Pos = 0 Then GetArg = Null: Exit Function

Next i

EndPos = InStr(Pos + 1, Text, Trennzeichen)

If EndPos = 0 Then GetArg = Null: Exit Function

GetArg = Mid(Text, Pos + Len(Trennzeichen), EndPos - Pos - Len(Trennzeichen))

End If

End Function

Die Funktion ermittelt das erste Vorkommen des Leerzeichens und gibt den linken Teil davon wieder.
in Deiner Abfrage erstellst Du dann ein neues Feld, wobei Du natürlich Deinen Feldnamen für das Vornamenfeld eintragen musst.
Ähnlich siehe Bild

strausto
16.05.2003, 09:27
debug.Print Left("Vorname Nachname",instr(1,"Vorname Nachname",chr(32)))
Vorname

TommyK
16.05.2003, 09:31
Die Lösung von Pittchen ist natürlich kürzer, aber die "GetArg"-Funktion ist variabler, wenn man verschiedene Lösungen in einer DB braucht.

Pittchen
16.05.2003, 09:44
Moin Tommy,

Dafür ist deine wesentlich eleganter und ich habe wieder was dazu gelernt:

:D :D ;)

Danke und Gruß Pittchen

Haschi
16.05.2003, 10:03
Hallo Pittchen, TommyK und Torsten

Das war echt ne super Hilfe. Besten Dank.

Der erste Vornamen klappt super. Nun hat der Haschi natürlich gedacht, er sei jetzt um einiges schlauer geworden :) und hat nun die Sub (von Pittchen) angepasst. Einfach "Left" durch "Right" ersetzen und dann sollte ja eigentlich der letzte Vornamen kommen.

Private Sub Befehl4_Click()
Dim strVornamen As String
Dim lngZeichenNr As Long

lngZeichenNr = InStr(Vornamen.Value, " ")
strVorname = Right(Vornamen.Value, lngZeichenNr)
MsgBox "Der Letzte Vorname =" & strVorname
End Sub

Da hat sich der Haschi wieder mal zu schnell gefreut. :confused: Leider kommt jetzt beim "Joseph Andreas Franz" ->> "s Franz".

Könnt Ihr mir da nochmals helfen. Wäre auch toll zu wissen, wie ich z.B. den zweiten Vornamen herausfiltern kann.

Gruss
Haschi

TommyK
16.05.2003, 10:13
Hallo,

wenn Du meine Funktion s.o. verwendest, dann kannst Du wenn 2 oder noch mehr Vornamen vorhanden sind immer die gleiche Funktion nehmen, Du müsst nur den 2. Parameter ändern:

z.B. für den 2. Vornamen: Vorname2: GetArg([DeinVorname];2;" ")

Pittchen
16.05.2003, 10:25
Moin Haschi

@Tommy: nix für ungut grins..

@Haschi:

so geht's auch:

<div><link href="http://www.ms-office-forum.net/forum/externals/codeconv.css" rel="stylesheet"><pre><span class="TOKEN">Private Sub</span> Vorname_Exit(Cancel <span class="TOKEN">As</span> <span class="TOKEN">Integer</span>)
<span class="TOKEN">Dim</span> strVorname <span class="TOKEN">As</span> <span class="TOKEN">String</span>
<span class="TOKEN">Dim</span> strVornameMitte <span class="TOKEN">As</span> <span class="TOKEN">String</span>
<span class="TOKEN">Dim</span> strMittelTeil <span class="TOKEN">As</span> <span class="TOKEN">String</span>
&nbsp;
<span class="TOKEN">Dim</span> lngZeichenNr1 <span class="TOKEN">As</span> <span class="TOKEN">Long</span>
<span class="TOKEN">Dim</span> lngZeichenNr2 <span class="TOKEN">As</span> <span class="TOKEN">Long</span>
&nbsp;
lngZeichenNr1 = InStr(Vorname.Value, &quot; &quot;)
strVorname = Left(Vorname.Value, lngZeichenNr1)
MsgBox &quot;Der erste Vorname =&quot; &amp; strVorname
&nbsp;
<span class="REM">'Zweiter Vorname</span>
strMittelTeil = Mid(Vorname.Value, lngZeichenNr1 + 1)
lngZeichenNr2 = InStr(strMittelTeil, &quot; &quot;)
strVornameMitte = Left(strMittelTeil, lngZeichenNr2 - 1)
MsgBox &quot;Der zweite Vorname = &quot; &amp; strVornameMitte
&nbsp;
<span class="TOKEN">End</span> <span class="TOKEN">Sub</span></pre></div>

Gruß Pittchen

strausto
16.05.2003, 10:56
@Pittchen

Nichts für Ungut!


Public Function NameSplit(strName As String, Fragment As Long)

Dim arrsplit() As String
arrsplit = Split(strName, Chr(32))

NameSplit = arrsplit(Fragment)


End Function



debug.print namesplit("vorname1 vorname2 Nachname",0)
vorname1



debug.print namesplit("vorname1 vorname2 Nachname",1)
vorname2



debug.print namesplit("vorname1 vorname2 Nachname",2)
Nachname

TommyK
16.05.2003, 11:02
@ Pittchen

Mist ist nur wenn der arme Mensch 3 oder gar 4 Vornamen hat.:weinen:


:grins: :grins: :grins:

Pittchen
16.05.2003, 11:02
Moin

@Torsten: das ist einer der vielen Gründe, warum ich dieses Forum so Klasse finde; kannte ich auch noch nicht; Danke dir
;)

@Tommy: das iss war; dann komme ich ganz schön ins Schleudern :angel: ;)

Gruß Pittchen :D :D :D

strausto
16.05.2003, 11:05
@Tommy

Der Split Funktion ist es egal wieviele Elemente der String besitzt.

TommyK
16.05.2003, 11:10
@ Torsten

da hast Du natürlich recht.

Haschi
16.05.2003, 12:40
Hallo ThommyK

Ich wollt's nun noch mit Deiner Funktion ausprobieren. Habe diese wie gesagt in ein neues Modul kopiert. Wenn ich nun aber via eine Abfrage die Funktion aufrufen will, so kommt immer folgende Fehlermeldung:

Undefined function 'GetArg' in expression

Meine Soundex-Funktion funktioniert. Deshalb meine Frage. Habe ich etwas vergessen oder muss man die Funktion noch irgendwie aktivieren?

Gruss
Haschi

Arne Dieckmann
16.05.2003, 12:46
Hier wird Dir auch geholfen: http://www.ms-office-forum.net/forum/showthread.php?s=&threadid=92094 und den Link darin verfolgen.

strausto
16.05.2003, 12:52
@Haschi

Mir ist unklar, warum Du es nicht mal mit meinem einfachen Code probierst?
Gefällt er Dir denn nicht?

Auch Arne ;) empfiehlt die Split Funktion!

TommyK
16.05.2003, 12:57
Hallo,

hab mal eine Bsp-DB angehängt.

Haschi
16.05.2003, 13:00
Hallo Arne

Merci für den Link. Funktioniert super, solange alle Datensätze 3 Vornamen haben. Wenn nun aber Person1 drei Vornamen und Person2 nur zwei Vornamen besitzt, so gibt es eine Fehlermeldung.

"Index ausserhalb des gültigen Bereiches"

Ich denke, da müsste man was einbauen, das wenn kein Vornamen mehr vorliegt einfach " " ausgegeben wird. Wie geht denn sowas?

Gruss
Haschi

Arne Dieckmann
16.05.2003, 13:05
Okay. Das hatte ich nicht bedacht. Der gleiche Fehler müsste bei Torstens sehr ähnlicher Lösung auch auftreten. Evtl. kannst Du das mit einem On Error innerhalb der Funktion SplitAb() lösen:

Public Function SplitAb(Eintrag, Trenner, Stelle)

On Error GoTo SplitAb_Err:

Dim SplitArray
SplitArray = Split(Eintrag, Trenner)
SplitAb = SplitArray(Stelle)

SplitAb_Exit:
Exit Function

SplitAb_Err:
If Err.Number = 9 Then
SplitAb = " "
Else
MsgBox Err.Description
End If
Resume SplitAb_Exit:

End Function

strausto
16.05.2003, 13:09
Public Function NameSplit(strName As String, Fragment As Long)

On Error Resume Next
Dim arrsplit() As String
arrsplit = Split(strName, Chr(32))
NameSplit = arrsplit(Fragment)

End Function

Haschi
16.05.2003, 13:57
Hallo zusammen

Entweder bin ich doof :stupid: oder :smashing:

Ich glaube es liegt bei all euren Lösungen das gleiche Problem vor:

Die SplitAb-Funktion Variante 1 funktioniert (natürlich mit oben besprochenen Fehlern)
------------------------------------------------------------
Public Function SplitAb1(Eintrag, Trenner, Stelle)

Dim SplitArray
SplitArray = Split(Eintrag, Trenner)
SplitAb1 = SplitArray(Stelle)

End Function
-------------------------------------------------------------


nun habe ich analog die verbesserte Version in ein neues Modul kopiert

---------------------------------------------------------------------------------------
Public Function SplitAb2(Eintrag, Trenner, Stelle)

On Error GoTo SplitAb2_Err:

Dim SplitArray
SplitArray = Split(Eintrag, Trenner)
SplitAb2 = SplitArray(Stelle)

SplitAb2_Exit:
Exit Function

SplitAb2_Err:
If Err.Number = 9 Then
SplitAb2 = " "
Else
MsgBox Err.Description
End If
Resume SplitAb2_Exit:

End Function
--------------------------------------------------------------------------------------


Seht Ihr irgend einen Grund warum die 2. Funktion nicht funktionieren soll. Ein ähnliches Problem gibt's mit der Bsp.Db von TommyK. Die Original-db funktioniert einwandfrei. Übernehme ich aber die Funktion in meine DB, dann gehts wieder nicht. Hat dies eventuell mit meiner Access Vers. 2000 oder müssen da noch Verweise oder sonst was eingestellt werden.

Please help me!
Gruss
Haschi

strausto
16.05.2003, 14:02
@ Haschi

Sag mal liest Du meine Beträge noch oder ignorierst Du diese. :redface:
Was spricht den gegen meine Methode????????? :confused:

Insofern Du Deine DB mal hochlädst, kann ich mir Dein Problem mal anschauen! :idee:

Ich glaube es liegt bei all euren Lösungen das gleiche Problem vor:


Wie äußert sich den Dein Probelm? :entsetzt:

Arne Dieckmann
16.05.2003, 14:25
Die Module dürfen nicht genauso wie eine darin enthaltene Funktion heissen. Ausserdem müssen die Funktionen global verfügbar sein. Also einfach die Funktionen so kopieren und in ein Modul setzten, das "MeinModul" heisst, aber nicht SplitAb, SplitAb2, NameSplit, GetArg - je nachdem, welche Du jetzt einsetzt.

@Torsten: Eigentlich spricht nur eine Sache gegen Deine Funktion: das festgesetzte Trennzeichen (Space bzw. Chr(32)). Ansonsten ist es ja das gleiche.

Haschi
16.05.2003, 14:45
Hallo zusammen!!

Was ich/wir um 9.59 heute morgen begonnen haben, funktioniert jetzt einwandfrei!! :dance: :happy: :knuddel:

Nach dem durchbrechenden Input von Arne funktionieren jetzt all eure Varianten!! Also vergebt einem Greenhorn, der nicht mal die Grundkenntnisse über das Schreiben von Modulen kennt. Habe heute aber viel gelernt, und das macht wirklich Spass.

@ strausto
Ich habe Deine Beiträge selbstverständlich gelesen wie alle übrigen auch. Also wenn das nicht so rüber gekommen ist. Sorry! Ich war halt so beschäftigt mit der Umsetzung aller Hinweise.

Dann geh ich jetzt mal schön weiter pröbeln und freue mich, ein anderes Mal wieder mit Euch zusammenzuarbeiten. Macht Spass!

Ein schönes Wochenend
Haschi

Arne Dieckmann
16.05.2003, 19:20
Hallo Haschi!

wenn Du Dich noch als Greenhorn bezeichnest, dann empfehle ich Dir diese Seite: Donkarls Access-FAQ (http://www.donkarl.com/AccessFAQ.htm?/FAQ/FAQStart.htm). Dort wirst Du sicherlich einige interessante Sachen finden.

Nouba
16.05.2003, 21:15
bei der Datennormalisierung verwende ich sowas wieFunction fctSplit( _
ByVal vvarZeichenkette As Variant, _
ByVal vstrTrennZchn As String, _
ByVal vintPosition As Integer) _
As Variant

' Ergebnisarray für Splitfunktion bereitstellen
Dim arr As Variant

arr = Split(Nz(vvarZeichenkette), vstrTrennZchn)

' Ergebnis ausgeben, falls Teilabschnitt vorhanden ist
If vintPosition <= UBound(arr) Then fctSplit = Trim(arr(vintPosition))
End Function

BTW: sollten die drei Vornamen in einem Tabellenfeld vorliegen, so verletzt das die Regel der 1. NF, die besagt, dass alle Feldinhalte atomar sein müssen Abhilfe schafft eine Tabelle in der je Datensatz ein Vorname plus ein Fremdschlüssel auf die bisherige Tabelle einzutragen ist. Der Link "Relationale Datenbanken" in meiner Fußzeile erklärt mehr dazu. Wenn man es weiter treiben will, könnte man statt der Vornamen auch einen Fremdschlüssel auf eine Vornamentabelle einsetzen.