Навигация (Перемещение по записям)
После открытия a таблицы Вы можете перемещаться по записям внутри нее.
Следующий обширный набор методов и свойства TDataSet обеспечивает все , что Вам нужно для доступа к любой конкретной записи внутри таблицы:
procedure First; - перемещение к первой записи в таблице
procedure Last; - перемещение к последней записи в таблице
procedure Next; - перемещение на одну запись вперед
procedure Prior; - перемещение на одну запись Назад
procedure MoveBy(Distance: Integer); - перемещение на N записей вперед или назад в таблице
Table1.MoveBy(1) - то же, что и Table1.Next. Аналогично, Table1.MoveBy(-1) - то же, что и Table1.Prior.
property BOF: Boolean read FBOF;
- read-only свойство, используемое для проверки, находитесь ли Вы в начале таблицы.
property EOF: Boolean read FEOF;
- read-only свойство, используемое для проверки, находитесь ли Вы в конце таблицы.
Свойства BOF возвращает true в трех случаях:
После того, как Вы открыли файл;
После того, как Вы вызывали TDataSet.First;
После того, как вызов TDataSet.Prior не выполняется ( после того, как Вы вызывали метод Prior много раз, Вы могли добраться до начала таблицы, и следующий вызов Prior будет неудачным - после этого BOF и будет возвращать True).
EOF возвращает True в следующих трех случаях:
После того, как Вы открыли пустой файл;
После того, как Вы вызывали TDataSet.Last;
После того, как вызов TDataSet.Next не выполняется.
Пример использования Prior, когда Вы попадаете к началу файла:
while not Table.Bof do begin
DoSomething; // какая-либо ваша выполняемая функция
Table1.Prior;
end;
В коде, показанном здесь, гипотетическая функция DoSomething будет вызвана сперва на текущей записи и затем на каждой следующей записи (от текущей и до начала таблицы). Цикл будет продолжаться до тех пор, пока вызов Table1.Prior не сможет больше переместить Вас на предыдущую запись в таблице. В этот момент BOF вернет True и программа выйдет из цикла. (Чтобы оптимизировать вышеприведенный код, установите DataSource1.Enabled в False перед началом цикла, и верните его в True после окончания цикла.)
Все сказанное относительно BOF также применимо и к EOF. Другими словами, код, приведенный ниже показывает простой способ пробежать по всем записям в a dataset:
Table1.First;
while not Table1.EOF do begin
DoSomething;
Table1.Next;
end;
Классическая ошибка в случаях, подобных этому: Вы входите в цикл while или repeat, но забываете вызывать Table1.Next:
Table1.First;
repeat
DoSomething;
until Table1.EOF;
Если Вы случайно написали такой код, то ваша машина зависнет, и Вы сможете выйти из цикла только нажав Ctrl-Alt-Del и прервав текущий процесс. Также, этот код мог бы вызвать проблемы, если Вы открыли пустую таблицу. Так как здесь используется цикл repeat , DoSomething был бы вызван один раз, даже если бы нечего было обрабатывать. Поэтому, лучше использовать цикл while вместо repeat в ситуациях подобных этой.
Доступ из программы к полям записи
Вы можете использовать одно из следующих свойств или методов, каждый из которых принадлежат TDataSet:
property Fields[Index: Integer];
- доступ по номеру поля (например, для 1-го поля Fields[0]- счет полей начинается с нуля)
function FieldByName(const FieldName: string): TField;
- доступ по имени поля (например, FieldsByName('PL_NUMBER')
property FieldCount; - возвращает число полей в текущей структуре записи
Пример: читаем номера всех полей
var
S: String;
begin
S := Fields[0].FieldName;
end;
Для получения данных, содержащихся в поле, можно использовать одно из следующих свойств:
property AsBoolean
property AsFloat
property AsInteger
property AsString
property AsDateTime
Пример: S := Table1.FieldByName(‘CustNo’).AsString;
Работа с Данными
Нужно учитывать свойство CanModify (оно само ‘read only’) . Если CanModify возвращает True, таблицу можно редактировать или добавлять записи в нее, а если False, то TTable находиться в состоянии ReadOnly.
Если Вы хотите установить DataSet в состояние только на чтение (Read Only), то Вы должны использовать свойство ReadOnly , не CanModify.
Следующие методы позволяют изменять данные, связанные с TTable ( все эти методы - часть TDataSet, они унаследованы и используются TTable и TQuery) :
procedure Edit; - переводит БД в режим редактирования
procedure Post; - изменения в данных записываются на диск
procedure Append; - добавление новой записи в таблицу
procedure Insert; - добавление новой записи в таблицу
Append и Insert аналогичны, хотя предпочтительнее использовать Append для неиндексированной,
а Insert для индексированной таблицы
procedure Cancel; - отмена результатов редактирования (если еще ны был вызван Post)
procedure Delete;
Всякий раз, когда Вы хотите программноизменить данные в TTable, Вы должны сначала перевести DataSet в режим редактирования (большинство визуальных компонент делают это автоматически, и при их использовании об этом не нужно заботиться).
Имеется a типичная последовательность, которую используют при изменении поля текущей записи:
Table1.Edit;
Table1.FieldByName(‘CustName’).AsString := ‘Fred’;
Table1.Post;
Также всякий раз, когда Вы сдвигаетесь с текущей записи, введенные Вами данные будут автоматически записаны на диск. Это означает, что вызовыFirst, Next, Prior иLast всегда выполняют Post , если Вы находились в режиме редактирования. (Если Вы работаете с данными на сервере и транзакциями, тогда правила, приведенные здесь, не применяются. Транзакции - это отдельный вопрос с их собственными специальными правилами).
Например, следующий код делает то же, что и код показанный выше, плюс к этому перемещает на следующую запись:
Table1.Edit;
Table1.FieldByName(‘CustNo’).AsInteger := 1234;
Table1.Next;
Пока метод Post не вызван (напрямую или косвенно), можно отменить результаты редактирования в любое время. Например, если Вы перевели таблицу в режим редактирования, и изменили данные в одном или более полей, Вы можете всегда вернуть запись в исходное состояние вызовом метода Cancel.
Пример:
begin
Table1.Insert; // переводит таблицу в режим вставки (новая запись с незаполненными полями вставляется в текущую позицию dataset)
Table1.FieldByName('Name').AsString := 'Russia';
Table1.FieldByName('Capital').AsString := 'Moscow';
Table1.Post;
end;
Нужно помнить, что просто вставка записи и заполнения ее полей недостаточно для того, чтобы изменить физически данные на диске. Для этого нужно еще вызывать Post. До вызова Post можно отказаться от вставки записи, вызвав Cancel.