В идеале вы должны переписать свой код как
YsDbQuerySelect.Open;
while not YsDbQuerySelect.eof do begin
// making a file... code removed, not relevant
YsDbQuerySelect.Next;
end;
YsDbQuerySelect.Close;
. Причина в том, что
if YsDbQuerySelect.RecordCount > 0 then begin
YsDbQuerySelect.First
совершенно не требуется, потому что: а) если запрос возвращает ноль записей, YsDbQuerySelect.eof
немедленно вернет значение False, поэтому while
l oop никогда не выполнится и б) если запрос действительно вернет какие-либо записи, курсор набора данных FDQuery будет на первой записи, поэтому вызов значение First
является излишним.
В любом случае, в целом плохая практика - делать поведение набора данных, подобное TQuery, зависимым от его переменной RecordCount
, поскольку оно может быть ненадежным и крайне неэффективным, поскольку может вызвать набор данных для извлечения всех совпадающих записей.
Если вам абсолютно необходимо проверить, что запрос возвращает записи и, если это не так, отправить сообщение пользователю, просто замените
if YsDbQuerySelect.RecordCount > 0 then begin // I get 6 records here
YsDbQuerySelect.First; // ********** Exception !
[etc]
на
if not YsDbQuerySelect.Eof then begin
// your while not eof loop
end
else begin
MesInfo('No data to send');
end;
Кстати, я не думаю, что вы должны рассматривать то, что вы описываете в своем собственном ответе, как решение проблемы, потому что если поведение, которое вы получаете, так как из-за повреждения файла .DFM (в чем я сомневаюсь), это может так же легко произойти снова.