Распечатать страницу

Поиск и перемещение в таблице VFP

« Назад

Команды

GO [RECORD] nRecordNumber [IN nWorkArea | cTableAlias]

или

GO TOP | BOTTOM [IN nWorkArea | cTableAlias]

или

GOTO [RECORD] nRecordNumber [IN nWorkArea | cTableAlias]

или

GOTO TOP | BOTTOM [IN nWorkArea | cTableAlias]

перемещают файловый указатель таблицы (текущей или указанной параметром nWorkArea | cTableAlias) на запись, имеющую заданный номер, или на начало или конец таблицы.

RECORD nRecordNumber – физический номер записи, на которой позиционируется таблица. Если номер превышает число записей таблицы, то VFP генерирует ошибку "Record is out of range".

TOP – позиционирует таблицу на ее первой записи. Если установлен возрастающий управляющий индекс, то первой является запись с наименьшим значением ключа, если – убывающий, то – с наибольшим. Если таблица используется без управляющего индекса, то первой является запись с номером 1. То есть команды GO 1 и GO TOP равноценны. При наличии управляющего индекса в общем случае GO 1 и GO TOP дают разные результаты.

Пример:

close databases

open database d:\HomeLibrary\HomeLibrary.dbc

&&

&& Управляющий индекс – AuthorId

use Authors order AuthorId

go top in Authors

? Recno('Authors')              && Возможный ответ: 7

go 1 in Authors

? Recno('Authors')              && Возможный ответ: 1

BOTTOM - позиционирует таблицу на ее последней записи. Если установлен возрастающий управляющий индекс, то последней является запись с наибольшим значением ключа, если – убывающий, то – с наименьшим. Если таблица используется без управляющего индекса, то послендней является запись с номером RECCOUNT( ).

Команда

SKIP [nRecords] [IN nWorkArea | cTableAlias]

перемещает таблицу вперед или назад.

Параметр:

nRecords – число записей, на которое перемещается файловый указатель. Если параметр опущен, но выполняется переход на следующую запись. Перемещение выполняется по направлению к концу файла, если nRecords > 0, и к началу файла, если  nRecords < 0.

Если SKIP уведет таблицу в конец файла, то RECNO( ) вернет RCCOUNT( ) + 1, а EOF( ) – .T. Если SKIP переместит таблицу в начало файла, то RECNO( ) вернет 1, а BOF( ) – .T.

Если таблица имеет управляющий индекс (тег или индексный IDX-файл), то SKIP перемещает таблицу, используя порядок, заданный этим индексом.

Команда

SCAN [NOOPTIMIZE] [Scope] [FOR lExpression1] [WHILE lExpression2]
                   [Commands]
                   [LOOP]
                   [EXIT]
         ENDSCAN

перемещает файловый указатель в текущей таблице, выполняя помещенную между SCAN и ENDSCAN последовательность операторов Commands для каждой записи таблицы, удовлетворяющей заданным условиям.

Рассматриваемая команда является конструкцией команд SCAN и ENDSCAN, которая может содержать команды LOOP и EXIT.

Команды (опции и параметры см. в табл. 1.7):

LOOP – команда, передающая контроль команде SCAN.

EXIT – команда, обеспечивающая выход из конструкции SCAN…ENDSCAN.

ENDSCAN – команда, завершающая конструкцию SCAN…ENDSCAN.

Замечание. VFP при достижении команды ENDSCAN автоматически выбирает таблицу, которая была текущей перед началом выполнения команды SCAN. Таким образом, внутри конструкции SCAN…ENDSCAN можно выбирать по мере необходимости нужную рабочую область, не помещая непосредственно перед ENDSCAN команду выбора таблицы, которой оперирует команда SCAN.

Пример 1. Просматривается таблица Authors, упорядоченная по коду автора (поле AuthorId). Печатаются фамилии авторов с четными кодами. Печать прекращается, когда код превысит число 20.

close databases

open database 'd:\HomeLibrary\HomeLibrary'

use Authors order tag AuthorId

select Authors

scan for Mod(AuthorId, 2) = 0 while AuthorId <= 20

? Author                             && Печатаем поле Author таблицы Authors

endscan

Тот же результат обеспечивается следующим кодом, содержащим команды DO WHILE ... ENDDO и SKIP.

use Authors order tag AuthorId

select Authors

do while AuthorId <= 20 and not Eof( )

if Mod(AuthorId, 2) = 0 then

? Author                             && Печатаем поле Author таблицы Authors

endif

skip

enddo

Пример 2. Выводятся названия книг. Для каждой книги печатаются имеющиеся в ней произведения.

close databases

open database 'd:\HomeLibrary\HomeLibrary'

use Books order tag Book in 0

use BooksContent order tag BookId in 0

select Books

scan

? Book                                && Печатаем название книги

select BooksContent

if Seek(Books.BookId) then

    scan for BooksContent.BookId = Books.BookId

&& Chr(9) – символ табуляции

    ? Chr(9) + Name                       && Печатаем название произведения

endscan

else

    ? Chr(9) + "Произведения не указаны"

endif

&& Автоматически выбирается таблица Books

endscan

Возможный результат:

Волчьи песни

Произведения не указаны

Дочь Ивана, мать Ивана (повесть). Рассказы

Дочь Ивана, Мать Ивана

В ту же землю

Нежданно-негаданно

Команда

LOCATE [FOR lExpression1] [Scope] [WHILE lExpression2] [NOOPTIMIZE]

выполняет поиск в текущей таблице первой записи, отвечающей логическому выражению lExpression1.

Файл позиционируется на найденной записи, или в конце, если запись не найдена.

