Zeichen aus einem String entfernen [ERLEDIGT]

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

rassekst
UDF-Programmierer
UDF-Programmierer
Beiträge: 97
Registriert: Mi, 01. Feb 2006 23:49
Wohnort: Glauchau
Kontaktdaten:

Beitrag von rassekst »

Hallo Manfred,

Wenn ich mir Dein Programm ansehe fällt mir zur Geschwindigkeitsverbesserung folgendes ein:

1.

Code: Alles auswählen

           IF UPPER(Substr(neuerstring,1,1)) == UPPER(zeichen)
 
Die Wandlung UPPER grundsätzlich außerhalb der Schleife setzen-

2.

Code: Alles auswählen

         IF UPPER(SUBSTR(neuerstring,1,3)) = "DER" .OR.;
            UPPER(SUBSTR(neuerstring,1,3)) = "DIE" .OR.;
            UPPER(SUBSTR(neuerstring,1,3)) = "DAS" .OR.;
            UPPER(SUBSTR(neuerstring,1,3)) = "THE" .OR.;
            UPPER(SUBSTR(neuerstring,1,3)) = "THA" .OR.;
            UPPER(SUBSTR(neuerstring,1,3)) = "DE " .OR.;
            UPPER(SUBSTR(neuerstring,1,3)) = "LE " .OR.;
            UPPER(SUBSTR(neuerstring,1,3)) = "LA "
            neuerstring := POSDEL(neuerstring,1,3)
         ENDIF
folgendermaßen schreiben:

Code: Alles auswählen

IF UPPER(SUBSTR(neuerstring,1,3))+'.' $ ;
"DER.DIE.DAS.THE.THA.DE .LE .LA ." 
   neuerstring := SUBSTR(neuerstring,4)
ENDIF
Warum nimmst Du nicht die Funktion CharRem() aus den XToolsIII

Mein Vorschlag wäre:

(es reicht für Deinen Aufruf eine Procedur)

Code: Alles auswählen

PROCEDURE entfernen(string)
LOCAL neuerstring := string

LOCAL zeichensatz       := "!§$%&/()=?^*+'#<>,;.:-_\{}[] "

IF !EMPTY(neustring)
    IF UPPER(SUBSTR(neuerstring,1,3))+'.' $ "DER.DIE.DAS.THE.THA.DE   .LE .LA ." 
       neuerstring := SUBSTR(neuerstring,4)
    ENDIF

   neuerstring = CharRem( zeichensatz,neuerstring)
  
ELSE
    string = neuerstring
ENDIF

RETURN
Vielleicht hilft das weiter.

Gruss Steffen
Zuletzt geändert von rassekst am Di, 31. Okt 2006 0:23, insgesamt 1-mal geändert.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Sehr viel schneller als SubStr() ist das hier, sagt jedenfalls Alaska (Vortrag auf der DevCon in NL):

Statt

Code: Alles auswählen

Substr(cString,i,3) 

Code: Alles auswählen

cString[i]+cString[i+1]+cString[i+2]
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Tom hat geschrieben:

Code: Alles auswählen

 cString[i]+cString[i+1]+cString[i+2] 
die neuen Zugriffsmethoden von Strings haben mich auch inspiriert darauf aufzubauen:
Ich brauchte die 2. Stelle des Benutzernamens, da dieser bei uns die Niederlassung kennzeichnet. Dann wurde das Programm an andere weitergegeben und die haben 1 stellige ( :?: ) Benutzernamen verwendet.

Code: Alles auswählen

cName := "X"
Substr(cName,3,1) ->  ""
cName[3] gibt einen Laufzeitfehler ...
Seither ist mein Verhältnis dazu wieder etwas abgekühlt ;)
Nicht falsch verstehen, der direkte Zugriff auf ein Zeichen im String ist schon sinnvoll, man muß aber immer die Länge des Strings im Auge behalten.

PS: wieso erscheint oben diese seltsame Grafik im Zitat ?
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

