Господа, а как поменять цвет фона под текстом в новом RichEditControl-е ?
» Использование DevExpress (часть 4)
Цитата:
Господа, а как поменять цвет фона под текстом в новом RichEditControl-е ?
В новом, это в каком?
Если у девок то вроде через Style.Color было.
Mic777
1. TdxRichEditControl
2. не цвет общего фона контрола, а цвет фона под текстом
Добавлено:
Так же вопрос как у это рича сделать вставку таблицы, или это ещё не прикручено ? ... просто хэлпа нету вот и непонятки с этим делом.
1. TdxRichEditControl
2. не цвет общего фона контрола, а цвет фона под текстом
Добавлено:
Так же вопрос как у это рича сделать вставку таблицы, или это ещё не прикручено ? ... просто хэлпа нету вот и непонятки с этим делом.
сам себе отвечу
uses dxRichEdit.Commands.ChangeProperties, dxRichEdit.Platform.Win.Control, dxRichEdit.Control, dxRichEdit.Commands,
Цвет бэкграунда фона:
var
AChangeFontBackColorCommand: TdxChangeFontBackColorCommand;
AState: IdxValueBasedCommandUIState<TColor>;
begin
AChangeFontBackColorCommand := TdxChangeFontBackColorCommand.Create(dxRichEditControl1);
try
AState := AChangeFontBackColorCommand.CreateDefaultCommandUIState as IdxValueBasedCommandUIState<TColor>;
AState.Value :=clRed;
AChangeFontBackColorCommand.ForceExecute(AState);
finally
AChangeFontBackColorCommand.Free;
end;
цвет фона:
var
AChangeFontColorCommand: TdxChangeFontColorCommand;
AState: IdxValueBasedCommandUIState<TColor>;
begin
AChangeFontColorCommand := TdxChangeFontColorCommand.Create(dxRichEditControl1);
try
AState := AChangeFontColorCommand.CreateDefaultCommandUIState as IdxValueBasedCommandUIState<TColor>;
AState.Value := clBlue;
AChangeFontColorCommand.ForceExecute(AState);
finally
AChangeFontColorCommand.Free;
end;
uses dxRichEdit.Commands.ChangeProperties, dxRichEdit.Platform.Win.Control, dxRichEdit.Control, dxRichEdit.Commands,
Цвет бэкграунда фона:
var
AChangeFontBackColorCommand: TdxChangeFontBackColorCommand;
AState: IdxValueBasedCommandUIState<TColor>;
begin
AChangeFontBackColorCommand := TdxChangeFontBackColorCommand.Create(dxRichEditControl1);
try
AState := AChangeFontBackColorCommand.CreateDefaultCommandUIState as IdxValueBasedCommandUIState<TColor>;
AState.Value :=clRed;
AChangeFontBackColorCommand.ForceExecute(AState);
finally
AChangeFontBackColorCommand.Free;
end;
цвет фона:
var
AChangeFontColorCommand: TdxChangeFontColorCommand;
AState: IdxValueBasedCommandUIState<TColor>;
begin
AChangeFontColorCommand := TdxChangeFontColorCommand.Create(dxRichEditControl1);
try
AState := AChangeFontColorCommand.CreateDefaultCommandUIState as IdxValueBasedCommandUIState<TColor>;
AState.Value := clBlue;
AChangeFontColorCommand.ForceExecute(AState);
finally
AChangeFontColorCommand.Free;
end;
G787
Может и мне ответите
У Вас dxRichEditControlRSхх.dpk в 64 бита откомпилировался?
А то у меня пишет "Fatal: F2600 Too many sections in ELF object dxRichEdit.DocumentModel.PieceTable when writing E:\OutBDS\XE7\win64\BPL\dxRichEditControlRS17.a".
Если компилится сбросьте конфигурационные файлы, может дело в них.
Или может знаете как с этим бороться?
Может и мне ответите
У Вас dxRichEditControlRSхх.dpk в 64 бита откомпилировался?
А то у меня пишет "Fatal: F2600 Too many sections in ELF object dxRichEdit.DocumentModel.PieceTable when writing E:\OutBDS\XE7\win64\BPL\dxRichEditControlRS17.a".
Если компилится сбросьте конфигурационные файлы, может дело в них.
Или может знаете как с этим бороться?
Цитата:
При 5 на конце результат округления не определен
Хм...как я помню из школьного курса пятерка округляет в большую сторону...или буржуи живут по другим законам? )))
Цитата:
В таблице, где есть колонка с деньгами, данные в этой колонке не должны содержать больше 2-х знаков после запятой. Если это не соблюдать, то при различных манипуляциях с этими данными Вас ждет очень много неприятных моментов, чего деньги очень не любят
Абсолютно согласен, но бывают не частые случаи когда официальный документ (например товарная накладная) содержит аж до 7 знаков после запятой...я даже такой суммы не знаю...нанокопейка какая-то )) По бухгалтерии ничего не сделаешь...должно быть как в документе и точка!
russko
Цитата:
Да, да и не только буржуи. Посмотрите во многих современных калькуляторах есть даже переключатель округлять вверх или вниз.
А вообще это давняя проблема и решается всегда в рамках практической задачи.
Советую почитать: __http://www.delphikingdom.com/asp/viewitem.asp?catalogID=1217
и __http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374
Там и насчет "помню из школьного курса" есть:
"...Чтобы его не обвинили в личных пристрастиях, критерием стала цифра перед пятеркой — если она четная, то округление вниз, иначе вверх. Это правило и называется правилом "Бухгалтерского" (или "Банковского") округления."
Цитата:
Хм...как я помню из школьного курса пятерка округляет в большую сторону...или буржуи живут по другим законам? )))
Да, да и не только буржуи. Посмотрите во многих современных калькуляторах есть даже переключатель округлять вверх или вниз.
А вообще это давняя проблема и решается всегда в рамках практической задачи.
Советую почитать: __http://www.delphikingdom.com/asp/viewitem.asp?catalogID=1217
и __http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374
Там и насчет "помню из школьного курса" есть:
"...Чтобы его не обвинили в личных пристрастиях, критерием стала цифра перед пятеркой — если она четная, то округление вниз, иначе вверх. Это правило и называется правилом "Бухгалтерского" (или "Банковского") округления."
Mic777
Спасибо, почитал пару статеек на тему банковского округления...просветился.
Странно, что экономисты и тем более бухгалтерия о таких вещах даже не слышала, пойду вразумлю неразумных)
Спасибо, почитал пару статеек на тему банковского округления...просветился.
Странно, что экономисты и тем более бухгалтерия о таких вещах даже не слышала, пойду вразумлю неразумных)
russko
Боюсь вразумить не получится, а вот спросить как вы хотите чтобы было посчитано можно.
Потому как: "Поэтому бухгалтеры нередко берут расчетную ведомость, и, как сказал классик, "ейною мордою начинают мне в харю тыкать". А проблема не касается ни машинной арифметики, ни алгоритма округления. Сформулировать ее можно так: если трое договорились делить доход поровну, а заработали 10 копеек, то как быть с лишней копейкой?
Правильный ответ — решить этот вопрос должна сама бухгалтерия."
Боюсь вразумить не получится, а вот спросить как вы хотите чтобы было посчитано можно.
Потому как: "Поэтому бухгалтеры нередко берут расчетную ведомость, и, как сказал классик, "ейною мордою начинают мне в харю тыкать". А проблема не касается ни машинной арифметики, ни алгоритма округления. Сформулировать ее можно так: если трое договорились делить доход поровну, а заработали 10 копеек, то как быть с лишней копейкой?
Правильный ответ — решить этот вопрос должна сама бухгалтерия."
V1s1ter
64, битную не ставил
судя по тому, что пишут на офф сайте девок, RichEditControl ещё очень сырой, а более менее внятная версия ожидается в пакете девок v2015
64, битную не ставил
судя по тому, что пишут на офф сайте девок, RichEditControl ещё очень сырой, а более менее внятная версия ожидается в пакете девок v2015
[more] Помогите с вопросом связанным с cxgrid.
Есть грид с датасетом и 6 колонками.
Регион, Объект, Объем, объем реализации, размещение и территориальная принадлежность.
Вроде все правильно, гружу данные из эксель файла, у колонок тип задаю числовой.
Но когда цикл доходит до значения 1 строки столбца Объем возникает ошибка:"Could not convert variant of type (Dispatch) into type integer" В чем может быть проблема? В данных Excel уверен, пробую на маленьком объеме строк(2 ).
procedure TFormListOBJ_REQ.dxBarButton17Click(Sender: TObject);
const
xlCellTypeLastCell = $0000000B;
//Тип последней заполненной ячейки
var
XLApp, Sheet: OLEVariant;
RangeMatrix: Variant;
x,y,iColIndex, iRowIndex: integer;
XLSFile: string;
begin
XLSFile:='C:\Documents and Settings\EPlan\Рабочий стол\21.xls';
//Создаем объект Excel
XLApp := CreateOleObject('Excel.Application');
try
//Делаем окно Excel невидимым
XLApp.Visible := True;
//Открываем Excel
XLApp.Workbooks.Open(XLSFile);
//Создаем объект страница(Sheet)
//и указываем номер листа в книги с которого будем осуществлять чтение
Sheet := XLApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1];
//активируем последнюю ячейку на листе
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
//получаем номер последней строки
x := Sheet.UsedRange.Rows.Count;
//получаем номер последнего столбца
y := Sheet.UsedRange.Columns.Count;
//устанавливаем количество столбцов в CxGrid
showmessage('Строк '+IntToStr(x)+' Стоблцов '+IntToStr(y));
with ViewList.DataController do
begin
// BeginUpdate;
// try
RecordCount := XLApp.ActiveCell.Row;
for iRowIndex := 0 to x-1 do
for iColIndex := 0 to y-1 do
begin
showmessage(Sheet.Cells[iRowIndex+1,iColIndex+1]) ;
Values[iRowIndex, iColIndex] := Sheet.Cells[iRowIndex+1,iColIndex+1];
ViewList.Columns[0].DataBinding.ValueType := 'String';
ViewList.Columns[1].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[2].DataBinding.ValueTypeClass := TcxIntegerValueType;
ViewList.Columns[3].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[4].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[5].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[6].DataBinding.ValueTypeClass := TcxStringValueType;
end
// finally z
// EndUpdate;
// end;
end;
finally
if not VarIsEmpty(XLApp) then
begin
XLApp.Quit;
XLAPP := Unassigned;
Sheet := Unassigned;
end;
end;
end; [/more]
Есть грид с датасетом и 6 колонками.
Регион, Объект, Объем, объем реализации, размещение и территориальная принадлежность.
Вроде все правильно, гружу данные из эксель файла, у колонок тип задаю числовой.
Но когда цикл доходит до значения 1 строки столбца Объем возникает ошибка:"Could not convert variant of type (Dispatch) into type integer" В чем может быть проблема? В данных Excel уверен, пробую на маленьком объеме строк(2 ).
procedure TFormListOBJ_REQ.dxBarButton17Click(Sender: TObject);
const
xlCellTypeLastCell = $0000000B;
//Тип последней заполненной ячейки
var
XLApp, Sheet: OLEVariant;
RangeMatrix: Variant;
x,y,iColIndex, iRowIndex: integer;
XLSFile: string;
begin
XLSFile:='C:\Documents and Settings\EPlan\Рабочий стол\21.xls';
//Создаем объект Excel
XLApp := CreateOleObject('Excel.Application');
try
//Делаем окно Excel невидимым
XLApp.Visible := True;
//Открываем Excel
XLApp.Workbooks.Open(XLSFile);
//Создаем объект страница(Sheet)
//и указываем номер листа в книги с которого будем осуществлять чтение
Sheet := XLApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1];
//активируем последнюю ячейку на листе
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
//получаем номер последней строки
x := Sheet.UsedRange.Rows.Count;
//получаем номер последнего столбца
y := Sheet.UsedRange.Columns.Count;
//устанавливаем количество столбцов в CxGrid
showmessage('Строк '+IntToStr(x)+' Стоблцов '+IntToStr(y));
with ViewList.DataController do
begin
// BeginUpdate;
// try
RecordCount := XLApp.ActiveCell.Row;
for iRowIndex := 0 to x-1 do
for iColIndex := 0 to y-1 do
begin
showmessage(Sheet.Cells[iRowIndex+1,iColIndex+1]) ;
Values[iRowIndex, iColIndex] := Sheet.Cells[iRowIndex+1,iColIndex+1];
ViewList.Columns[0].DataBinding.ValueType := 'String';
ViewList.Columns[1].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[2].DataBinding.ValueTypeClass := TcxIntegerValueType;
ViewList.Columns[3].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[4].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[5].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[6].DataBinding.ValueTypeClass := TcxStringValueType;
end
// finally z
// EndUpdate;
// end;
end;
finally
if not VarIsEmpty(XLApp) then
begin
XLApp.Quit;
XLAPP := Unassigned;
Sheet := Unassigned;
end;
end;
end; [/more]
bigrunner1
а данные экселя можно глянуть?
Добавлено:
bigrunner1
и тут:
"Values[iRowIndex, iColIndex] := Sheet.Cells[iRowIndex+1,iColIndex+1];
ViewList.Columns[0].DataBinding.ValueType := 'String';
ViewList.Columns[1].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[2].DataBinding.ValueTypeClass := TcxIntegerValueType;
ViewList.Columns[3].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[4].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[5].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[6].DataBinding.ValueTypeClass := TcxStringValueType;
"
зачем в цикле каждый раз определять тип данных, почему это не сделать один раз
к тому же получается сначала присваиваешь Value, а потом только задаешь тип
а что будет если колонка вообще не заполнена = null, а тип уже задан в Integer?
а данные экселя можно глянуть?
Добавлено:
bigrunner1
и тут:
"Values[iRowIndex, iColIndex] := Sheet.Cells[iRowIndex+1,iColIndex+1];
ViewList.Columns[0].DataBinding.ValueType := 'String';
ViewList.Columns[1].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[2].DataBinding.ValueTypeClass := TcxIntegerValueType;
ViewList.Columns[3].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[4].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[5].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[6].DataBinding.ValueTypeClass := TcxStringValueType;
"
зачем в цикле каждый раз определять тип данных, почему это не сделать один раз
к тому же получается сначала присваиваешь Value, а потом только задаешь тип
а что будет если колонка вообще не заполнена = null, а тип уже задан в Integer?
Липецкая область Обьект1 150 0 0 Мелкий опт
Ростовская область Обьект2 0 0 0 Розница
Добавлено:
Тут конечно согласен, не учел. Проверка на null нужна.
Добавлено:
Убрал задание типов,до цикла, результат тотже. Ругается на тип Dispatch
Ростовская область Обьект2 0 0 0 Розница
Добавлено:
Тут конечно согласен, не учел. Проверка на null нужна.
Добавлено:
Убрал задание типов,до цикла, результат тотже. Ругается на тип Dispatch
bigrunner1
я б делал не проверкой, а функцией конвертации - если тебе нужны для какой-то колонки только числовые данные то и получай их уже через функцию
ну к примеру типа такой:
function VarToInt(const AValue: Variant): Integer;
begin
Result := StrToIntDef(VarToStrDef(AValue, EmptyStr), 0);
end;
ну и это:
ViewList.Columns[0].DataBinding.ValueType := 'String';
ViewList.Columns[1].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[2].DataBinding.ValueTypeClass := TcxIntegerValueType;
ViewList.Columns[3].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[4].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[5].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[6].DataBinding.ValueTypeClass := TcxStringValueType;
вообще б убрал.
мне кажется будет работать прекрасно и без него.
Добавлено:
bigrunner1
Ровненько твой код только закоментил то, что говорил
работает без проверки на null, если заполнены все ячейки.
Проверил только что на Delphi 2010 / DevExpress 12.2.10
[more]
procedure TForm1.Button1Click(Sender: TObject);
const
xlCellTypeLastCell = $0000000B;
//Тип последней заполненной ячейки
var
XLApp, Sheet: OLEVariant;
RangeMatrix: Variant;
x,y,iColIndex, iRowIndex: integer;
XLSFile: string;
begin
XLSFile:='D:\12.xlsx';
//Создаем объект Excel
XLApp := CreateOleObject('Excel.Application');
try
//Делаем окно Excel невидимым
XLApp.Visible := True;
//Открываем Excel
XLApp.Workbooks.Open(XLSFile);
//Создаем объект страница(Sheet)
//и указываем номер листа в книги с которого будем осуществлять чтение
Sheet := XLApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1];
//активируем последнюю ячейку на листе
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
//получаем номер последней строки
x := Sheet.UsedRange.Rows.Count;
//получаем номер последнего столбца
y := Sheet.UsedRange.Columns.Count;
//устанавливаем количество столбцов в CxGrid
showmessage('Строк '+IntToStr(x)+' Стоблцов '+IntToStr(y));
with ViewList.DataController do
begin
// BeginUpdate;
// try
RecordCount := XLApp.ActiveCell.Row;
for iRowIndex := 0 to x-1 do
for iColIndex := 0 to y-1 do
begin
showmessage(Sheet.Cells[iRowIndex+1,iColIndex+1]) ;
Values[iRowIndex, iColIndex] := Sheet.Cells[iRowIndex+1,iColIndex+1];
{ViewList.Columns[0].DataBinding.ValueType := 'String';
ViewList.Columns[1].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[2].DataBinding.ValueTypeClass := TcxIntegerValueType;
ViewList.Columns[3].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[4].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[5].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[6].DataBinding.ValueTypeClass := TcxStringValueType;}
end
// finally z
// EndUpdate;
// end;
end;
finally
if not VarIsEmpty(XLApp) then
begin
XLApp.Quit;
XLAPP := Unassigned;
Sheet := Unassigned;
end;
end;
end;
[/more]
я б делал не проверкой, а функцией конвертации - если тебе нужны для какой-то колонки только числовые данные то и получай их уже через функцию
ну к примеру типа такой:
function VarToInt(const AValue: Variant): Integer;
begin
Result := StrToIntDef(VarToStrDef(AValue, EmptyStr), 0);
end;
ну и это:
ViewList.Columns[0].DataBinding.ValueType := 'String';
ViewList.Columns[1].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[2].DataBinding.ValueTypeClass := TcxIntegerValueType;
ViewList.Columns[3].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[4].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[5].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[6].DataBinding.ValueTypeClass := TcxStringValueType;
вообще б убрал.
мне кажется будет работать прекрасно и без него.
Добавлено:
bigrunner1
Ровненько твой код только закоментил то, что говорил
работает без проверки на null, если заполнены все ячейки.
Проверил только что на Delphi 2010 / DevExpress 12.2.10
[more]
procedure TForm1.Button1Click(Sender: TObject);
const
xlCellTypeLastCell = $0000000B;
//Тип последней заполненной ячейки
var
XLApp, Sheet: OLEVariant;
RangeMatrix: Variant;
x,y,iColIndex, iRowIndex: integer;
XLSFile: string;
begin
XLSFile:='D:\12.xlsx';
//Создаем объект Excel
XLApp := CreateOleObject('Excel.Application');
try
//Делаем окно Excel невидимым
XLApp.Visible := True;
//Открываем Excel
XLApp.Workbooks.Open(XLSFile);
//Создаем объект страница(Sheet)
//и указываем номер листа в книги с которого будем осуществлять чтение
Sheet := XLApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1];
//активируем последнюю ячейку на листе
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
//получаем номер последней строки
x := Sheet.UsedRange.Rows.Count;
//получаем номер последнего столбца
y := Sheet.UsedRange.Columns.Count;
//устанавливаем количество столбцов в CxGrid
showmessage('Строк '+IntToStr(x)+' Стоблцов '+IntToStr(y));
with ViewList.DataController do
begin
// BeginUpdate;
// try
RecordCount := XLApp.ActiveCell.Row;
for iRowIndex := 0 to x-1 do
for iColIndex := 0 to y-1 do
begin
showmessage(Sheet.Cells[iRowIndex+1,iColIndex+1]) ;
Values[iRowIndex, iColIndex] := Sheet.Cells[iRowIndex+1,iColIndex+1];
{ViewList.Columns[0].DataBinding.ValueType := 'String';
ViewList.Columns[1].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[2].DataBinding.ValueTypeClass := TcxIntegerValueType;
ViewList.Columns[3].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[4].DataBinding.ValueTypeClass := TcxFloatValueType;
ViewList.Columns[5].DataBinding.ValueTypeClass := TcxStringValueType;
ViewList.Columns[6].DataBinding.ValueTypeClass := TcxStringValueType;}
end
// finally z
// EndUpdate;
// end;
end;
finally
if not VarIsEmpty(XLApp) then
begin
XLApp.Quit;
XLAPP := Unassigned;
Sheet := Unassigned;
end;
end;
end;
[/more]
MagistrAnatol
Думаю можно.
У них есть интересный компонент, позволяющий вызвать форму, описывающую условия фильтра.
Можно задавать не только равенство, но и вхождение строки, сравнение на больше меньше и т.п.
Причем для разных типов полей будут свои операции сравнения.
Компоненты TcxFilterControl и TcxDBFilterControl.
Почитать можно в хелпе.
Есть для наживки статья на хабре: __http://habrahabr.ru/post/84277/
Такой же механизм используется в фильтре грида.
Добавлено:
А надо ли вообще фильтр?
Насколько я понял из скрина - там везде мастер-детал зависимость - фильтр будет громоздким решением, имхо.
По быстрому, навскидку, можно грид прикрутить многоуровневый или пару (чтобы не сильно много вложений было).
Думаю можно.
У них есть интересный компонент, позволяющий вызвать форму, описывающую условия фильтра.
Можно задавать не только равенство, но и вхождение строки, сравнение на больше меньше и т.п.
Причем для разных типов полей будут свои операции сравнения.
Компоненты TcxFilterControl и TcxDBFilterControl.
Почитать можно в хелпе.
Есть для наживки статья на хабре: __http://habrahabr.ru/post/84277/
Такой же механизм используется в фильтре грида.
Добавлено:
А надо ли вообще фильтр?
Насколько я понял из скрина - там везде мастер-детал зависимость - фильтр будет громоздким решением, имхо.
По быстрому, навскидку, можно грид прикрутить многоуровневый или пару (чтобы не сильно много вложений было).
Плохо видно картинку, но уверен, что можно
MagistrAnatol
ну тут на картинке по идее 4 штуки TcxGrid с checkColumn, в коде видимость/невидимость проставляется и фильтрация там же
З.Ы.
вот интересно, если выбраны, как на картинке дома 1 и 2 - ведь у каждого будет квартира №1
или если выбрать 2 населенных пункта и у каждого улица Ленина - что будет
ну тут на картинке по идее 4 штуки TcxGrid с checkColumn, в коде видимость/невидимость проставляется и фильтрация там же
З.Ы.
вот интересно, если выбраны, как на картинке дома 1 и 2 - ведь у каждого будет квартира №1
или если выбрать 2 населенных пункта и у каждого улица Ленина - что будет
ant0ni02004
ну по существующей структуре базы у каждого населенного пункта свои улицы, то есть теоретически в таблице улиц может быть 100 улиц Ленина.
Ето фильтр отбора абонентов по адресному признаку - город/улица - мастер-датайл - каждый абонент привязан к улице, у каждого абонента свой дом-квартира.
Так что запрос отрабатывает корректно .
Просто я думал что у девок есть похожие готовые панельки фильтров, а через гриды немного придется посношаться с временными таблицами.
ну по существующей структуре базы у каждого населенного пункта свои улицы, то есть теоретически в таблице улиц может быть 100 улиц Ленина.
Ето фильтр отбора абонентов по адресному признаку - город/улица - мастер-датайл - каждый абонент привязан к улице, у каждого абонента свой дом-квартира.
Так что запрос отрабатывает корректно .
Просто я думал что у девок есть похожие готовые панельки фильтров, а через гриды немного придется посношаться с временными таблицами.
Не работал ли кто с TdxSpreadSheet - как получить доступ к значениям конкретной ячейки, блин облазил всю сеть доки ноль, шляпа эпическая какая то, версия Дев 2014.2.2
Andryshok
cxSpreadSheet1.Sheet.GetCellObject(1,2).CellValue
cxSpreadSheet1.Sheet.GetCellObject(1,2).CellValue
exteris нет там такого класса cxSpreadSheet1, я говорю про класс TdxSpreadSheet - у него нет таких методов, в любом случае уже можно забить, вопрос решил обычным TMS ным гридом с XLS адаптером для оного, ибо писать много кода лень (само собой можно было прочитать excel и записать в обычный грид и т.п.), но лень под плевую задачу писать много кода
Помогите допилить фильтр
Код: void __fastcall TfrmOper::AdvMultiButtonEdit2Change(TObject *Sender)
{
if (AdvMultiButtonEdit2->Text!="")
{
V_sprOper->DataController->Filter->BeginUpdate();
TcxFilterCriteriaItemList *AItemList = V_sprOper->DataController->Filter->Root->AddItemList(fboAnd);
AItemList->Criteria->Options>>fcoCaseInsensitive;
AItemList->AddItem(V_sprOperOPER_NAME,foLike,"%"+AdvMultiButtonEdit2->Text+"%","%"+AdvMultiButtonEdit2->Text+"%");
V_sprOper->DataController->Filter->EndUpdate();
V_sprOper->DataController->Filter->Active=true;
}
else
{
V_sprOper->DataController->Filter->BeginUpdate();
V_sprOper->DataController->Filter->RemoveItemByItemLink(V_sprOperOPER_NAME);
V_sprOper->DataController->Filter->EndUpdate();
}
}
Код: void __fastcall TfrmOper::AdvMultiButtonEdit2Change(TObject *Sender)
{
if (AdvMultiButtonEdit2->Text!="")
{
V_sprOper->DataController->Filter->BeginUpdate();
TcxFilterCriteriaItemList *AItemList = V_sprOper->DataController->Filter->Root->AddItemList(fboAnd);
AItemList->Criteria->Options>>fcoCaseInsensitive;
AItemList->AddItem(V_sprOperOPER_NAME,foLike,"%"+AdvMultiButtonEdit2->Text+"%","%"+AdvMultiButtonEdit2->Text+"%");
V_sprOper->DataController->Filter->EndUpdate();
V_sprOper->DataController->Filter->Active=true;
}
else
{
V_sprOper->DataController->Filter->BeginUpdate();
V_sprOper->DataController->Filter->RemoveItemByItemLink(V_sprOperOPER_NAME);
V_sprOper->DataController->Filter->EndUpdate();
}
}
Вот доконал, может кому пригодится
Не пойму почему, но LowerCase и AnsiLowerCase - отрабатывали некорректно
Код: void __fastcall TfrmOper::AdvMultiButtonEdit2Change(TObject *Sender)
{
String txtToFind=AnsiUpperCase(AdvMultiButtonEdit2->Text);
V_sprOper->Invalidate(true);
if (txtToFind!="")
{
V_sprOper->DataController->Filter->BeginUpdate();
TcxFilterCriteriaItemList *AItemList = V_sprOper->DataController->Filter->Root->AddItemList(fboAnd);
AItemList->Criteria->Options>>fcoCaseInsensitive;
AItemList->AddItem(V_sprOperOPER_NAME,foLike,"%"+txtToFind+"%","%"+txtToFind+"%");
V_sprOper->DataController->Filter->EndUpdate();
V_sprOper->DataController->Filter->Active=true;
}
else
{
V_sprOper->DataController->Filter->BeginUpdate();
V_sprOper->DataController->Filter->RemoveItemByItemLink(V_sprOperOPER_NAME);
V_sprOper->DataController->Filter->EndUpdate();
}
txtToFind=NULL;
}
//---------------------------------------------------------------------------
void __fastcall TfrmOper::V_sprOperOPER_NAMECustomDrawCell(TcxCustomGridTableView *Sender,
TcxCanvas *ACanvas, TcxGridTableDataCellViewInfo *AViewInfo,
bool &ADone)
{
TRect ARect, ATextToDrawRect;
String ACellText, ASearchText, ATextToDraw;
int ACol;
int i, iStart;
ACol = AViewInfo->Item->Index;
ACanvas->Canvas->Brush->Style = bsSolid;
ACanvas->Canvas->FillRect(AViewInfo->Bounds);
ACellText = AViewInfo->GridRecord->DisplayTexts[0];
ATextToDraw = ACellText;
ASearchText = AdvMultiButtonEdit2->Text;
ARect = AViewInfo->TextAreaBounds;
iStart = Pos(AnsiUpperCase(ASearchText), AnsiUpperCase(ACellText));
if (ASearchText.Length() > 0 && iStart > 0)
{
// Draw pre-matched text
ATextToDrawRect = ARect;
ATextToDraw = ACellText.SubString(1, iStart - 1);
if (ATextToDraw != "" )
{
ATextToDrawRect.Right = ATextToDrawRect.Left + ACanvas->TextWidth(ATextToDraw);
SetBkMode(ACanvas->Handle, TRANSPARENT);
ACanvas->Font->Assign(AViewInfo->Style->Font);
ACanvas->FillRect(ATextToDrawRect);
ACanvas->DrawTexT(ATextToDraw, ATextToDrawRect, DT_LEFT);
ATextToDrawRect.Left = ATextToDrawRect.Right;
}
// Draw matched text
ATextToDraw = ACellText.SubString(iStart, ASearchText.Length());
ACanvas->Font->Color = clWhite;
ACanvas->Brush->Color = clGreen;//clBlue;
ACanvas->Font->Style=TFontStyles()<<fsBold;
ATextToDrawRect.Right = ATextToDrawRect.Left + ACanvas->TextWidth(ATextToDraw);
ACanvas->FillRect(ATextToDrawRect);
ACanvas->DrawTexT(ATextToDraw, ATextToDrawRect, DT_LEFT);
// Prepare post-matched text
ATextToDrawRect.Left = ATextToDrawRect.Right;
ATextToDrawRect.Right = ARect.Right;
ARect = ATextToDrawRect;
ATextToDraw = ACellText.SubString(iStart + ASearchText.Length(), ACellText.Length());
}
SetBkMode(ACanvas->Handle, TRANSPARENT);
ACanvas->Font->Assign(AViewInfo->Style->Font);
ACanvas->DrawTexT(ATextToDraw, ARect, 0);
ADone = true;
}
Не пойму почему, но LowerCase и AnsiLowerCase - отрабатывали некорректно
Код: void __fastcall TfrmOper::AdvMultiButtonEdit2Change(TObject *Sender)
{
String txtToFind=AnsiUpperCase(AdvMultiButtonEdit2->Text);
V_sprOper->Invalidate(true);
if (txtToFind!="")
{
V_sprOper->DataController->Filter->BeginUpdate();
TcxFilterCriteriaItemList *AItemList = V_sprOper->DataController->Filter->Root->AddItemList(fboAnd);
AItemList->Criteria->Options>>fcoCaseInsensitive;
AItemList->AddItem(V_sprOperOPER_NAME,foLike,"%"+txtToFind+"%","%"+txtToFind+"%");
V_sprOper->DataController->Filter->EndUpdate();
V_sprOper->DataController->Filter->Active=true;
}
else
{
V_sprOper->DataController->Filter->BeginUpdate();
V_sprOper->DataController->Filter->RemoveItemByItemLink(V_sprOperOPER_NAME);
V_sprOper->DataController->Filter->EndUpdate();
}
txtToFind=NULL;
}
//---------------------------------------------------------------------------
void __fastcall TfrmOper::V_sprOperOPER_NAMECustomDrawCell(TcxCustomGridTableView *Sender,
TcxCanvas *ACanvas, TcxGridTableDataCellViewInfo *AViewInfo,
bool &ADone)
{
TRect ARect, ATextToDrawRect;
String ACellText, ASearchText, ATextToDraw;
int ACol;
int i, iStart;
ACol = AViewInfo->Item->Index;
ACanvas->Canvas->Brush->Style = bsSolid;
ACanvas->Canvas->FillRect(AViewInfo->Bounds);
ACellText = AViewInfo->GridRecord->DisplayTexts[0];
ATextToDraw = ACellText;
ASearchText = AdvMultiButtonEdit2->Text;
ARect = AViewInfo->TextAreaBounds;
iStart = Pos(AnsiUpperCase(ASearchText), AnsiUpperCase(ACellText));
if (ASearchText.Length() > 0 && iStart > 0)
{
// Draw pre-matched text
ATextToDrawRect = ARect;
ATextToDraw = ACellText.SubString(1, iStart - 1);
if (ATextToDraw != "" )
{
ATextToDrawRect.Right = ATextToDrawRect.Left + ACanvas->TextWidth(ATextToDraw);
SetBkMode(ACanvas->Handle, TRANSPARENT);
ACanvas->Font->Assign(AViewInfo->Style->Font);
ACanvas->FillRect(ATextToDrawRect);
ACanvas->DrawTexT(ATextToDraw, ATextToDrawRect, DT_LEFT);
ATextToDrawRect.Left = ATextToDrawRect.Right;
}
// Draw matched text
ATextToDraw = ACellText.SubString(iStart, ASearchText.Length());
ACanvas->Font->Color = clWhite;
ACanvas->Brush->Color = clGreen;//clBlue;
ACanvas->Font->Style=TFontStyles()<<fsBold;
ATextToDrawRect.Right = ATextToDrawRect.Left + ACanvas->TextWidth(ATextToDraw);
ACanvas->FillRect(ATextToDrawRect);
ACanvas->DrawTexT(ATextToDraw, ATextToDrawRect, DT_LEFT);
// Prepare post-matched text
ATextToDrawRect.Left = ATextToDrawRect.Right;
ATextToDrawRect.Right = ARect.Right;
ARect = ATextToDrawRect;
ATextToDraw = ACellText.SubString(iStart + ASearchText.Length(), ACellText.Length());
}
SetBkMode(ACanvas->Handle, TRANSPARENT);
ACanvas->Font->Assign(AViewInfo->Style->Font);
ACanvas->DrawTexT(ATextToDraw, ARect, 0);
ADone = true;
}
MagistrAnatol Не хотите ли выучить тег more , у вас простыни на всю страницу
MagistrAnatol
Цитата:
Цитата:
1)Могу конечно ошибаться, но мне кажется - указав эту опцию Вы никак не сможете напугать оператор like. Насколько известно - like соответствует одноимённому оператору SQL. В его задачи входило не просто определить есть ли такой текст %bla-bla%, а гораздо более - соответствует ли поле определённой маске. Можно писать знак ? можно не ставить % можно написать %1%2% - это не просто есть 1 и 2 - это ещё и 1 идёт перед 2. Когда порядок неважен пишут like %1% and like %2%. Выполняя SQL запрос Вы не можете указать CaseInsensitive, его нет в синтаксисе like и никто Вам приводить строки к верхнему регистру, перед вычислением маски не будет. SQL сервера не знают, что Вам регистр не важен и будут вычислять только с учётом регистра. На месте Девок, я бы это реализовал. Но думаю они боялись шокировать этим пользователей. Никто ведь заранее не предупреждён что опция fcoCaseInsensitive способна повлиять на like. Скорее наоборот - все ожидают, что она никак не влияет. Можно было красиво добавить fcoLikeCaseInsensitive.
2)Очень насторожило что если строка меняется и не пустая, фильтры только добавляются, накапливаются даже в том случае, если в тексте уже вообще не существует ранее добавленного "%"+txtToFind+"%". Так и было задумано?
3)В первой перерисовке где while (Y!=0) возможно Y=0, нигде до этого условия изменения переменной Y я не увидел.
4)Вторая перерисовка где ACellText = AViewInfo->GridRecord->DisplayTexts[0]; я бы реально проверил поставив breakpoint. Незнаю, у Вас можно ставить breakpoint? По идее DisplayTexts[0] я бы понимал как текст нулевой колонки. Какие то гриды умеют рисовать колонку с номером записи либо квадратиком для позиции в гриде. У них нулевая колонка это тот квадратик. У других гридин колонки можно менять местами, когда 0 это позиция, а когда номер колонки я не знаю - тупо проверяю. Если нет брейкпоинтов, можно тупо добавить параметры Pos(AnsiUpperCase(ASearchText), AnsiUpperCase(ACellText)); в отдельную пустую мемку. По идее мы увидим даже все записи, а не только первую которую рисуем. Если событие вызывается на каждую ячейку, то у вас будет дублирование текста нулевой колонки например.
Цитата:
Помогите допилить фильтр
Цитата:
AItemList->Criteria->Options>>fcoCaseInsensitive;
1)Могу конечно ошибаться, но мне кажется - указав эту опцию Вы никак не сможете напугать оператор like. Насколько известно - like соответствует одноимённому оператору SQL. В его задачи входило не просто определить есть ли такой текст %bla-bla%, а гораздо более - соответствует ли поле определённой маске. Можно писать знак ? можно не ставить % можно написать %1%2% - это не просто есть 1 и 2 - это ещё и 1 идёт перед 2. Когда порядок неважен пишут like %1% and like %2%. Выполняя SQL запрос Вы не можете указать CaseInsensitive, его нет в синтаксисе like и никто Вам приводить строки к верхнему регистру, перед вычислением маски не будет. SQL сервера не знают, что Вам регистр не важен и будут вычислять только с учётом регистра. На месте Девок, я бы это реализовал. Но думаю они боялись шокировать этим пользователей. Никто ведь заранее не предупреждён что опция fcoCaseInsensitive способна повлиять на like. Скорее наоборот - все ожидают, что она никак не влияет. Можно было красиво добавить fcoLikeCaseInsensitive.
2)Очень насторожило что если строка меняется и не пустая, фильтры только добавляются, накапливаются даже в том случае, если в тексте уже вообще не существует ранее добавленного "%"+txtToFind+"%". Так и было задумано?
3)В первой перерисовке где while (Y!=0) возможно Y=0, нигде до этого условия изменения переменной Y я не увидел.
4)Вторая перерисовка где ACellText = AViewInfo->GridRecord->DisplayTexts[0]; я бы реально проверил поставив breakpoint. Незнаю, у Вас можно ставить breakpoint? По идее DisplayTexts[0] я бы понимал как текст нулевой колонки. Какие то гриды умеют рисовать колонку с номером записи либо квадратиком для позиции в гриде. У них нулевая колонка это тот квадратик. У других гридин колонки можно менять местами, когда 0 это позиция, а когда номер колонки я не знаю - тупо проверяю. Если нет брейкпоинтов, можно тупо добавить параметры Pos(AnsiUpperCase(ASearchText), AnsiUpperCase(ACellText)); в отдельную пустую мемку. По идее мы увидим даже все записи, а не только первую которую рисуем. Если событие вызывается на каждую ячейку, то у вас будет дублирование текста нулевой колонки например.
Подскажите, можно ли PopUp для cxExtLookupComboBox показать в виде формы?
Цитата:
PopUp для cxExtLookupComboBox
Это какой-то особенный компонент?
Добавлено:
Цитата:
PopUp для cxExtLookupComboBox показать в виде формы
или что означает "в виде формы"?
X11
Немного запарался и написал бред
Есть ли возможность показать раскрывающийся список cxExtLookupComboBox в виде отдельной формы? Скорее всего вряд ли .
Мне лень создавать дополнительную форму с гридом, а поиск в списке cxExtLookupComboBox не совсем удобен.
Немного запарался и написал бред
Есть ли возможность показать раскрывающийся список cxExtLookupComboBox в виде отдельной формы? Скорее всего вряд ли .
Мне лень создавать дополнительную форму с гридом, а поиск в списке cxExtLookupComboBox не совсем удобен.
Ты имеешь ввиду, что нужно показывать сетку в любом месте, а не только там, где лежит cxExtLookupComboBox?
Что мешает написать несколько строк кода по созданию формы? И влепить туда сетку?
Что мешает написать несколько строк кода по созданию формы? И влепить туда сетку?
Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
Предыдущая тема: Помогите пожалуйста с блокировкой клавиатуры и мышки
Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.