Таблица, в которой выполняется поиск, может быть неиндексированной. В этом случае выполняется последовательный поиск.

Опции и параметры описаны в табл. 1.7.

При задании в FOR условия поиска следует, по возможности, употреблять оптимизируемое выражение lExpression1. Тогда в запросе, создаваемом LOCATE, будет использована рашмор-оптимизация.

Команда LOCATE работает быстрее, чем использование SET FILTER с тем же условием, что и в LOCATE, и GO TOP.

Номер найденной записи возвращает RECNO( ). Если запись найдена, то FOUND( ), если вызвана, вернет .T., если не найдена, то – .F. При этом функция EOF( ) вернет .T., а RECNO( ) – число записей в таблице + 1.

Если SET TALK установлен в ON, то после удачного поиска в статус-строке отобразится номер найденной записи, при неудаче – сообщение "End of Locate scope".

Последующие, отвечающие заданным LOCATE условиям, записи находятся командой CONTINUE.

Функции LOCATE и CONTINUE осуществляют поиск в текущей рабочей области. Если в ней нет открытой таблицы, то возникнет диалог Open.

Пример. Печатаются фамилии всех авторов, начинающиеся с буквы Л, таблицы Authors, открытой без управляющего индекса.

close databases

open database d:\HomeLibrary\HomeLibrary.dbc

use Authors

select Authors

oldExact = Set('EXACT')

set exact off

locate for Author = 'Л'

if not Found( ) then

MessageBox('Нет авторов с фамилией, начинающейся с буквы Л')

else

do while Found( )

? Authors.Author

continue

enddo

endif

&& Используем макроподстановку

set exact &oldExact

Команда

CONTINUE

продолжает поиск, начатый предшествующей командой LOCATE.

Команда перемещает файл на следующую запись, отвечающую логическому выражению, заданному в команде LOCATE. Функция FOUND( ), если вызвана, вернет .T.

Если же такой записи больше не имеется, то файловый указатель устанавливается в конце файла. Функция EOF( ), если вызвана, вернет в такой ситуации .T., функция FOUND( ) – .F., функция RECNO( ) – число записей в таблице + 1.

Пример см. в описании команды LOCATE

Команда

SEEK eExpression [ORDER nIndexNumber | IDXIndexFileName
                  
| [TAG] TagName [OF CDXFileName]

                   [ASCENDING | DESCENDING]] [IN nWorkArea | cTableAlias]

ищет в индексированной таблице запись, значение индексного выражения которой отвечает eExpression.

Файл позиционируется либо на найденной записи, либо в конце файла, если запись не обнаружена. Если запись найдена, то функция FOUND( ) , если вызвана, вернет .T.; если не найдена, то – .F. При этом функция EOF( ) вернет .T.

На результаты поиска влияет установка команды SET NEAR, а также команды SET EXACT: совпадение должно быть полным, если SET EXACT установлен в ON.

Опции и параметры:

eExpression – искомое значение индексного ключа.

nIndexNumber – позиция в списке открытых индексных IDX-файлов и CDX-файлов, по которой выбирается индекс или тег. Порядок нумерации индексов и тегов см. в описании команды SET ORDER.

ORDER IDXIndexFileName – имя IDX-файла, в котором ищется eExpression.

ORDER [TAG] TagName – имя тега, в котором ищется eExpression.

OF CDXFileName – имя CDX-файла, которому принадлежит тег TagName. Опция употребляется, если в разных CDX-файлах таблицы имеются одноименные теги.

Если имеются совпадающие имена IDX-файла и тега, то приоритет имеет IDX-файл.

Если параметр nIndexNumber | IDXIndexFileName | TagNamee опущен, то берется управляющий индекс. Если его нет, то VFP генерирует ошибку.

Если параметр nIndexNumber | IDXIndexFileName | TagNamee имеется, то берется индекс (тег), определяемый этим параметром.

ASCENDING – задает поиск в возрастающем порядке: первоначально ищется первый ключ, отвечающей eExpression.

DESCENDING – задает поиск в убывающем порядке: первоначально ищется последний ключ, отвечающей eExpression.

Пример. Печатаются фамилии всех авторов, начинающиеся с буквы Л, таблицы Authors, открытой с управляющим тегом Author.

close databases

open database d:\HomeLibrary\HomeLibrary.dbc

use Authors order Author

select Authors

set exact off

seek 'Л'

if Found( ) then

&& Записи обрабатываются в порядке, определяемом тегом Author

&& Перемещаемся по записям, поле Author которых начинается с буквы Л

do while Authors.Author = 'Л' and not Eof( )

? Authors.Author

skip

enddo

else

MessageBox('Нет авторов с фамилией, начинающейся с буквы Л')

endif

Команда

SET NEAR ON | OFF

определяет положение файла (таблицы) после неудачного поиска, выполненного командой SEEK.

Опции:

ON – таблица позиционируется на ближайшей схожей записи, если поиск, выполненный SEEK, неудачен. Функции FOUND( ) и EOF( ), если их употребить после поиска, вернут .F.

OFF – (по умолчанию) таблица позиционируется в конце, если поиск, выполненный SEEK неудачен. Функции FOUND( ) и EOF( ), если их употребить после поиска, вернут соответственно .F. и .T.

Замечание. Функция RECNO(0), вызванная после SEEK, вернет номер ближайшей схожей записи независимо от установки SET NEAR. Если, однако, такая запись не найдена, RECNO(0) вернет 0, а вызов GO RECNO(0) приведет к генерации ошибки.

Установка SET NEAR сохраняется с текущей сессией данных.