Форум: "Начинающим";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];
ВнизTopRow в DBGrid Найти похожие ветки
← →
PZ (2006-11-08 18:44) [0]Здравствуйте.
У меня простейшая база данных из одной таблицы, объемом порядка 2500 записей. Набор данных создается компонентом TClientDataSet и отображается компонентом DBRxGrid.
Мне хотелось бы, чтобы некая запись моей базы по заданному условию отображалась в верхней строчке DBRxGrid (какбы аналог свойства StringGrid.TopRow). Прошу дать практический совет, как реализовать эту задачу, желательно с примером. (Delphi 7)
С уважением, PZ
← →
Jeer © (2006-11-08 18:48) [1]Ввести поле "ONTOP" boolean, присваивать нужной записи значение True и новый select, но это извращение.
← →
PZ (2006-11-08 19:01) [2]А как без извращения? Возможно ли сделать?
← →
Desdechado © (2006-11-08 19:05) [3]отсортируй по этому условию
← →
PZ (2006-11-08 19:22) [4]Нет, немного не так. У меня база отсортирована по алфавиту. Нарушать порядок не желательно. Надо только чтобы заданная строка оказалась в верхней строке. А те, что ниже - остались внизу, те, что выше - остались вверху. После чего мышкой можно было бы сдвигать все строки вверх-вниз без нарушения порядка. То есть, именно, как в SringGrid делается.
← →
evvcom © (2006-11-08 19:31) [5]select
*,
case when <моя строка> then 0 else 1 end as ord
from ...
order by ord, fam
← →
rar © (2006-11-08 19:37) [6]может создать два запроса и объединить их по Union
← →
evvcom © (2006-11-08 19:39) [7]> [6] rar © (08.11.06 19:37)
зачем 2 запроса, если можно одним?
← →
PZ (2006-11-08 19:41) [8]Чувствую, что не совсем то, что мне надо. Видимо простого решения не существует. Тем не менее спасибо всем за участие.
← →
evvcom © (2006-11-08 19:46) [9]> [8] PZ (08.11.06 19:41)
> Чувствую, что не совсем то, что мне надо
Так ты объяснить толком не можешь, чего же тебе надо!
← →
V-A-V © (2006-11-08 22:32) [10]> Ввести поле "ONTOP" boolean, присваивать нужной записи значение True и новый select, но это извращение.
ну почему-же если нельзя и очень хочется, то можно...
создаем поле "isOnTop" и для нухной записи в нухный момент присваеваем ему True, а остальным записям False
> Нет, немного не так. У меня база отсортирована по алфавиту. Нарушать порядок не желательно.
ну и естественно должен быть соответствующий индекс типа "isOnTop;Name"
← →
ЮЮ © (2006-11-09 03:36) [11]Насколько я понял, человек просто хочет спозиционировать датасет в гриде так, чтобы определенная запись оказалось первой в этом гриде.
А текущая какая? В DBgrid-e её присутствие на экране обязательно.
Поэтому, сделав её текущей, она обязательно попадет в Грид. Но, скорей всего, в его середину.
Теперь, обратившись к DBGrid.DataLink (protected), можно узнать на какой строке находится эта запись, и какая запись последняя. Теперь надо сделать текущнй последнюю, сделать MoveBy, вызвав скроллинг НД в гриде, и опять сделать текущей нашу запись, которая будет к этому времени верхней в гриде.
← →
PZ (2006-11-09 10:24) [12]> [11] ЮЮ © (09.11.06 03:36)
> Насколько я понял, человек просто хочет спозиционировать датасет в гриде так, чтобы определенная запись оказалось первой в этом гриде.
Вы действительно правильно поняли меня. Как бы теперь практически реализовать Ваше предложение? Может быть покажите на примере?
С уважением PZ
← →
ЮЮ © (2006-11-09 10:28) [13]
> Как бы теперь практически реализовать Ваше предложение?
По тексту в [11] код. С проблемами вернуться сюда.
Кстати, текущая запись НД отличается от той, что должна быть первой в гриде?
← →
PZ (2006-11-09 10:41) [14][13] ЮЮ © (09.11.06 10:28)
Я вывожу всю свою талицу в DBGrid. Высвечиваются первые 15 записей. Текущая - первая.
Та запись, которая должна быть первой находится где-нибудь на сотом или 321-м месте.
(Что такое НД - я не понимаю).
← →
ЮЮ © (2006-11-09 10:49) [15]НД - набор данных. DBGrid.DataSource.DataSet
> Та запись, которая должна быть первой находится где-нибудь
> на сотом или 321-м месте.
Шаг 1.
Сделать так, чтобы нужная запись оказалась на экране:
DBGrid.DataSource.DataSet.Locate(<ключевое поле>, <значение>, []);
Появилась в гриде?
← →
PZ (2006-11-09 11:08) [16]Нет. Остаются первые 15 строчек вверху.
← →
ЮЮ © (2006-11-09 11:10) [17]
> Нет. Остаются первые 15 строчек вверху.
А никто этого на Шаг 1. и не обещал.
Вопрос был: Появилась в гриде?
← →
PZ (2006-11-09 11:16) [18]Нет. Я же сказал, остаются первые 15 строчек вверху, а искомая запись где-то далеко внизу.
← →
ЮЮ © (2006-11-09 11:19) [19]Тогда код приведи и в каком обработчике написано
← →
ЮЮ © (2006-11-09 11:32) [20]Ушел за кодом и не вернулся :)
← →
PZ (2006-11-09 11:41) [21]Код очень большой. Даю две характерные, на мой взгляд, процедуры:
procedure TTV_ViewerFrm.FormCreate(Sender: TObject);
begin
Try
ReadIniFile(); // Здесь получаю имя файла FileName
ClientDataSet1.LoadFromFile(ClientDataSet1.FileName);
ClientDataSet1.Open;
// DBGrid.DataSource.DataSet.Locate(Nachalo, "12:00", []); // Сюда вставлял
Except
MessageDlg(...);
End;
Init; // Здесь некоторые начальные условия
end; { TTV_ViewerFrm.FormCreate }
procedure TTV_ViewerFrm.PnButClick(Sender: TObject);
Var
S : String;
begin
If (Sender is TLbSpeedButton) then
begin
S := GetPoDate; // Здесь выборка по дате
ClientDataSet1.Filter := S;
ClientDataSet1.Filtered := True;
// Сортировать по номеру и началу
ClientDataSet1.IndexFieldNames := "Nomer; Nachalo";
DBGrid.DataSource.DataSet.Locate(Nachalo, "12:00", []); // Сюда вставил
DBGrid.Refresh;
end;
end; { TTV_ViewerFrm.PnButClick }
← →
PZ (2006-11-09 11:51) [22]Delphi 7, Win XP.
На форме DBRxGrid, DataSource, ClientDataSet
← →
ЮЮ © (2006-11-09 12:16) [23]// Сюда вставлял
Для начала напиши как обработчик на нажатие кнопки. После отладки вставляй этот метод куда хочешь.
Тип поля Nachalo?
Вот код, который делает то, что надо:type TDBGridAccess = class(TDBGrid); // для доступа к protected св-вам
procedure TForm1.Button1Click(Sender: TObject);
var
code: integer;
delta: integer;
locateRow: integer;
totalRow: integer;
begin
code := StrToIntDef(Edit1.Text, -1);
Query1.Locate("Code", code, []);
locateRow := TDBGridAccess(DBGrid1).DataLink.ActiveRecord;
totalRow := TDBGridAccess(DBGrid1).DataLink.RecordCount;
delta := totalRow - 1;
Query1.MoveBy(delta); // "текущая" запись станет первой в гриде
if not Query1.EOF then
Query1.MoveBy(-delta) // делаем её текущей
else
Query1.MoveBy(-totalRow + locateRow + 1); // делаем её текущей
end;
← →
ЮЮ © (2006-11-09 12:27) [24]Побочный эффект: если запись не найдена, то текущая запись становится верхней в гриде.
Для избежания надо
if Query1.Locate("Code", code, []) then begin
...
end;
← →
PZ (2006-11-09 12:29) [25]Тип поля Nachalo? - String
ЮЮ, спасибо за помощь. Буду разбираться с Вашим кодом. Сожалею, что Вам пришлось потратить столько времени на меня.
С уважением PZ
← →
evvcom © (2006-11-09 14:35) [26]> [11] ЮЮ © (09.11.06 03:36)
Телепат?
> [12] PZ (09.11.06 10:24)
> Вы действительно правильно поняли меня.
Телепат!
:-))))))))
← →
PZ (2006-11-09 15:51) [27]Моя база данных содержится в файле типа .cds. Компонент Query ее не понимает.
Я записал обработчик с использованием ClientDataSet.
После запуска моей программы при нажатии на Button1 возникает ошибка со следующим сообщением:
Project TV_Viewer.exe raised exception class EAccessViolation with message "Access Violation at address 00407816 in module "TV_Viewer.exe". Read address 00000030". Process stoped....
Не могу понять в чем причина. Что делать?
type TDBGridAccess = class(TDBGrid); // для доступа к protected св-вам
procedure TTV_ViewerFrm.Button1Click(Sender: TObject);
var
MyCode : String[5];
code : integer;
delta : integer;
locateRow : integer;
totalRow : integer;
begin
MyCode := "15:45";
ClientDataSet1.DataSource.DataSet.Locate("Nachalo", MyCode, []); // Здесь ошибка
// Поле "Nachalo" типа String, Size = 5
locateRow := TDBGridAccess(DBGrid).DataLink.ActiveRecord;
totalRow := TDBGridAccess(DBGrid).DataLink.RecordCount;
delta := totalRow - 1;
ClientDataSet1.DataSource.DataSet.MoveBy(Delta);
if not ClientDataSet1.EOF then
ClientDataSet1.DataSource.DataSet.MoveBy(-Delta) // делаем её текущей
else
ClientDataSet1.DataSource.DataSet.MoveBy(-totalRow + locateRow + 1); // делаем её текущей
{
type TDBGridAccess = class(TDBGrid); // для доступа к protected св-вам
procedure TForm1.Button1Click(Sender: TObject);
var
code: integer;
delta: integer;
locateRow: integer;
totalRow: integer;
begin
code := StrToIntDef(Edit1.Text, -1);
Query1.Locate("Code", code, []);
locateRow := TDBGridAccess(DBGrid1).DataLink.ActiveRecord;
totalRow := TDBGridAccess(DBGrid1).DataLink.RecordCount;
delta := totalRow - 1;
Query1.MoveBy(delta); // "текущая" запись станет первой в гриде
if not Query1.EOF then
Query1.MoveBy(-delta) // делаем её текущей
else
Query1.MoveBy(-totalRow + locateRow + 1); // делаем её текущей
end;
}
end;
← →
Anatoly Podgoretsky © (2006-11-09 16:05) [28]> cds сокращение от ClientDataSet.
По ошибке, что то не создано.
← →
PZ (2006-11-09 16:20) [29]> [28] Anatoly Podgoretsky © (09.11.06 16:05)
Что может быть не создано? Все же остальное работает, если не нажимать эту кнопку.
← →
Anatoly Podgoretsky © (2006-11-09 16:31) [30]> PZ (09.11.2006 16:20:29) [29]
А кто его знает, тут есть неизвестные переменные.
Но сообщение точно говорит, что, что-то не создано.
У тебя отладчик есть? Воспользуйся. Укажи строку где возникает ошибка.
← →
PZ (2006-11-09 16:34) [31]Вот именно в отладчике это сообщение и возникает
← →
Anatoly Podgoretsky © (2006-11-09 16:44) [32]> PZ (09.11.2006 16:34:31) [31]
Скриншот в студию, что бы был виден номер строки.
← →
PZ (2006-11-09 16:56) [33]Наконец я сообразил, в чем дело.
Надо не ClientDataSet1 задействовать, а DBGrid, т. е. должно быть
ClientDataSet1.DataSource.DataSet.Locate("Nachalo", MyCode, []); // Здесь ошибка
DBGrid.DataSource.DataSet.Locate("Nachalo", MyCode, []); // Здесь и далее нет ошибки
Спасибо Anatoly Podgoretsky
Еще раз спасибо ЮЮ
Спасибо всем, принимавшим участникам обсуждения моего вопроса
С уважением, PZ
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.039 c