So,

ich habe jetzt einmal ein wenig gebastelt:

aus dem hier

Code: Alles auswählen

function ohneArtikel(cIndexKey)       
LOCAL cArtikel
       LOCAL lFertig   := .F.
       LOCAL nArtikel1 := 0       // wird nach jedem gefunden Artikel 1 hochgezählt,
       LOCAL nArtikel2 := 0       // damit kein Endlosdurchlauf geschieht, bei mehrfach Artikel im Feld
       LOCAL nIndexOrgLaenge := LEN(cIndexKey)    // wird nachher für die evtl. fehlenden Zeichen benötigt
       LOCAL nMenge32                                                           // Leerzeichen
       LOCAL nMenge33                                                           // !
       LOCAL nMenge34                                                           // "
       LOCAL nMenge35                                                           // #
       LOCAL nMenge38                                                           // &
       LOCAL nMenge39                                                           // '
       LOCAL nMenge40                                                           // (
       LOCAL nMenge42                                                           // *
       LOCAL nMenge43                                                           // +
       LOCAL nMenge44                                                           // ,
       LOCAL nMenge46                                                           // .
       LOCAL nMenge95                                                           // _

       DO WHILE ! lFertig
          lFertig := .T.
          IF EMPTY(cIndexKey)                                                   // das kann auch vorkommen
             EXIT                                                               // es würde sonst arg lange dauern
          ENDIF
          nMenge32 := COUNTLEFT(cIndexKey,CHR(32))                              // Leerzeichen
          nMenge33 := COUNTLEFT(cIndexKey,CHR(33))                              // !
          nMenge34 := COUNTLEFT(cIndexKey,CHR(34))                              // "
          nMenge35 := COUNTLEFT(cIndexKey,CHR(35))                              // #
          nMenge38 := COUNTLEFT(cIndexKey,CHR(38))                              // $
          nMenge39 := COUNTLEFT(cIndexKey,CHR(39))                              // %
          nMenge40 := COUNTLEFT(cIndexKey,CHR(40))                              // (
          nMenge42 := COUNTLEFT(cIndexKey,CHR(42))                              // *
          nMenge43 := COUNTLEFT(cIndexKey,CHR(43))                              // +
          nMenge44 := COUNTLEFT(cIndexKey,CHR(44))                              // ,
          nMenge46 := COUNTLEFT(cIndexKey,CHR(46))                              // .
          nMenge95 := COUNTLEFT(cIndexKey,CHR(95))                              // _
          IF nMenge32 > 0         // mußer hier rein, weil jetzt auch Leerezeichen am Anfang sein können
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge32 + 1,nIndexOrgLaenge-nMenge32) + SPACE(nMenge32),1)
             lFertig   := .F.
          ELSEIF nMenge33 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge33 + 1,nIndexOrgLaenge-nMenge33) + SPACE(nMenge33),1)
             lFertig   := .F.
          ELSEIF nMenge34 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge34 + 1,nIndexOrgLaenge-nMenge34) + SPACE(nMenge34),1)
             lFertig   := .F.
          ELSEIF nMenge35 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge35 + 1,nIndexOrgLaenge-nMenge35) + SPACE(nMenge35),1)
             lFertig   := .F.
          ELSEIF nMenge38 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge38 + 1,nIndexOrgLaenge-nMenge38) + SPACE(nMenge38),1)
             lFertig   := .F.
          ELSEIF nMenge39 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge39 + 1,nIndexOrgLaenge-nMenge39) + SPACE(nMenge39),1)
             lFertig   := .F.
          ELSEIF nMenge40 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge40 + 1,nIndexOrgLaenge-nMenge40) + SPACE(nMenge40),1)
             lFertig   := .F.
          ELSEIF nMenge42 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge42 + 1,nIndexOrgLaenge-nMenge42) + SPACE(nMenge42),1)
             lFertig   := .F.
          ELSEIF nMenge43 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge43 + 1,nIndexOrgLaenge-nMenge43) + SPACE(nMenge43),1)
             lFertig   := .F.
          ELSEIF nMenge44 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge44 + 1,nIndexOrgLaenge-nMenge44) + SPACE(nMenge44),1)
             lFertig   := .F.
          ELSEIF nMenge46 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge46 + 1,nIndexOrgLaenge-nMenge46) + SPACE(nMenge46),1)
             lFertig   := .F.
          ELSEIF nMenge95 > 0
             cIndexKey := TOKENUPPER(SUBSTR(cIndexKey,nMenge95 + 1,nIndexOrgLaenge-nMenge95) + SPACE(nMenge95),1)
             lFertig   := .F.
          ELSEIF UPPER(SUBSTR(cIndexKey,1,4)) == "DER " .OR.;
             UPPER(SUBSTR(cIndexKey,1,4)) == "DIE " .OR.;
             UPPER(SUBSTR(cIndexKey,1,4)) == "DAS " .OR.;
             UPPER(SUBSTR(cIndexKey,1,4)) == "THE " .OR.;
             UPPER(SUBSTR(cIndexKey,1,4)) == "THA "
             IF nArtikel1 = 0                                                   // 1. Durchlauf, alles ok
                cArtikel  := SubStr(cIndexKey,1,3)                              // Artikel merken
                cIndexKey := SUBSTR(cIndexKey,4,46)                             // Artikel eliminieren
                cIndexKey := TRIM(cIndexKey)                                    // LeerZeichen hinten entfernen
                cIndexKey += ", " + cArtikel                                    // Artikel hinten dranpacken
                cIndexKey := TOKENUPPER(cIndexKey,1)    // Anfangsbuchstaben groß
                cIndexKey := PADRIGHT(cIndexKey,50)     // jetzt wird wieder auf Originallänge aufgefüllt
                lFertig   := .F.
             ENDIF
             nArtikel1++
          ELSEIF UPPER(SUBSTR(cIndexKey,1,3)) == "LA "
             IF nArtikel2 = 0                                                   // 1.Durchlauf, alles ok
                cArtikel  := SubStr(cIndexKey,1,2)                              // Artikel merken
                cIndexKey := SUBSTR(cIndexKey,3,47)                             // Artikel eliminieren
                cIndexKey := TRIM(cIndexKey)                                    // LeerZeichen hinten entfernen
                cIndexKey += ", " + cArtikel                                    // Artikel hinten dranpacken
                cIndexKey := TOKENUPPER(cIndexKey,1)                            // Anfangsbuchstaben groß
                cIndexKey := PADRIGHT(cIndexKey,50)    // jetzt wird wieder auf Originallänge aufgefüllt
                lFertig   := .F.
             ENDIF
             nArtikel2++
          ENDIF
       ENDDO
       return cIndexKey
