Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

FAQ - Вопросы - ответы - советы - Базы данных

Вопрос:

Как научить VCL делать REFRESH для запросов правильно? Особенно интересует REFRESH для связки MASTER-DETAIL.

Ответ:

Старо как мир, и нет ничего военного:

PROCEDURE  REFRESHQUERY (QUERY : TQUERY; F : BOOLEAN);
VAR B : TBOOKMARK;
BEGIN
 WITH QUERY DO
   IF QUERY.ACTIVE THEN
   BEGIN
     B:=GETBOOKMARK;
     TRY
       CLOSE;
       UNPREPARE;  {Если не поставить этого, то если используется SELECT
SP, то иногда последующая операция вешает сервер.
                    Кто скажет почему?!}
       ACTIVE:=TRUE;
       IF F THEN BEGIN
         TRY
           GOTOBOOKMARK(B)
         EXCEPT
           ON EDATABASEERROR DO FIRST;
         END
       END
       ELSE FIRST;
     FINALLY
       FREEBOOKMARK(B);
     END;
   END;
END;

Уфф! Кажется, лучше уже не сделать. :)

DBTABLES можно опционально пропатчить (см.в конце), чтобы иметь такой вот рулезный DETAIL QUERY.

UPDATE FOR DBTABLES.PAS

    NEW INTERFACE FUNCTION DOREFRESHQUERY CAN REFRESH TQUERY COMPONENT IN
MASTER-DETAIL SCHEME AND ALONE.
    TQUERY.REFRESHPARAMS SHOULD BE UPDATED

FUNCTION GETFIELDNAMESSTR(DATASET: TDATASET): STRING;
VAR
  I: INTEGER;
BEGIN
  RESULT := '';
  WITH DATASET DO
    FOR I := 0 TO FIELDCOUNT - 1 DO
      RESULT := RESULT + FIELDS[I].FIELDNAME + ';';
END;

PROCEDURE DOREFRESHQUERY(QUERY: TQUERY; KEYFIELDS: STRING; BOOKMARKSEARCH:
BOOLEAN);
VAR
  FIELDS: TLIST;
  KEYVALUES: VARIANT;
  KEYNAMES: STRING;
  BMK: TBOOKMARK;
  I: INTEGER;
  BOOKMARKFOUND: BOOLEAN;
  CANLOCATE: BOOLEAN;
BEGIN
  FIELDS := TLIST.CREATE;
  IF KEYFIELDS = '' THEN KEYFIELDS := GETFIELDNAMESSTR(QUERY);
  TRY
    QUERY.GETFIELDLIST(FIELDS, KEYFIELDS);
    FOR I := FIELDS.COUNT - 1 DOWNTO 0 DO
      WITH TFIELD(FIELDS[I]) DO
        IF CALCULATED OR LOOKUP THEN FIELDS.DELETE(I);
    CANLOCATE := FIELDS.COUNT > 0;
    IF CANLOCATE THEN
    BEGIN
      IF FIELDS.COUNT = 1 THEN
        KEYVALUES := TFIELD(FIELDS[0]).VALUE
      ELSE BEGIN
        KEYVALUES := VARARRAYCREATE([0, FIELDS.COUNT - 1], VARVARIANT);
        KEYVALUES[0] := TFIELD(FIELDS[0]).VALUE;
      END;
      KEYNAMES := TFIELD(FIELDS[0]).FIELDNAME;
      FOR I := 1 TO FIELDS.COUNT - 1 DO
      BEGIN
        KEYNAMES := KEYNAMES + ';' + TFIELD(FIELDS[I]).FIELDNAME;
        KEYVALUES[I] := TFIELD(FIELDS[I]).VALUE;
      END;
    END;
  FINALLY
    FIELDS.FREE;
  END;
  WITH QUERY DO
  BEGIN
    BMK := NIL;
    DISABLECONTROLS;
    TRY
      BOOKMARKFOUND := FALSE;
      IF BOOKMARKSEARCH THEN
        BMK := GETBOOKMARK;
      CLOSE;
      OPEN;
      IF ASSIGNED(BMK) THEN
      TRY
        GOTOBOOKMARK(BMK);
        BOOKMARKFOUND := TRUE;
      EXCEPT  END;
      IF NOT BOOKMARKFOUND AND CANLOCATE THEN
        LOCATE(KEYNAMES, KEYVALUES, []);
    FINALLY
      ENABLECONTROLS;
      SCREEN.CURSOR := CRDEFAULT;
      FREEBOOKMARK(BMK);
    END;
  END;
END;


PROCEDURE TQUERY.REFRESHPARAMS;
VAR
  DATASET: TDATASET;
BEGIN
  DISABLECONTROLS;
  TRY
    IF FDATALINK.DATASOURCE  NIL THEN
    BEGIN
      DATASET := FDATALINK.DATASOURCE.DATASET;
      IF DATASET  NIL THEN
        IF DATASET.ACTIVE AND (DATASET.STATE  DSSETKEY) THEN
          DOREFRESHQUERY(SELF, GETFIELDNAMESSTR(SELF), FALSE);
    END;
  FINALLY
    ENABLECONTROLS;
  END;
END;

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог