установить фильтр на - INLIST - Visual Foxpro 7 - PullRequest
0 голосов
/ 09 февраля 2012

Я работаю над устаревшим кодом, и у меня возникла следующая замечательная проблема. Я надеюсь, что некоторые эксперты FoxPro могут помочь!

Инфраструктура этой унаследованной системы настроена таким образом, что мне приходится использовать встроенный механизм выражений для возврата набора результатов, поэтому не нужно переходить на SQL (я знаю, что это будет намного проще!)

Вот проблема.

Мне нужно иметь возможность сделать что-то вроде

PUBLIC ARRAY(20) ArrayOfValuesToFilterBy

SELECT dataTable 
SET FILTER TO logicalField = .T. and otherField NOT INLIST(ArrayOfValuesToFilterBy)

Однако я знаю, что это не сработает, мне просто нужна эквивалентность ... без использования SQL.

Я могу создать список значений для фильтрации с помощью SQL, но не окончательный выбор записи из-за ограничений устаревшей инфраструктуры.

Спасибо!

Ответы [ 3 ]

2 голосов
/ 09 февраля 2012

Во-первых, логическое поле, которое вам не нужно делать явным

, установите фильтр в Logicalfield = .t.

, вы можете просто

установить фильтр в LogicalField илиустановите для фильтра значение НЕ LogicalField

Далее по массиву.В VFP есть функция ASCAN (), которая сканирует массив на предмет значения, если найден, возвращает номер строки в массиве, который соответствует тому, что вы ищете.

Что касается массивов ... например: DIMENSIONMyArray [3] MyArray [1] = "test1" MyArray [2] = "что-то" MyArray [3] = "что-нибудь еще"

?ASCAN (MyArray, "else") && это вернет 0?ASCAN (MyArray, «что-нибудь еще») && это вернет 3

Если вы выполняете «set filter», массив должен находиться «в области видимости» на время действия фильтра.Если вы установите фильтр в процедуре, массив существует, оставьте процедуру и массив исчезнет, ​​все готово.

Итак, вы можете сделать

set filter to LogicalField and ASCAN( YourArray, StringColumnFromTable ) > 0

Теперь, если хотитеподмножество WORK WITH, вы можете выполнить SQL-Select и перетащить данные в CURSOR (временную таблицу чтения-записи), которая имеет те же возможности, что и исходная таблица (за исключением автоматического увеличения при добавлении) ...

Обычно я называю свои временные курсоры с префиксом «C_» для «CURSOR OF», поэтому, когда я работаю с таблицами, я знаю, доступны ли их производственные данные или просто для временных целей для более быстрого отображения, представления, извлечения из другихпроисхождение по мере необходимости.

use in select( "C_FinalRecords" )
select * from YourTable ;
   where LogicalField ;
     and ASCAN( YourArray, StringColumnFromTable ) > 0;
   into cursor C_FinalRecords READWRITE

Затем вы можете просто использовать это ...

select C_FinalRecords
scan
   do something with the record, or values of it...
endscan

или .. привязать к сетке в форме, и т.д ...

0 голосов
/ 21 марта 2012

Здесь я делаю некоторые предположения, что вы хотите создать фильтр с динамическим оператором списка? Если это правильно, поиграйте с этим примером: -

lcList1="ABCD"
lcList2="EFGH"
lcList3="IJKL"
lcList4="MNOP"
lcList5="QRST"

lcFullList=""
lcFullList=lcFullList+"'"+lcList1+"',"
lcFullList=lcFullList+"'"+lcList2+"',"
lcFullList=lcFullList+"'"+lcList3+"',"
lcFullList=lcFullList+"'"+lcList4+"',"
lcFullList=lcFullList+"'"+lcList5+"'"



lcField="PCode"

lcFilter="SET FILTER TO INLIST ("+lcField+","+lcFullList+")"

В результате вышеизложенного будет создан следующий оператор фильтра и сохранен в lcFilter

УСТАНОВИТЬ ФИЛЬТР ДЛЯ ВСТАВКИ (PCode, 'ABCD', 'EFGH', 'IJKL', 'MNOP', 'QRST')

затем вы можете использовать подстановку макросов

Select dataTable
&lcFilter 

Имейте в виду, что могут быть некоторые ограничения на количество элементов, которые вы можете определить в операторе INLIST ()

0 голосов
/ 09 февраля 2012

Функция INLIST () принимает выражение для поиска и до 24 выражений того же типа данных для поиска.

SELECT dataTable 
SET FILTER TO logicalField = .T. AND NOT INLIST(otherField, 'Value1', 'Value2', 'Value3', 'Value4')
...