Funktion verursacht schlechte Performance

20. November 2007 11:28

Hallo zusammen,

ich habe ein riesiges Problem mit der Performance beim Aufruf und Blätten eines Formulars. Bei der Fehlersuche bin ich über die Funktion "Personensuche" gestolpert. Kommentiere ich diese Funktion aus, ist die Performance ok. Hat jemand eine Idee, wie man diese Funktion performanter gestalten könnte?

Code:
// -----------------------------------------
// PersonenSuchen()
// -----------------------------------------

Gliederung.GET(GliederungsNr);
RESET;
SETCURRENTKEY("Contact No.","Mailing Group Code","Alternative Gliederung");

VerbandKontakte.RESET;
VerbandKontakte.SETFILTER(VerbandKontakte."Show as Contact Person",'%1',TRUE);
VerbandKontakte.SETFILTER(VerbandKontakte."Organization Type",'%1',Gliederung."Organization Type");


//Erst die, die keine alternative Gliederungsnummer haben

IF VerbandKontakte.FIND('-') THEN
BEGIN
  REPEAT
    IF VerteilerCode_v = '' THEN
     VerteilerCode_v := VerbandKontakte."Mailing Group"
    ELSE
     VerteilerCode_v := VerteilerCode_v + ' | ' + VerbandKontakte."Mailing Group";
  UNTIL VerbandKontakte.NEXT = 0;
 
  CASE Gliederung."Organization Type" OF
    Gliederung."Organization Type"::State:   SETFILTER("Structure No.",COPYSTR(GliederungsNr,1,2) + '??????');
    Gliederung."Organization Type"::Region:  SETFILTER("Structure No.",COPYSTR(GliederungsNr,1,4) + '????');
    Gliederung."Organization Type"::County:  SETFILTER("Structure No.",COPYSTR(GliederungsNr,1,6) + '??');
    Gliederung."Organization Type"::City:    SETFILTER("Structure No.",GliederungsNr);
  END;

  SETFILTER("Alternative Gliederung",'');
  SETFILTER("Mailing Group Code",VerteilerCode_v);
  IF FIND('-') THEN
    REPEAT
      MARK(TRUE)
    UNTIL NEXT = 0;
END;

//Jetzt die mit den Alternativen Gliederungsnummer

IF VerteilerCode_v <> '' THEN
BEGIN
  SETRANGE("Structure No.");
  SETRANGE("Alternative Gliederung",GliederungsNr);
  IF FIND('-') THEN
    REPEAT
      MARK(TRUE)
    UNTIL NEXT = 0;
END;

//UND JETZT den Filter für die Tabelle basteln

  SETRANGE("Structure No.");
  SETRANGE("Alternative Gliederung");
  SETRANGE("Mailing Group Code");
  MARKEDONLY(TRUE);
  CurrForm.UPDATE(FALSE);


Bin wie immer für jeden Tipp dankbar. Gruß Markus

20. November 2007 12:00

Eventuell die entsprechenden Tabellen mal optimieren.

20. November 2007 12:03

Meinst Du damit, in den Tabellen Schlüssel anzulegen und in der Funktion mit SETCURRENTKEY diese Schlüssel verwenden?

Re: Funktion verursacht schlechte Performance

20. November 2007 13:08

Hi Markus!

mgerhartz hat geschrieben:[...] Bei der Fehlersuche bin ich über die Funktion "Personensuche" gestolpert.

In welchem Trigger wird diese Funktion aufgerufen?

Gruß, Marc

20. November 2007 14:24

Hi Marc,

im Form - OnAfterGetRecord Trigger:

SETRANGE("Structure No.");
CurrForm."Schatzmeister/Vorsitzender".FORM.PersonenSuchen("Structure No.");

Als Zwischenlösung habe ich diese Zeile auskommentiert und auf der Form einen Button hinterlegt, der diese Funktion ausführt. So kann man also problemlos blättern und nur, wenn die Daten der Subform aktualisiert werden sollen, betätigt man den Button. In diesem Zusammenhang noch eine andere Frage. Wie bekomme ich es hin, dass die Subform beim Aufrufen des Formulars erst einmal leer ist. Bis jetzt werden noch die Daten des letzten Aufrufs angezeigt.

@ Trotzdem frage ich mich, warum die Funktion so lange braucht.

20. November 2007 14:28

Die Funktion gehört m.E. in den OnAfterGetCurrRecord. Probiers mal aus.

20. November 2007 14:32

Hi Natalie,

das bringt auch keine Veränderung. Im wesentlichen geht es mir um die schlechte Performance der Funktion. Z. B. auch dann, wenn ich diese wie oben beschrieben über den Funktionsbutton ausführen lasse.

Gruß

Markus

20. November 2007 14:59

Was mir auffällt:
Ersetze MARK(TRUE) beser durch
Code:
IF NOT MARK THEN
  MARK(TRUE);

denn ein eventuelles zweifaches MARK löst das MARK wieder.

Außerdem ist der Schüssel nicht gut, weil eine Contact No. als Filter erwartet wird - darauf wird aber nie gefiltert.

An deiner Stelle würde ich das ganze Prozedere nicht mit Rec machen, sondern mit einer temporären Recordvariable: Rec.Datensätze, die du sonst markieren würdest, kopierst du per INSERT in deinen Temp. Record.
Deine Form muss diesen Temp. Record dann anzeigen. Schau dir dazu als Beispiel im Standard die Form 6510 an.

Ob das für dich in Frage kommt, hängt aber von versch. Dingen ab:
Wie ist die Form eigentlich aufgebaut? an welche Tabelle ist sie gebunden, ist es eine Main-/Subformstruktur ...?

20. November 2007 15:10

Hi Natalie,

Richtig, es ist eine Main-/Subformstruktur. Du Subformenen beziehen sich auf andere Tabellen als die Mainform. Die Subform, die Probleme bereitet, ist die der Ansprechpartner. Zum aktualisieren der Sub-Form wird die Funktion "Personensuche" über den Form-OnAfterGetRecord Trigger ausgeführt.
Wie man in der o. b. Funktion sehen kann, wird zuerst die Tabelle Verbandkontakte nach den Verteilerschlüsseln von relevanten Ansprechpartner durchsucht. Diese Verteilerschlüssel werden dann benutzt, um in der Verteilertabelle den entsprechenden Kontakt ausfindig zu machen und anzuzeigen.

20. November 2007 15:40

Gut, das bekräftigt nur das, was ich schon gesagt habe.

Ist die Subform durch einen SubformLink mit der Mainform verbunden?
Dies sollte bei dir ja nicht der Fall sein, da sich die Datensätze ja selbst berechnen müssen (mit MARKEDONLY).
Falls doch, den Link wieder herausnehmen.

20. November 2007 18:12

Hi Natalie,

danke für Deine Tipps. Ich werde erst am Donnerstag wieder dazu kommen ein bisschen was auszuprobieren. Ich melde mich dann wieder.

Byby

P.S.: Die Subform ist nicht über einen Subformlink verbunden.