Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

mehrfach hintereinander vorkommende Zeichen (Häufung) auf ein Zeichen reduzieren

Begonnen von nurmikss, Februar 15, 2019, 10:48:54

⏪ vorheriges - nächstes ⏩

nurmikss

Hallo,
ich habe entdeckt, dass jemand in Text-Eingabefeldern nach einem Zeilenumbruch Einrückungen erzeugt hat, indem er mehrere Leerzeichen getippt hat (wie bei der Schreibmaschine). Das funktioniert natürlich nur, solange die Breite des dargestellten Feldes unverändert bleibt. Sobald das Feld in einem anderen Zusammenhang (also mit anderer Breite) dargestellt wird, verrutscht alles.
Hinzu kommt, dass die Anzahl der aufeinanderfolgenden Leerzeichen nicht konstant ist - also: manchmal beträgt die Einrückung 3 Leerzeichen, ein anderes Mal 20 Leerzeichen.

Wie kann ich alle Leerzeichen, die mehrfach hintereinander vorkommen, auf ein Leerzeichen reduzieren ?

Natürlich könnte ich Änderungsabfrage machen, in der zwei Leerzeichen durch ein Leerzeichen ersetzt wird und die Abfrage so oft durchlaufen lassen, bis es keinen Treffer mehr gibt. Aber das kommt mir etwas mühselig und plump vor. Gibt es da eine elegantere Methode ?
Ich verwende Microsoft Office Professional plus 2010

ebs17

Die eigentliche Eleganz würde darin bestehen, solche Zustände gleich bei Datenerzeugung und vor Speicherung abzuwehren.

Etwas weniger aufwändig wie Dauerfeuer mit Aktualisierungsabfragen wäre der Einsatz einer entsprechenden Funktion innerhalb der einen Abfrage:
Public Function InnerTrim(ByVal ThisString As String) As String
' mehrfache Lehrzeichen entfernen
    Dim sResult As String
    sResult = ThisString
    Do While InStr(1, sResult, "  ") > 0
        sResult = Replace(sResult, "  ", " ")
    Loop
    InnerTrim = sResult
End Function
Mit freundlichem Glück Auf!

Eberhard

nurmikss

Zitat von: ebs17 am Februar 15, 2019, 13:03:33
... solche Zustände gleich bei Datenerzeugung und vor Speicherung abzuwehren.
Ja. Leider sieht das kommerzielle Programm, mit dem die Daten erfasst wurden, eine solche Prüfung nicht vor.

Ich komme vorausichtlich erst nach dem Wochenende dazu, Deinen Vorschlag auszuprobieren. Du hast das Dauerfeuer an eine Funktion übergeben.

Elegant geht das in Word (Suchen und Ersetzen mit Mustervergleich bzw. regulären Ausdrücken):
Suchen nach: [ ]{2;} d.h. Suche nach Leerzeichen, wo es 2fach oder öfter hintereinander vorkommt.
Ersetzen durch: Leerzeichen.
Eine entsprechende Syntax gibt es in Access nicht ?
Ich verwende Microsoft Office Professional plus 2010

Beaker s.a.

@nurmikss
Doch, reguläre Ausdrücke kannst du auch in Access verwenden.
Entweder durch setzen eines Verweises auf "Microsoft VBScript Regular
Expression x.x" oder per Late Binding.
gruss ekkehard
Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

ebs17

Selbstverständlich kann man reguläre Ausdrücke verwenden, eingebaut als Funktion: Codebeispiel - "Intelligente" Textanalyse
Für die genannte kleine Anforderung wird aber die gezeigte schlanke VBA-Funktion schneller sein, schon weil man sich nicht über ein zusätzliches Objekt bedienen muss.
Aber für richtige Aufgabenstellungen darf man an RegEx denken.
Mit freundlichem Glück Auf!

Eberhard

nurmikss

Das klingt ja sehr mächtig, damit muss ich mich beschäftigen  !
Verstehe ich das richtig: für reguläre Ausdrücke muss ich VBA schreiben oder geht das (wie in Word) auch direkt in einer Abfrage ?
Was mich etwas irritiert, ist der Hinweis in der Microsoft-Referenz: "We're no longer updating this content regularly."
Ich verwende Microsoft Office Professional plus 2010

ebs17

Unmittelbar in der Abfrage (SQL) funktionieren nur ganz einfache Mustersuchen, die man kennt (LIKE, die wenigen verwendbaren Wildcards).

Jet-SQL selber hat einen sehr sparsamen Sprachumfang. Wenn man es aber über Access ausführt, macht der sogenannte Expression Service die Verwendung von VBA-Funktionen, Access-Funktionen (Nz, DLookup) sowie eigendefinierten Funktionen möglich. Man kann also eigengewünschte Funktionalität in eine Funktion legen und dabei auch externe Objekte (ADODB, RegEx uva. einbinden). Man sollte nur den möglicherweise auftretenden Aufwand im Auge haben, wenn z.B. eine aufwändige Funktion pro Datensatz über sehr viele Datensätze auszuführen wäre.

Sowie: Nicht mehr updaten und abschalten ist zweierlei. Das letztere kann ich mir nicht vorstellen, weil eine Mustersuche in recht vielen verschiedenen Programmiersprachen vorkommt und ein Abschalten ein kräftiges Signal zum Ignorieren einer solch betroffenen Sprache wäre.
Mit freundlichem Glück Auf!

Eberhard

nurmikss

Mit Verweisen auf "Microsoft VBScript Regular Expression x.x" (welche Version ?) oder per Late Binding hatte ich noch nichts zu tun.
Könnt Ihr mir da ein paar Schritte aufzeigen, wie das geht oder einen entsprechenden Link schicken ?
Ich verwende Microsoft Office Professional plus 2010


nurmikss

So, jetzt fehlt mir noch ein kleiner Schritt vom Einzelstring zu allen Feldeinträgen in einer Tabelle.

Ich habe bereits
den Verweis auf Microsoft VBScript Regular Expression 5.5 aktiviert, dann folgende Ersetzungs-Funktion geschrieben:
Function ersetze(mystring As String, Muster As String, Ersatz As String)
Dim regex As New RegExp
regex.Global = True
regex.Pattern = Muster
Set fundstellen = regex.Execute(mystring)

ersetze = regex.Replace(mystring, Ersatz)
End Function

Im VBA-Direktbereich bekomme ich folgendes Ergebnis:
debug.print ersetze("einsXzweiXXdreiXXXvierXXXXende","X{2,}","_")
Ergebnis:            einsXzwei_drei_vier_ende

Das heißt, die Funktion ersetzt alle "X", die 2fach oder öfter auftreten durch ein "-".
Sie ist also geeignet, (nach einer kleinen Abwandlung) meine überflüssigen Leerzeichen zu reduzieren.

Aber: Wie übertrage ich das jetzt ? Es sollen in TabelleA alle überflüssigen Leerzeichen in Feld MeinText entfernt werden (also in allen Datensätzen).

Ach ja: den Code "Set fundstellen = regex.Execute(mystring)" hab ich zwar abgeschrieben, aber nicht verstanden. Kann mir noch jemand erklären ob / wofür er gut ist ?
Ich verwende Microsoft Office Professional plus 2010

nurmikss

Es klappt (ich habe nicht geglaubt, dass es soo einfach ist). Vielen Dank !

Folgende Änderungsabfrage ersetzt alle Vorkommen von 2 oder mehr Leerzeichen hintereinander durch ein einzelnes Leerzeichen. Durch die og. Funktion kann ich jetzt reguläre Ausdrücke als Suchmuster verwenden, was vorher nicht möglich war:
UPDATE [Tabelle Test]
SET [Tabelle Test].Textfeld = ersetze(Textfeld," {2,}"," ")
WHERE [Tabelle Test].[textfeld] Like "*  *";

Die WHERE-Klausel ist dabei nicht zwingend nötig, schränkt aber die Zahl der zu ändernden Datensätze  (findet Datensätze mit Leerzeichenhäufung).

Kann mir noch jemand den Codeschnipsel "Set fundstellen = regex.Execute(mystring)" aus der og. Funktion erklären ?
Ich verwende Microsoft Office Professional plus 2010

ebs17

Dieses Stück ist sinnfrei in dieser Funktion.

Die Methode Execute füllt eine Matchcollection (die da schon nicht mal deklariert ist), also eine Auflistung von Treffern gemäß dem verwendeten Suchmuster. Das würde man tun, um mit diesen isolierten Matches etwas weiteres anzufangen.
Mit freundlichem Glück Auf!

Eberhard