AXForum  
Вернуться   AXForum > Microsoft Dynamics NAV > NAV: Прочие вопросы
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 10.01.2013, 18:24   #1  
logger_imported is offline
logger_imported
Участник
Аватар для logger_imported
 
41 / 10 (1) +
Регистрация: 27.10.2006
Фильтрация данных в форме по «виртуальным» полям с использованием методов OnFindRecord и OnNextRecord формы

Цель данной публикации – описать возможность фильтрации данных в форме по «виртуальным» полям с использованием методов OnFindRecord и OnNextRecord формы. Данный вопрос частично освещён на многих Интернет-ресурсах, но полного разложения «по полочкам» с конкретными примерами найти практически нереально. В рамках подготовки публикации были собраны почти все «шишки» данного метода фильтрации. Если внимательные читатели при анализе решения обнаружат неточность – просим сообщать незамедлительно.

Используемые термины:
• «виртуальное» поле формы – некое поле записи, отображаемое на форме. Не связано ни с одним полем таблицы. Значение поля вычисляется в триггере OnAfterGetRecord формы.

История вопроса
Заказчик имел ряд форм, в которых использовались «виртуальные» поля. Необходимо было сделать механизм отбора записей. При этом пользователь должен был иметь возможность отобрать записи по одному из следующих алгоритмов – все записи, только записи с определённым статусом, только записи без определённого статуса.

Варианты решения
• Использование механизма маркировки записей. Недостаток - много времени уходит на перебор записей и проставление маркировок, затраты времени.
• Подмена записей в форме данными из виртуальной таблицы с использованием методов OnFindRecord и OnNextRecord формы. Недостаток - необходимость управлять временной таблицей при любом изменении записей, затраты времени.
• Игнорирование записей, не удовлетворяющих условию отбора, с использованием методов OnFindRecord и OnNextRecord формы. Недостаток – работает немного дольше, чем обычная форма.

Как догадался читатель, был выбран последний вариант.

Реализация
На форме были добавлены 4 функции (см. приложенные файлы с проектом):
1. ShowThisRecord
Код:
  IF g_AdditionsFilter=g_AdditionsFilter::All THEN
    EXIT(TRUE);

  CASE g_AdditionsFilter OF
    g_AdditionsFilter::WithAdditions: BEGIN
      IF CheckAdditionsExists(p_FilterExampleTable1)=FALSE THEN EXIT(FALSE) ELSE EXIT(TRUE);
    END;
    g_AdditionsFilter::WithoutAdditions: BEGIN
      IF CheckAdditionsExists(p_FilterExampleTable1)=TRUE THEN EXIT(FALSE) ELSE EXIT(TRUE);
    END;
  END;
2. FINDPosition
Код:
RecRef2.COPY(Rec);
IF Which = '' THEN Which := '=';
FOR i := 1 TO STRLEN(Which) DO
CASE Which[i] OF
  '-': BEGIN
    IF Rec.FIND('-') THEN REPEAT
      IF ShowThisRecord(Rec) THEN EXIT(TRUE);
    UNTIL Rec.NEXT = 0;
  END;
  '+': BEGIN
    IF Rec.FIND('+') THEN REPEAT
      IF ShowThisRecord(Rec) THEN EXIT(TRUE);
    UNTIL Rec.NEXT(-1) = 0;
  END;
  '=': BEGIN
    IF Rec.FIND THEN
      IF ShowThisRecord(Rec) THEN EXIT(TRUE);
  END;
  '>': BEGIN
    IF NEXTPosition(Rec, 1) <> 0 THEN
      EXIT(TRUE);
  END;
  '<': BEGIN
    IF NEXTPosition(Rec, -1) <> 0 THEN
      EXIT(TRUE);
  END;
END;
Rec.COPY(RecRef2);
EXIT(FALSE);
3. NEXTPosition
Код:
IF Steps = 0 THEN EXIT;
IF Steps > 0 THEN
  Direction := 1
ELSE
  Direction := -1;
RecRef2.COPY(RecRef);
RecRef3.COPY(RecRef);
REPEAT
  IF RecRef.NEXT(Direction) = 0 THEN BEGIN
    RecRef.COPY(RecRef3);
    EXIT;
  END;
  IF ShowThisRecord(RecRef) THEN BEGIN 
    RecRef3.COPY(RecRef);
    StepsCount += Direction;
  END;
UNTIL ABS(StepsCount) >= ABS(Steps);
IF StepsCount = 0 THEN
  RecRef.COPY(RecRef2)
ELSE
  RecRef.COPY(RecRef3);
4. CheckAdditionsExists
Код:
l_FilterExampleTable2.RESET;
l_FilterExampleTable2.SETFILTER(l_FilterExampleTable2."Example Code",p_ExampleFilterTable1."No.");
EXIT(l_FilterExampleTable2.FIND('-'));
В триггеры формы был внесён следующий код (см. приложенные файлы с проектом):
1. OnFindRecord
Код:
Found := FINDPosition(Which);
EXIT(Found);
2. OnNextRecord
Код:
RecRes.COPY(Rec);
NextStep := NEXTPosition(RecRes,Steps);
IF NextStep <> 0 THEN Rec.COPY(RecRes);
EXIT(NextStep);
Решение работает достаточно быстро и удовлетворяет требования Заказчика.
Полный код решения на простом примере приложен в файлах find-next.fob, find-next.txt
Вложения
Тип файла: fob find-next.fob (24.4 Кб, 403 просмотров)
Тип файла: txt find-next.txt (12.8 Кб, 375 просмотров)
__________________
Незнание закона не освобождает от ответственности... От ответственности освобождает знание закона!
Компания НЭТИ - http://i-neti.ru/
 

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 10:43.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.