Поделиться через


Работа с наборами записей

Область применения: Access 2013, Office 2013

Объект Recordset имеет встроенные функции, позволяющие изменять порядок данных в результирующем наборе, искать определенную запись на основе заданных вами критериев и даже оптимизировать эти операции поиска с помощью индексов. Доступны ли эти функции для использования, зависит от поставщика, а в некоторых случаях (например, от свойства Index ) зависит от структуры самого источника данных.

Упорядочение данных

Часто наиболее эффективным способом упорядочивания данных в наборе записей является указание предложения ORDER BY в команде SQL, используемой для возврата результатов. Однако может потребоваться изменить порядок данных в уже созданном наборе записей . С помощью свойства Sort можно установить порядок, в котором проходят строки набора записей . Кроме того, свойство Filter определяет, какие строки доступны при обходе строк.

Свойство Sort задает или возвращает строковое значение, указывающее имена полей в наборе записей , по которым выполняется сортировка. Каждое имя отделяется запятой и при необходимости следует пробел и ключевое слово ASC (который сортирует поле по возрастанию) или DESC (который сортирует поле в порядке убывания). По умолчанию, если ключевое слово не указан, поле сортируется по возрастанию.

Операция сортировки эффективна, так как данные физически не переупорядочены, а просто обращаются в порядке, указанном индексом.

Свойство Sort требует, чтобы свойство CursorLocation было задано как adUseClient. Для каждого поля, указанного в свойстве Sort , будет создан временный индекс, если индекс еще не существует.

Если для свойства Sort задана пустая строка, строки будут сброшены в исходном порядке и будут удалены временные индексы. Существующие индексы не будут удалены.

Предположим, что набор записей содержит три поля с именами firstName, middleInitial и lastName. Присвойте свойству Sort строку "", которая упорядочит набор записей по фамилии в порядке убывания, а затем по имени по возрастанию. Средний инициал игнорируется.

Поле, на которые ссылается строка условий сортировки, не может называться "ASC" или "DESC", так как эти имена конфликтуют с ключевыми словами ASC и DESC. Присвойте поле с конфликтующим именем псевдоним с помощью ключевое слово AS в запросе, который возвращает набор записей.

Дополнительные сведения о фильтрации наборов записей см. в разделе Фильтрация результатов далее в этом разделе.

Поиск определенной записи

ADO предоставляет методы Find и Seek для поиска определенной записи в наборе записей. Метод Find поддерживается различными поставщиками, но ограничен одним условием поиска. Метод Seek поддерживает поиск по нескольким критериям, но не поддерживается многими поставщиками.

Индексы полей могут значительно повысить производительность свойств метода Find объекта Recordset и Сортировки и Фильтра. Вы можете создать внутренний индекс для объекта Field , задав его динамическое свойство Optimize . Это динамическое свойство добавляется в коллекцию Свойств объекта Field, если для свойства CursorLocation задано значение adUseClient. Помните, что этот индекс является внутренним для ADO— вы не можете получить к нему доступ или использовать его для каких-либо других целей. Кроме того, этот индекс отличается от свойства Index объекта Recordset.

Метод Find быстро находит значение в столбце (поле) набора записей. Часто можно повысить скорость операции метода Find для столбца с помощью свойства Optimize для создания индекса.

Метод Find ограничивает поиск содержимым одного поля. Метод Seek требует наличия индекса и других ограничений. Если вам нужно выполнить поиск по нескольким полям, которые не являются основой индекса, или если поставщик не поддерживает индексы, можно ограничить результаты с помощью свойства Filter объекта Recordset .

Поиск

Метод Find выполняет поиск строки, удовлетворяющей указанному критерию, в наборе записей . При необходимости можно указать направление поиска, начальную строку и смещение от начальной строки. Если условие выполнено, текущая позиция строки устанавливается для найденной записи; В противном случае позиция устанавливается в конце (или начале) набора записей в зависимости от направления поиска.

Для критерия можно указать только имя одного столбца. Другими словами, этот метод не поддерживает поиск по нескольким столбцам.

Оператор сравнения для критерия может быть ">" (больше), "<" (меньше чем), "=" (равно), ">=" (больше или равно), "<=" (меньше или равно), "<>" (не равно) или "LIKE" (сопоставление шаблонов).

