TBookmark
Напомню коды, осуществляющие изменение цвета.
if( RxCheckListBox1->Checked[ RxCheckListBox1->ItemIndex ] ){
TR = RxCheckListBox1->Items->Strings[RxCheckListBox1->ItemIndex];
DBGridEh2->OnGetCellParams = DBGridEh2GetCellParams;
DBGridEh2->Refresh(); }
}
С помощью события DBGridEh2GetCellParams меняется фон и цвет шрифта у этих записей (но индикатор остается прежним).
for(int i = 0;i < RxCheckListBox1->Items->Count;i++)
{
if(RxCheckListBox1->Checked)
if(Eh_Oper->DataSource->DataSet->FieldByName("GostID")->AsString.Trim().SubString(1,2) == RxCheckListBox1->Items->Strings)
{
AFont->Color = clRed;
Background = TColor(0x00C6FFFF);
break;
}
}
}
Для выделения записей был совет использовать закладку.
TBookmark SavePlace;
ds = DBGridEh2->DataSource->DataSet;
SavePlace = ds->GetBookmark();
ds->FindPrior();
ds->GotoBookmark(SavePlace);
ds->FreeBookmark(SavePlace);
Тема для меня новая, поэтому не соображу, куда нужно всунуть закладку. Причем, как-то нужно создать массив закладок, а потом их вытаскивать.
Мне нужно, чтобы записи, отмеченные по ЧекЛистБоксу стали выделенными (как если бы применялось событие DBGridEh2DrawColumnCell) и можно было бы задать условие if (DBGridEh2->SelectedRows->Count > 0) (в данном случае это условие не работает).
Если быть откровенной, то с этим вопросом так намучалась, что хотелось бы, чтобы нашелся добрый человек и разжевал все "по полочкам".:)
Прошу извинить, что в который раз обращаюсь с этим же вопросом, но для меня он оказался крайне сложным. Причем, на 2-х форумах никаких мыслей по поводу темы не высказывали. И только на этом помогли. Поэтому прошу снова помочь разобраться с вопросом до конца. Напомню суть дела: мне нужно, чтобы при нажатии на Item ЧекЛистБокса у блока записей в таблице Грид менялся цвет фона и шрифта, и в дальнейшем с записями можно было работать как с выделенными.
Напомню коды, осуществляющие изменение цвета.
С помощью события DBGridEh2GetCellParams меняется фон и цвет шрифта у этих записей (но индикатор остается прежним).
Для выделения записей был совет использовать закладку.
Тема для меня новая, поэтому не соображу, куда нужно всунуть закладку. Причем, как-то нужно создать массив закладок, а потом их вытаскивать.
Мне нужно, чтобы записи, отмеченные по ЧекЛистБоксу стали выделенными (как если бы применялось событие DBGridEh2DrawColumnCell) и можно было бы задать условие if (DBGridEh2->SelectedRows->Count > 0) (в данном случае это условие не работает).
Если быть откровенной, то с этим вопросом так намучалась, что хотелось бы, чтобы нашелся добрый человек и разжевал все "по полочкам".:)
TBookmark* SavePlace;
//После открытия таблицы
SavePlace = new Tbookmark [Table->RecCount]; //Это мы заводим массив закладок
//При обработке CellParam
TDBGridEh * Eh_Oper = (TDBGridEh *)Sender;
for(int i = 0;i < RxCheckListBox1->Items->Count;i++)
{
if(RxCheckListBox1->Checked)
if(Eh_Oper->DataSource->DataSet->FieldByName("GostID")->AsString.Trim().SubString(1,2) == RxCheckListBox1->Items->Strings)
{
AFont->Color = clRed;
Background = TColor(0x00C6FFFF);
//сюда добавляем закладку.
SavePlace[Eh_Oper->DataSource->DataSet->RecNo] = Eh_Oper->DataSource->DataSet->GetBookmark();
break;
}
else
SavePlace[Eh_Oper->DataSource->DataSet->RecNo] = NULL;
}
}
//При копировании выделенных записей в другую таблицу
TDBGridEh* Eh_Oper = (TDBGridEh *)Sender;
TDataSet* ds = Eh_Oper->DataSource->DataSet;
for(i = 0;i < ds->RecNum;i++)
{
if(SavePlace != NULL)
{
ds->GotoBookmark(SavePlace);
//ds теперь указывает на запись, заложенную закладкой
//т.е. она вроде как selected.
//и ее можно копировать
}
}
[COLOR=blue]for(i = 0;i < ds->RecNum;i++)[/COLOR] . Вообще, наверное не RecNum, а RecNo?
Дальше этой фразы код не выполняется.
Я на событие кнопки вставила код:
[COLOR=blue]void __fastcall TFormCard::Button1Click(TObject *Sender)
{
TDBGridEh* Eh_Oper = (TDBGridEh *)Sender;
TDataSet* ds = Eh_Oper->DataSource->DataSet;
for(int i = 0;i < ds->RecNo;i++)
{
if(SavePlace != NULL)
{
ds->GotoBookmark(SavePlace);
COPY_Bookmark(); // В функцию загнан код копирования
}
}
}[/COLOR]
Если на событие кнопки проверить такой код:
[COLOR=blue]if (Grid_Oper->SelectedRows->Count == 0) return;
COPY_Bookmark(); // В функцию загнан код копирования[/COLOR] код работает и в БД копируются записи, выделенные в Гриде с помощью Grid_OperDrawColumnCell.
{
// Создаем таблицу - приемник
CreateNewTable();
TField *fld = ds->FindField("CardID");
if (!fld) return;
AnsiString sqltext;
ds->GotoBookmark((void *)Grid_Oper->SelectedRows->Items.c_str());
sqltext += ",";
sqltext += fld->AsString;
TADOCommand *cmd = ADOCommand1;
cmd->ParamCheck = true;
cmd->Prepared = false;
cmd->CommandText = AnsiString("") +"\
Insert Into dbo.Load_Bookmark \n\
Select CardID, KodSyst, GostID, NameRD, Sapis, dmhP, Massa, Gruppa,\n\
PlechoX, PlechoY, PlechoZ, Department, Developer, Prozent \n\
From " + CardRef_tv+" \n\
Where CardID in (" + sqltext + ") \n\
";
cmd->Execute();
ModuleLoad->ADOBookmark->SQL->Text = "Select CardID, KodSyst, GostID, NameRD, Sapis, dmhP, Massa, Gruppa,\
PlechoX, PlechoY, PlechoZ, Department, Developer, Prozent, (Massa * Prozent/100) AS MASSA_PR, \
(Massa * Prozent*PlechoX/100) AS MX_PR, (Massa * Prozent*PlechoY/100) AS MY_PR, (Massa * Prozent*PlechoZ/100) AS MZ_PR \
From dbo.Load_Bookmark ";
// просмотреть результат
Grid_Where->DataSource->DataSet = ModuleLoad->ADOBookmark;
Grid_Where->DataSource->DataSet->Active = true;
}
Код проходит без ошибок, но действия не выполняет.
Давайте по порядку.
TBookmark позволяет запоминать позицию и состояние текущей записи таблицы. Как-бы поставить на ней метку (BookMark1 = Table1->DataSet->GetBookmark()). И потом в любой момент времени на эту метку вернутся (Table1->DataSet->GotoBookmark(BookMark1)). Ни какого отношения к Grid она не имеет. Просто вам нужно поставить метки на все записи таблицы, которые удовлетворяют условиям CheckBox. Для этого можно организовать массив меток размерность равной количеству записей в вашей таблице или создать список меток (но это сложнее). При копировании Вашей таблицы в другую Вы должны просмотреть массив этих меток, каждый раз возвращаться к нужной записи (Table1->DataSet->GotoBookmark(BookMark1))и копировать ее в другую таблицу. Аналогом этому являелся список меток SelectedRows в Gride, но для этого списка к сожалению не определен метод Add. Т.Е. вы не можете сами добавлять туда закладки. Именно поэтому приходится их вести самому.
программа останавливается и я не могу проверить код далее.
У меня выскакивает сообщение, что RecNum не является членом TDataSet. Я поначалу поставила RecNo, а теперь по смыслу вижу, что это не верно. Посмотрела по свойствам TDataSet, там нет [COLOR=orangered]RecNum[/COLOR], но и нет ничего подходящего. Кстати и нет [COLOR=orangered]RecCount[/COLOR]. У меня возникает вопрос, Ваш код применителен для 5-го Билдера? В 6-м ничего подобного нет.
Я до копирования не дохожу. На строке программа останавливается и я не могу проверить код далее.
У меня выскакивает сообщение, что RecNum не является членом TDataSet. Я поначалу поставила RecNo, а теперь по смыслу вижу, что это не верно. Посмотрела по свойствам TDataSet, там нет [COLOR=orangered]RecNum[/COLOR], но и нет ничего подходящего. Кстати и нет [COLOR=orangered]RecCount[/COLOR]. У меня возникает вопрос, Ваш код применителен для 5-го Билдера? В 6-м ничего подобного нет.
Свойство называется RecordCount. Простите, что ввел в заблуждение. Спешил и текст не проверил. Кстати корректнее было бы всетаки обрабатывать список меток. Да и памяти меньше это все занимает. К сожалению завал на работе и по этой причине, отлаженный и проверенный код пока предоставить не могу. Но я думаю Вы и сами справитесь.
Пытаюсь рассуждать:
SavePlace = new Tbookmark [Table->RecCount]; //Это мы заводим массив закладок
[/COLOR]. Допустим, таблица открывается, в Гриде 20 строк. Значит, образуются 20 закладок.
Далее нажимаю на ЧекЛистБокс и у меня по Item-у меняют цвет фона, допустим 6 строк, начиная с 5-й строки (RecNo=5). Здесь, начиная с 5-й строки, запоминаются 6 закладок. В событии копирования мне эти закладки нужно вытащить
if(SavePlace != NULL)
{
ds->GotoBookmark(SavePlace);
}}
[/COLOR]. Но на for программа останавливается. RecNo - это первая строка, на которой есть выделение, но не количество выделенных строк. По идее, цикл нужен для выделенных строк, но я же не знаю, сколько их выделено? Вот с этого момента я не могу сдвинуться.
AlexandrVSmirno, спасибо за терпение. Но, видимо, без Вашей помощи не раскрутить. Я понимаю, что такое отсутствие времени, поэтому, торопить не буду. По-возможности, помогите дойти до конца, а я буду периодически посматривать на вопрос.
Пытаюсь рассуждать:[/COLOR]. Допустим, таблица открывается, в Гриде 20 строк. Значит, образуются 20 закладок.
Далее нажимаю на ЧекЛистБокс и у меня по Item-у меняют цвет фона, допустим 6 строк, начиная с 5-й строки (RecNo=5). Здесь, начиная с 5-й строки, запоминаются 6 закладок. В событии копирования мне эти закладки нужно вытащить
[/COLOR]. Но на for программа останавливается. RecNo - это первая строка, на которой есть выделение, но не количество выделенных строк. По идее, цикл нужен для выделенных строк, но я же не знаю, сколько их выделено? Вот с этого момента я не могу сдвинуться.
Я тут набросал небольшой примерчик. Правда у меня RxDBGrid, так что параметры несколько не совпадают ну да ладно. Я использую две TTable отображенные на одну и туже таблицу. Table1 для того чтобы обрабатывать закладки и Table2 для грида. Мои отмеченные закладочки вывожу в Memo (опять же для примера, чтобы наглядно было).
#include <DB.hpp>
#include <DBGrids.hpp>
#include <Grids.hpp>
#include <DBTables.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TCheckListBox *CheckListBox1;
TRxDBGrid *RxDBGrid1;
TDataSource *DataSource1;
TDatabase *Database1;
TTable *Table1;
TMemo *Memo1;
TTable *Table2;
void __fastcall CheckListBox1ClickCheck(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall RxDBGrid1GetCellParams(TObject *Sender, TField *Field,
TFont *AFont, TColor &Background, bool Highlight);
private: // User declarations
public: // User declarations
TList* myBMList; //это и есть список наших закладочек
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//Таперь с-файл
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "RXDBCtrl"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
myBMList = new TList;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CheckListBox1ClickCheck(TObject *Sender)
{
TBookmark curPos = Table1->GetBookmark();
myBMList->Clear();
Table1->First();
while(!Table1->Eof)
{
TBookmark curBM = Table1->GetBookmark();
for(int i = 0;i < CheckListBox1->Count;i++)
{
if(CheckListBox1->Checked)
{
if(Table1->FieldByName("FAlpha")->AsString == CheckListBox1->Items->Strings)
{
myBMList->Add(curBM); //запоминаем закладку
}
}
}
Table1->Next();
}
//а это с понтом копирование
Memo1->Lines->Clear();
for(int i = 0; i < myBMList->Count;i++)
{
Table1->GotoBookmark(myBMList->Items);
Memo1->Lines->Add(Table1->FieldByName("FName")->AsString);
}
//-------
Table1->GotoBookmark(curPos);
Table1->FreeBookmark(curPos);
RxDBGrid1->Refresh();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
myBMList->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
delete myBMList;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RxDBGrid1GetCellParams(TObject *Sender,
TField *Field, TFont *AFont, TColor &Background, bool Highlight)
{
for(int i = 0;i < CheckListBox1->Count;i++)
{
if(CheckListBox1->Checked)
if(Table2->FieldByName("FAlpha")->AsString == CheckListBox1->Items->Strings)
Background = clGreen;
}
}
//---------------------------------------------------------------------------
ЗЫ: Таблица состоит из двух полей:
FName - Фамилия
FAlpha - первая буква фамилии
а CheckListBox1 - русский алфавит.
richel, а не могла бы ты выложить полностью весь код своей проги, охота посмотреть, тоже занимаюсь подобным, но че-то ничего не получается, хоть глянуть, синтаксис и т.д.
Весь не могу. Не из жадности. Я пытаюсь автоматизировать основной расчет при проектировании судна, который на протяжении существования кораблестроения так никто не заалгоритмировал. Я уже сделала 2/3 программы, оан настолько обширная, что если бы сама не была в недалеком прошлом специалистом в этой области, уже бы и не вспомнила, что наворочала.
Сейчас конкретная задача такая: есть таблица с огромным количеством данных, которые отображаются в Гриде. Нужно иметь возможность выделения большого количества строк (смена цвета фона и шрифта), удовлетворяющих критерию Итема компонента ЧекЛистБокса, и одновременно с этим, выделения по одной строке в любом месте Грида. Так же хотелось бы иметь возможность отмены выделений (вдруг ошибочно выделила). Затем все строки, окрашенные в другой фон и цвет шрифта скопировать в другую таблицу (таблицу-приемник).
В решении окрашивания по Итему AlexandrVSmirno мне оч-е-нь помог. Копирование одиночных строк тоже получилось, так как можно задать условие, если строки являются выделенными
а вот с последней задачей пока не удалось справиться. На данный момент разбираюсь с последним примером, который выложил AlexandrVSmirno. Он у меня получился. Но там принцип немного другой. Пытаюсь применить пример к своей задаче.
Поэтому прошу сообщить, что конкретно интересует? И лучше сообщить e-mail, может придется выкладывать большой код. И еще маленький организационный момент: приболела, работаю дома. Интернет постоянно обрывается, как- будто сижу в тайге. И очень долго грузится. Время сжирает, а толку мало. Моя помощь может растянуться.
а вот с последней задачей пока не удалось справиться. На данный момент разбираюсь с последним примером, который выложил AlexandrVSmirno. Он у меня получился. Но там принцип немного другой. Пытаюсь применить пример к своей задаче.
Поэтому прошу сообщить, что конкретно интересует? И лучше сообщить e-mail, может придется выкладывать большой код. И еще маленький организационный момент: приболела, работаю дома. Интернет постоянно обрывается, как- будто сижу в тайге. И очень долго грузится. Время сжирает, а толку мало. Моя помощь может растянуться.
Что я имел ввиду:
Если пльзователь выделяет строку в таблице, используя мышь, то внутренними методами grid этто выделение добавляется в SelectedRows, но к сожалению борланд не дал возможности программно туда что либо добавить. SelectedRows можно только читать или очистить. Для CheckListBox я навесил сверху такой же список, только веду его уже сам. Поэтому при копировании необходимо обрабатывать сначала SelectedRows, а затем еще и этот список. В результате мы захватим и то, что пользователь выделил в grid и то что выделил через CheckListBox.
ЗЫ: Желаю скорого выздоровления и с праздником - Днем св. Валентина.
Наверное, Святой Валентин помог мне разобраться в Вашем коде и наставил меня на путь истинный. Поэтому, задача, которую я муссирую уже недели три (такого еще не было), наконец решена была еще вчера. Об этом я пыталась уведомить заинтересованные массы, но страничка форума так и не открылась.
Отдаю себе отчет, что без Вашей помощи мне было бы не разобраться. Хорошо, что есть форумы, а в них - бескорыстные специалисты, ибо не представляю, как без отсутствия литературы и без курсов можно все это освоить. Но, к счастью, уже немало сделала серьезных вещей. Но Билдер бездонен. Еще учиться и учиться...
Очень Вам благодарна.
А для Baracus-а выкладываю готовый кусочек программы, который я отрабатывала отдельно. Если что не понятно, готова продолжить общение.
А вообще, дома почему-то лучше думается.;)
PS: Что-то я не поняла, а что, нет возможности прикрепить файл? Тогда только могу прислать по e-mail.
Спасибо за поздравления, Alexandr!:) Вы очень внимательны. Это приятно.
Наверное, Святой Валентин помог мне разобраться в Вашем коде и наставил меня на путь истинный. Поэтому, задача, которую я муссирую уже недели три (такого еще не было), наконец решена была еще вчера. Об этом я пыталась уведомить заинтересованные массы, но страничка форума так и не открылась.
Отдаю себе отчет, что без Вашей помощи мне было бы не разобраться. Хорошо, что есть форумы, а в них - бескорыстные специалисты, ибо не представляю, как без отсутствия литературы и без курсов можно все это освоить. Но, к счастью, уже немало сделала серьезных вещей. Но Билдер бездонен. Еще учиться и учиться...
Очень Вам благодарна.
А для Baracus-а выкладываю готовый кусочек программы, который я отрабатывала отдельно. Если что не понятно, готова продолжить общение.
А вообще, дома почему-то лучше думается.;)
PS: Что-то я не поняла, а что, нет возможности прикрепить файл? Тогда только могу прислать по e-mail.
Поздравляю с победой. Так держать. А дома лучше думается потому, что тишина и кофе всегда под рукой. Ну и покурить можно, если кто курящий.
А для Baracus-а выкладываю готовый кусочек программы, который я отрабатывала отдельно. Если что не понятно, готова продолжить общение.
А вообще, дома почему-то лучше думается.;)
PS: Что-то я не поняла, а что, нет возможности прикрепить файл? Тогда только могу прислать по e-mail.
Мое мыло mr.prezident[собака]mail.ru
Заранее большое спасибо:)