wurde das hier:

Code: Alles auswählen

FUNCTION indexohne(cIndexKey)
         LOCAL cArtikel   entfernen"
         LOCAL lFertig   := .F.
         LOCAL nArtikel1 := 0                // wird nach jedem gefunden Artikel 1 hochgezählt,
         LOCAL nArtikel2 := 0                // damit kein Endlosdurchlauf geschieht, bei mehrfach Artikel im Feld
         LOCAL nIndexOrgLaenge := LEN(cIndexKey)      // wird nachher für die evtl. fehlenden Zeichen benötigt
         LOCAL nMenge32                                                           // Leerzeichen
         LOCAL nMenge33                                                           // !
         LOCAL nMenge34                                                           // "
         LOCAL nMenge35                                                           // #
         LOCAL nMenge38                                                           // &
         LOCAL nMenge39                                                           // '
         LOCAL nMenge40                                                           // (
         LOCAL nMenge41
         LOCAL nMenge42                                                           // *
         LOCAL nMenge43                                                           // +
         LOCAL nMenge44                                                           // ,
         LOCAL nMenge45                                                           //-
         LOCAL nMenge46                                                           // .
         LOCAL nMenge47                                                           // /
         LOCAL nMenge58
         LOCAL nMenge62
         LOCAL nMenge63
         LOCAL nMenge92                                                           // \
         LOCAL nMenge94
         LOCAL nMenge95                                                           // _
         LOCAL nMenge96
         LOCAL nMenge180

         DO WHILE ! lFertig
            lFertig := .T.
            IF EMPTY(cIndexKey)                                                   // das kann auch vorkommen
               EXIT                                                               // es würde sonst arg lange dauern
            ENDIF
            nMenge32 := COUNTLEFT(cIndexKey,CHR(32))                              // Leerzeichen
            nMenge33 := COUNTLEFT(cIndexKey,CHR(33))                              // !
            nMenge34 := COUNTLEFT(cIndexKey,CHR(34))                              // "
            nMenge35 := COUNTLEFT(cIndexKey,CHR(35))                              // #
            nMenge38 := COUNTLEFT(cIndexKey,CHR(38))                              // $
            nMenge39 := COUNTLEFT(cIndexKey,CHR(39))                              // %
            nMenge40 := COUNTLEFT(cIndexKey,CHR(40))                              // (
            nMenge41 := COUNTLEFT(cIndexKey,CHR(41))
            nMenge42 := COUNTLEFT(cIndexKey,CHR(42))                              // *
            nMenge43 := COUNTLEFT(cIndexKey,CHR(43))                              // +
            nMenge44 := COUNTLEFT(cIndexKey,CHR(44))                              // ,
            nMenge45 := COUNTLEFT(cIndexKey,CHR(45))                              // -
            nMenge46 := COUNTLEFT(cIndexKey,CHR(46))                              // .
            nMenge47 := COUNTLEFT(cIndexKey,CHR(47))                              // /
            nMenge58 := COUNTLEFT(cIndexKey,CHR(58))
            nMenge62 := COUNTLEFT(cIndexKey,CHR(62))
            nMenge63 := COUNTLEFT(cIndexKey,CHR(63))
            nMenge92 := COUNTLEFT(cIndexKey,CHR(92))                              // \
            nMenge94 := COUNTLEFT(cIndexKey,CHR(94))
            nMenge95 := COUNTLEFT(cIndexKey,CHR(95))                              // _
            nMenge96 := COUNTLEFT(cIndexKey,CHR(96))
            nMenge180 := COUNTLEFT(cIndexKey,CHR(180))
            IF nMenge32+nMenge33+nMenge34+nMenge35+nMenge38+nMenge39+nMenge40+nMenge41+nMenge42+;
               nMenge43+nMenge44+nMenge45+nMenge46+nMenge47+nMenge62+nMenge63+;
               nMenge92+nMenge94+nMenge95+nMenge96 > 0
               cIndexKey := SUBSTR(cIndexKey,2,nIndexOrgLaenge-1) + SPACE(1)
               lFertig   := .F.
            ELSEIF SUBSTR(cIndexKey,1,4) == "DER " .OR.;
               SUBSTR(cIndexKey,1,4) == "DIE " .OR.;
               SUBSTR(cIndexKey,1,4) == "DAS " .OR.;
               SUBSTR(cIndexKey,1,4) == "THE " .OR.;
               SUBSTR(cIndexKey,1,4) == "THA "
               IF nArtikel1 = 0                                                   // 1. Durchlauf, alles ok
                  cArtikel  := SubStr(cIndexKey,1,3)                              // Artikel merken
                  cIndexKey := SUBSTR(cIndexKey,4,46)                             // Artikel eliminieren
                  cIndexKey := TRIM(cIndexKey)                                    // LeerZeichen hinten entfernen
                  cIndexKey += ", " + cArtikel                                    // Artikel hinten dranpacken
                  cIndexKey := PADRIGHT(cIndexKey,50)   // jetzt wird wieder auf Originallänge aufgefüllt
                  lFertig   := .F.
               ENDIF
               nArtikel1++
            ELSEIF SUBSTR(cIndexKey,1,3) == "LA "
               IF nArtikel2 = 0                                                   // 1.Durchlauf, alles ok
                  cArtikel  := SubStr(cIndexKey,1,2)                              // Artikel merken
                  cIndexKey := SUBSTR(cIndexKey,3,47)                             // Artikel eliminieren
                  cIndexKey := TRIM(cIndexKey)                                    // LeerZeichen hinten entfernen
                  cIndexKey += ", " + cArtikel                                    // Artikel hinten dranpacken
                  cIndexKey := PADRIGHT(cIndexKey,50)    // jetzt wird wieder auf Originallänge aufgefüllt
                  lFertig   := .F.
               ENDIF
               nArtikel2++
            ENDIF
         ENDDO
         RETURN cIndexkey