Значение условия может быть строкой, числом с плавающей запятой или датой. Строковые значения разделяются одними кавычками или знаками "#" (числовой знак) (например, "state = "WA" или "state = #WA#"). Значения даты разделяются знаками "#" (числовой знак) (например, "start_date > #22/97#").

Если оператор сравнения имеет значение like, строковое значение может содержать звездочку (*) для поиска одного или нескольких вхождений любого символа или подстроки. Например, "состояние, как "M*"" соответствует штату Мэн и Массачусетс. Вы также можете использовать начальные и конечные звездочки для поиска подстроки, содержащейся в значениях. Например, "состояние, подобное "*as*"" соответствует Аляске, Арканзасу и Массачусетсу.

Звездочки можно использовать только в конце строки условия или вместе в начале и в конце строки условия, как показано выше. Звездочка не может использоваться в качестве подстановочного знака ('*str') или внедренного подстановочного знака ('s*r'). Это приведет к ошибке.

Поиск и индекс

Используйте метод Seek в сочетании со свойством Index, если базовый поставщик поддерживает индексы в объекте Recordset . Используйте метод Supports(adSeek), чтобы определить, поддерживает ли базовый поставщик поиск, и метод Supports(adIndex), чтобы определить, поддерживает ли поставщик индексы. (Например, поставщик OLE DB для Microsoft Jet поддерживает поиск и индекс.)

Если поиск не находит нужную строку, ошибка не возникает, и строка размещается в конце набора записей. Перед выполнением этого метода задайте для свойства Index нужный индекс.

Этот метод поддерживается только с серверными курсорами. Поиск не поддерживается, если значение свойства CursorLocation объекта Recordset имеет значение adUseClient.

Этот метод можно использовать, только если объект Recordset открыт со значением CommandTypeEnumadCmdTableDirect.

Фильтрация результатов

Метод Find ограничивает поиск содержимым одного поля. Метод Seek требует наличия индекса и других ограничений. Если вам нужно выполнить поиск по нескольким полям, которые не являются основой индекса, или если поставщик не поддерживает индексы, можно ограничить результаты с помощью свойства Filter объекта Recordset .

Используйте свойство Filter для выборочного отображения записей в объекте Recordset . Отфильтрованный набор записей становится текущим курсором, что означает, что записи, которые не соответствуют условиям фильтра , недоступны в наборе записей до удаления фильтра . Затрагиваются другие свойства, возвращающие значения на основе текущего курсора, например AbsolutePosition, AbsolutePage, RecordCount и PageCount. Это связано с тем, что задание свойства Filter определенного значения приведет к перемещению текущей записи в первую запись, удовлетворяющую новому значению.

Свойство Filter принимает аргумент variant. Это значение представляет один из трех методов использования свойства Filter : строку условия, константу FilterGroupEnum или массив закладок. Дополнительные сведения см. в разделах Фильтрация со строкой условий, Фильтрация с константой и Фильтрация с помощью закладок далее в этом разделе.

Примечание.

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

Чтобы удалить фильтр из набора записей, используйте константу adFilterNone . Установка для свойства Filter значения строки нулевой длины ("") имеет тот же эффект, что и использование константы adFilterNone .

Фильтрация по строке условия

Строка условия состоит из предложений в формате FieldName Operator Value (например, LastName = 'Smith'). Составные предложения можно создавать путем объединения отдельных предложений с помощью and (например, LastName = 'Smith' AND FirstName = 'John'") и OR (например, ). Составные предложения можно создавать путем объединения отдельных предложений с помощью and (например, LastName = 'Smith' AND FirstName = 'John'") и OR (например, LastName = 'Smith' OR LastName = 'Jones'). Используйте следующие рекомендации для строк условий.

  • FieldName должно быть допустимым именем поля из набора записей. Если имя поля содержит пробелы, необходимо заключить имя в квадратные скобки.

  • Оператор должен иметь один из следующих значений: <, >, <=, >=, <>, =или LIKE.

  • Value — это значение, с которым вы будете сравнивать значения полей (например, "Smith", #8/24/95#, 12,345 или 50,00 долл. США). Используйте одинарные кавычки (') со строками и знаки фунта (#) с датами. Для чисел можно использовать десятичные знаки, знаки доллара и научные нотации. Если оператор имеет значение LIKE, значение может использовать подстановочные знаки. Допускаются только подстановочные знаки звездочки (*) и знака процента (%) и они должны быть последним символом в строке. Значение не может иметь значение NULL.

    Примечание.

    Чтобы включить одинарные кавычки (') в значение фильтра, используйте две одинарные кавычки, которые представляют одну. Например, для фильтрации по О'Мэлли строка условий должна иметь значение "col1 = 'O''Malley'".

    Чтобы включить одинарные кавычки как в начале, так и в конце значения фильтра, заключите строку в знаки фунта (#). Например, для фильтрации по "1", строка условия должна быть "col1 = #'1'#".

Приоритет между AND и OR отсутствует. Предложения можно группировать в круглые скобки. Однако нельзя группировать предложения, присоединенные с помощью OR, а затем присоединить группу к другому предложению с помощью И, как показано ниже:

 
(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John' 

Вместо этого этот фильтр следует создать следующим образом:

 
(LastName = 'Smith' AND FirstName = 'John') OR (LastName = 'Jones' AND FirstName = 'John') 

В предложении LIKE можно использовать подстановочный знак в начале и конце шаблона (например, LastName Like '*mit*') или только в конце шаблона (например, ) или только в конце шаблона (например, LastName Like 'Smit*').

Фильтрация с константой

Для фильтрации наборов записей доступны следующие константы.

Константа

Описание

adFilterAffectedRecords

Фильтры для просмотра только записей, выполняемых последним вызовом Delete, Resync, UpdateBatch или CancelBatch .

adFilterConflictingRecords

Фильтры для просмотра записей, которые завершили сбой последнего пакетного обновления.

adFilterFetchedRecords

Фильтры для просмотра записей в текущем кэше, то есть результатов последнего вызова для получения записей из базы данных.

adFilterNone

Удаляет текущий фильтр и восстанавливает все записи для просмотра.

adFilterPendingRecords

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

Константы фильтра упрощают разрешение конфликтов отдельных записей в режиме пакетного обновления, позволяя просматривать, например, только те записи, которые были созданы во время последнего вызова метода UpdateBatch , как показано в следующем примере:

 
'BeginDeleteGroup 
    'add some bogus records 
    With objRs1 
        For i = 0 To 8 
            .AddNew 
            .Fields("CompanyName") = "Shipper Number " & i + 1 
            .Fields("Phone") = "(425) 555-000" & (i + 1) 
            .Update 
        Next i 
         
    're-connect & update 
        .ActiveConnection = GetNewConnection 
        .UpdateBatch 
         
    'filter on newly added records 
        .Filter = adFilterAffectedRecords 
        Debug.Print "Deleting the " & .RecordCount & _ 
                    " records you just added." 
         
    'delete the newly added bogus records 
        .Delete adAffectGroup 
        .Filter = adFilterNone 
        Debug.Print .RecordCount & " records remain." 
         
        .Close 
    End With 
'EndDeleteGroup 

Фильтрация по закладкам

Наконец, можно передать массив вариантов закладок в свойство Filter . Результирующий курсор будет содержать только те записи, закладка которых была передана в свойство . В следующем примере кода создается массив закладок на основе записей в наборе записей , имеющих значение "B" в поле ProductName . Затем он передает массив в свойство Filter и отображает сведения о результирующей отфильтрованной наборе записей.

 
'BeginFilterBkmk 
    Dim vBkmkArray() As Variant 
    Dim i As Integer 
 
    'Recordset created using "SELECT * FROM Products" as command. 
    'So, we will check to see if ProductName has a capital B, and 
    'if so, add to the array. 
    i = 0 
    Do While Not objRs.EOF 
        If InStr(1, objRs("ProductName"), "B") Then 
            ReDim Preserve vBkmkArray(i) 
            vBkmkArray(i) = objRs.Bookmark 
            i = i + 1 
            Debug.Print objRs("ProductName") 
        End If 
        objRs.MoveNext 
    Loop 
     
    'Filter using the array of bookmarks. 
    objRs.Filter = vBkmkArray 
     
    objRs.MoveFirst 
    Do While Not objRs.EOF 
        Debug.Print objRs("ProductName") 
        objRs.MoveNext 
    Loop 
    'EndFilterBkmk 

Создание клона набора записей

Метод Clone используется для создания нескольких повторяющихся объектов Recordset , особенно если требуется сохранить несколько текущих записей в заданном наборе записей. Использование метода Clone эффективнее, чем создание и открытие нового объекта Recordset с тем же определением, что и исходный.

Для текущей записи созданного клона изначально устанавливается первая запись. Текущий указатель записи в клонированном наборе записей не синхронизируется с исходным или наоборот. Вы можете перемещаться по каждому набору записей независимо.

Изменения, внесенные в один объект Recordset, видны во всех его клонах независимо от типа курсора. Однако после выполнения запроса в исходном наборе записей клоны больше не будут синхронизированы с исходным.

При закрытии исходного набора записей не закрываются его копии, а также не закрываются исходные или другие копии.

Клонировать объект Recordset можно только в том случае, если он поддерживает закладки. Значения закладок являются взаимозаменяемыми; то есть ссылка на закладку из одного объекта Recordset ссылается на одну и ту же запись в любом из ее клонов.