Warum ich diesen Blödsinn oben mit jeder IF Abfrage gebaut habe, weiß ich heute auch nicht mehr. Aber egal

So, knapp 536000 Datensätze

einfacher NTX Index ohne Function ca.13 Sekunden

Index mit Funktion = 32 Sekunden

cIndexKey wird Upper() übergeben, also ist schon groß wenn er kommt. Das hatte ich damals übersehen und deshalb nochmals Upper überall eingebaut. Tokenupper war auch überflüssig, hat aber alles nix gebracht. Auch der Tipp von Steffen dies nicht in die Schleife einzubauen, brachte keinen Tempogewinn.

Egal, was ich gemacht habe, es gab keinen Tempovorteil. Ich denke mir jetzt aber, der Rest wird irgendwie bremsen. Nur fehlt mir jetzt irgendwie der Schmalz. Hat jemand eine Idee, wie man den Rest vereinfachen kann?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Manfred,
warum arbeitest Du nicht mit strtran()?
Länge des Indexausdruckes ermitteln, alle strtran()s ausführen (wobei die Zeichen durch nichts ersetzt, also gelöscht werden), dann wird der Ausdruck wieder auf die alte Länge gebracht.

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Martin,

weil ich im Moment überhaupt keine Ahnung habe, wie ich weiter vorgehen könnte. Sprich, es herrscht Leere in meinem Kopf. Es muß ja irgendwie eine Schleife sein, die immer wieder durchgeht und prüft.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Äh - nein, wieso?
In etwa so:

Code: Alles auswählen

...
nLen := len( cIndexKey )
cText1 := strtran( cIndexKey, Chr(32), )
cText2 := strtran( cText1, Chr(33), )
cText1 := strtran( cText2, Chr(34), )
...
cText2 := strtran( cText1, chr(180 ), )
cText1 := strtran( cText2, "DIE ", )
...
Return left( cText2 + space( nLen ), nLen )
Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Jou,

dett Jeschäfft iss richtig. Und was machst Du, wenn die ersten Prüfungen erst Erfolg hätten, nachdem ein Zeichen später entfernt wurde?

Beispiel:

?(Fragezeichen) <- sieht blöd aus, jibbet abba.

Fragezeichen wird entfernt und dann die Klammer. Also muß es eine Schleife sein. Oder stehe ich auf der Leitung? Es könnte ja auch andersherum sein (?Fragezeichen. Was passiert dann?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Ah - OK!
Nun, wenn Du die durch das Löschen neu entstehenden Kombinationen ebenfalls überarbeiten willst, dann ja - eventuell so:

Code: Alles auswählen

... 
nLen := len( cIndexKey )
nLen1 := 0
nLen2 := nLen
cText2 := cIndexKey
do while nLen1 <> nLen2
   nLen2 := len( cText2 )
   cText1 := strtran( cText2, Chr(32), ) 
   cText2 := strtran( cText1, Chr(33), ) 
   cText1 := strtran( cText2, Chr(34), ) 
   ... 
   cText2 := strtran( cText1, chr(180 ), ) 
   cText1 := strtran( cText2, "DIE ", ) 
   ... 
   cText2 := strtran( cText1, "THA ", )
   nLen1 := len( cText2 )
enddo
Return left( cText2 + space( nLen ), nLen )
Wichtig dabei ist halt, dass die letzte Zuweisung in der While-Schleife wieder in der Variablen cText2 mündet, damit die erste Zeile in der While-Schleife dann wieder funktioniert...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Ooops,

ich stelle wieder fest, ich drücke mich falsch aus.

Ich wollte den ganzen Murks jetzt so optimieren, dass ich von dieser längeren Laufzeit möglichst herunterkomme. (Falls es überhaupt geht) Wie Hubert schon weiter oben erwähnt hat, ist die Do while Schleife nicht gerade das Schnellste. Ich hatte gehofft, hier einen Turbotipp zu bekommen, der Tempo macht. Weil ihr auf dem Gebiet ja einfach besser seid als ich.. :roll:
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Manfred,
die While-Loop ist nicht der einzige Engpass...
Probier es mal aus - vielleicht ist das so ja schon schneller, als Deine optimierte Variante...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Na gut,

ich werde es mal testen.

Melde mich wieder. Versprochen :lol:
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Manfred,
kleiner Denkfehler: Die strtran()-Zeilen mit den einzelnen chr(nnn)s brauchst Du natürlich nicht in der While-Schleife machen!!
Nur die Teile, in denen Du Buchstabenfolgen löschen willst ("DIE ", "THA ", ...) müssen natürlich in die Schleife!!!!

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Martin,

ist es schon so spät, oder wieso habe ich das Gefühl ich schlafe?

Wieso die CHR() nicht in der Schleife? Gerade die, da können doch zig Möglichkeiten sein, die nach und nach geprüft werden müssen.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Manfred,
Du kannst in einem String eine Zeichenart nur einmal löschen - wenn das Zeichen nicht mehr drin ist, brauchst Du es auch nicht mehr prüfen!
strtran( "Dies ist ein Test für das Ersetzen", "i", ) löscht alle "i" in dem Satz!
-> Des st en Test für das Ersetzen
Auch durch das spätere Löschen von Buchstabenfolgen können dann keine "i" mehr reinkommen!

Gute Nacht,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

ich schmeiß mich morgen nochmals daran. Heute ist es mir auch schon zu spät
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Tach,

so, die Sache mit StrTran() klappt nicht so, wie ich es brauche. Man kann der Funktion sagen, wie oft sie das machen soll, aber nicht ab wo bis wo. Oder ich bin zu blöde....

Code: Alles auswählen

FUNCTION indexohne(cIndexKey)
         LOCAL aZeichen := {;
                            {")",1},;
                            {"(",1},;
                            {"!",1};
                           }
         LOCAL cIndexKey2 := cIndexKey
         LOCAL lFertig    := .F.
         LOCAL nIndexOrgLaenge := LEN(cIndexKey)              // wird nachher für die evtl. fehlenden Zeichen benötigt
         LOCAL nIndexNeuLaenge

         DO WHILE ! lFertig
            lFertig := .T.
            IF EMPTY(cIndexKey)                                                   // das kann auch vorkommen
               EXIT                                                               // es würde sonst arg lange dauern
            ENDIF
            Aeval(aZeichen, {|x,nI| cIndexKey := StrTran(cIndexKey,aZeichen[nI,1],,1,aZeichen[nI,2])})
            nIndexNeuLaenge := Len(cIndexKey)
            IF nIndexOrgLaenge <> nIndexNeuLaenge
               cIndexKey +=  + SPACE(nIndexOrgLaenge - nIndexNeuLaenge)
               lFertig := .F.
            ENDIF
         ENDDO
         RETURN cIndexkey
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

dass man StrTran() die Anzahl vorschreiben kann habe ich noch nie gehört, vielleicht ein neues Feature ? :wink:

Aber wenn du willst, dass es von Zeichen 101 genau 100 Zeichen ersetzt, musst du mit Substr() vorarbeiten:

Code: Alles auswählen

cStart := left(cTxt,100) 
cEnde := substr(cTxt,201)
cMitte := strTran(substr(cTxt,101,100),"x","y")
? cStart + cMitte + cEnde
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Äh Manfred,
was machst Du da?
Strtran ersetzt alle Zeichen in einem String durch andere Zeichen!
Also nicht zeichenweise durcharbeiten!

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hm, was mache ich da?

Nun, ich hatte es erst so verstanden, dass ich StrTRan() sagen kann, was wann und wie oft wo ersetzt wird. Das war wohl ein Irrtum.

Aber cStrimg = meine Zeichenkette
cSeek = Das Zeichen was ersetzt werden soll

Das klappt ja auch soweit

cReplace = Das neue Zeichen, oder aber nichts und dann wird gelöscht

Das klappt auch

nStart = da lag mein Denkfehler. es ist nicht ab wann in dem String, sondern ab dem 1.gefundenen Zeichen

nCount = wie oft und ich dachte bis wohin....

Tja, schade dumm gelaufen
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Manfred,
wieso dumm gelaufen? Ist doch so viel einfacher! Alle "verbotenen" Zeichen löschen, die darin vorkommen - egal wie oft!
Und dann den String wieder auf die richtige Länge auffüllen!

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Martin,

ja, das will ich aber nicht.... Es dürfen nur die am Anfang sein. Das Teil haut sie mir raus, egal wo sie stehen, wenn auch nur 1x, wie gewünscht. Also heißt es weitersuchen nach einer schnellen, knappen Lösung.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Wie - nur am Anfang? Nur an der ersten Stelle?

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Puh,

also, wenn das Teil so aussieht "/ Test" dann muß erst das / und dann das Leerzeichen entfernt werden, damit sowas hier steht "Test"

Es macht aber sowas hier "Test / Test"

"TestTest" Und das kann ich nicht gebrauchen.
Ich denke aber, ich habe gerade eine andere Lösung gefunden und teste sie gerade.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21200
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hmhmhmhm,

das kann es auch nicht sein

Code: Alles auswählen

FUNCTION indexohne(cIndexKey)
         LOCAL aZeichen := {;
                            {")",1},;
                            {"(",1},;
                            {"!",1},;
                            {" ",1},;
                            {"§",1},;
                            {"$",1},;
                            {"%",1},;
                            {"&",1},;
                            {"/",1},;
                            {"?",1},;
                            {"\",1},;
                            {"´",1},;
                            {"`",1},;
                            {"'",1},;
                            {"#",1};
                           }
         LOCAL cIndexKey2 := cIndexKey
         LOCAL lFertig    := .F.
         LOCAL nIndexOrgLaenge := LEN(cIndexKey)      // wird nachher für die evtl. fehlenden Zeichen benötigt
         LOCAL nIndexNeuLaenge

         DO WHILE ! lFertig
            lFertig := .T.
            IF EMPTY(cIndexKey)                                                   // das kann auch vorkommen
               EXIT                                                               // es würde sonst arg lange dauern
            ENDIF
            Aeval(aZeichen, {|x,nI| IF(CountLeft(cIndexKey,aZeichen[nI,1]) > 0,cIndexKey := StrTran(cIndexKey,aZeichen[nI,1],,1,aZeichen[nI,2]),NIL)})
            nIndexNeuLaenge := Len(cIndexKey)
            IF nIndexOrgLaenge <> nIndexNeuLaenge
               cIndexKey +=  + SPACE(nIndexOrgLaenge - nIndexNeuLaenge)
               lFertig := .F.
            ENDIF
         ENDDO
         RETURN cIndexkey
Das dauert jetzt sogar über 50 Sekunden und es ist nicht einmal die Artikelprüfung mit drin.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Antworten